ignitify 1.2.1 → 2.0.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/ignitify.cjs CHANGED
@@ -1136,14 +1136,18 @@ function fill(pattern, ...params) {
1136
1136
  if (i !== params.length) throw new Error(`route ${pattern}: takes ${i} parameter(s), given ${params.length}`);
1137
1137
  return out2;
1138
1138
  }
1139
+ function isValidIdempotencyKey(key) {
1140
+ return IDEMPOTENCY_KEY_PATTERN.test(key);
1141
+ }
1139
1142
  function isTerminalRunStatus(status) {
1140
1143
  return TERMINAL_RUN_STATUSES.includes(status);
1141
1144
  }
1142
- var DOT_SEGMENTS, TENANT_ROUTES, KEY_EXPIRED_ERROR, TENANT_PATHS, API_VERSION, API_VERSION_HEADER, CLIENT_FLOOR_HEADER, CLI_VERSION_HEADER, TERMINAL_RUN_STATUSES, init_api_routes = __esm({ "../../packages/contract/api-routes.ts"() {
1145
+ var DOT_SEGMENTS, TENANT_ROUTES, KEY_EXPIRED_ERROR, TENANT_PATHS, API_VERSION, API_VERSION_HEADER, CLIENT_FLOOR_HEADER, RETRY_AFTER_HEADER, CLI_VERSION_HEADER, IDEMPOTENCY_KEY_HEADER, IDEMPOTENT_REPLAYED_HEADER, IDEMPOTENCY_KEY_PATTERN, TERMINAL_RUN_STATUSES, init_api_routes = __esm({ "../../packages/contract/api-routes.ts"() {
1143
1146
  "use strict";
1144
1147
  init_define_IGNITIFY_CLIENT_FILES();
1145
1148
  DOT_SEGMENTS = /* @__PURE__ */ new Set([".", ".."]);
1146
- TENANT_ROUTES = { TASKS: "/tasks", TASK_BY_ID: "/tasks/:id", TASK_DELETION_PREVIEW: "/tasks/:id/deletion-preview", DEPLOYMENTS: "/deployments", DEPLOYMENT_BY_ID: "/deployments/:id", RUNS: "/runs", RUN_BY_ID: "/runs/:id", RUN_CANCEL: "/runs/:id/cancel", WHOAMI: "/whoami", PACKAGE_ADVICE: "/packages/advice", VMS: "/vms", VM_BY_ID: "/vms/:id", HOOKS: "/hooks", TRIGGER: "/hooks/trigger", TRIGGER_HOOK: "/hooks/trigger/:hookId", SECRETS: "/secrets", SECRET_BY_NAME: "/secrets/:name", SCHEDULES: "/schedules", SCHEDULE_BY_ID: "/schedules/:id", USAGE: "/usage", RUN_LOGS: "/runs/:id/logs", DEPLOYMENT_LOGS: "/deployments/:id/logs", DEPLOYMENT_HOOKS: "/deployments/:id/hooks", DEPLOYMENT_NOTIFY: "/deployments/:id/notify", HOOK_BY_ID: "/hooks/:id", READYZ: "/readyz", LIVEZ: "/livez", AUTH_DEVICE: "/auth/device", AUTH_DEVICE_TOKEN: "/auth/device/token", AUTH_KEY: "/auth/key" }, KEY_EXPIRED_ERROR = "API key has expired", TENANT_PATHS = { TASKS: TENANT_ROUTES.TASKS, TASK_BY_ID: (id) => fill(TENANT_ROUTES.TASK_BY_ID, id), TASK_DELETION_PREVIEW: (id) => fill(TENANT_ROUTES.TASK_DELETION_PREVIEW, id), DEPLOYMENTS: TENANT_ROUTES.DEPLOYMENTS, DEPLOYMENT_BY_ID: (id) => fill(TENANT_ROUTES.DEPLOYMENT_BY_ID, id), DEPLOYMENT_LOGS: (id) => fill(TENANT_ROUTES.DEPLOYMENT_LOGS, id), RUNS: TENANT_ROUTES.RUNS, RUN_BY_ID: (id) => fill(TENANT_ROUTES.RUN_BY_ID, id), RUN_CANCEL: (id) => fill(TENANT_ROUTES.RUN_CANCEL, id), RUN_LOGS: (id) => fill(TENANT_ROUTES.RUN_LOGS, id), WHOAMI: TENANT_ROUTES.WHOAMI, PACKAGE_ADVICE: TENANT_ROUTES.PACKAGE_ADVICE, VMS: TENANT_ROUTES.VMS, VM_BY_ID: (id) => fill(TENANT_ROUTES.VM_BY_ID, id), HOOKS: TENANT_ROUTES.HOOKS, TRIGGER: TENANT_ROUTES.TRIGGER, TRIGGER_HOOK: (hookId) => fill(TENANT_ROUTES.TRIGGER_HOOK, hookId), SECRETS: TENANT_ROUTES.SECRETS, SECRET_BY_NAME: (name) => fill(TENANT_ROUTES.SECRET_BY_NAME, name), SCHEDULES: TENANT_ROUTES.SCHEDULES, SCHEDULE_BY_ID: (id) => fill(TENANT_ROUTES.SCHEDULE_BY_ID, id), USAGE: TENANT_ROUTES.USAGE, DEPLOYMENT_HOOKS: (id) => fill(TENANT_ROUTES.DEPLOYMENT_HOOKS, id), DEPLOYMENT_NOTIFY: (id) => fill(TENANT_ROUTES.DEPLOYMENT_NOTIFY, id), HOOK_BY_ID: (id) => fill(TENANT_ROUTES.HOOK_BY_ID, id), READYZ: TENANT_ROUTES.READYZ, LIVEZ: TENANT_ROUTES.LIVEZ, AUTH_DEVICE: TENANT_ROUTES.AUTH_DEVICE, AUTH_DEVICE_TOKEN: TENANT_ROUTES.AUTH_DEVICE_TOKEN, AUTH_KEY: TENANT_ROUTES.AUTH_KEY }, API_VERSION = "1", API_VERSION_HEADER = "X-Api-Version", CLIENT_FLOOR_HEADER = "X-Client-Floor", CLI_VERSION_HEADER = "X-Ignitify-Cli", TERMINAL_RUN_STATUSES = ["COMPLETED", "FAILED", "CANCELLED"];
1149
+ TENANT_ROUTES = { TASKS: "/tasks", TASK_BY_ID: "/tasks/:id", TASK_DELETION_PREVIEW: "/tasks/:id/deletion-preview", DEPLOYMENTS: "/deployments", DEPLOYMENT_BY_ID: "/deployments/:id", RUNS: "/runs", RUN_BY_ID: "/runs/:id", RUN_CANCEL: "/runs/:id/cancel", WHOAMI: "/whoami", PACKAGE_ADVICE: "/packages/advice", VMS: "/vms", VM_BY_ID: "/vms/:id", HOOKS: "/hooks", TRIGGER: "/hooks/trigger", TRIGGER_HOOK: "/hooks/trigger/:hookId", SECRETS: "/secrets", SECRET_BY_NAME: "/secrets/:name", SCHEDULES: "/schedules", SCHEDULE_BY_ID: "/schedules/:id", USAGE: "/usage", USAGE_SERIES: "/usage/series", RUN_LOGS: "/runs/:id/logs", RUN_TIMELINE: "/runs/:id/timeline", RUN_FAILURES: "/runs/failures", DEPLOYMENT_LOGS: "/deployments/:id/logs", DEPLOYMENT_HOOKS: "/deployments/:id/hooks", DEPLOYMENT_NOTIFY: "/deployments/:id/notify", HOOK_BY_ID: "/hooks/:id", READYZ: "/readyz", LIVEZ: "/livez", AUTH_DEVICE: "/auth/device", AUTH_DEVICE_TOKEN: "/auth/device/token", AUTH_KEY: "/auth/key", NOTIFICATIONS: "/notifications", USERS: "/users", USER_BY_ID: "/users/:id", GROUPS: "/groups", GROUP_BY_ID: "/groups/:id", GROUP_PERMISSION: "/groups/:id/permissions/:permission", GROUP_USER: "/groups/:id/users/:user", KEYS: "/keys", KEY_BY_ID: "/keys/:id" }, KEY_EXPIRED_ERROR = "API key has expired", TENANT_PATHS = { TASKS: TENANT_ROUTES.TASKS, TASK_BY_ID: (id) => fill(TENANT_ROUTES.TASK_BY_ID, id), TASK_DELETION_PREVIEW: (id) => fill(TENANT_ROUTES.TASK_DELETION_PREVIEW, id), DEPLOYMENTS: TENANT_ROUTES.DEPLOYMENTS, DEPLOYMENT_BY_ID: (id) => fill(TENANT_ROUTES.DEPLOYMENT_BY_ID, id), DEPLOYMENT_LOGS: (id) => fill(TENANT_ROUTES.DEPLOYMENT_LOGS, id), RUNS: TENANT_ROUTES.RUNS, RUN_BY_ID: (id) => fill(TENANT_ROUTES.RUN_BY_ID, id), RUN_CANCEL: (id) => fill(TENANT_ROUTES.RUN_CANCEL, id), RUN_LOGS: (id) => fill(TENANT_ROUTES.RUN_LOGS, id), RUN_TIMELINE: (id) => fill(TENANT_ROUTES.RUN_TIMELINE, id), RUN_FAILURES: TENANT_ROUTES.RUN_FAILURES, WHOAMI: TENANT_ROUTES.WHOAMI, PACKAGE_ADVICE: TENANT_ROUTES.PACKAGE_ADVICE, VMS: TENANT_ROUTES.VMS, VM_BY_ID: (id) => fill(TENANT_ROUTES.VM_BY_ID, id), HOOKS: TENANT_ROUTES.HOOKS, TRIGGER: TENANT_ROUTES.TRIGGER, TRIGGER_HOOK: (hookId) => fill(TENANT_ROUTES.TRIGGER_HOOK, hookId), SECRETS: TENANT_ROUTES.SECRETS, SECRET_BY_NAME: (name) => fill(TENANT_ROUTES.SECRET_BY_NAME, name), SCHEDULES: TENANT_ROUTES.SCHEDULES, SCHEDULE_BY_ID: (id) => fill(TENANT_ROUTES.SCHEDULE_BY_ID, id), USAGE: TENANT_ROUTES.USAGE, USAGE_SERIES: TENANT_ROUTES.USAGE_SERIES, DEPLOYMENT_HOOKS: (id) => fill(TENANT_ROUTES.DEPLOYMENT_HOOKS, id), DEPLOYMENT_NOTIFY: (id) => fill(TENANT_ROUTES.DEPLOYMENT_NOTIFY, id), HOOK_BY_ID: (id) => fill(TENANT_ROUTES.HOOK_BY_ID, id), READYZ: TENANT_ROUTES.READYZ, LIVEZ: TENANT_ROUTES.LIVEZ, AUTH_DEVICE: TENANT_ROUTES.AUTH_DEVICE, AUTH_DEVICE_TOKEN: TENANT_ROUTES.AUTH_DEVICE_TOKEN, AUTH_KEY: TENANT_ROUTES.AUTH_KEY, NOTIFICATIONS: TENANT_ROUTES.NOTIFICATIONS, USERS: TENANT_ROUTES.USERS, USER_BY_ID: (name) => fill(TENANT_ROUTES.USER_BY_ID, name), GROUPS: TENANT_ROUTES.GROUPS, GROUP_BY_ID: (name) => fill(TENANT_ROUTES.GROUP_BY_ID, name), GROUP_PERMISSION: (name, permission) => fill(TENANT_ROUTES.GROUP_PERMISSION, name, permission), GROUP_USER: (name, user) => fill(TENANT_ROUTES.GROUP_USER, name, user), KEYS: TENANT_ROUTES.KEYS, KEY_BY_ID: (id) => fill(TENANT_ROUTES.KEY_BY_ID, id) }, API_VERSION = "1", API_VERSION_HEADER = "X-Api-Version", CLIENT_FLOOR_HEADER = "X-Client-Floor", RETRY_AFTER_HEADER = "Retry-After", CLI_VERSION_HEADER = "X-Ignitify-Cli", IDEMPOTENCY_KEY_HEADER = "Idempotency-Key", IDEMPOTENT_REPLAYED_HEADER = "Idempotent-Replayed", IDEMPOTENCY_KEY_PATTERN = /^[A-Za-z0-9._:-]{8,255}$/;
1150
+ TERMINAL_RUN_STATUSES = ["COMPLETED", "FAILED", "CANCELLED"];
1147
1151
  } });
1148
1152
  var CALLBACK_PATH_PREFIX, init_callback_path = __esm({ "../../packages/contract/callback-path.ts"() {
1149
1153
  "use strict";
@@ -1158,11 +1162,22 @@ var init_limits = __esm({ "../../packages/contract/limits.ts"() {
1158
1162
  "use strict";
1159
1163
  init_define_IGNITIFY_CLIENT_FILES();
1160
1164
  } });
1165
+ var init_currencies = __esm({ "../../packages/contract/currencies.ts"() {
1166
+ "use strict";
1167
+ init_define_IGNITIFY_CLIENT_FILES();
1168
+ } });
1161
1169
  var TASK_CONFIG_FILENAMES, RUNTIME_REGISTRY, RUNTIME_IDS, LIVE_RUNTIME_IDS, isRuntimeId, TASK_CONFIG_AJV_OPTIONS, TASK_CONFIG_SCHEMA, BUILD_REFUSAL_STAGES, BUILD_STAGES, init_task_config = __esm({ "../../packages/contract/task-config.ts"() {
1162
1170
  "use strict";
1163
1171
  init_define_IGNITIFY_CLIENT_FILES();
1164
1172
  TASK_CONFIG_FILENAMES = ["task.yaml", "task.yml", "task.json"], RUNTIME_REGISTRY = Object.freeze({ node: Object.freeze({ entryFile: "index.ts", depManifest: "package.json", lockfile: "package-lock.json", wireRuntime: "node22", status: "live" }), python: Object.freeze({ entryFile: "main.py", depManifest: "requirements.txt", lockfile: "requirements.txt", wireRuntime: "python3.11", status: "live" }), go: Object.freeze({ entryFile: "main.go", depManifest: "go.mod", lockfile: "go.sum", wireRuntime: "go", status: "live" }), rust: Object.freeze({ entryFile: "src/main.rs", depManifest: "Cargo.toml", lockfile: "Cargo.lock", wireRuntime: "rust", status: "live" }) }), RUNTIME_IDS = Object.keys(RUNTIME_REGISTRY), LIVE_RUNTIME_IDS = RUNTIME_IDS.filter((id) => RUNTIME_REGISTRY[id].status === "live"), isRuntimeId = (v) => typeof v == "string" && Object.prototype.hasOwnProperty.call(RUNTIME_REGISTRY, v), TASK_CONFIG_AJV_OPTIONS = Object.freeze({ allErrors: true, strict: true, useDefaults: false }), TASK_CONFIG_SCHEMA = Object.freeze({ $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://ignitify.dev/schemas/task-config/v1.json", title: "Ignitify task configuration", type: "object", required: ["schema_version", "slug", "runtime"], additionalProperties: false, properties: { schema_version: { const: 1 }, slug: { type: "string", minLength: 1 }, runtime: { enum: [...RUNTIME_IDS] }, entry: { type: "string", minLength: 1 }, execution: { type: "object" }, secrets: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true }, run: { type: "object", additionalProperties: false, properties: { payload: { type: "object" }, preset: { type: "string", minLength: 1 }, timeout_sec: { type: "integer", exclusiveMinimum: 0 } } }, build: { type: "object", additionalProperties: false, properties: { allowed_hosts: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true }, ship: { type: "array", items: { type: "string", minLength: 1 }, uniqueItems: true }, system_packages: { type: "array", items: { type: "string", minLength: 1 } } } } } }), BUILD_REFUSAL_STAGES = ["read", "fetch", "build", "smoke"], BUILD_STAGES = ["done", ...BUILD_REFUSAL_STAGES, "builder", "image", "cap"];
1165
1173
  } });
1174
+ function parseJsonText(text) {
1175
+ try {
1176
+ return { ok: true, value: JSON.parse(text) };
1177
+ } catch {
1178
+ return { ok: false };
1179
+ }
1180
+ }
1166
1181
  var isRecord, init_wire_json = __esm({ "../../packages/contract/wire-json.ts"() {
1167
1182
  "use strict";
1168
1183
  init_define_IGNITIFY_CLIENT_FILES();
@@ -1244,33 +1259,30 @@ function privateKeyFileWarning(relPath) {
1244
1259
  let base = relPath.slice(relPath.lastIndexOf("/") + 1).toLowerCase();
1245
1260
  return base.endsWith(".pem") || base.endsWith(".key") || base.startsWith("id_rsa") && !base.endsWith(".pub") ? `${relPath} looks like a private key and is uploaded with the task, then stored in the image. If it is a secret, remove it (secrets go through \`secret:set\`); to keep a harmless file out, list it in \`.ignitifyignore\`` : null;
1246
1261
  }
1247
- function sourceManifest(entries, config) {
1262
+ function checkSourceManifest(entries, config) {
1248
1263
  let expected = rootConfigName(entries.map((e) => e.path));
1249
- if ((config?.name ?? null) !== expected) throw new Error(`source manifest: the task config in the key must be ${expected ?? "none"}, not ${config?.name ?? "none"}`);
1264
+ if ((config?.name ?? null) !== expected) return refused(`the task config in the key must be ${expected ?? "none"}, not ${config?.name ?? "none"}`);
1250
1265
  let configLine = [];
1251
1266
  if (config !== null) try {
1252
1267
  configLine = [`config ${config.name} ${configKeyText(config.value)}`];
1253
1268
  } catch (e) {
1254
- throw new Error(`source manifest: ${config.name}: ${errText(e)}`, { cause: e });
1269
+ return refused(`${config.name}: ${errText(e)}`);
1255
1270
  }
1256
1271
  let seen = /* @__PURE__ */ new Set();
1257
1272
  for (let e of entries) {
1258
- if (typeof e.path != "string" || e.path === "") throw new Error("source manifest: empty path");
1259
- if (e.path.includes("\\")) throw new Error(`source manifest: path contains a backslash: ${JSON.stringify(e.path)}. Separators must be normalised to "/" before hashing, or the same tree hashes differently per platform.`);
1260
- if (e.path.startsWith("/")) throw new Error(`source manifest: absolute path: ${e.path}`);
1261
- if (!isCanonicalRelativePath(e.path)) throw new Error(`source manifest: non-canonical path: ${e.path}`);
1262
- if (e.path.includes(`
1263
- `) || e.path.includes(" ")) throw new Error(`source manifest: path contains a tab or newline: ${JSON.stringify(e.path)}`);
1264
- if (!Number.isSafeInteger(e.size) || e.size < 0) throw new Error(`source manifest: bad size for ${e.path}: ${String(e.size)}`);
1265
- if (!isSha256Hex(e.sha256)) throw new Error(`source manifest: sha256 for ${e.path} must be 64 lowercase hex chars`);
1266
- if (seen.has(e.path)) throw new Error(`source manifest: duplicate path: ${e.path}`);
1273
+ let bad = entryRefusal(e, seen);
1274
+ if (bad !== null) return refused(bad);
1267
1275
  seen.add(e.path);
1268
1276
  }
1269
1277
  let lines = entries.filter((e) => e.path !== config?.name).sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0).map((e) => `${e.exec ? "755" : "644"} ${e.size} ${e.sha256} ${e.path}`);
1270
- return [`ignitify-source/${SOURCE_MANIFEST_VERSION}`, ...configLine, ...lines, ""].join(`
1271
- `);
1278
+ return { ok: true, text: [`ignitify-source/${SOURCE_MANIFEST_VERSION}`, ...configLine, ...lines, ""].join(`
1279
+ `) };
1272
1280
  }
1273
- var SOURCE_MANIFEST_VERSION, RUN_ONLY_CONFIG_KEYS, CONFIG_KEY_TEXT_MAX_BYTES, UPLOAD_MAX_BYTES, CONFIG_KEY_MAX_DEPTH, SOURCE_EXCLUDED_DIRS, SOURCE_EXCLUDED_ROOT_DIRS, SOURCE_EXCLUDED_FILE_PREFIXES, CREDENTIAL_KEYS, CREDENTIAL_CHECKED_FILES, isCanonicalRelativePath, init_source_manifest = __esm({ "../../packages/contract/source-manifest.ts"() {
1281
+ function entryRefusal(e, seen) {
1282
+ return typeof e.path != "string" || e.path === "" ? "empty path" : e.path.includes("\\") ? `path contains a backslash: ${JSON.stringify(e.path)}. Separators must be normalised to "/" before hashing, or the same tree hashes differently per platform.` : e.path.startsWith("/") ? `absolute path: ${e.path}` : isCanonicalRelativePath(e.path) ? e.path.includes(`
1283
+ `) || e.path.includes(" ") ? `path contains a tab or newline: ${JSON.stringify(e.path)}` : !Number.isSafeInteger(e.size) || e.size < 0 ? `bad size for ${e.path}: ${String(e.size)}` : isSha256Hex(e.sha256) ? seen.has(e.path) ? `duplicate path: ${e.path}` : null : `sha256 for ${e.path} must be 64 lowercase hex chars` : `non-canonical path: ${e.path}`;
1284
+ }
1285
+ var SOURCE_MANIFEST_VERSION, RUN_ONLY_CONFIG_KEYS, CONFIG_KEY_TEXT_MAX_BYTES, UPLOAD_MAX_BYTES, CONFIG_KEY_MAX_DEPTH, SOURCE_EXCLUDED_DIRS, SOURCE_EXCLUDED_ROOT_DIRS, SOURCE_EXCLUDED_FILE_PREFIXES, CREDENTIAL_KEYS, CREDENTIAL_CHECKED_FILES, isCanonicalRelativePath, refused, init_source_manifest = __esm({ "../../packages/contract/source-manifest.ts"() {
1274
1286
  "use strict";
1275
1287
  init_define_IGNITIFY_CLIENT_FILES();
1276
1288
  init_task_config();
@@ -1279,6 +1291,7 @@ var SOURCE_MANIFEST_VERSION, RUN_ONLY_CONFIG_KEYS, CONFIG_KEY_TEXT_MAX_BYTES, UP
1279
1291
  SOURCE_MANIFEST_VERSION = "v2", RUN_ONLY_CONFIG_KEYS = Object.freeze(["execution", "secrets", "run"]), CONFIG_KEY_TEXT_MAX_BYTES = 64 * 1024, UPLOAD_MAX_BYTES = 64 * 1024 * 1024, CONFIG_KEY_MAX_DEPTH = 64;
1280
1292
  SOURCE_EXCLUDED_DIRS = Object.freeze([".git", ".ignitify", "node_modules", "__pycache__", ".venv", "venv", ".mypy_cache", ".pytest_cache"]), SOURCE_EXCLUDED_ROOT_DIRS = Object.freeze(["target", "dist"]), SOURCE_EXCLUDED_FILE_PREFIXES = Object.freeze([".env"]), CREDENTIAL_KEYS = Object.freeze({ ".npmrc": /^[ \t]*(?![#;])[^=\n]*_(?:authToken|auth|password)[ \t]*=[ \t]*(?!\$\{\w+\}[ \t]*$)\S/m, ".yarnrc.yml": /^[ \t]*npmAuth(?:Token|Ident)[ \t]*:[ \t]*(?!["']?\$\{\w+\}["']?[ \t]*$)\S/m }), CREDENTIAL_CHECKED_FILES = Object.freeze(Object.keys(CREDENTIAL_KEYS));
1281
1293
  isCanonicalRelativePath = (p) => !p.startsWith("/") && !p.includes("\\") && p.split("/").every((seg) => seg !== "" && seg !== "." && seg !== "..");
1294
+ refused = (reason) => ({ ok: false, reason });
1282
1295
  } });
1283
1296
  function normaliseSystemPackages(declared) {
1284
1297
  return [...new Set(declared)].sort();
@@ -1297,10 +1310,10 @@ var init_package_advice = __esm({ "../../packages/contract/package-advice.ts"()
1297
1310
  "use strict";
1298
1311
  init_define_IGNITIFY_CLIENT_FILES();
1299
1312
  } });
1300
- var USAGE_AXES, USAGE_DETAIL_COMMAND, RESETS_AT_NEXT_RENEWAL, init_usage = __esm({ "../../packages/contract/usage.ts"() {
1313
+ var USAGE_AXES, AXIS_UNIT, USAGE_DETAIL_COMMAND, RESETS_AT_NEXT_RENEWAL, init_usage = __esm({ "../../packages/contract/usage.ts"() {
1301
1314
  "use strict";
1302
1315
  init_define_IGNITIFY_CLIENT_FILES();
1303
- USAGE_AXES = ["compute", "network", "network_in", "disk", "scratch", "runs", "pin", "build"], USAGE_DETAIL_COMMAND = "ignitify quota", RESETS_AT_NEXT_RENEWAL = "your next paid renewal";
1316
+ USAGE_AXES = ["compute", "network", "network_in", "disk", "scratch", "runs", "pin", "build"], AXIS_UNIT = { compute: "ms", network: "bytes", network_in: "bytes", disk: "byte-hours", scratch: "byte-hours", runs: "runs", pin: "ms", build: "ms" }, USAGE_DETAIL_COMMAND = "ignitify quota", RESETS_AT_NEXT_RENEWAL = "your next paid renewal";
1304
1317
  } });
1305
1318
  function formatUserCode(code) {
1306
1319
  if (code.length !== 8) return code;
@@ -1319,12 +1332,65 @@ var init_backoff = __esm({ "../../packages/contract/backoff.ts"() {
1319
1332
  "use strict";
1320
1333
  init_define_IGNITIFY_CLIENT_FILES();
1321
1334
  } });
1335
+ var init_tenant_account = __esm({ "../../packages/contract/tenant-account.ts"() {
1336
+ "use strict";
1337
+ init_define_IGNITIFY_CLIENT_FILES();
1338
+ } });
1339
+ function retryAfterMs(value, nowMs) {
1340
+ if (value === null || value.trim() === "") return null;
1341
+ let text = value.trim(), ms = /^\d+$/.test(text) ? Number(text) * 1e3 : /[a-z]/i.test(text) ? Date.parse(text) - nowMs : Number.NaN;
1342
+ return Number.isNaN(ms) ? null : Math.min(Math.max(2e3, ms), WEB_POLL.BACKOFF_CEILING_MS);
1343
+ }
1344
+ var WEB_POLL, NO_TASK_NAME_TEXT, OBS_QUERY, FAILURE_CLASSES, FAILURE_CLASS_TEXT, OBS_REFUSAL, init_tenant_telemetry = __esm({ "../../packages/contract/tenant-telemetry.ts"() {
1345
+ "use strict";
1346
+ init_define_IGNITIFY_CLIENT_FILES();
1347
+ WEB_POLL = { LIVE_MS: 5e3, SUMMARY_MS: 6e4, JITTER: 0.1, BACKOFF_CEILING_MS: 6e4 };
1348
+ NO_TASK_NAME_TEXT = "(no task name)", OBS_QUERY = { CURSOR: "cursor", WAIT_SEC: "wait_sec", FROM_OFFSET: "from_offset", STATUS: "status", DAYS: "days" }, FAILURE_CLASSES = ["task", "limit", "cancelled", "platform"], FAILURE_CLASS_TEXT = { task: { label: "Your task", hint: "The code or the deployment failed: an exit code, a crash, a timeout." }, limit: { label: "A limit", hint: "A limit of your plan stopped the run. You can change it." }, cancelled: { label: "Cancelled", hint: "Someone asked the run to stop." }, platform: { label: "The platform", hint: "Something on our side failed. We see these too." } }, OBS_REFUSAL = { NEVER_RAN: { error: "run-never-ran", detail: "this run was not dispatched to a VM" }, INVALID_CURSOR: { error: "invalid-cursor", detail: "from_offset must be 0 or a next_offset that this run's output returned" }, AGENT_OUTDATED_CURSOR: { error: "agent-outdated-cursor", detail: "the host that ran this run cannot read output from an offset; read it without from_offset" }, HOST_GONE: { error: "host-gone", detail: "the host that ran this VM is no longer in the fleet" }, OUTPUT_GONE: { error: "no-file", detail: "the host no longer holds this run's output" }, INVALID_TIMELINE_CURSOR: { error: "invalid-timeline-cursor", detail: "cursor must be a cursor that this run's timeline returned" }, INVALID_DAYS: { error: "invalid-days", detail: "days must be a whole number of days, 1 or more" }, INVALID_WAIT: { error: "invalid-wait", detail: "wait_sec must be whole seconds from 0 to 20" }, WAIT_REFUSED: { error: "wait-refused", detail: "too many open waits; retry after the Retry-After seconds" }, UNAVAILABLE: { error: "obs-unavailable", detail: "the read cannot be served now; retry after the Retry-After seconds" } };
1349
+ } });
1350
+ function isPermission(value) {
1351
+ return typeof value == "string" && PERMISSIONS.has(value);
1352
+ }
1353
+ var PERMISSION, PERMISSIONS, PERMISSION_DESCRIPTION, ACCESS_MARKER, ACCESS_REFUSAL, ACCESS_NAME_PATTERN, ACCESS_NAME_RULE, KEY_LIST_QUERY, init_tenant_access = __esm({ "../../packages/contract/tenant-access.ts"() {
1354
+ "use strict";
1355
+ init_define_IGNITIFY_CLIENT_FILES();
1356
+ PERMISSION = { TASKS_READ: "tasks.read", TASKS_WRITE: "tasks.write", DEPLOYMENTS_READ: "deployments.read", DEPLOYMENTS_WRITE: "deployments.write", RUNS_READ: "runs.read", RUNS_WRITE: "runs.write", SECRETS_READ: "secrets.read", SECRETS_WRITE: "secrets.write", HOOKS_READ: "hooks.read", HOOKS_WRITE: "hooks.write", USAGE_READ: "usage.read" }, PERMISSIONS = new Set(Object.values(PERMISSION));
1357
+ PERMISSION_DESCRIPTION = { [PERMISSION.TASKS_READ]: "Read tasks", [PERMISSION.TASKS_WRITE]: "Create and delete tasks", [PERMISSION.DEPLOYMENTS_READ]: "Read deployments and build logs", [PERMISSION.DEPLOYMENTS_WRITE]: "Deploy, delete a deployment, ask for package advice", [PERMISSION.RUNS_READ]: "Read runs, logs, timeline, failures, schedules, VMs", [PERMISSION.RUNS_WRITE]: "Start, cancel, delete runs; cancel schedules; stop VMs", [PERMISSION.SECRETS_READ]: "List secret names (values are never readable)", [PERMISSION.SECRETS_WRITE]: "Set and delete secrets", [PERMISSION.HOOKS_READ]: "List hooks", [PERMISSION.HOOKS_WRITE]: "Create and delete hooks; set notify", [PERMISSION.USAGE_READ]: "Usage, series, notifications" }, ACCESS_MARKER = { ANY_KEY: "any-key", OWNER: "owner" }, ACCESS_REFUSAL = { PERMISSION_DENIED: "permission-denied", OWNER_REQUIRED: "owner-required", USER_NOT_FOUND: "user-not-found", GROUP_NOT_FOUND: "group-not-found", NAME_TAKEN: "name-taken", UNKNOWN_PERMISSION: "unknown-permission" }, ACCESS_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/, ACCESS_NAME_RULE = "1 to 63 lower case letters, digits and '-', starting with a letter or digit", KEY_LIST_QUERY = { USER: "user" };
1358
+ } });
1359
+ var NOTIFICATION_KINDS, NOTIFICATION_KIND_INFO, ALERT_KINDS, CRITICAL_ALERT_KINDS, NOTIFICATION_FILTERS, NOTIFICATION_RETENTION_DAYS, NOTIFICATION_PAGE_MAX, NOTIFICATION_PAGE_DEFAULT, NOTIFICATION_QUERY, NOTIFICATION_REFUSAL, init_tenant_notifications = __esm({ "../../packages/contract/tenant-notifications.ts"() {
1360
+ "use strict";
1361
+ init_define_IGNITIFY_CLIENT_FILES();
1362
+ init_api_routes();
1363
+ init_tenant_telemetry();
1364
+ NOTIFICATION_KINDS = ["limit.reached", "limit.near", "runs.failing", "callback.failing", "schedule.missed", "pin.lost", "plan.changed"], NOTIFICATION_KIND_INFO = { "limit.reached": { class: "alert", severity: "critical", label: "Monthly limit reached" }, "limit.near": { class: "notification", severity: "warning", label: "Monthly limit near" }, "runs.failing": { class: "alert", severity: "warning", label: "Runs failing" }, "callback.failing": { class: "alert", severity: "warning", label: "Run callbacks failing" }, "schedule.missed": { class: "notification", severity: "warning", label: "Schedule did not run" }, "pin.lost": { class: "notification", severity: "warning", label: "Pinned VM lost" }, "plan.changed": { class: "notification", severity: "info", label: "Plan changed" } }, ALERT_KINDS = NOTIFICATION_KINDS.filter((k) => NOTIFICATION_KIND_INFO[k].class === "alert"), CRITICAL_ALERT_KINDS = ALERT_KINDS.filter((k) => NOTIFICATION_KIND_INFO[k].severity === "critical"), NOTIFICATION_FILTERS = ["all", "unread", "open"], NOTIFICATION_RETENTION_DAYS = 30, NOTIFICATION_PAGE_MAX = 100, NOTIFICATION_PAGE_DEFAULT = 25, NOTIFICATION_QUERY = { FILTER: "filter", KIND: "kind", CURSOR: OBS_QUERY.CURSOR, LIMIT: "limit" }, NOTIFICATION_REFUSAL = { INVALID_FILTER: { error: "invalid-filter", detail: `filter must be one of: ${NOTIFICATION_FILTERS.join(", ")}` }, INVALID_KIND: { error: "invalid-kind", detail: `kind must be one of: ${NOTIFICATION_KINDS.join(", ")}` }, INVALID_LIMIT: { error: "invalid-limit", detail: "limit must be a whole number, 1 or more" }, INVALID_CURSOR: { error: "invalid-cursor", detail: "cursor must be a cursor that this list returned" } };
1365
+ } });
1366
+ var SITE_LINKS, init_web_nav = __esm({ "../../packages/contract/web-nav.ts"() {
1367
+ "use strict";
1368
+ init_define_IGNITIFY_CLIENT_FILES();
1369
+ SITE_LINKS = { DOCS: "https://ignitify.dev/docs", CLI_REFERENCE: "https://ignitify.dev/docs/cli/all", PRICING: "https://ignitify.dev/pricing" };
1370
+ } });
1371
+ var init_web_frame = __esm({ "../../packages/contract/web-frame.ts"() {
1372
+ "use strict";
1373
+ init_define_IGNITIFY_CLIENT_FILES();
1374
+ init_api_routes();
1375
+ init_tenant_account();
1376
+ init_web_nav();
1377
+ } });
1378
+ function stripControl(text, keep = KEEP_NONE) {
1379
+ return text.replace(CONTROL_UNIT, (unit) => keep(unit) ? unit : unit.startsWith("\r") ? `
1380
+ ` : "");
1381
+ }
1382
+ var CONTROL_UNIT, KEEP_NONE, init_control_text = __esm({ "../../packages/contract/control-text.ts"() {
1383
+ "use strict";
1384
+ init_define_IGNITIFY_CLIENT_FILES();
1385
+ CONTROL_UNIT = /\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\)?|[PX^_][^\x1b]*(?:\x1b\\)?|[ -/]*[0-~])?|\r\n?|[\u0000-\u0008\u000b\u000c\u000e-\u001a\u001c-\u001f\u007f-\u009f]/g, KEEP_NONE = () => false;
1386
+ } });
1322
1387
  var init_tenant = __esm({ "../../packages/contract/tenant/index.ts"() {
1323
1388
  "use strict";
1324
1389
  init_define_IGNITIFY_CLIENT_FILES();
1325
1390
  init_api_routes();
1326
1391
  init_callback_path();
1327
1392
  init_limits();
1393
+ init_currencies();
1328
1394
  init_task_config();
1329
1395
  init_source_manifest();
1330
1396
  init_system_packages();
@@ -1335,21 +1401,28 @@ var init_tenant = __esm({ "../../packages/contract/tenant/index.ts"() {
1335
1401
  init_digest();
1336
1402
  init_device_code();
1337
1403
  init_backoff();
1404
+ init_tenant_account();
1405
+ init_tenant_telemetry();
1406
+ init_tenant_access();
1407
+ init_tenant_notifications();
1408
+ init_web_nav();
1409
+ init_web_frame();
1410
+ init_control_text();
1338
1411
  } });
1339
1412
  function valueFlags(map2) {
1340
1413
  return Object.fromEntries(Object.keys(map2).map((flag) => [flag, "value"]));
1341
1414
  }
1342
- var COMMANDS, IGNORE_FILE, STATE, CREDENTIALS, LOGIN, LOGIN_VIEW, NETWORK, ENV, DEFAULT_TASKS_DIR, DEFAULTS, UPGRADE_COMMAND, PAYLOAD_LIMIT_FALLBACK_BYTES, RESULT_LIMIT_FALLBACK_BYTES, RUN_LIST_FLAG_PARAMS, VM_LIST_FLAG_PARAMS, GLOBAL_FLAGS, SERVER_FLAGS, HIDDEN_FLAGS, SHORT_FLAGS, VERSION_TOKENS, VALIDATE, ADVICE, INTEGRATION, NO_FLAGS, DIR, PAGE, YES, RAW, USAGE_FLAG_PARAMS, USAGE_FILTERS, COMMAND_META, VERSION_META, MESSAGES, RUN_STATUS, ACTIVE_RUN_STATUSES, DEPLOYMENT_STATUS, POLL, WAIT, init_constants = __esm({ "src/constants/index.ts"() {
1415
+ var COMMANDS, IGNORE_FILE, STATE, CREDENTIALS, LOGIN, LOGIN_VIEW, NETWORK, ENV, DEFAULT_TASKS_DIR, RELEASE_BUILD, DEFAULTS, UPGRADE_COMMAND, PAYLOAD_LIMIT_FALLBACK_BYTES, RESULT_LIMIT_FALLBACK_BYTES, RUN_LIST_FLAG_PARAMS, VM_LIST_FLAG_PARAMS, GLOBAL_FLAGS, SHORT_FLAGS, VERSION_TOKENS, VALIDATE, ADVICE, INTEGRATION, NO_FLAGS, DIR, PAGE, YES, RAW, FOLLOW_FLAG, DAYS_FLAG, USAGE_FLAG_PARAMS, USAGE_FILTERS, NOTIFICATION_LIST_FLAG_PARAMS, COMMAND_META, VERSION_META, KEY_REVOKE_COMMAND, MESSAGES, ACCESS, RUN_STATUS, ACTIVE_RUN_STATUSES, DEPLOYMENT_STATUS, POLL, WAIT, FOLLOW, MS_PER_SECOND, BUSY_READ, FOLLOW_MESSAGES, init_constants = __esm({ "src/constants/index.ts"() {
1343
1416
  "use strict";
1344
1417
  init_define_IGNITIFY_CLIENT_FILES();
1345
1418
  init_http_client();
1346
1419
  init_tenant();
1347
1420
  init_tenant();
1348
1421
  init_tenant();
1349
- COMMANDS = { HELP: "help", LOGIN: "login", LOGOUT: "logout", WHOAMI: "whoami", QUOTA: "quota", TASK_CREATE: "task:create", TASK_LIST: "task:list", TASK_GET: "task:get", TASK_DELETE: "task:delete", TASK_VALIDATE: "task:validate", TASK_PACK: "task:pack", TASK_DEPLOY: "task:deploy", TASK_RUN: "task:run", DEPLOYMENT_LIST: "deployment:list", DEPLOYMENT_GET: "deployment:get", DEPLOYMENT_LOGS: "deployment:logs", DEPLOYMENT_DELETE: "deployment:delete", RUN_LIST: "run:list", RUN_GET: "run:get", RUN_LOGS: "run:logs", RUN_DELETE: "run:delete", RUN_CANCEL: "run:cancel", VM_LIST: "vm:list", VM_GET: "vm:get", VM_DELETE: "vm:delete", SECRET_SET: "secret:set", SECRET_LIST: "secret:list", SECRET_DELETE: "secret:delete", SCHEDULE_LIST: "schedule:list", SCHEDULE_CANCEL: "schedule:cancel", HOOK_CREATE: "hook:create", HOOK_LIST: "hook:list", HOOK_DELETE: "hook:delete", NOTIFY_SET: "notify:set", INTEGRATION_ADD: "integration:add", USAGE: "usage", USAGE_EXPORT: "usage:export" }, IGNORE_FILE = ".ignitifyignore", STATE = { DIR: ".ignitify", FILE: "state.json", GITIGNORE_FILE: ".gitignore", GITIGNORE_TEXT: `# written by ignitify: local state, never commit
1422
+ COMMANDS = { HELP: "help", LOGIN: "login", LOGOUT: "logout", WHOAMI: "whoami", QUOTA: "quota", TASK_CREATE: "task:create", TASK_LIST: "task:list", TASK_GET: "task:get", TASK_DELETE: "task:delete", TASK_VALIDATE: "task:validate", TASK_PACK: "task:pack", TASK_DEPLOY: "task:deploy", TASK_RUN: "task:run", DEPLOYMENT_LIST: "deployment:list", DEPLOYMENT_GET: "deployment:get", DEPLOYMENT_LOGS: "deployment:logs", DEPLOYMENT_DELETE: "deployment:delete", RUN_LIST: "run:list", RUN_GET: "run:get", RUN_LOGS: "run:logs", RUN_TIMELINE: "run:timeline", RUN_FAILURES: "run:failures", RUN_DELETE: "run:delete", RUN_CANCEL: "run:cancel", VM_LIST: "vm:list", VM_GET: "vm:get", VM_DELETE: "vm:delete", SECRET_SET: "secret:set", SECRET_LIST: "secret:list", SECRET_DELETE: "secret:delete", SCHEDULE_LIST: "schedule:list", SCHEDULE_CANCEL: "schedule:cancel", HOOK_CREATE: "hook:create", HOOK_LIST: "hook:list", HOOK_DELETE: "hook:delete", NOTIFY_SET: "notify:set", INTEGRATION_ADD: "integration:add", USAGE: "usage", USAGE_EXPORT: "usage:export", USAGE_SERIES: "usage:series", NOTIFICATION_LIST: "notification:list", PERMISSION_LIST: "permission:list", USER_CREATE: "user:create", USER_LIST: "user:list", USER_GET: "user:get", USER_REMOVE: "user:remove", GROUP_CREATE: "group:create", GROUP_LIST: "group:list", GROUP_GET: "group:get", GROUP_GRANT: "group:grant", GROUP_REVOKE: "group:revoke", GROUP_ADD_USER: "group:add-user", GROUP_REMOVE_USER: "group:remove-user", GROUP_DELETE: "group:delete", KEY_CREATE: "key:create", KEY_LIST: "key:list", KEY_REVOKE: "key:revoke" }, IGNORE_FILE = ".ignitifyignore", STATE = { DIR: ".ignitify", FILE: "state.json", GITIGNORE_FILE: ".gitignore", GITIGNORE_TEXT: `# written by ignitify: local state, never commit
1350
1423
  *
1351
- ` }, CREDENTIALS = { DIR_NAME: "ignitify", FILE_NAME: "credentials.json", DIR_MODE: 448, FILE_MODE: 384 }, LOGIN = { MAX_RETRIES: 3, KEY_TTL_DAYS: 90, MIN_POLL_INTERVAL_SEC: 5, BROWSER_SCHEMES: ["https:", "http:"] }, LOGIN_VIEW = { TITLE: "Sign in to Ignitify", OPEN_PAGE: "Open this page:", ASK_OPERATOR: "Give this code to your operator, who approves it:", CHECK_CODE: "Check this code", SAME_CODE: "The page must show the same code.", WAITING_STATIC: (minutes) => `Waiting for approval. The code expires in ${minutes} minutes.`, WAITING_LIVE: (left) => `Waiting for approval... code expires in ${left}`, CANCELLED: "Sign-in cancelled. Nothing was saved.", SIGNED_IN: "Signed in", SIGNED_OUT: "Signed out", KEY_EXPIRES: (days) => `${days} days after last use; each use renews it`, YES: "yes", ROWS: { ACCOUNT: "Account", ACCOUNT_ID: "Account id", KEY_LABEL: "Key label", KEY_EXPIRES: "Key expires", SAVED_TO: "Saved to", REVOKED: "Revoked", DELETED: "Deleted" } }, NETWORK = { REASONS: { ECONNREFUSED: "nothing accepts connections there", ENOTFOUND: "the host name is unknown", EAI_AGAIN: "the host name lookup failed", ETIMEDOUT: "the connection timed out", UND_ERR_CONNECT_TIMEOUT: "the connection timed out", ECONNRESET: "the connection was reset" }, TLS_WORDS: "the TLS certificate was not accepted", TLS_CODES: ["CERT_HAS_EXPIRED", "CERT_NOT_YET_VALID", "DEPTH_ZERO_SELF_SIGNED_CERT", "SELF_SIGNED_CERT_IN_CHAIN", "UNABLE_TO_VERIFY_LEAF_SIGNATURE", "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"], TLS_CODE_PREFIXES: ["ERR_TLS_", "ERR_SSL_"], CODE_PATTERN: /^[A-Z][A-Z0-9_]*$/, DETAIL_MAX_CHARS: 80 }, ENV = { TASKS_DIR: "IGNITIFY_TASKS_DIR", KEY: "IGNITIFY_API_KEY" }, DEFAULT_TASKS_DIR = "tasks", DEFAULTS = { API_URL: "https://api.ignitify.dev" }, UPGRADE_COMMAND = "npm install --global ignitify@latest", PAYLOAD_LIMIT_FALLBACK_BYTES = 10240, RESULT_LIMIT_FALLBACK_BYTES = 10240, RUN_LIST_FLAG_PARAMS = { status: "status", "deployment-id": "deployment_id", "task-name": "task_name", preset: "preset", "correlation-id": "correlation_id", "vm-id": "vm_id", ...PAGE_FLAG_PARAMS }, VM_LIST_FLAG_PARAMS = { "deployment-id": "deployment_id", "task-name": "task_name", preset: "preset", "older-than": "older_than", ...PAGE_FLAG_PARAMS }, GLOBAL_FLAGS = { json: "bool", help: "bool" }, SERVER_FLAGS = { api: "value" }, HIDDEN_FLAGS = ["api"], SHORT_FLAGS = { h: "help", y: "yes" }, VERSION_TOKENS = ["--version", "-v"];
1352
- VALIDATE = { VALID: "task config valid" }, ADVICE = { FLAG: "review-packages", TIMEOUT_MS: 6e4, FAULT_STATUSES: [400, 401, 403], SECONDS_ONLY_BELOW: 60, SECONDS_PER_MINUTE: 60, NO_PACKAGES: "this task lists no build.system_packages", SKIPPED: (reason) => `AI check skipped: ${reason}`, RATE_LIMITED: (retryAfterS) => `rate limited, try again in ${retryAfterS} s`, UNAVAILABLE: (reason) => `the review is unavailable (${reason})`, NO_ANSWER: (status, message) => status === null ? message : `server answered ${status}`, FAULT: (status, body) => `AI check failed (HTTP ${status}): ${body}`, BAD_NAMES: (bad) => `not valid package names: ${bad.join(", ")}`, TOO_MANY: (count, max) => `${count} packages listed, the most is ${max}`, BASIS: { measured: "measured", model: "model estimate" }, NO_FIT: (driveMib, capMib) => `does not fit: ${driveMib} MiB of packages against the ${capMib} MiB image store of your tier`, TITLE: "Package review", NOTE: "AI advice only. A suggestion is not checked against Debian.", COLUMNS: { PACKAGE: "Package", VERDICT: "Verdict", SIZE: "Size", NOTE: "Note", SUGGEST: "Suggest" }, NOT_DOUBLE_CHECKED: "not double-checked by the second model", RESULT_CLEAN: (total) => `No concerns found in ${total} package${total === 1 ? "" : "s"}.`, RESULT_FLAGGED: (total, flagged) => `${total} package${total === 1 ? "" : "s"} checked, ${flagged} to look at.`, NOT_ANSWERED: (names) => `No AI answer for: ${names.join(", ")}. The review could not judge ${names.length === 1 ? "it" : "them"}.`, BUILD_TITLE: "Build time", BUILD_LABELS: { ADDED: "Added", APPLIES: "Applies to", SIZE: "Packages size", LEFT_OUT: "Left out" }, BUILD_NONE: "nothing: your tenant already holds the drive for this list", BUILD_ADDED: (range, basis) => `about ${range} (${basis})`, BUILD_APPLIES: "the first deploy of this list. A later code-only redeploy reuses the drive.", BUILD_SIZE: (mib, capMib) => capMib === null ? `${mib} MiB` : `${mib} MiB of ${capMib} MiB (the image store of your tier)`, BUILD_LEFT_OUT: (names) => `${names.join(", ")} (unusable, or size unknown)` }, INTEGRATION = { PACKAGE_JSON: "package.json", NODE_MODULES: "node_modules", RUNTIME: "node", NPM: "npm", TARBALL_EXT: ".tgz", PACKED_ROOT: "package", PACK_TMP_PREFIX: "ignitify-integration-pack-", PACK_ARGS: (pkg, destDir, taskDir) => ["pack", pkg, "--pack-destination", destDir, "--prefix", taskDir], INSTALL_ARGS: (spec, taskDir) => ["install", spec, "--save-prod", "--ignore-scripts", "--prefix", taskDir], PACKED_MAX_BYTES: 8 * 1024 * 1024, ZLIB_TOO_BIG: "ERR_BUFFER_TOO_LARGE", VERSION_PATTERN: /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/, QUESTION: "Apply?", REGISTRY_URL: "https://registry.npmjs.org", REGISTRY_ACCEPT: "application/vnd.npm.install-v1+json", REGISTRY_TIMEOUT_MS: 5e3, NOTED_FIELDS: ["execution.network.type", "run.preset"], USAGE: "usage: ignitify integration:add <name> --task <slug> [--yes | --dry-run] [--dir <base-dir>]", TASK_REQUIRED: "--task <slug> is required: the task folder to add the integration to", YES_WITH_DRY_RUN: "--yes and --dry-run cannot be used together", BAD_NAME: (name, pattern) => `integration name ${JSON.stringify(name)} must match ${pattern}`, NOT_NODE: (runtime) => `integrations work with Node tasks only; this task has runtime "${runtime}"`, NO_PACKAGE_JSON: (taskDir) => `${taskDir} has no package.json: run npm init in the task folder first; nothing was changed`, NOT_INTERACTIVE: "Refusing to proceed: not a TTY. Re-run with --yes to apply the plan, or with --dry-run to see it.", PACK_FAILED: (pkg, code) => `npm pack ${pkg} failed${code === null ? "" : ` (exit ${code})`}; nothing in the task was changed`, INSTALL_FAILED: (spec, code) => `npm install ${spec} failed${code === null ? "" : ` (exit ${code})`}; task.yaml was not changed`, INSTALLED: (spec) => `${spec} installed`, BAD_VERSION: (pkg, version2) => `${pkg}: its package.json version ${JSON.stringify(version2)} is not a plain x.y.z version; nothing in the task was changed`, PACKED_TOO_BIG: (file, max) => `${file} unpacks to more than ${max} bytes: refused, nothing in the task was changed`, INSTALL_ONLY: (spec) => `installs ${spec}; task.yaml unchanged`, NOT_AN_INTEGRATION: (pkg, file) => `${pkg} has no ${file}: it is not an integration package`, BAD_MANIFEST: (pkg, issue) => `${pkg} integration.yaml: ${issue}`, UNREADABLE: (file, reason) => `cannot read ${file}: ${reason}`, WRITE_MISMATCH: (file) => `the edited ${file} does not read back as the plan; nothing was written`, YOU_ADD: "you add:", NO_CHANGES: "task.yaml already has every setting this integration needs; nothing to write", DRY_RUN: "dry run: task.yaml was not changed", WRITTEN: (file) => `${file} updated`, NOT_INSTALLED: (pkgs) => `${pkgs.join(", ")} ${pkgs.length === 1 ? "is" : "are"} in package.json but not in node_modules: run npm install, then task:validate again`, OBSOLETE: (pkg, version2, latest) => `${pkg}@${version2} is obsolete: use ${latest}`, OBSOLETE_SKIPPED: (reason) => `obsolete-version check skipped: ${reason}`, REGISTRY_UNREACHABLE: "the npm registry did not answer (offline?)", REGISTRY_NOT_FOUND: (pkg) => `${pkg} is not on the npm registry` }, NO_FLAGS = {}, DIR = { dir: "value" }, PAGE = valueFlags(PAGE_FLAG_PARAMS), YES = { yes: "bool" }, RAW = { raw: "bool" }, USAGE_FLAG_PARAMS = { period: "period", axis: "axis", vm: "vm", run: "run" }, USAGE_FILTERS = valueFlags(USAGE_FLAG_PARAMS), COMMAND_META = { [COMMANDS.HELP]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.LOGIN]: { flags: { ...SERVER_FLAGS, "no-browser": "bool", name: "value" }, positionals: 0, confirms: false }, [COMMANDS.LOGOUT]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.WHOAMI]: { flags: SERVER_FLAGS, positionals: 0, confirms: false }, [COMMANDS.QUOTA]: { flags: SERVER_FLAGS, positionals: 0, confirms: false }, [COMMANDS.TASK_CREATE]: { flags: { ...SERVER_FLAGS, ...DIR, lang: "value", local: "bool", "no-init": "bool", "no-scaffold": "bool" }, positionals: 1, confirms: false }, [COMMANDS.TASK_LIST]: { flags: { ...SERVER_FLAGS, ...PAGE }, positionals: 0, confirms: false }, [COMMANDS.TASK_GET]: { flags: { ...SERVER_FLAGS, ...DIR }, positionals: 1, confirms: false }, [COMMANDS.TASK_DELETE]: { flags: { ...SERVER_FLAGS, ...DIR, ...YES }, positionals: 1, confirms: true }, [COMMANDS.TASK_VALIDATE]: { flags: { ...SERVER_FLAGS, ...DIR, [ADVICE.FLAG]: "bool" }, positionals: 1, confirms: false }, [COMMANDS.TASK_PACK]: { flags: DIR, positionals: 1, confirms: false }, [COMMANDS.TASK_DEPLOY]: { flags: { ...SERVER_FLAGS, ...DIR, check: "bool" }, positionals: 1, confirms: false }, [COMMANDS.TASK_RUN]: { flags: { deployment: "value", payload: "value", "timeout-sec": "value", "on-busy": "value", at: "value", wait: "bool", ...DIR, ...SERVER_FLAGS }, positionals: 1, confirms: false }, [COMMANDS.DEPLOYMENT_LIST]: { flags: { ...SERVER_FLAGS, ...PAGE }, positionals: 0, confirms: false }, [COMMANDS.DEPLOYMENT_GET]: { flags: SERVER_FLAGS, positionals: 1, confirms: false }, [COMMANDS.DEPLOYMENT_LOGS]: { flags: { ...SERVER_FLAGS, ...RAW }, positionals: 1, confirms: false }, [COMMANDS.DEPLOYMENT_DELETE]: { flags: { ...SERVER_FLAGS, ...YES }, positionals: 1, confirms: true }, [COMMANDS.RUN_LIST]: { flags: { ...SERVER_FLAGS, ...valueFlags(RUN_LIST_FLAG_PARAMS) }, positionals: 0, confirms: false }, [COMMANDS.RUN_GET]: { flags: { ...SERVER_FLAGS, full: "bool" }, positionals: 1, confirms: false }, [COMMANDS.RUN_LOGS]: { flags: { ...SERVER_FLAGS, ...RAW }, positionals: 1, confirms: false }, [COMMANDS.RUN_DELETE]: { flags: { ...SERVER_FLAGS, ...YES }, positionals: 1, confirms: true }, [COMMANDS.RUN_CANCEL]: { flags: { ...SERVER_FLAGS, ...YES, force: "bool", grace: "value" }, positionals: 1, confirms: true }, [COMMANDS.VM_LIST]: { flags: { ...SERVER_FLAGS, ...valueFlags(VM_LIST_FLAG_PARAMS), pinned: "bool" }, positionals: 0, confirms: false }, [COMMANDS.VM_GET]: { flags: SERVER_FLAGS, positionals: 1, confirms: false }, [COMMANDS.VM_DELETE]: { flags: { ...SERVER_FLAGS, ...YES, force: "bool" }, positionals: 1, confirms: true }, [COMMANDS.SECRET_SET]: { flags: { ...SERVER_FLAGS, stdin: "bool", value: "value" }, positionals: 1, confirms: false, secretArgv: true }, [COMMANDS.SECRET_LIST]: { flags: SERVER_FLAGS, positionals: 0, confirms: false }, [COMMANDS.SECRET_DELETE]: { flags: { ...SERVER_FLAGS, ...YES }, positionals: 1, confirms: true }, [COMMANDS.SCHEDULE_LIST]: { flags: SERVER_FLAGS, positionals: 0, confirms: false }, [COMMANDS.SCHEDULE_CANCEL]: { flags: { ...SERVER_FLAGS, ...YES }, positionals: 1, confirms: true }, [COMMANDS.HOOK_CREATE]: { flags: { ...SERVER_FLAGS, "task-name": "value" }, positionals: 1, confirms: false }, [COMMANDS.HOOK_LIST]: { flags: { ...SERVER_FLAGS, ...PAGE }, positionals: 1, confirms: false }, [COMMANDS.HOOK_DELETE]: { flags: { ...SERVER_FLAGS, ...YES }, positionals: 1, confirms: true }, [COMMANDS.NOTIFY_SET]: { flags: { ...SERVER_FLAGS, url: "value", clear: "bool", "secret-stdin": "bool", secret: "value" }, positionals: 1, confirms: false, secretArgv: true }, [COMMANDS.INTEGRATION_ADD]: { flags: { ...DIR, ...YES, task: "value", "dry-run": "bool" }, positionals: 1, confirms: true }, [COMMANDS.USAGE]: { flags: { ...SERVER_FLAGS, ...USAGE_FILTERS, runs: "bool", vms: "bool" }, positionals: 0, confirms: false }, [COMMANDS.USAGE_EXPORT]: { flags: { ...SERVER_FLAGS, ...USAGE_FILTERS, csv: "bool" }, positionals: 0, confirms: false } }, VERSION_META = { flags: SERVER_FLAGS, positionals: 0, confirms: false }, MESSAGES = { NOT_SIGNED_IN: "Not signed in. Run 'ignitify login', or set the IGNITIFY_API_KEY environment variable.", CREDENTIALS_SYMLINK: (file) => `${file} is a symbolic link. Remove it and run 'ignitify login' again.`, CREDENTIALS_NOT_FILE: (file) => `${file} is not a regular file. Remove it and run 'ignitify login' again.`, CREDENTIALS_NOT_OWNED: (file) => `${file} belongs to another user. Remove it and run 'ignitify login' again.`, CREDENTIALS_TOO_OPEN: (file, mode) => `${file} can be read by other users (mode 0${mode}). Run: chmod 600 ${file}`, CREDENTIALS_UNREADABLE: (file) => `${file} is not a valid credentials file. Remove it and run 'ignitify login' again.`, CREDENTIALS_OTHER_URL: (fileUrl, url) => `The saved key is for ${fileUrl}, not ${url}. Run 'ignitify login --api ${url}'.`, CREDENTIALS_DIR_NOT_DIR: (dir) => `${dir} is not a folder. Remove it and run 'ignitify login' again.`, API_URL_NOT_URL: (url) => `The API address "${url}" is not a URL.`, API_URL_NOT_HTTPS: (url) => `The API address ${url} is not https. The CLI sends your key only over https, or over plain http to this machine (localhost, 127.0.0.1, ::1).`, LOGIN_REPLACED: (label) => `Note: replaced the key "${label}" of another machine. Use 'ignitify login --name <other-label>' to keep both.`, LOGIN_EXPIRED: (code) => `The code ${code} expired before it was approved. Run 'ignitify login' again.`, LOGIN_REFUSED: (reason) => `The sign-in was refused: ${reason}.`, LOGIN_UNKNOWN: "The sign-in code is unknown or was already used. Run 'ignitify login' again.", LOGIN_BAD_ANSWER: "The server sent a sign-in answer with no usable key. Nothing was saved.", LOGIN_BAD_START: "The server sent a sign-in start that the CLI cannot use (no code, or no wait times). Nothing was started.", ENV_KEY_OVERRIDES_LOGIN: "Note: the IGNITIFY_API_KEY environment variable is set, so it is used instead of your saved login.", KEY_EXPIRED_HINT: "Run 'ignitify login' to sign in again.", LOGIN_TOO_MANY: "Too many sign-in attempts from this network. Try again later.", LOGIN_CAP: (limit) => `This account already has the most API keys its plan allows${limit === null ? "" : ` (${limit})`}. Remove one, or approve with "replace", then run 'ignitify login' again.`, CANNOT_REACH: (url, detail) => `Cannot reach ${url}${detail === null ? "" : ` (${detail})`}. Check your network and run 'ignitify login' again.`, UNREACHABLE: (origin, detail) => `Cannot reach ${origin}${detail === null ? "" : ` (${detail})`}.`, LOGOUT_NOTHING: "Not signed in. There are no saved credentials.", LOGOUT_ENV_NOTE: "Note: the IGNITIFY_API_KEY environment variable is still set. Logout does not change it.", LOGOUT_NOT_REVOKED: (label) => `Warning: the server did not revoke the key, so it may still work. The saved credentials were deleted. Ask your operator to revoke the key "${label}".`, SLUG_MISSING: (source) => `'slug' is required in ${source}`, SLUG_INVALID: (source, reason) => `${source}: 'slug' ${reason}`, PRESET_INVALID: "run.preset must be a non-empty string", PRESET_UNKNOWN: (source, name, valid) => `${source}: unknown run.preset "${name}" (valid: ${valid.join(", ")}). An unrecognised preset would silently fall back to the platform default, giving you a different instance class than you declared.`, TIMEOUT_INVALID: "run.timeout_sec must be a positive number", TASK_ID_REQUIRED: "a <task-id> is required", TASK_ID_INVALID: (id, reason) => `task id ${JSON.stringify(id)} ${reason}`, ERROR: (message) => `Error: ${message}`, ERROR_PREFIX: "Error:", SERVER_TRACE_ID: (id) => `server trace id: ${id}`, ARG_REQUIRED: (label) => `${label} is required`, UNKNOWN_COMMAND: "unknown command", SEE_HELP: "Run 'ignitify help' to see every command.", UNKNOWN_SHORT_FLAG: (short, long, command) => `unknown flag ${short} (--${long}) for ${command}`, GRACE_INVALID: (got) => `--grace must be a whole number of milliseconds, 0 or more (got ${JSON.stringify(got)})`, GRACE_WITH_FORCE: "--grace has no effect with --force (force stops the run now)", TASK_LIMITS: (payload, result) => `payload max ${payload}, result max ${result}; over the limit the run fails`, PAYLOAD_OVER_LIMIT: (bytes, limit) => `payload is ${bytes} bytes; the limit is ${limit} bytes`, PAYLOAD_REFUSED_BY_SERVER: (limit) => `the server refused the payload as too large; the limit is ${limit} bytes`, DEFAULT_PAYLOAD_OVER_LIMIT: (source, bytes, limit) => `${source}: run.payload is ${bytes} bytes; the offline limit is ${limit} bytes (the server may allow more)`, IGNORED_BY_FILE: `ignored by ${IGNORE_FILE}`, IGNORED_COUNT: (n) => `${n} path(s) left out by ${IGNORE_FILE}`, TASK_DELETED: "task deleted", TASK_LINK_REMOVED: "Removed local link", TASK_LINK_NOT_REMOVED: (link, reason) => `Warning: the task is deleted, but its local link was not removed (${reason}). Remove ${link} by hand.`, DEPLOY_DELETED: "deployment deleted", RUN_DELETED: "run deleted", ABORTED: "Aborted.", CONFIRM_PROCEED: "Proceed?", SECRET_SET_USAGE: "usage: ignitify secret:set <NAME> --stdin (the value is read from stdin)", SECRET_VALUE_EMPTY: "secret:set read an empty value from stdin \u2014 nothing was stored (pipe the value in: `--stdin < value-file`)", SECRET_VALUE_ON_ARGV: `secret:set takes no value on argv: it is visible in \`ps\` and is written to your shell history. Pipe it on stdin, e.g.
1424
+ ` }, CREDENTIALS = { DIR_NAME: "ignitify", FILE_NAME: "credentials.json", DIR_MODE: 448, FILE_MODE: 384 }, LOGIN = { MAX_RETRIES: 3, KEY_TTL_DAYS: 90, MIN_POLL_INTERVAL_SEC: 5, BROWSER_SCHEMES: ["https:", "http:"] }, LOGIN_VIEW = { TITLE: "Sign in to Ignitify", OPEN_PAGE: "Open this page:", ASK_OPERATOR: "Give this code to your operator, who approves it:", CHECK_CODE: "Check this code", SAME_CODE: "The page must show the same code.", WAITING_STATIC: (minutes) => `Waiting for approval. The code expires in ${minutes} minutes.`, WAITING_LIVE: (left) => `Waiting for approval... code expires in ${left}`, CANCELLED: "Sign-in cancelled. Nothing was saved.", SIGNED_IN: "Signed in", SIGNED_OUT: "Signed out", KEY_EXPIRES: (days) => `${days} days after last use; each use renews it`, YES: "yes", ROWS: { ACCOUNT: "Account", ACCOUNT_ID: "Account id", KEY_LABEL: "Key label", KEY_EXPIRES: "Key expires", SAVED_TO: "Saved to", REVOKED: "Revoked", DELETED: "Deleted" } }, NETWORK = { REASONS: { ECONNREFUSED: "nothing accepts connections there", ENOTFOUND: "the host name is unknown", EAI_AGAIN: "the host name lookup failed", ETIMEDOUT: "the connection timed out", UND_ERR_CONNECT_TIMEOUT: "the connection timed out", ECONNRESET: "the connection was reset" }, TLS_WORDS: "the TLS certificate was not accepted", TLS_CODES: ["CERT_HAS_EXPIRED", "CERT_NOT_YET_VALID", "DEPTH_ZERO_SELF_SIGNED_CERT", "SELF_SIGNED_CERT_IN_CHAIN", "UNABLE_TO_VERIFY_LEAF_SIGNATURE", "UNABLE_TO_GET_ISSUER_CERT_LOCALLY"], TLS_CODE_PREFIXES: ["ERR_TLS_", "ERR_SSL_"], CODE_PATTERN: /^[A-Z][A-Z0-9_]*$/, DETAIL_MAX_CHARS: 80 }, ENV = { TASKS_DIR: "IGNITIFY_TASKS_DIR", KEY: "IGNITIFY_API_KEY", DEV_API_URL: "IGNITIFY_DEV_API_URL" }, DEFAULT_TASKS_DIR = "tasks", RELEASE_BUILD = true, DEFAULTS = { API_URL: "https://api.ignitify.dev" }, UPGRADE_COMMAND = "npm install --global ignitify@latest", PAYLOAD_LIMIT_FALLBACK_BYTES = 10240, RESULT_LIMIT_FALLBACK_BYTES = 10240, RUN_LIST_FLAG_PARAMS = { status: "status", "deployment-id": "deployment_id", "task-name": "task_name", preset: "preset", "correlation-id": "correlation_id", "vm-id": "vm_id", ...PAGE_FLAG_PARAMS }, VM_LIST_FLAG_PARAMS = { "deployment-id": "deployment_id", "task-name": "task_name", preset: "preset", "older-than": "older_than", ...PAGE_FLAG_PARAMS }, GLOBAL_FLAGS = { json: "bool", help: "bool" }, SHORT_FLAGS = { h: "help", y: "yes" }, VERSION_TOKENS = ["--version", "-v"];
1425
+ VALIDATE = { VALID: "task config valid" }, ADVICE = { FLAG: "review-packages", TIMEOUT_MS: 6e4, FAULT_STATUSES: [400, 401, 403], SECONDS_ONLY_BELOW: 60, SECONDS_PER_MINUTE: 60, NO_PACKAGES: "this task lists no build.system_packages", SKIPPED: (reason) => `AI check skipped: ${reason}`, RATE_LIMITED: (retryAfterS) => `rate limited, try again in ${retryAfterS} s`, UNAVAILABLE: (reason) => `the review is unavailable (${reason})`, NO_ANSWER: (status, message) => status === null ? message : `server answered ${status}`, FAULT: (status, body) => `AI check failed (HTTP ${status}): ${body}`, BAD_NAMES: (bad) => `not valid package names: ${bad.join(", ")}`, TOO_MANY: (count, max) => `${count} packages listed, the most is ${max}`, BASIS: { measured: "measured", model: "model estimate" }, NO_FIT: (driveMib, capMib) => `does not fit: ${driveMib} MiB of packages against the ${capMib} MiB image store of your tier`, TITLE: "Package review", NOTE: "AI advice only. A suggestion is not checked against Debian.", COLUMNS: { PACKAGE: "Package", VERDICT: "Verdict", SIZE: "Size", NOTE: "Note", SUGGEST: "Suggest" }, NOT_DOUBLE_CHECKED: "not double-checked by the second model", RESULT_CLEAN: (total) => `No concerns found in ${total} package${total === 1 ? "" : "s"}.`, RESULT_FLAGGED: (total, flagged) => `${total} package${total === 1 ? "" : "s"} checked, ${flagged} to look at.`, NOT_ANSWERED: (names) => `No AI answer for: ${names.join(", ")}. The review could not judge ${names.length === 1 ? "it" : "them"}.`, BUILD_TITLE: "Build time", BUILD_LABELS: { ADDED: "Added", APPLIES: "Applies to", SIZE: "Packages size", LEFT_OUT: "Left out" }, BUILD_NONE: "nothing: your tenant already holds the drive for this list", BUILD_ADDED: (range, basis) => `about ${range} (${basis})`, BUILD_APPLIES: "the first deploy of this list. A later code-only redeploy reuses the drive.", BUILD_SIZE: (mib, capMib) => capMib === null ? `${mib} MiB` : `${mib} MiB of ${capMib} MiB (the image store of your tier)`, BUILD_LEFT_OUT: (names) => `${names.join(", ")} (unusable, or size unknown)` }, INTEGRATION = { PACKAGE_JSON: "package.json", NODE_MODULES: "node_modules", RUNTIME: "node", NPM: "npm", TARBALL_EXT: ".tgz", PACKED_ROOT: "package", PACK_TMP_PREFIX: "ignitify-integration-pack-", PACK_ARGS: (pkg, destDir, taskDir) => ["pack", pkg, "--pack-destination", destDir, "--prefix", taskDir], INSTALL_ARGS: (spec, taskDir) => ["install", spec, "--save-prod", "--ignore-scripts", "--prefix", taskDir], PACKED_MAX_BYTES: 8 * 1024 * 1024, ZLIB_TOO_BIG: "ERR_BUFFER_TOO_LARGE", VERSION_PATTERN: /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/, QUESTION: "Apply?", REGISTRY_URL: "https://registry.npmjs.org", REGISTRY_ACCEPT: "application/vnd.npm.install-v1+json", REGISTRY_TIMEOUT_MS: 5e3, NOTED_FIELDS: ["execution.network.type", "run.preset"], USAGE: "usage: ignitify integration:add <name> --task <slug> [--yes | --dry-run] [--dir <base-dir>]", TASK_REQUIRED: "--task <slug> is required: the task folder to add the integration to", YES_WITH_DRY_RUN: "--yes and --dry-run cannot be used together", BAD_NAME: (name, pattern) => `integration name ${JSON.stringify(name)} must match ${pattern}`, NOT_NODE: (runtime) => `integrations work with Node tasks only; this task has runtime "${runtime}"`, NO_PACKAGE_JSON: (taskDir) => `${taskDir} has no package.json: run npm init in the task folder first; nothing was changed`, NOT_INTERACTIVE: "Refusing to proceed: not a TTY. Re-run with --yes to apply the plan, or with --dry-run to see it.", PACK_FAILED: (pkg, code) => `npm pack ${pkg} failed${code === null ? "" : ` (exit ${code})`}; nothing in the task was changed`, INSTALL_FAILED: (spec, code) => `npm install ${spec} failed${code === null ? "" : ` (exit ${code})`}; task.yaml was not changed`, INSTALLED: (spec) => `${spec} installed`, BAD_VERSION: (pkg, version2) => `${pkg}: its package.json version ${JSON.stringify(version2)} is not a plain x.y.z version; nothing in the task was changed`, PACKED_TOO_BIG: (file, max) => `${file} unpacks to more than ${max} bytes: refused, nothing in the task was changed`, INSTALL_ONLY: (spec) => `installs ${spec}; task.yaml unchanged`, NOT_AN_INTEGRATION: (pkg, file) => `${pkg} has no ${file}: it is not an integration package`, BAD_MANIFEST: (pkg, issue) => `${pkg} integration.yaml: ${issue}`, UNREADABLE: (file, reason) => `cannot read ${file}: ${reason}`, WRITE_MISMATCH: (file) => `the edited ${file} does not read back as the plan; nothing was written`, YOU_ADD: "you add:", NO_CHANGES: "task.yaml already has every setting this integration needs; nothing to write", DRY_RUN: "dry run: task.yaml was not changed", WRITTEN: (file) => `${file} updated`, NOT_INSTALLED: (pkgs) => `${pkgs.join(", ")} ${pkgs.length === 1 ? "is" : "are"} in package.json but not in node_modules: run npm install, then task:validate again`, OBSOLETE: (pkg, version2, latest) => `${pkg}@${version2} is obsolete: use ${latest}`, OBSOLETE_SKIPPED: (reason) => `obsolete-version check skipped: ${reason}`, REGISTRY_UNREACHABLE: "the npm registry did not answer (offline?)", REGISTRY_NOT_FOUND: (pkg) => `${pkg} is not on the npm registry` }, NO_FLAGS = {}, DIR = { dir: "value" }, PAGE = valueFlags(PAGE_FLAG_PARAMS), YES = { yes: "bool" }, RAW = { raw: "bool" }, FOLLOW_FLAG = { follow: "bool" }, DAYS_FLAG = { days: "value" }, USAGE_FLAG_PARAMS = { period: "period", axis: "axis", vm: "vm", run: "run" }, USAGE_FILTERS = valueFlags(USAGE_FLAG_PARAMS), NOTIFICATION_LIST_FLAG_PARAMS = { kind: NOTIFICATION_QUERY.KIND, limit: NOTIFICATION_QUERY.LIMIT }, COMMAND_META = { [COMMANDS.HELP]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.LOGIN]: { flags: { "no-browser": "bool", name: "value" }, positionals: 0, confirms: false }, [COMMANDS.LOGOUT]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.WHOAMI]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.QUOTA]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.TASK_CREATE]: { flags: { ...DIR, lang: "value", local: "bool", "no-init": "bool", "no-scaffold": "bool" }, positionals: 1, confirms: false }, [COMMANDS.TASK_LIST]: { flags: PAGE, positionals: 0, confirms: false }, [COMMANDS.TASK_GET]: { flags: DIR, positionals: 1, confirms: false }, [COMMANDS.TASK_DELETE]: { flags: { ...DIR, ...YES }, positionals: 1, confirms: true }, [COMMANDS.TASK_VALIDATE]: { flags: { ...DIR, [ADVICE.FLAG]: "bool" }, positionals: 1, confirms: false }, [COMMANDS.TASK_PACK]: { flags: DIR, positionals: 1, confirms: false }, [COMMANDS.TASK_DEPLOY]: { flags: { ...DIR, check: "bool" }, positionals: 1, confirms: false }, [COMMANDS.TASK_RUN]: { flags: { deployment: "value", payload: "value", "timeout-sec": "value", "on-busy": "value", at: "value", "idempotency-key": "value", wait: "bool", ...DIR }, positionals: 1, confirms: false }, [COMMANDS.DEPLOYMENT_LIST]: { flags: PAGE, positionals: 0, confirms: false }, [COMMANDS.DEPLOYMENT_GET]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.DEPLOYMENT_LOGS]: { flags: RAW, positionals: 1, confirms: false }, [COMMANDS.DEPLOYMENT_DELETE]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.RUN_LIST]: { flags: valueFlags(RUN_LIST_FLAG_PARAMS), positionals: 0, confirms: false }, [COMMANDS.RUN_GET]: { flags: { full: "bool" }, positionals: 1, confirms: false }, [COMMANDS.RUN_LOGS]: { flags: { ...RAW, ...FOLLOW_FLAG, tail: "value" }, positionals: 1, confirms: false }, [COMMANDS.RUN_TIMELINE]: { flags: FOLLOW_FLAG, positionals: 1, confirms: false }, [COMMANDS.RUN_FAILURES]: { flags: DAYS_FLAG, positionals: 0, confirms: false }, [COMMANDS.RUN_DELETE]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.RUN_CANCEL]: { flags: { ...YES, force: "bool", grace: "value" }, positionals: 1, confirms: true }, [COMMANDS.VM_LIST]: { flags: { ...valueFlags(VM_LIST_FLAG_PARAMS), pinned: "bool" }, positionals: 0, confirms: false }, [COMMANDS.VM_GET]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.VM_DELETE]: { flags: { ...YES, force: "bool" }, positionals: 1, confirms: true }, [COMMANDS.SECRET_SET]: { flags: { stdin: "bool", value: "value" }, positionals: 1, confirms: false, secretArgv: true }, [COMMANDS.SECRET_LIST]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.SECRET_DELETE]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.SCHEDULE_LIST]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.SCHEDULE_CANCEL]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.HOOK_CREATE]: { flags: { "task-name": "value" }, positionals: 1, confirms: false }, [COMMANDS.HOOK_LIST]: { flags: PAGE, positionals: 1, confirms: false }, [COMMANDS.HOOK_DELETE]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.NOTIFY_SET]: { flags: { url: "value", clear: "bool", "secret-stdin": "bool", secret: "value" }, positionals: 1, confirms: false, secretArgv: true }, [COMMANDS.INTEGRATION_ADD]: { flags: { ...DIR, ...YES, task: "value", "dry-run": "bool" }, positionals: 1, confirms: true }, [COMMANDS.USAGE]: { flags: { ...USAGE_FILTERS, runs: "bool", vms: "bool" }, positionals: 0, confirms: false }, [COMMANDS.USAGE_EXPORT]: { flags: { ...USAGE_FILTERS, csv: "bool" }, positionals: 0, confirms: false }, [COMMANDS.USAGE_SERIES]: { flags: DAYS_FLAG, positionals: 0, confirms: false }, [COMMANDS.NOTIFICATION_LIST]: { flags: { ...valueFlags(NOTIFICATION_LIST_FLAG_PARAMS), unread: "bool", open: "bool" }, positionals: 0, confirms: false }, [COMMANDS.PERMISSION_LIST]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.USER_CREATE]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.USER_LIST]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.USER_GET]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.USER_REMOVE]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.GROUP_CREATE]: { flags: { permissions: "value" }, positionals: 1, confirms: false }, [COMMANDS.GROUP_LIST]: { flags: NO_FLAGS, positionals: 0, confirms: false }, [COMMANDS.GROUP_GET]: { flags: NO_FLAGS, positionals: 1, confirms: false }, [COMMANDS.GROUP_GRANT]: { flags: NO_FLAGS, positionals: 2, confirms: false }, [COMMANDS.GROUP_REVOKE]: { flags: NO_FLAGS, positionals: 2, confirms: false }, [COMMANDS.GROUP_ADD_USER]: { flags: NO_FLAGS, positionals: 2, confirms: false }, [COMMANDS.GROUP_REMOVE_USER]: { flags: NO_FLAGS, positionals: 2, confirms: false }, [COMMANDS.GROUP_DELETE]: { flags: YES, positionals: 1, confirms: true }, [COMMANDS.KEY_CREATE]: { flags: { user: "value", label: "value", out: "value" }, positionals: 0, confirms: false }, [COMMANDS.KEY_LIST]: { flags: { user: "value" }, positionals: 0, confirms: false }, [COMMANDS.KEY_REVOKE]: { flags: YES, positionals: 1, confirms: true } }, VERSION_META = { flags: NO_FLAGS, positionals: 0, confirms: false }, KEY_REVOKE_COMMAND = (id) => `ignitify ${COMMANDS.KEY_REVOKE} ${id}`, MESSAGES = { NOT_SIGNED_IN: "Not signed in. Run 'ignitify login', or set the IGNITIFY_API_KEY environment variable.", CREDENTIALS_SYMLINK: (file) => `${file} is a symbolic link. Remove it and run 'ignitify login' again.`, CREDENTIALS_NOT_FILE: (file) => `${file} is not a regular file. Remove it and run 'ignitify login' again.`, CREDENTIALS_NOT_OWNED: (file) => `${file} belongs to another user. Remove it and run 'ignitify login' again.`, CREDENTIALS_TOO_OPEN: (file, mode) => `${file} can be read by other users (mode 0${mode}). Run: chmod 600 ${file}`, CREDENTIALS_UNREADABLE: (file) => `${file} is not a valid credentials file. Remove it and run 'ignitify login' again.`, CREDENTIALS_OTHER_URL: (fileUrl, url) => `The saved key is for ${fileUrl}, not ${url}. Run 'ignitify login'.`, CREDENTIALS_DIR_NOT_DIR: (dir) => `${dir} is not a folder. Remove it and run 'ignitify login' again.`, API_URL_NOT_URL: (url) => `The API address "${url}" is not a URL.`, API_URL_NOT_HTTPS: (url) => `The API address ${url} is not https. The CLI sends your key only over https, or over plain http to this machine (localhost, 127.0.0.1, ::1).`, LOGIN_REPLACED: (label) => `Note: replaced the key "${label}" of another machine. Use 'ignitify login --name <other-label>' to keep both.`, LOGIN_EXPIRED: (code) => `The code ${code} expired before it was approved. Run 'ignitify login' again.`, LOGIN_REFUSED: (reason) => `The sign-in was refused: ${reason}.`, LOGIN_UNKNOWN: "The sign-in code is unknown or was already used. Run 'ignitify login' again.", LOGIN_BAD_ANSWER: "The server sent a sign-in answer with no usable key. Nothing was saved.", LOGIN_BAD_START: "The server sent a sign-in start that the CLI cannot use (no code, or no wait times). Nothing was started.", ENV_KEY_OVERRIDES_LOGIN: "Note: the IGNITIFY_API_KEY environment variable is set, so it is used instead of your saved login.", KEY_EXPIRED_HINT: "Run 'ignitify login' to sign in again.", LOGIN_TOO_MANY: "Too many sign-in attempts from this network. Try again later.", LOGIN_CAP: (limit) => `This account already has the most API keys its plan allows${limit === null ? "" : ` (${limit})`}. Remove one, or approve with "replace", then run 'ignitify login' again.`, CANNOT_REACH: (url, detail) => `Cannot reach ${url}${detail === null ? "" : ` (${detail})`}. Check your network and run 'ignitify login' again.`, UNREACHABLE: (origin, detail) => `Cannot reach ${origin}${detail === null ? "" : ` (${detail})`}.`, LOGOUT_NOTHING: "Not signed in. There are no saved credentials.", LOGOUT_ENV_NOTE: "Note: the IGNITIFY_API_KEY environment variable is still set. Logout does not change it.", LOGOUT_NOT_REVOKED: (label) => `Warning: the server did not revoke the key, so it may still work. The saved credentials were deleted. Ask your operator to revoke the key "${label}".`, SLUG_MISSING: (source) => `'slug' is required in ${source}`, SLUG_INVALID: (source, reason) => `${source}: 'slug' ${reason}`, PRESET_INVALID: "run.preset must be a non-empty string", PRESET_UNKNOWN: (source, name, valid) => `${source}: unknown run.preset "${name}" (valid: ${valid.join(", ")}). An unrecognised preset would silently fall back to the platform default, giving you a different instance class than you declared.`, TIMEOUT_INVALID: "run.timeout_sec must be a positive number", TASK_ID_REQUIRED: "a <task-id> is required", TASK_ID_INVALID: (id, reason) => `task id ${JSON.stringify(id)} ${reason}`, TASK_NOT_REGISTERED: (taskId, dirFlag) => `this folder is not registered yet (no task_id in .ignitify/state.json). Run: ignitify task:create ${taskId} --no-scaffold${dirFlag === void 0 ? "" : ` --dir ${dirFlag}`}, then deploy again.`, ERROR: (message) => `Error: ${message}`, ERROR_PREFIX: "Error:", SERVER_TRACE_ID: (id) => `server trace id: ${id}`, ARG_REQUIRED: (label) => `${label} is required`, UNKNOWN_COMMAND: "unknown command", SEE_HELP: "Run 'ignitify help' to see every command.", UNKNOWN_SHORT_FLAG: (short, long, command) => `unknown flag ${short} (--${long}) for ${command}`, GRACE_INVALID: (got) => `--grace must be a whole number of milliseconds, 0 or more (got ${JSON.stringify(got)})`, GRACE_WITH_FORCE: "--grace has no effect with --force (force stops the run now)", TASK_LIMITS: (payload, result) => `payload max ${payload}, result max ${result}; over the limit the run fails`, PAYLOAD_OVER_LIMIT: (bytes, limit) => `payload is ${bytes} bytes; the limit is ${limit} bytes`, PAYLOAD_REFUSED_BY_SERVER: (limit) => `the server refused the payload as too large; the limit is ${limit} bytes`, DEFAULT_PAYLOAD_OVER_LIMIT: (source, bytes, limit) => `${source}: run.payload is ${bytes} bytes; the offline limit is ${limit} bytes (the server may allow more)`, IGNORED_BY_FILE: `ignored by ${IGNORE_FILE}`, IGNORED_COUNT: (n) => `${n} path(s) left out by ${IGNORE_FILE}`, TASK_DELETED: "task deleted", TASK_LINK_REMOVED: "Removed local link", TASK_LINK_NOT_REMOVED: (link, reason) => `Warning: the task is deleted, but its local link was not removed (${reason}). Remove ${link} by hand.`, DEPLOY_DELETED: "deployment deleted", RUN_DELETED: "run deleted", ABORTED: "Aborted.", CONFIRM_PROCEED: "Proceed?", SECRET_SET_USAGE: "usage: ignitify secret:set <NAME> --stdin (the value is read from stdin)", SECRET_VALUE_EMPTY: "secret:set read an empty value from stdin \u2014 nothing was stored (pipe the value in: `--stdin < value-file`)", SECRET_VALUE_ON_ARGV: `secret:set takes no value on argv: it is visible in \`ps\` and is written to your shell history. Pipe it on stdin, e.g.
1353
1426
  ignitify secret:set <NAME> --stdin < value-file
1354
1427
  printf %s "$VALUE" | ignitify secret:set <NAME> --stdin
1355
1428
  \u26A0\uFE0F The value you just typed is already in your history \u2014 rotate it.`, NOTIFY_SECRET_ON_ARGV: '--secret is not accepted: a value on argv is visible in `ps` and is written to your shell history. Use --secret-stdin, e.g.\n printf %s "$SECRET" | ignitify notify:set <deployment-id> --url <https://\u2026> --secret-stdin\n\u26A0\uFE0F The value you just typed is already in your history \u2014 rotate it.', HOOK_CREATE_USAGE: "usage: ignitify hook:create <deployment-id> --task-name <name>", HOOK_TASK_NAME_REQUIRED: `--task-name <name> is required: a hook starts a run of ONE task in the deployment, and a run without a task name fails.
@@ -1357,14 +1430,15 @@ usage: ignitify hook:create <deployment-id> --task-name <name>`, HOOK_LIST_USAGE
1357
1430
  ignitify notify:set <deployment-id> --clear
1358
1431
  --secret-stdin reads the signing secret (at least ${32} characters) from stdin; it is
1359
1432
  required with --url. There is no --secret flag: a value on argv is visible in \`ps\`
1360
- and lands in your shell history.`, NOTIFY_URL_NEEDS_SECRET: "--url needs --secret-stdin: the server refuses a notify target with no signing secret.", NOTIFY_SECRET_EMPTY: "--secret-stdin read an empty value from stdin.", NOTIFY_URL_WITH_CLEAR: "--url and --clear cannot be used together.", NOTIFY_SECRET_STDIN_VALUE: "--secret-stdin takes no value: pipe the secret on stdin.", HOOK_SECRET_SHOWN_ONCE: "\u26A0\uFE0F The secret below is shown ONCE and cannot be read back \u2014 hook:list never returns it. Store it now; if it is lost, delete the hook and create a new one.", HOOK_PAYLOAD_LIMIT: (limit) => `A webhook body over ${limit} is refused with 413 before the signature is checked.`, SECRET_DELETE_USAGE: "usage: ignitify secret:delete <NAME>", USAGE_EXPORT_USAGE: "usage: ignitify usage:export [--period YYYY-MM] (--json|--csv) (name exactly one format)", LATEST_DEPLOY_BUILDING: (task, deploymentId) => `the latest deploy of ${task} is still building (${deploymentId}). Wait for it ('ignitify deployment:get ${deploymentId}'), or pass --deployment <id> to run an older one.`, LATEST_DEPLOY_FAILED: (task, reason) => `the latest deploy of ${task} failed: ${reason ?? "no reason recorded"}. Fix the task and run 'ignitify task:deploy ${task}' again, or pass --deployment <id> to run an older one.`, RUN_AT_WITH_WAIT: "--wait cannot be used with --at: a scheduled run has no run id until it fires. Drop --wait; follow it later with 'ignitify schedule:list' and 'ignitify run:list'.", SECRET_STORED: (name) => `secret ${name} stored`, SECRET_REMOVED: (name) => `secret ${name} removed` }, RUN_STATUS = { PENDING: "PENDING", PROVISIONING: "PROVISIONING", RUNNING: "RUNNING", RETRYING: "RETRYING", COMPLETED: "COMPLETED", FAILED: "FAILED", CANCELLED: "CANCELLED" }, ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([RUN_STATUS.PENDING, RUN_STATUS.PROVISIONING, RUN_STATUS.RUNNING, RUN_STATUS.RETRYING]), DEPLOYMENT_STATUS = { BUILDING: "BUILDING", READY: "READY", FAILED: "FAILED", ARCHIVED: "ARCHIVED" }, POLL = { DEPLOY: { BASE_MS: 500, MAX_MS: 1e3, TIMEOUT_MS: 900 * 1e3 }, RUN: { BASE_MS: 500, MAX_MS: 3e3, TIMEOUT_MS: 1800 * 1e3 }, ERROR: { MIN_TRIES: 3, GRACE_MS: 6e4 } }, WAIT = { UPLOADING: (slug2, size) => `Uploading ${slug2}${size ? ` (${size})` : ""}`, UPLOAD_FAILED: "Upload failed", BUILDING: (deploymentId) => `Building image ${deploymentId}`, BUILT: "Image built", REUSED: "Image already built \u2014 reused", BUILD_FAILED: "Build failed", BUILD_FAILED_DETAIL: (deploymentId, reason) => `deployment ${deploymentId} failed to build \u2014 ${reason}`, BUILD_TIMEOUT: "Still building after 15 minutes \u2014 stopped waiting", BUILD_TIMEOUT_DETAIL: (deploymentId) => `deployment ${deploymentId} is still building after 15 minutes. The build has NOT been cancelled \u2014 check it with 'ignitify deployment:get ${deploymentId}'.`, RUN: (runId, status) => `Run ${runId} ${status}`, RUN_SUBMITTED: (runId) => `Run ${runId} submitted`, RUN_ENDED: (status) => `Run ${status}`, RUN_TIMEOUT: (status) => `Run is still ${status} after 30 minutes \u2014 stopped waiting`, RUN_TIMEOUT_DETAIL: (runId) => `The run has NOT been cancelled \u2014 check it with 'ignitify run:get ${runId}'.`, HINT_RETRYING: "lost contact with the server \u2014 retrying", LOST: "Lost contact with the server \u2014 stopped waiting", LOST_BUILD_DETAIL: (deploymentId, cause) => `stopped waiting for deployment ${deploymentId}: ${cause}. The build has NOT been cancelled \u2014 check it with 'ignitify deployment:get ${deploymentId}'.`, LOST_RUN_DETAIL: (runId, cause) => `stopped waiting for run ${runId}: ${cause}. The run has NOT been cancelled \u2014 check it with 'ignitify run:get ${runId}'.`, HINT_BUILD: "Ctrl+C stops waiting, not the build", HINT_RUN: "Ctrl+C stops waiting, not the run", INTERRUPTED_BUILD: (deploymentId, started) => `Stopped waiting. The build ${started ? "keeps running" : "is queued"} on the server \u2014 nothing was cancelled.
1433
+ and lands in your shell history.`, NOTIFY_URL_NEEDS_SECRET: "--url needs --secret-stdin: the server refuses a notify target with no signing secret.", NOTIFY_SECRET_EMPTY: "--secret-stdin read an empty value from stdin.", NOTIFY_URL_WITH_CLEAR: "--url and --clear cannot be used together.", NOTIFY_SECRET_STDIN_VALUE: "--secret-stdin takes no value: pipe the secret on stdin.", HOOK_SECRET_SHOWN_ONCE: "\u26A0\uFE0F The secret below is shown ONCE and cannot be read back \u2014 hook:list never returns it. Store it now; if it is lost, delete the hook and create a new one.", HOOK_SECRET_REDACTED: (id) => `the server answered without the secret (a replay of an earlier request), and it is not shown again. Delete ${id} with 'ignitify hook:delete ${id}' and create another to get a new secret.`, HOOK_PAYLOAD_LIMIT: (limit) => `A webhook body over ${limit} is refused with 413 before the signature is checked.`, SECRET_DELETE_USAGE: "usage: ignitify secret:delete <NAME>", USAGE_EXPORT_USAGE: "usage: ignitify usage:export [--period YYYY-MM] (--json|--csv) (name exactly one format)", DAYS_INVALID: (raw) => `--days must be a whole number of days, 1 or more (got ${JSON.stringify(raw)})`, NOTIFICATION_ONE_VIEW: "Choose --unread or --open, not both.", NOTIFICATION_MORE: (max) => `Older notifications exist. Raise --limit (at most ${max}), or open Notifications in the app.`, NOTIFICATION_MORE_IN_APP: "Older notifications exist. Open Notifications in the app to see them.", LATEST_DEPLOY_BUILDING: (task, deploymentId) => `the latest deploy of ${task} is still building (${deploymentId}). Wait for it ('ignitify deployment:get ${deploymentId}'), or pass --deployment <id> to run an older one.`, LATEST_DEPLOY_FAILED: (task, reason) => `the latest deploy of ${task} failed: ${reason ?? "no reason recorded"}. Fix the task and run 'ignitify task:deploy ${task}' again, or pass --deployment <id> to run an older one.`, RUN_AT_WITH_WAIT: "--wait cannot be used with --at: a scheduled run has no run id until it fires. Drop --wait; follow it later with 'ignitify schedule:list' and 'ignitify run:list'.", IDEMPOTENCY_KEY_INVALID: (key) => `--idempotency-key must be 8 to 255 characters of A-Z a-z 0-9 . _ : -, got: ${key}`, RUN_REPLAYED: "this is the answer to an earlier request with the same --idempotency-key; no new run was started.", IDEMPOTENCY_KEY_REUSED_HINT: "Use a new --idempotency-key for a different run. Reuse a key only to retry the same run.", IDEMPOTENCY_IN_PROGRESS_HINT: "If an earlier request with this key is still running, retry with the same key shortly.", SECRET_STORED: (name) => `secret ${name} stored`, SECRET_REMOVED: (name) => `secret ${name} removed`, ACCESS_NAME_INVALID: (kind, name) => `${kind} name ${JSON.stringify(name)} is not valid: use ${ACCESS_NAME_RULE}`, PERMISSION_UNKNOWN: (permission) => `unknown permission ${JSON.stringify(permission)}. Run 'ignitify permission:list' to see the permissions.`, PERMISSION_NOT_GRANTABLE: (marker) => `${JSON.stringify(marker)} is not a permission and cannot be granted: only owner keys manage access.`, PERMISSIONS_REQUIRED: "--permissions <p1,p2,\u2026> is required: name at least one permission, comma-separated.", KEY_USER_REQUIRED: "--user <name> is required: a key belongs to one user. Owner keys come from ignitify login.", KEY_LABEL_REQUIRED: "--label <text> is required: it tells you later where the key is used.", KEY_SHOWN_ONCE: "\u26A0\uFE0F The key below is shown ONCE and cannot be read back. Hand it over now; if it is lost, revoke it and create another.", KEY_OUT_EXISTS: (file) => `${file} already exists. key:create --out writes a new file only and never follows a link. Choose another name; no key was created.`, KEY_OUT_FAILED: (file, reason) => `cannot create ${file} (${reason}); no key was created.`, KEY_OUT_WRITE_FAILED: (file, reason, id) => `cannot write ${file} (${reason}). Key ${id} was created but its value is lost: revoke it with '${KEY_REVOKE_COMMAND(id)}' and create another.`, KEY_WRITTEN: (id, file) => `key ${id} written to ${file} (mode 0600). Hand the file over, then delete your copy.`, KEY_REDACTED: (id) => `the server answered without the key (a replay of an earlier request). Revoke ${id} with '${KEY_REVOKE_COMMAND(id)}' and create another.`, USER_CREATED: (name) => `user ${name} created`, USER_REMOVED: (name, keys) => `user ${name} removed; ${keys} key(s) revoked`, GROUP_CREATED: (name) => `group ${name} created`, GROUP_GRANTED: (name, permission) => `group ${name} now has ${permission}`, GROUP_REVOKED: (name, permission) => `group ${name} no longer has ${permission}`, GROUP_USER_ADDED: (group, user) => `user ${user} added to group ${group}`, GROUP_USER_REMOVED: (group, user) => `user ${user} removed from group ${group}`, GROUP_DELETED: (name) => `group ${name} deleted`, KEY_REVOKED: (id) => `key ${id} revoked`, ACCESS_PERMISSION_DENIED: (needed) => needed === null ? "permission denied: this key lacks the permission this command needs. Ask the owner to grant it to one of your groups." : `permission denied: this key needs the ${needed} permission. Ask the owner to grant it to one of your groups.`, ACCESS_OWNER_REQUIRED: "owner key required: only owner keys manage users, groups and keys. This is a user key.", ACCESS_REFUSED: (error, reason) => `${error} (${reason})` }, ACCESS = { OWNER: "owner", SEPARATOR: ",", USER: "user", GROUP: "group", TASKS_WRITE_NOTE: "tasks.write can delete deployments and runs too: deleting a task deletes its deployments, cancels and deletes their runs and stops their VMs. Grant it only where deployments.write and runs.write are acceptable too.", SECRETS_READ_NOTE: "deployments.write plus runs.write can read secret values in practice: deploy code that prints its environment, then run it.", HOOKS_WRITE_NOTE: "hooks.write can start runs (a hook trigger starts a run) and can send run results to any URL. Grant it only where runs.write is acceptable too." }, RUN_STATUS = { PENDING: "PENDING", PROVISIONING: "PROVISIONING", RUNNING: "RUNNING", RETRYING: "RETRYING", COMPLETED: "COMPLETED", FAILED: "FAILED", CANCELLED: "CANCELLED" }, ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([RUN_STATUS.PENDING, RUN_STATUS.PROVISIONING, RUN_STATUS.RUNNING, RUN_STATUS.RETRYING]), DEPLOYMENT_STATUS = { BUILDING: "BUILDING", READY: "READY", FAILED: "FAILED", ARCHIVED: "ARCHIVED" }, POLL = { DEPLOY: { BASE_MS: 500, MAX_MS: 1e3, TIMEOUT_MS: 900 * 1e3 }, RUN: { BASE_MS: 500, MAX_MS: 3e3, TIMEOUT_MS: 1800 * 1e3 }, ERROR: { MIN_TRIES: 3, GRACE_MS: 6e4 } }, WAIT = { UPLOADING: (slug2, size) => `Uploading ${slug2}${size ? ` (${size})` : ""}`, UPLOAD_FAILED: "Upload failed", BUILDING: (deploymentId) => `Building image ${deploymentId}`, BUILT: "Image built", REUSED: "Image already built \u2014 reused", BUILD_FAILED: "Build failed", BUILD_FAILED_DETAIL: (deploymentId, reason) => `deployment ${deploymentId} failed to build \u2014 ${reason}`, BUILD_TIMEOUT: "Still building after 15 minutes \u2014 stopped waiting", BUILD_TIMEOUT_DETAIL: (deploymentId) => `deployment ${deploymentId} is still building after 15 minutes. The build has NOT been cancelled \u2014 check it with 'ignitify deployment:get ${deploymentId}'.`, RUN: (runId, status) => `Run ${runId} ${status}`, RUN_SUBMITTED: (runId) => `Run ${runId} submitted`, RUN_ENDED: (status) => `Run ${status}`, RUN_TIMEOUT: (status) => `Run is still ${status} after 30 minutes \u2014 stopped waiting`, RUN_TIMEOUT_DETAIL: (runId) => `The run has NOT been cancelled \u2014 check it with 'ignitify run:get ${runId}'.`, HINT_RETRYING: "lost contact with the server \u2014 retrying", LOST: "Lost contact with the server \u2014 stopped waiting", LOST_BUILD_DETAIL: (deploymentId, cause) => `stopped waiting for deployment ${deploymentId}: ${cause}. The build has NOT been cancelled \u2014 check it with 'ignitify deployment:get ${deploymentId}'.`, LOST_RUN_DETAIL: (runId, cause) => `stopped waiting for run ${runId}: ${cause}. The run has NOT been cancelled \u2014 check it with 'ignitify run:get ${runId}'.`, HINT_BUILD: "Ctrl+C stops waiting, not the build", HINT_RUN: "Ctrl+C stops waiting, not the run", INTERRUPTED_BUILD: (deploymentId, started) => `Stopped waiting. The build ${started ? "keeps running" : "is queued"} on the server \u2014 nothing was cancelled.
1361
1434
  Check it with: ignitify deployment:get ${deploymentId}`, INTERRUPTED_RUN: (runId) => `Stopped waiting. The run keeps going on the server \u2014 nothing was cancelled.
1362
- Check it with: ignitify run:get ${runId}` };
1435
+ Check it with: ignitify run:get ${runId}` }, FOLLOW = { WAIT_SEC: 20, IDLE_MS: 2e3, RETRY_FALLBACK_MS: 2e3 }, MS_PER_SECOND = 1e3, BUSY_READ = { MAX_RETRIES: 3, NOTE: (seconds) => `server busy, retrying in ${seconds}s` }, FOLLOW_MESSAGES = { AGENT_OUTDATED: "the host is running an older agent; try again after the update, or read it without --follow or --tail", API_NO_CURSOR: "this API cannot follow output yet; run the command without --follow or --tail", TAIL_INVALID: (raw) => `--tail must be a whole number of lines, 1 or more (got ${JSON.stringify(raw)})`, INTERRUPTED: (runId) => `Stopped following. The run keeps going on the server \u2014 nothing was cancelled.
1436
+ Check it with: ignitify run:get ${runId}`, STILL_LIVE: (status) => `Run ${status} \u2014 still live; add --follow to watch it` };
1363
1437
  } });
1364
1438
  var ANSI, GLYPHS, LAYOUT, LABELS, EMPTY_LISTS, DISPLAY_CAPS, TITLES, PER_BRAIN_MARKER, PER_BRAIN_FOOTNOTE, POLICY_UNIT_NOTES, HIDDEN_FIELDS, RESULT_MESSAGES, RUN_CANCEL_OUTCOME, init_constants2 = __esm({ "src/output/constants.ts"() {
1365
1439
  "use strict";
1366
1440
  init_define_IGNITIFY_CLIENT_FILES();
1367
- ANSI = { reset: "\x1B[0m", bold: "\x1B[1m", dim: "\x1B[2m", underline: "\x1B[4m", red: "\x1B[31m", green: "\x1B[32m", yellow: "\x1B[33m", cyan: "\x1B[36m", clearLine: "\r\x1B[2K", hideCursor: "\x1B[?25l", showCursor: "\x1B[?25h" }, GLYPHS = { unicode: { ok: "\u2713", err: "\u2717", warn: "\u26A0", bullet: "\u2022", ellipsis: "\u2026", dash: "\u2014", rule: "\u2500", box: { tl: "\u250C", tr: "\u2510", bl: "\u2514", br: "\u2518", h: "\u2500", v: "\u2502" }, frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"] }, ascii: { ok: "OK", err: "x", warn: "!", bullet: "*", ellipsis: "...", dash: "-", rule: "-", box: { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|" }, frames: ["-", "\\", "|", "/"] } }, LAYOUT = { MAX_WIDTH: 80, INDENT: " ", GAP: " ", MIN_COLUMN: 8, SPINNER_MS: 100, NO_UNICODE_TERMS: ["dumb", "linux"] }, LABELS = { NEXT_STEP: "Next Step:", SYSTEM_RESOURCES: "System Resources:", RESULT: "Result:", MORE_LINES: (n) => `\u2026 ${n} more lines (run:get --full shows all)`, BUILD_LOG: "Build log:", PLATFORM_BUILT_IMAGE: "Image: built and stored by the platform; there is nothing for you to download.", EARLIER_LINES: (n) => `\u2026 ${n} earlier lines (deployment:get <id> shows all)`, NO_RESULTS: "(No results)", EMPTY: "(empty)" }, EMPTY_LISTS = { ANY: { message: "(No results)" }, TASKS: { message: "No tasks yet.", next: "Create one with: ignitify task:create <task-id>" }, DEPLOYMENTS: { message: "No deployments yet.", next: "Build one with: ignitify task:deploy <task-id>" }, RUNS: { message: "No runs yet.", next: "Start one with: ignitify task:run <task-id>" }, VMS: { message: "No live VMs." }, SCHEDULES: { message: "No scheduled runs.", next: "Schedule one with: ignitify task:run <task-id> --at <iso>" }, HOOKS: { message: "No webhooks yet.", next: "Create one with: ignitify hook:create <deployment-id> --task-name <name>" } }, DISPLAY_CAPS = { RESULT_MAX_LINES: 40, BUILD_LOG_TAIL_LINES: 30, ERROR_MAX_CHARS: 2e3 }, TITLES = { TENANT_PROFILE: "Tenant Profile", TASK_REGISTERED: "Task Registered", SOURCE_PACK: "Source Upload (nothing built, nothing sent)", DEPLOYMENT_CREATED: "Deployment Created", RUN_SUBMITTED: "Run Submitted", RUN_DETAILS: "Run Details", DEPLOYMENT_DETAILS: "Deployment Details", VM_DETAILS: "VM Details", USAGE: "Usage & Limits", UNIT_WEIGHTS: "Units per run (by preset)", ENTITLEMENTS: "Entitlements (tier policy)", ENFORCED: "Enforced Limits (what this server applies)" }, PER_BRAIN_MARKER = "(per server)", PER_BRAIN_FOOTNOTE = " (per server) \u2014 each server applies this limit on its own, so the limit across all servers is at least this.", POLICY_UNIT_NOTES = { max_compute_seconds_month: "(run seconds, not the VM time `usage` shows as compute)" }, HIDDEN_FIELDS = { SCALAR: ["payload", "result", "slug"], LIST: ["payload", "result", "execution"] }, RESULT_MESSAGES = { TASK_GET_OFFLINE: (reason) => `Note: ${reason.replace(/\.$/, "")}. The server sections show UNKNOWN.`, TASK_CREATED_LOCAL: (lang, taskId, dir) => `Created ${lang} task ${taskId} at ${dir} (local only \u2014 not registered)`, HOOK_CREATED_TITLE: "Webhook Created", HOOK_SECRET_KEY: "secret (shown ONCE)", HOOK_DELETED: (id) => `Webhook deleted: ${id}`, NOTIFY_SET: (deploymentId, url) => `Notify URL for ${deploymentId} set to ${url}`, NOTIFY_CLEARED: (deploymentId) => `Notify URL for ${deploymentId} cleared`, SCHEDULE_CANCELLED: (id) => `Schedule cancelled: ${id}`, SCHEDULE_CANCEL_PREVIEW: (id) => `Will cancel schedule ${id} \u2014 it will never fire.`, SCHEDULE_NOT_CANCELLED: (id) => `Schedule ${id} was NOT cancelled: not found, already fired, or currently firing.`, HOOK_DELETE_PREVIEW: (id) => `Will delete webhook ${id}. A sender that posts to it is refused from then on.`, SECRET_DELETE_PREVIEW: (name) => `Will delete secret ${name}. Its value cannot be read back.`, DEPLOYMENT_DELETE_PREVIEW: (id) => `Will soft-delete deployment ${id} and all its runs (cascade).`, RUN_DELETE_PREVIEW: (id) => `Will soft-delete run ${id}.`, RUN_ALREADY_OVER: (id, status) => `Run ${id} is already ${status} \u2014 nothing to cancel.`, RUN_CANCEL_PREVIEW: (id, force) => force ? `Will cancel run ${id} immediately (force: destroys the VM even if it is pinned).` : `Will ask run ${id} to stop gracefully; it is killed if it does not finish in time.`, RUN_STOPPING: (id, grace, was) => `Run ${id} is stopping${grace}${was} \u2014 still RUNNING until it finishes or the grace expires.`, RUN_CANCELLED: (id, was) => `Run cancelled: ${id}${was}`, LOG_TRUNCATED: (lines) => `truncated \u2014 ${lines} line(s) shown; the log was cut at the size cap.`, NO_SECRETS: "(no secrets)", NO_SECRETS_NEXT: "Store one with: ignitify secret:set <NAME> --stdin" }, RUN_CANCEL_OUTCOME = { ALREADY_TERMINAL: "already-terminal", DRAINING: "draining", CANCELLED: "cancelled" };
1441
+ ANSI = { reset: "\x1B[0m", bold: "\x1B[1m", dim: "\x1B[2m", underline: "\x1B[4m", red: "\x1B[31m", green: "\x1B[32m", yellow: "\x1B[33m", cyan: "\x1B[36m", clearLine: "\r\x1B[2K", hideCursor: "\x1B[?25l", showCursor: "\x1B[?25h" }, GLYPHS = { unicode: { ok: "\u2713", err: "\u2717", warn: "\u26A0", bullet: "\u2022", ellipsis: "\u2026", dash: "\u2014", rule: "\u2500", box: { tl: "\u250C", tr: "\u2510", bl: "\u2514", br: "\u2518", h: "\u2500", v: "\u2502" }, frames: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"] }, ascii: { ok: "OK", err: "x", warn: "!", bullet: "*", ellipsis: "...", dash: "-", rule: "-", box: { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|" }, frames: ["-", "\\", "|", "/"] } }, LAYOUT = { MAX_WIDTH: 80, INDENT: " ", GAP: " ", MIN_COLUMN: 8, SPINNER_MS: 100, NO_UNICODE_TERMS: ["dumb", "linux"] }, LABELS = { NEXT_STEP: "Next Step:", SYSTEM_RESOURCES: "System Resources:", RESULT: "Result:", MORE_LINES: (n) => `\u2026 ${n} more lines (run:get --full shows all)`, BUILD_LOG: "Build log:", PLATFORM_BUILT_IMAGE: "Image: built and stored by the platform; there is nothing for you to download.", EARLIER_LINES: (n) => `\u2026 ${n} earlier lines (deployment:get <id> shows all)`, NO_RESULTS: "(No results)", EMPTY: "(empty)" }, EMPTY_LISTS = { ANY: { message: "(No results)" }, TASKS: { message: "No tasks yet.", next: "Create one with: ignitify task:create <task-id>" }, DEPLOYMENTS: { message: "No deployments yet.", next: "Build one with: ignitify task:deploy <task-id>" }, RUNS: { message: "No runs yet.", next: "Start one with: ignitify task:run <task-id>" }, VMS: { message: "No live VMs." }, SCHEDULES: { message: "No scheduled runs.", next: "Schedule one with: ignitify task:run <task-id> --at <iso>" }, HOOKS: { message: "No webhooks yet.", next: "Create one with: ignitify hook:create <deployment-id> --task-name <name>" }, USERS: { message: "No users yet.", next: "Create one with: ignitify user:create <name>" }, GROUPS: { message: "No groups yet.", next: "Create one with: ignitify group:create <name> --permissions <p1,p2>" }, KEYS: { message: "No live keys." } }, DISPLAY_CAPS = { RESULT_MAX_LINES: 40, BUILD_LOG_TAIL_LINES: 30, ERROR_MAX_CHARS: 2e3 }, TITLES = { TENANT_PROFILE: "Tenant Profile", KEY_ACCESS: "This Key", TASK_REGISTERED: "Task Registered", SOURCE_PACK: "Source Upload (nothing built, nothing sent)", DEPLOYMENT_CREATED: "Deployment Created", RUN_SUBMITTED: "Run Submitted", RUN_DETAILS: "Run Details", DEPLOYMENT_DETAILS: "Deployment Details", VM_DETAILS: "VM Details", USAGE: "Usage & Limits", UNIT_WEIGHTS: "Units per run (by preset)", ENTITLEMENTS: "Entitlements (tier policy)", ENFORCED: "Enforced Limits (what this server applies)" }, PER_BRAIN_MARKER = "(per server)", PER_BRAIN_FOOTNOTE = " (per server) \u2014 each server applies this limit on its own, so the limit across all servers is at least this.", POLICY_UNIT_NOTES = { max_compute_seconds_month: "(run seconds, not the VM time `usage` shows as compute)" }, HIDDEN_FIELDS = { SCALAR: ["payload", "result", "slug"], LIST: ["payload", "result", "execution"] }, RESULT_MESSAGES = { TASK_GET_OFFLINE: (reason) => `Note: ${reason.replace(/\.$/, "")}. The server sections show UNKNOWN.`, TASK_CREATED_LOCAL: (lang, taskId, dir) => `Created ${lang} task ${taskId} at ${dir} (local only \u2014 not registered)`, HOOK_CREATED_TITLE: "Webhook Created", HOOK_SECRET_KEY: "secret (shown ONCE)", HOOK_DELETED: (id) => `Webhook deleted: ${id}`, NOTIFY_SET: (deploymentId, url) => `Notify URL for ${deploymentId} set to ${url}`, NOTIFY_CLEARED: (deploymentId) => `Notify URL for ${deploymentId} cleared`, SCHEDULE_CANCELLED: (id) => `Schedule cancelled: ${id}`, SCHEDULE_CANCEL_PREVIEW: (id) => `Will cancel schedule ${id} \u2014 it will never fire.`, SCHEDULE_NOT_CANCELLED: (id) => `Schedule ${id} was NOT cancelled: not found, already fired, or currently firing.`, HOOK_DELETE_PREVIEW: (id) => `Will delete webhook ${id}. A sender that posts to it is refused from then on.`, SECRET_DELETE_PREVIEW: (name) => `Will delete secret ${name}. Its value cannot be read back.`, DEPLOYMENT_DELETE_PREVIEW: (id) => `Will soft-delete deployment ${id} and all its runs (cascade).`, RUN_DELETE_PREVIEW: (id) => `Will soft-delete run ${id}.`, RUN_ALREADY_OVER: (id, status) => `Run ${id} is already ${status} \u2014 nothing to cancel.`, RUN_CANCEL_PREVIEW: (id, force) => force ? `Will cancel run ${id} immediately (force: destroys the VM even if it is pinned).` : `Will ask run ${id} to stop gracefully; it is killed if it does not finish in time.`, RUN_STOPPING: (id, grace, was) => `Run ${id} is stopping${grace}${was} \u2014 still RUNNING until it finishes or the grace expires.`, RUN_CANCELLED: (id, was) => `Run cancelled: ${id}${was}`, LOG_TRUNCATED: (lines) => `truncated \u2014 ${lines} line(s) shown; the log was cut at the size cap.`, USER_REMOVE_PREVIEW: (name) => `Will remove user ${name} and revoke every key of the user. The keys stop working at once.`, GROUP_DELETE_PREVIEW: (name) => `Will delete group ${name}. Its users lose the permissions it grants; users and keys stay.`, KEY_REVOKE_PREVIEW: (id) => `Will revoke key ${id}. A program that uses it is refused from then on.`, KEY_CREATED_TITLE: "Key Created", KEY_RAW_KEY: "key (shown ONCE)", USER_KEYS_TITLE: "Keys", NONE: "-", NO_SECRETS: "(no secrets)", NO_SECRETS_NEXT: "Store one with: ignitify secret:set <NAME> --stdin" }, RUN_CANCEL_OUTCOME = { ALREADY_TERMINAL: "already-terminal", DRAINING: "draining", CANCELLED: "cancelled" };
1368
1442
  } });
1369
1443
  function makeStyle(o) {
1370
1444
  let p = (...codes) => paint(o.colour, ...codes), columns = Math.max(o.width, 1);
@@ -1394,15 +1468,15 @@ function paintStatus(st, status) {
1394
1468
  let s = String(status).toUpperCase(), tone = STATUS_TONE[s];
1395
1469
  return tone === "ok" ? st.green(s) : tone === "busy" ? st.yellow(s) : tone === "bad" ? st.red(s) : st.dim(s);
1396
1470
  }
1397
- var paint, PLAIN, resolveStyle, plain, plainLines, TERMINAL_CONTROL, SGR, terminalSafe, stripAnsi, visibleLength, padVisible, cut, STATUS_TONE, init_style = __esm({ "src/output/style.ts"() {
1471
+ var paint, PLAIN, resolveStyle, plain, plainLines, SGR, isColour, terminalSafe, stripAnsi, visibleLength, padVisible, cut, STATUS_TONE, init_style = __esm({ "src/output/style.ts"() {
1398
1472
  "use strict";
1399
1473
  init_define_IGNITIFY_CLIENT_FILES();
1474
+ init_tenant();
1400
1475
  init_constants2();
1401
1476
  paint = (on, ...codes) => (s) => on && s !== "" ? `${codes.join("")}${s}${ANSI.reset}` : s;
1402
1477
  PLAIN = makeStyle({ colour: false, unicode: true, width: LAYOUT.MAX_WIDTH });
1403
1478
  resolveStyle = (f) => makeStyle({ colour: wantsColour(f), unicode: wantsUnicode(f), width: f.columns !== void 0 && f.columns > 0 ? f.columns : LAYOUT.MAX_WIDTH });
1404
- plain = (s) => s.replace(/[\u0000-\u001f\u007f-\u009f]/g, ""), plainLines = (s) => s.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, ""), TERMINAL_CONTROL = /\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\)?|[PX^_][^\x1b]*(?:\x1b\\)?|[ -/]*[0-~])?|\r\n?|[\u0000-\u0008\u000b\u000c\u000e-\u001a\u001c-\u001f\u007f-\u009f]/g, SGR = /^\x1b\[[0-9;:]*m$/, terminalSafe = (s, keepColour) => s.replace(TERMINAL_CONTROL, (m) => keepColour && SGR.test(m) ? m : m.startsWith("\r") ? `
1405
- ` : ""), stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, ""), visibleLength = (s) => stripAnsi(s).length, padVisible = (s, width) => s + " ".repeat(Math.max(0, width - visibleLength(s))), cut = (s, max, ellipsis) => s.length <= max || max <= ellipsis.length ? s : `${s.slice(0, max - ellipsis.length)}${ellipsis}`;
1479
+ plain = (s) => s.replace(/[\u0000-\u001f\u007f-\u009f]/g, ""), plainLines = (s) => s.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g, ""), SGR = /^\x1b\[[0-9;:]*m$/, isColour = (unit) => SGR.test(unit), terminalSafe = (s, keepColour) => keepColour ? stripControl(s, isColour) : stripControl(s), stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, ""), visibleLength = (s) => stripAnsi(s).length, padVisible = (s, width) => s + " ".repeat(Math.max(0, width - visibleLength(s))), cut = (s, max, ellipsis) => s.length <= max || max <= ellipsis.length ? s : `${s.slice(0, max - ellipsis.length)}${ellipsis}`;
1406
1480
  STATUS_TONE = { COMPLETED: "ok", READY: "ok", ACTIVE: "ok", DONE: "ok", OK: "ok", PENDING: "busy", PROVISIONING: "busy", RUNNING: "busy", RETRYING: "busy", BUILDING: "busy", FAILED: "bad" };
1407
1481
  } });
1408
1482
  function cellText(v) {
@@ -1496,6 +1570,94 @@ var heading, successLine, errorMark, warnMark, noteLine, emptyState, init_blocks
1496
1570
  heading = (st, title, ok2 = false) => ok2 ? st.bold(st.green(`${st.glyphs.ok} ${title}`)) : st.bold(title), successLine = (st, text) => `${st.green(st.glyphs.ok)} ${text}`, errorMark = (st, text) => `${st.red(st.glyphs.err)} ${text}`, warnMark = (st, text) => `${st.yellow(st.glyphs.warn)} ${text}`, noteLine = (st, text) => st.yellow(text), emptyState = (st, message, next) => next === void 0 ? st.dim(message) : `${st.dim(message)}
1497
1571
  ${st.dim(next)}`;
1498
1572
  } });
1573
+ function checkAccessName(kind, name) {
1574
+ return ACCESS_NAME_PATTERN.test(name) ? { ok: true, value: name } : { ok: false, message: MESSAGES.ACCESS_NAME_INVALID(kind, name) };
1575
+ }
1576
+ function checkPermission(permission) {
1577
+ return isPermission(permission) ? { ok: true, value: permission } : { ok: false, message: MARKERS.includes(permission) ? MESSAGES.PERMISSION_NOT_GRANTABLE(permission) : MESSAGES.PERMISSION_UNKNOWN(permission) };
1578
+ }
1579
+ function parsePermissions(raw) {
1580
+ let names = (raw ?? "").split(ACCESS.SEPARATOR).map((p) => p.trim()).filter((p) => p !== "");
1581
+ if (names.length === 0) return { ok: false, message: MESSAGES.PERMISSIONS_REQUIRED };
1582
+ let out2 = [];
1583
+ for (let name of names) {
1584
+ let checked = checkPermission(name);
1585
+ if (!checked.ok) return checked;
1586
+ out2.includes(checked.value) || out2.push(checked.value);
1587
+ }
1588
+ return { ok: true, value: out2 };
1589
+ }
1590
+ function permissionNote(permission) {
1591
+ if (permission === PERMISSION.TASKS_WRITE) return ACCESS.TASKS_WRITE_NOTE;
1592
+ if (permission === PERMISSION.SECRETS_READ) return ACCESS.SECRETS_READ_NOTE;
1593
+ if (permission === PERMISSION.HOOKS_WRITE) return ACCESS.HOOKS_WRITE_NOTE;
1594
+ }
1595
+ function permissionRows() {
1596
+ return CATALOGUE.map((permission) => {
1597
+ let note = permissionNote(permission);
1598
+ return { permission, description: PERMISSION_DESCRIPTION[permission], ...note === void 0 ? {} : { note } };
1599
+ });
1600
+ }
1601
+ function accessRefusalText(e) {
1602
+ let body = httpErrorJson(e)?.body, reason = body?.reason;
1603
+ if (typeof reason != "string" || !REFUSALS.includes(reason)) return null;
1604
+ if (reason === ACCESS_REFUSAL.PERMISSION_DENIED) {
1605
+ let needed = body?.needed;
1606
+ return MESSAGES.ACCESS_PERMISSION_DENIED(typeof needed == "string" && needed !== "" ? needed : null);
1607
+ }
1608
+ if (reason === ACCESS_REFUSAL.OWNER_REQUIRED) return MESSAGES.ACCESS_OWNER_REQUIRED;
1609
+ let error = body?.error;
1610
+ return MESSAGES.ACCESS_REFUSED(typeof error == "string" && error !== "" ? error : reason, reason);
1611
+ }
1612
+ var CATALOGUE, MARKERS, REFUSALS, keyUser, init_access = __esm({ "src/core/access.ts"() {
1613
+ "use strict";
1614
+ init_define_IGNITIFY_CLIENT_FILES();
1615
+ init_http_client();
1616
+ init_tenant();
1617
+ init_constants();
1618
+ CATALOGUE = Object.values(PERMISSION), MARKERS = Object.values(ACCESS_MARKER), REFUSALS = Object.values(ACCESS_REFUSAL);
1619
+ keyUser = (user) => user ?? ACCESS.OWNER;
1620
+ } });
1621
+ function renderPermissions(st, rows) {
1622
+ return renderTable(st, [{ header: "permission", keep: true }, { header: "allows", wrap: true }], rows.map((r) => [r.permission, r.note === void 0 ? r.description : `${r.description}. Note: ${r.note}`]));
1623
+ }
1624
+ function renderUsers(st, users) {
1625
+ return users.length === 0 ? emptyState(st, EMPTY_LISTS.USERS.message, EMPTY_LISTS.USERS.next) : renderTable(st, [{ header: "name", keep: true }, { header: "resource_id", keep: true }, { header: "created_at", keep: true }], users.map((u) => [u.name, u.resource_id, u.created_at]));
1626
+ }
1627
+ function renderKeys(st, keys) {
1628
+ return keys.length === 0 ? emptyState(st, EMPTY_LISTS.KEYS.message) : renderTable(st, [{ header: "resource_id", keep: true }, { header: "user", keep: true }, { header: "label" }, { header: "created_at", keep: true }, { header: "last_used_at", keep: true }], keys.map((k) => [k.resource_id, keyUser(k.user), k.label, k.created_at, k.last_used_at]));
1629
+ }
1630
+ function renderUser(st, user) {
1631
+ return `${renderFields(st, { name: user.name, resource_id: user.resource_id, created_at: user.created_at, groups: joined(user.groups), permissions: joined(user.permissions) })}
1632
+
1633
+ ${heading(st, RESULT_MESSAGES.USER_KEYS_TITLE)}
1634
+ ${renderKeys(st, user.keys)}`;
1635
+ }
1636
+ function renderGroups(st, groups) {
1637
+ return groups.length === 0 ? emptyState(st, EMPTY_LISTS.GROUPS.message, EMPTY_LISTS.GROUPS.next) : renderTable(st, [{ header: "name", keep: true }, { header: "permissions", wrap: true }, { header: "created_at", keep: true }], groups.map((g) => [g.name, joined(g.permissions), g.created_at]));
1638
+ }
1639
+ function renderGroup(st, group) {
1640
+ return renderFields(st, { name: group.name, resource_id: group.resource_id, created_at: group.created_at, permissions: joined(group.permissions), users: joined(group.users) });
1641
+ }
1642
+ function renderKeyAccess(st, access) {
1643
+ return renderFields(st, { key: access.key, user: keyUser(access.user), groups: joined(access.groups), permissions: joined(access.permissions) });
1644
+ }
1645
+ function renderKeyCreated(st, created) {
1646
+ let { raw_key, secret_redacted: _redacted, ...rest } = created, rows = { ...rest, [RESULT_MESSAGES.KEY_RAW_KEY]: raw_key }, paint2 = { [RESULT_MESSAGES.KEY_RAW_KEY]: (s) => st.bold(st.yellow(s)) };
1647
+ return `
1648
+ ${heading(st, RESULT_MESSAGES.KEY_CREATED_TITLE, true)}
1649
+ ${renderFields(st, rows, void 0, paint2)}
1650
+ `;
1651
+ }
1652
+ var joined, init_access2 = __esm({ "src/output/access.ts"() {
1653
+ "use strict";
1654
+ init_define_IGNITIFY_CLIENT_FILES();
1655
+ init_access();
1656
+ init_blocks();
1657
+ init_constants2();
1658
+ init_table();
1659
+ joined = (items) => items.length === 0 ? RESULT_MESSAGES.NONE : items.join(", ");
1660
+ } });
1499
1661
  function isStorageMib(value) {
1500
1662
  return typeof value == "number" && Number.isInteger(value) && value > 0;
1501
1663
  }
@@ -1631,6 +1793,7 @@ var sectionHeader, layout, filterScalars, filterDisplayKeys, BYTE_UNITS2, format
1631
1793
  init_table();
1632
1794
  init_blocks();
1633
1795
  init_style();
1796
+ init_access2();
1634
1797
  init_constants2();
1635
1798
  init_tenant();
1636
1799
  init_execution();
@@ -1647,10 +1810,10 @@ ${heading(st, title, success)}
1647
1810
  return `${exp === 0 ? value : value.toFixed(1)} ${BYTE_UNITS2[exp]}`;
1648
1811
  }, quotaLine = (used, max) => `${used} / ${max ?? "unlimited"}`, storeLine = (used, max) => max === void 0 ? formatBytes(used) : `${formatBytes(used)} / ${max === null ? "unlimited" : formatBytes(max)}`, renderWhoami = (data, st = PLAIN) => {
1649
1812
  if (!data) return "";
1650
- let { limits, usage, tier, policy, bound_by, status_reason, policy_scope, enforced, unit_weights, capacity, ...identity } = data, identityRows = { ...identity };
1813
+ let { limits, usage, tier, policy, bound_by, status_reason, policy_scope, enforced, unit_weights, capacity, access, ...identity } = data, identityRows = { ...identity };
1651
1814
  typeof status_reason == "string" && status_reason !== "" && (identityRows.status_reason = status_reason), tier && (identityRows.tier = `${tier.name} v${tier.version}`), bound_by && (identityRows.bound_by = bound_by);
1652
1815
  let out2 = layout(sectionHeader(st, TITLES.TENANT_PROFILE), renderFields(st, filterDisplayKeys(identityRows)));
1653
- return (limits || usage) && (out2 += renderUsageBlocks(st, limits, usage)), out2 += capacityBlock(st, capacity), hasUnits(limits) && unit_weights && (out2 += renderUnitWeights(st, unit_weights)), policy && (out2 += renderPolicyBlock(st, policy, policy_scope?.per_brain ?? [])), enforced && enforced.length > 0 && (out2 += renderEnforcedBlock(st, enforced)), out2;
1816
+ return access && (out2 += layout(sectionHeader(st, TITLES.KEY_ACCESS), renderKeyAccess(st, access))), (limits || usage) && (out2 += renderUsageBlocks(st, limits, usage)), out2 += capacityBlock(st, capacity), hasUnits(limits) && unit_weights && (out2 += renderUnitWeights(st, unit_weights)), policy && (out2 += renderPolicyBlock(st, policy, policy_scope?.per_brain ?? [])), enforced && enforced.length > 0 && (out2 += renderEnforcedBlock(st, enforced)), out2;
1654
1817
  }, hasUnits = (limits) => typeof limits?.max_units == "number", renderUnitWeights = (st, weights) => layout(sectionHeader(st, TITLES.UNIT_WEIGHTS), renderFields(st, Object.fromEntries(Object.entries(weights).map(([p, w]) => [p, String(w)])))), showEnforced = (v) => v === null ? "\u2014" : String(v), renderEnforcedBlock = (st, rows) => {
1655
1818
  let enforcedText = (r) => {
1656
1819
  let value = showEnforced(r.enforced);
@@ -1874,7 +2037,7 @@ ${notice()}
1874
2037
  process.removeListener("SIGINT", handler);
1875
2038
  }
1876
2039
  }
1877
- var spinnerGlyph, realEvery, NOOP, init_progress = __esm({ "src/output/progress.ts"() {
2040
+ var spinnerGlyph, realEvery, NOOP, NO_PROGRESS, init_progress = __esm({ "src/output/progress.ts"() {
1878
2041
  "use strict";
1879
2042
  init_define_IGNITIFY_CLIENT_FILES();
1880
2043
  init_constants2();
@@ -1890,13 +2053,15 @@ var spinnerGlyph, realEvery, NOOP, init_progress = __esm({ "src/output/progress.
1890
2053
  }, fail() {
1891
2054
  }, stop() {
1892
2055
  } };
2056
+ NO_PROGRESS = { stop: () => {
2057
+ } };
1893
2058
  } });
1894
- var AXES, DIR2, YES2, RAW2, PAGE2, VERSION_HELP, COMMAND_HELP, HELP_PAGE, init_help = __esm({ "src/constants/help.ts"() {
2059
+ var OWNER_ONLY, PERMISSION_NOTES, AXES, DIR2, YES2, RAW2, SERIES_DAYS, FAILURES_DAYS, PAGE2, VERSION_HELP, COMMAND_HELP, HELP_PAGE, init_help = __esm({ "src/constants/help.ts"() {
1895
2060
  "use strict";
1896
2061
  init_define_IGNITIFY_CLIENT_FILES();
1897
2062
  init_tenant();
1898
2063
  init_constants();
1899
- AXES = USAGE_AXES.join("|"), DIR2 = { dir: { text: "Folder that holds your task folders.", default: `$${ENV.TASKS_DIR}, else ${DEFAULT_TASKS_DIR}` } }, YES2 = { yes: { text: "Skip the question (needed when not interactive)." } }, RAW2 = { raw: { text: "Print the bytes exactly as received. Without it, the colours are kept on a colour terminal and every other control code is removed." } }, PAGE2 = { limit: { text: "Rows on the page. The server sets the default and the largest value." }, "after-id": { text: "Page cursor: the id of the last row of the page before." }, after: { text: "Only rows after this ISO 8601 time." } }, VERSION_HELP = { summary: "Print the client version, and the API version if the server answers.", usage: ["ignitify --version"], notes: ["Needs no key. Warns when this client is older than the API supports."] }, COMMAND_HELP = { [COMMANDS.HELP]: { summary: "Print the usage of every command, or of one command.", usage: ["ignitify help [<command>]"], args: { command: "A command name. Leave it out to print every command." }, notes: ["`ignitify <command> --help` prints the same page."], examples: ["ignitify help task:run"] }, [COMMANDS.LOGIN]: { summary: "Sign this machine in and save its API key.", usage: ["ignitify login [--name <label>] [--no-browser]"], flags: { name: { text: "A label for this machine's key; keeps two machines with one hostname apart.", default: "the hostname" }, "no-browser": { text: "Print the sign-in page, but do not open it." } }, notes: ["The key is saved in ~/.config/ignitify/credentials.json (mode 0600)."], examples: ["ignitify login", "ignitify login --name build-server --no-browser"] }, [COMMANDS.LOGOUT]: { summary: "Revoke this machine's key and delete the saved file.", usage: ["ignitify logout"] }, [COMMANDS.WHOAMI]: { summary: "Show who your key belongs to, your limits and usage.", usage: ["ignitify whoami"] }, [COMMANDS.QUOTA]: { summary: "Show what you hold now against your limits.", usage: ["ignitify quota"] }, [COMMANDS.TASK_CREATE]: { summary: "Register a task name and write its starter files.", usage: ["ignitify task:create <task-id> [--lang node|python|go|rust] [--local] [--no-init] [--no-scaffold] [--dir <base-dir>]"], args: { "task-id": "The task name: also the folder name and the slug in task.yaml." }, flags: { lang: { text: "Language of the starter files.", default: "node" }, local: { text: "Write the files only. Calls no server and needs no key." }, "no-init": { text: "Write the short starter that has only run(), without init code." }, "no-scaffold": { text: "Register the task name but write no files." }, ...DIR2 }, examples: ["ignitify task:create image-resize", "ignitify task:create image-resize --lang python --local"] }, [COMMANDS.TASK_LIST]: { summary: "List your tasks, one page at a time.", usage: ["ignitify task:list [--limit N] [--after-id <id>] [--after <iso>]"], flags: PAGE2 }, [COMMANDS.TASK_GET]: { summary: "Report a task's deploys, runs and next-step verdicts.", usage: ["ignitify task:get <task-id> [--dir <base-dir>]"], args: { "task-id": "The task folder name." }, flags: DIR2, notes: ["Shows whether the next deploy builds a new image and the next run boots a new VM, with the reasons."] }, [COMMANDS.TASK_VALIDATE]: { summary: "Check task.yaml on your machine; builds nothing.", usage: ["ignitify task:validate <task-id> [--dir <base-dir>] [--review-packages]"], args: { "task-id": "The task folder name." }, flags: { ...DIR2, "review-packages": { text: "Then ask the server for an AI review of build.system_packages." } }, notes: ["The review is advice only: the exit code never changes.", "Only package names and the runtime id leave this machine; never code, slug or secrets.", "It also checks that task.yaml still covers each @ignitify-integrations/* package in package.json. A listed package that is not in node_modules stops the check: run npm install first.", "With integrations installed, it sends their package names to the public npm registry (registry.npmjs.org) to find obsolete versions: a warning only. With no network, that warning is skipped with a note."] }, [COMMANDS.TASK_PACK]: { summary: "List the files task:deploy would upload; builds nothing.", usage: ["ignitify task:pack <task-id> [--dir <base-dir>]"], args: { "task-id": "The task folder name." }, flags: DIR2 }, [COMMANDS.TASK_DEPLOY]: { summary: "Upload the task source and wait until the image is built.", usage: ["ignitify task:deploy <task-id> [--dir <base-dir>] [--check]"], args: { "task-id": "The task folder name." }, flags: { ...DIR2, check: { text: "Run every local check, then stop. Nothing is uploaded." } }, notes: ["Ctrl+C stops waiting, not the build."], examples: ["ignitify task:deploy image-resize", "ignitify task:deploy image-resize --check"] }, [COMMANDS.TASK_RUN]: { summary: "Start one run of a task from its latest deployment.", usage: ["ignitify task:run <task-id> [--dir <base-dir>] [--deployment <id>] [--payload <json>] [--timeout-sec <n>] [--on-busy queue|reject] [--at <iso>] [--wait]"], args: { "task-id": "The task folder name." }, flags: { ...DIR2, deployment: { text: "Run this deployment instead of the task's latest deploy.", default: "the task's latest deploy" }, payload: { text: "JSON input for this run only.", default: "run.payload from task.yaml" }, "timeout-sec": { text: "Time limit in seconds for this run only.", default: "run.timeout_sec from task.yaml" }, "on-busy": { text: "When the run cannot start at once: queue waits for room (a limited time), reject fails at once.", default: "queue" }, at: { text: "Schedule the run for this ISO 8601 time. No run exists until it fires." }, wait: { text: "Follow the run to its end, then print it with its result." } }, notes: ["With --wait the exit code is 0 only when the run is COMPLETED. Ctrl+C stops waiting, not the run.", "--payload and --timeout-sec apply to this run only; task.yaml is never written.", "A bidirectional task runs one VM at a time; --on-busy covers that case too."], examples: ["ignitify task:run image-resize --wait", `ignitify task:run image-resize --payload '{"width":320}'`, "ignitify task:run image-resize --at 2027-01-15T03:00:00Z"] }, [COMMANDS.TASK_DELETE]: { summary: "Delete a task with all its deployments and runs.", usage: ["ignitify task:delete <task-id> [--dir <base-dir>] [--yes] [--json]"], args: { "task-id": "The task folder name, or the task id." }, flags: { ...DIR2, ...YES2, json: { text: "Print the plan and the result as one JSON document." } }, notes: ["Also removes the .ignitify/ link of every local folder linked to it; your files are kept."] }, [COMMANDS.DEPLOYMENT_LIST]: { summary: "List your deployments with the size of each image.", usage: ["ignitify deployment:list [--limit N] [--after-id <id>] [--after <iso>]"], flags: PAGE2 }, [COMMANDS.DEPLOYMENT_GET]: { summary: "Show one deployment: status, size, integrity.", usage: ["ignitify deployment:get <deployment-id>"], args: { "deployment-id": "The deployment id, from task:deploy or deployment:list." } }, [COMMANDS.DEPLOYMENT_LOGS]: { summary: "Print the build log of a deployment, as the build wrote it.", usage: ["ignitify deployment:logs <deployment-id> [--raw]"], args: { "deployment-id": "The deployment id." }, flags: RAW2, notes: ["The output goes to stdout; a truncated answer says so on stderr."] }, [COMMANDS.DEPLOYMENT_DELETE]: { summary: "Delete a deployment together with its runs.", usage: ["ignitify deployment:delete <deployment-id> [--yes]"], args: { "deployment-id": "The deployment id." }, flags: YES2 }, [COMMANDS.RUN_LIST]: { summary: "List your runs, with filters.", usage: ["ignitify run:list [--status S] [--deployment-id D] [--task-name N] [--preset P] [--correlation-id C] [--vm-id V] [--limit N] [--after-id <id>] [--after <iso>]"], flags: { status: { text: "Only runs in this status, for example FAILED." }, "deployment-id": { text: "Only runs of this deployment." }, "task-name": { text: "Only runs of this task." }, preset: { text: "Only runs on this instance class." }, "correlation-id": { text: "Only runs with this correlation id." }, "vm-id": { text: "Only runs that used this VM." }, ...PAGE2 } }, [COMMANDS.RUN_GET]: { summary: "Show one run: status, timing and the result of the task.", usage: ["ignitify run:get <run-id> [--full]"], args: { "run-id": "The run id, from task:run or run:list." }, flags: { full: { text: "Print the whole run as JSON, every field the API returns." } } }, [COMMANDS.RUN_LOGS]: { summary: "Print the console output of a run, as the task wrote it.", usage: ["ignitify run:logs <run-id> [--raw]"], args: { "run-id": "The run id." }, flags: RAW2, notes: ["The output goes to stdout; a truncated answer says so on stderr."] }, [COMMANDS.RUN_DELETE]: { summary: "Delete the record of a run; does not stop a live run.", usage: ["ignitify run:delete <run-id> [--yes]"], args: { "run-id": "The run id." }, flags: YES2 }, [COMMANDS.RUN_CANCEL]: { summary: "Stop a live run, gracefully by default.", usage: ["ignitify run:cancel <run-id> [--yes] [--force] [--grace <ms>]"], args: { "run-id": "The run id." }, flags: { ...YES2, force: { text: "Kill the run now. Also needed when the run is on a pinned VM." }, grace: { text: "Ask for a longer wind-down, in milliseconds. The server limits it." } } }, [COMMANDS.VM_LIST]: { summary: "List your live VMs with their state, age and idle time.", usage: ["ignitify vm:list [--pinned] [--deployment-id D] [--task-name N] [--preset P] [--older-than 24h] [--limit N] [--after-id <vm-id>] [--after <iso>]"], flags: { pinned: { text: "Only pinned VMs: they stay up until you delete them." }, "deployment-id": { text: "Only VMs of this deployment." }, "task-name": { text: "Only VMs of this task." }, preset: { text: "Only VMs of this instance class." }, "older-than": { text: "Only VMs older than this age, for example 24h." }, limit: PAGE2.limit, "after-id": { text: "Page cursor: the VM id of the last row of the page before." }, after: { text: "Only VMs booted after this ISO 8601 time." } } }, [COMMANDS.VM_GET]: { summary: "Show one VM: residency, state, age and its task nature.", usage: ["ignitify vm:get <vm-id>"], args: { "vm-id": "The VM id, from vm:list." } }, [COMMANDS.VM_DELETE]: { summary: "Tear down a VM by hand.", usage: ["ignitify vm:delete <vm-id> [--yes] [--force]"], args: { "vm-id": "The VM id." }, flags: { ...YES2, force: { text: "Allow the delete of a pinned VM. It does not skip the question." } } }, [COMMANDS.SECRET_SET]: { summary: "Store a secret value under a name, read from stdin.", usage: ["ignitify secret:set <NAME> --stdin"], args: { NAME: "The secret name. List it in `secrets` in task.yaml to use it." }, flags: { stdin: { text: "Read the value from stdin. A value on the command line is refused." } }, examples: ['printf %s "$VALUE" | ignitify secret:set DB_PASSWORD --stdin'] }, [COMMANDS.SECRET_LIST]: { summary: "List the names of your secrets.", usage: ["ignitify secret:list"] }, [COMMANDS.SECRET_DELETE]: { summary: "Delete a secret.", usage: ["ignitify secret:delete <NAME> [--yes]"], args: { NAME: "The secret name." }, flags: YES2 }, [COMMANDS.INTEGRATION_ADD]: { summary: "Add an integration package to a Node task and write its settings into task.yaml.", usage: ["ignitify integration:add <name> --task <slug> [--yes | --dry-run] [--dir <base-dir>]"], args: { name: "The integration name. The npm package is @ignitify-integrations/<name>." }, flags: { task: { text: "The task folder name to add the integration to." }, yes: { text: "Apply the plan without the question (needed when not interactive)." }, "dry-run": { text: "Show the plan, then stop. Nothing in the task is changed." }, ...DIR2 }, notes: ["It downloads the latest @ignitify-integrations/<name> with npm pack into a temporary folder and reads the plan from that file. Nothing in the task changes before you answer y.", "The plan shows every task.yaml change, then what you add yourself: secret values and hosts that differ per task.", "After y (or with --yes), it runs npm install @ignitify-integrations/<name>@<that version> in the task folder (a normal dependency, with --ignore-scripts as the build uses), then writes task.yaml. If the install fails, task.yaml is not written.", "An N, --dry-run or a refusal changes nothing: no package.json, lockfile, node_modules or task.yaml change.", "A setting that conflicts with task.yaml, or more egress hosts than the platform allows, is refused and nothing is written.", "Adding the same integration again changes nothing. To upgrade, add it again. To remove it, run npm uninstall; the settings it added stay yours to delete."], examples: ["ignitify integration:add s3-storage --task launch-event", "ignitify integration:add stream --task launch-event --dry-run"] }, [COMMANDS.SCHEDULE_LIST]: { summary: "List runs that wait for a time, soonest first.", usage: ["ignitify schedule:list"] }, [COMMANDS.SCHEDULE_CANCEL]: { summary: "Cancel one scheduled run so that it never fires.", usage: ["ignitify schedule:cancel <sch-id> [--yes]"], args: { "sch-id": "The schedule id, from task:run --at or schedule:list." }, flags: YES2, notes: ['"0 rows" means it is already firing or fired.'] }, [COMMANDS.HOOK_CREATE]: { summary: "Create a webhook that starts a run of one task.", usage: ["ignitify hook:create <deployment-id> --task-name <name>"], args: { "deployment-id": "The deployment the webhook belongs to." }, flags: { "task-name": { text: "The task that each run starts. Required." } }, notes: ["The reply carries a `secret` shown ONCE: hook:list never returns it."] }, [COMMANDS.HOOK_LIST]: { summary: "List the webhooks of a deployment.", usage: ["ignitify hook:list <deployment-id> [--limit N] [--after-id <id>] [--after <iso>]"], args: { "deployment-id": "The deployment id." }, flags: PAGE2 }, [COMMANDS.HOOK_DELETE]: { summary: "Delete a webhook.", usage: ["ignitify hook:delete <hook-resource-id> [--yes]"], args: { "hook-resource-id": "The HOOK's id (hok_\u2026), not the deployment's." }, flags: YES2 }, [COMMANDS.NOTIFY_SET]: { summary: "Set or clear the callback URL of a deployment.", usage: ["ignitify notify:set <deployment-id> --url <https://\u2026> --secret-stdin", "ignitify notify:set <deployment-id> --clear"], args: { "deployment-id": "The deployment id." }, flags: { url: { text: "The HTTPS address to call. Needs --secret-stdin." }, "secret-stdin": { text: "Read the signing secret from stdin. Needed with --url." }, clear: { text: "Remove the callback URL. Cannot be used with --url." } }, notes: ["There is no --secret flag: a value on argv is in `ps` and in your shell history."] }, [COMMANDS.USAGE]: { summary: "Show what you used in one month, by axis.", usage: [`ignitify usage [--period YYYY-MM] [--axis ${AXES}] [--vm <vm-id>] [--run <run-id>] [--runs|--vms] [--json]`], flags: { period: { text: "The month to show, as YYYY-MM.", default: "this month" }, axis: { text: "Show one axis only." }, vm: { text: "Only the usage of this VM." }, run: { text: "Only the usage of this run." }, runs: { text: "Add the lines behind the totals, one per run." }, vms: { text: "Add the lines behind the totals, one per VM." }, json: { text: "Print the report as JSON." } } }, [COMMANDS.USAGE_EXPORT]: { summary: "Export the usage lines of a month as JSON or CSV.", usage: [`ignitify usage:export [--period YYYY-MM] [--axis ${AXES}] [--vm <vm-id>] [--run <run-id>] (--json|--csv)`], flags: { period: { text: "The month to export, as YYYY-MM.", default: "this month" }, axis: { text: "Export one axis only." }, vm: { text: "Only the lines of this VM." }, run: { text: "Only the lines of this run." }, json: { text: "Print the lines as a JSON array." }, csv: { text: "Print the lines as CSV." } }, notes: ["Name exactly one format: --json or --csv."] } }, HELP_PAGE = { TITLE: "ignitify", TAGLINE: "create, deploy and run tasks", USAGE: "ignitify <command> [arguments] [flags]", USAGE_NOTE: "Every command is <resource>:<verb>.", QUICK_START: [{ command: "ignitify login", text: "Sign this machine in." }, { command: "ignitify task:create my-task", text: "Register a task and write its files." }, { command: "ignitify task:deploy my-task", text: "Build it on the platform." }, { command: "ignitify task:run my-task --wait", text: "Run it and print the result." }], GROUPS: [{ title: "Tasks", resources: ["task"] }, { title: "Deployments", resources: ["deployment"] }, { title: "Runs", resources: ["run"] }, { title: "VMs", resources: ["vm"] }, { title: "Secrets", resources: ["secret"] }, { title: "Integrations", resources: ["integration"] }, { title: "Schedules", resources: ["schedule"] }, { title: "Webhooks", resources: ["hook", "notify"] }, { title: "Account and usage", resources: ["login", "logout", "whoami", "quota", "usage", "help"] }], GLOBAL_FLAGS: [{ flag: "--json", text: "Print the result as one JSON document on stdout." }, { flag: "-h, --help", text: "Print help for the command." }, { flag: "-y, --yes", text: "Answer yes to a delete's question (for scripts)." }, { flag: "-v, --version", text: "Print the client and API version (first word only)." }], ENV: [{ name: ENV.KEY, text: "Your API key, for CI. Wins over the saved login." }, { name: ENV.TASKS_DIR, text: `Folder that holds your task folders (default: ${DEFAULT_TASKS_DIR}).` }, { name: "NO_COLOR", text: "Set to any value to turn colour off." }], NOTES: ["Delete commands always ask first; --force unlocks a refusal, it does not skip the question.", "A flag or argument a command does not take is refused, not ignored.", "On error the CLI prints a clean message and exits non-zero."], DOCS: "https://ignitify.dev/docs", MORE: "Run 'ignitify <command> --help' for the flags of one command.", H: { USAGE: "Usage", QUICK_START: "Quick start", GLOBAL_FLAGS: "Global flags", ENV: "Environment", NOTES: "Good to know", DOCS: "Docs", DESCRIPTION: "Description", ARGUMENTS: "Arguments", FLAGS: "Flags", EXAMPLES: "Examples" }, COLUMNS: { COMMAND: "COMMAND", WHAT: "WHAT IT DOES", FLAG: "FLAG", VALUE: "VALUE", DEFAULT: "DEFAULT", DESCRIPTION: "DESCRIPTION", NAME: "NAME", ARG: "ARGUMENT" }, SWITCH: "switch", DEFAULT: (value) => `Default: ${value}.`, REQUIRED: "required" };
2064
+ OWNER_ONLY = "Needs an owner key (from ignitify login). A user key is refused with owner-required.", PERMISSION_NOTES = [ACCESS.TASKS_WRITE_NOTE, ACCESS.SECRETS_READ_NOTE, ACCESS.HOOKS_WRITE_NOTE], AXES = USAGE_AXES.join("|"), DIR2 = { dir: { text: "Folder that holds your task folders.", default: `$${ENV.TASKS_DIR}, else ${DEFAULT_TASKS_DIR}` } }, YES2 = { yes: { text: "Skip the question (needed when not interactive)." } }, RAW2 = { raw: { text: "Print the bytes exactly as received. Without it, the colours are kept on a colour terminal and every other control code is removed." } }, SERIES_DAYS = { days: { text: `How many UTC days to show, today included. More than ${92} is read as ${92}.`, default: `${30}` } }, FAILURES_DAYS = { days: { text: `How many UTC days to show, today included. More than ${31} is read as ${31}.`, default: `${30}` } }, PAGE2 = { limit: { text: "Rows on the page. The server sets the default and the largest value." }, "after-id": { text: "Page cursor: the id of the last row of the page before." }, after: { text: "Only rows after this ISO 8601 time." } }, VERSION_HELP = { summary: "Print the client version, and the API version if the server answers.", usage: ["ignitify --version"], notes: ["Needs no key. Warns when this client is older than the API supports."] }, COMMAND_HELP = { [COMMANDS.HELP]: { summary: "Print the usage of every command, or of one command.", usage: ["ignitify help [<command>]"], args: { command: "A command name. Leave it out to print every command." }, notes: ["`ignitify <command> --help` prints the same page."], examples: ["ignitify help task:run"] }, [COMMANDS.LOGIN]: { summary: "Sign this machine in and save its API key.", usage: ["ignitify login [--name <label>] [--no-browser]"], flags: { name: { text: "A label for this machine's key; keeps two machines with one hostname apart.", default: "the hostname" }, "no-browser": { text: "Print the sign-in page, but do not open it." } }, notes: ["The key is saved in ~/.config/ignitify/credentials.json (mode 0600)."], examples: ["ignitify login", "ignitify login --name build-server --no-browser"] }, [COMMANDS.LOGOUT]: { summary: "Revoke this machine's key and delete the saved file.", usage: ["ignitify logout"] }, [COMMANDS.WHOAMI]: { summary: "Show who your key belongs to, your limits and usage.", usage: ["ignitify whoami"] }, [COMMANDS.QUOTA]: { summary: "Show what you hold now against your limits.", usage: ["ignitify quota"] }, [COMMANDS.TASK_CREATE]: { summary: "Register a task name and write its starter files.", usage: ["ignitify task:create <task-id> [--lang node|python|go|rust] [--local] [--no-init] [--no-scaffold] [--dir <base-dir>]"], args: { "task-id": "The task name: also the folder name and the slug in task.yaml." }, flags: { lang: { text: "Language of the starter files.", default: "node" }, local: { text: "Write the files only. Calls no server and needs no key." }, "no-init": { text: "Write the short starter that has only run(), without init code." }, "no-scaffold": { text: "Register the task name but write no files." }, ...DIR2 }, examples: ["ignitify task:create image-resize", "ignitify task:create image-resize --lang python --local"] }, [COMMANDS.TASK_LIST]: { summary: "List your tasks, one page at a time.", usage: ["ignitify task:list [--limit N] [--after-id <id>] [--after <iso>]"], flags: PAGE2 }, [COMMANDS.TASK_GET]: { summary: "Report a task's deploys, runs and next-step verdicts.", usage: ["ignitify task:get <task-id> [--dir <base-dir>]"], args: { "task-id": "The task folder name." }, flags: DIR2, notes: ["Shows whether the next deploy builds a new image and the next run boots a new VM, with the reasons."] }, [COMMANDS.TASK_VALIDATE]: { summary: "Check task.yaml on your machine; builds nothing.", usage: ["ignitify task:validate <task-id> [--dir <base-dir>] [--review-packages]"], args: { "task-id": "The task folder name." }, flags: { ...DIR2, "review-packages": { text: "Then ask the server for an AI review of build.system_packages." } }, notes: ["The review is advice only: the exit code never changes.", "Only package names and the runtime id leave this machine; never code, slug or secrets.", "It also checks that task.yaml still covers each @ignitify-integrations/* package in package.json. A listed package that is not in node_modules stops the check: run npm install first.", "With integrations installed, it sends their package names to the public npm registry (registry.npmjs.org) to find obsolete versions: a warning only. With no network, that warning is skipped with a note."] }, [COMMANDS.TASK_PACK]: { summary: "List the files task:deploy would upload; builds nothing.", usage: ["ignitify task:pack <task-id> [--dir <base-dir>]"], args: { "task-id": "The task folder name." }, flags: DIR2 }, [COMMANDS.TASK_DEPLOY]: { summary: "Upload the task source and wait until the image is built.", usage: ["ignitify task:deploy <task-id> [--dir <base-dir>] [--check]"], args: { "task-id": "The task folder name." }, flags: { ...DIR2, check: { text: "Run every local check, then stop. Nothing is uploaded." } }, notes: ["Ctrl+C stops waiting, not the build."], examples: ["ignitify task:deploy image-resize", "ignitify task:deploy image-resize --check"] }, [COMMANDS.TASK_RUN]: { summary: "Start one run of a task from its latest deployment.", usage: ["ignitify task:run <task-id> [--dir <base-dir>] [--deployment <id>] [--payload <json>] [--timeout-sec <n>] [--on-busy queue|reject] [--at <iso>] [--idempotency-key <key>] [--wait]"], args: { "task-id": "The task folder name." }, flags: { ...DIR2, deployment: { text: "Run this deployment instead of the task's latest deploy.", default: "the task's latest deploy" }, payload: { text: "JSON input for this run only.", default: "run.payload from task.yaml" }, "timeout-sec": { text: "Time limit in seconds for this run only.", default: "run.timeout_sec from task.yaml" }, "on-busy": { text: "When the run cannot start at once: queue waits for room (a limited time), reject fails at once.", default: "queue" }, at: { text: "Schedule the run for this ISO 8601 time. No run exists until it fires." }, "idempotency-key": { text: "Start at most one run for this key (8 to 255 characters of A-Z a-z 0-9 . _ : -). A retry with the same key gets the first answer again." }, wait: { text: "Follow the run to its end, then print it with its result." } }, notes: ["With --wait the exit code is 0 only when the run is COMPLETED. Ctrl+C stops waiting, not the run.", "--payload and --timeout-sec apply to this run only; task.yaml is never written.", "A bidirectional task runs one VM at a time; --on-busy covers that case too.", "Use --idempotency-key when a script retries after a network error. Use a new key for each new run; the same key with a different run is refused. Pin --deployment in such a script: a new deploy between two tries changes the request."], examples: ["ignitify task:run image-resize --wait", `ignitify task:run image-resize --payload '{"width":320}'`, "ignitify task:run image-resize --at 2027-01-15T03:00:00Z"] }, [COMMANDS.TASK_DELETE]: { summary: "Delete a task with all its deployments and runs.", usage: ["ignitify task:delete <task-id> [--dir <base-dir>] [--yes] [--json]"], args: { "task-id": "The task folder name, or the task id." }, flags: { ...DIR2, ...YES2, json: { text: "Print the plan and the result as one JSON document." } }, notes: ["Also removes the .ignitify/ link of every local folder linked to it; your files are kept."] }, [COMMANDS.DEPLOYMENT_LIST]: { summary: "List your deployments with the size of each image.", usage: ["ignitify deployment:list [--limit N] [--after-id <id>] [--after <iso>]"], flags: PAGE2 }, [COMMANDS.DEPLOYMENT_GET]: { summary: "Show one deployment: status, size, integrity.", usage: ["ignitify deployment:get <deployment-id>"], args: { "deployment-id": "The deployment id, from task:deploy or deployment:list." } }, [COMMANDS.DEPLOYMENT_LOGS]: { summary: "Print the build log of a deployment, as the build wrote it.", usage: ["ignitify deployment:logs <deployment-id> [--raw]"], args: { "deployment-id": "The deployment id." }, flags: RAW2, notes: ["The output goes to stdout; a truncated answer says so on stderr."] }, [COMMANDS.DEPLOYMENT_DELETE]: { summary: "Delete a deployment together with its runs.", usage: ["ignitify deployment:delete <deployment-id> [--yes]"], args: { "deployment-id": "The deployment id." }, flags: YES2 }, [COMMANDS.RUN_LIST]: { summary: "List your runs, with filters.", usage: ["ignitify run:list [--status S] [--deployment-id D] [--task-name N] [--preset P] [--correlation-id C] [--vm-id V] [--limit N] [--after-id <id>] [--after <iso>]"], flags: { status: { text: "Only runs in this status, for example FAILED." }, "deployment-id": { text: "Only runs of this deployment." }, "task-name": { text: "Only runs of this task." }, preset: { text: "Only runs on this instance class." }, "correlation-id": { text: "Only runs with this correlation id." }, "vm-id": { text: "Only runs that used this VM." }, ...PAGE2 } }, [COMMANDS.RUN_GET]: { summary: "Show one run: status, timing and the result of the task.", usage: ["ignitify run:get <run-id> [--full]"], args: { "run-id": "The run id, from task:run or run:list." }, flags: { full: { text: "Print the whole run as JSON, every field the API returns." } } }, [COMMANDS.RUN_LOGS]: { summary: "Print the console output of a run, as the task wrote it.", usage: ["ignitify run:logs <run-id> [--follow] [--tail N] [--raw]"], args: { "run-id": "The run id." }, flags: { ...RAW2, follow: { text: "Keep printing new output until the run has ended." }, tail: { text: "Print only the last N lines of the output so far. With --follow, go on from there." } }, notes: ["Output is best-effort. The host keeps it for 30 days at most. A read that is cut at the size cap says so on stderr. Use --follow to watch a live run.", "The output goes to stdout. With --json and --follow or --tail, each chunk is one JSON line with the offset to read from next.", "Ctrl+C stops following, not the run."], examples: ["ignitify run:logs <run-id> --follow", "ignitify run:logs <run-id> --tail 50"] }, [COMMANDS.RUN_TIMELINE]: { summary: "Show what happened to a run: one line per event, then how it ended.", usage: ["ignitify run:timeline <run-id> [--follow]"], args: { "run-id": "The run id." }, flags: { follow: { text: "Keep printing new events until the run has ended." } }, notes: ["When the run has ended, the exit code is 0 only when it is COMPLETED. A live run read without --follow exits 0.", "With --json --follow, each page of events is one JSON line. Ctrl+C stops following, not the run."], examples: ["ignitify run:timeline <run-id> --follow"] }, [COMMANDS.RUN_FAILURES]: { summary: "Show how your runs failed: by class, then the tasks that fail most.", usage: ["ignitify run:failures [--days N] [--json]"], flags: { ...FAILURES_DAYS, json: { text: "Print the report as JSON." } }, notes: ["A failure is a run that ended FAILED or CANCELLED. The task list leaves out cancelled runs.", "Classes: task (your code or deployment), limit (a plan limit), cancelled, platform (our side)."], examples: ["ignitify run:failures", "ignitify run:failures --days 7"] }, [COMMANDS.NOTIFICATION_LIST]: { summary: "List your notifications and alerts, newest first.", usage: ["ignitify notification:list [--unread | --open] [--kind <kind>] [--limit N] [--json]"], flags: { unread: { text: "Only the notifications you have not read." }, open: { text: "Only the alerts that are still open." }, kind: { text: `Only this kind: ${NOTIFICATION_KINDS.join(", ")}.` }, limit: { text: `How many to show. More than ${NOTIFICATION_PAGE_MAX} is read as ${NOTIFICATION_PAGE_MAX}.`, default: `${NOTIFICATION_PAGE_DEFAULT}` }, json: { text: "Print the page as JSON." } }, notes: [`We keep notifications for ${NOTIFICATION_RETENTION_DAYS} days. Mark them read in the app; this command does not change them.`], examples: ["ignitify notification:list --unread", "ignitify notification:list --open --json"] }, [COMMANDS.RUN_DELETE]: { summary: "Delete the record of a run; does not stop a live run.", usage: ["ignitify run:delete <run-id> [--yes]"], args: { "run-id": "The run id." }, flags: YES2 }, [COMMANDS.RUN_CANCEL]: { summary: "Stop a live run, gracefully by default.", usage: ["ignitify run:cancel <run-id> [--yes] [--force] [--grace <ms>]"], args: { "run-id": "The run id." }, flags: { ...YES2, force: { text: "Kill the run now. Also needed when the run is on a pinned VM." }, grace: { text: "Ask for a longer wind-down, in milliseconds. The server limits it." } } }, [COMMANDS.VM_LIST]: { summary: "List your live VMs with their state, age and idle time.", usage: ["ignitify vm:list [--pinned] [--deployment-id D] [--task-name N] [--preset P] [--older-than 24h] [--limit N] [--after-id <vm-id>] [--after <iso>]"], flags: { pinned: { text: "Only pinned VMs: they stay up until you delete them." }, "deployment-id": { text: "Only VMs of this deployment." }, "task-name": { text: "Only VMs of this task." }, preset: { text: "Only VMs of this instance class." }, "older-than": { text: "Only VMs older than this age, for example 24h." }, limit: PAGE2.limit, "after-id": { text: "Page cursor: the VM id of the last row of the page before." }, after: { text: "Only VMs booted after this ISO 8601 time." } } }, [COMMANDS.VM_GET]: { summary: "Show one VM: residency, state, age and its task nature.", usage: ["ignitify vm:get <vm-id>"], args: { "vm-id": "The VM id, from vm:list." } }, [COMMANDS.VM_DELETE]: { summary: "Tear down a VM by hand.", usage: ["ignitify vm:delete <vm-id> [--yes] [--force]"], args: { "vm-id": "The VM id." }, flags: { ...YES2, force: { text: "Allow the delete of a pinned VM. It does not skip the question." } } }, [COMMANDS.SECRET_SET]: { summary: "Store a secret value under a name, read from stdin.", usage: ["ignitify secret:set <NAME> --stdin"], args: { NAME: "The secret name. List it in `secrets` in task.yaml to use it." }, flags: { stdin: { text: "Read the value from stdin. A value on the command line is refused." } }, examples: ['printf %s "$VALUE" | ignitify secret:set DB_PASSWORD --stdin'] }, [COMMANDS.SECRET_LIST]: { summary: "List the names of your secrets.", usage: ["ignitify secret:list"] }, [COMMANDS.SECRET_DELETE]: { summary: "Delete a secret.", usage: ["ignitify secret:delete <NAME> [--yes]"], args: { NAME: "The secret name." }, flags: YES2 }, [COMMANDS.INTEGRATION_ADD]: { summary: "Add an integration package to a Node task and write its settings into task.yaml.", usage: ["ignitify integration:add <name> --task <slug> [--yes | --dry-run] [--dir <base-dir>]"], args: { name: "The integration name. The npm package is @ignitify-integrations/<name>." }, flags: { task: { text: "The task folder name to add the integration to." }, yes: { text: "Apply the plan without the question (needed when not interactive)." }, "dry-run": { text: "Show the plan, then stop. Nothing in the task is changed." }, ...DIR2 }, notes: ["It downloads the latest @ignitify-integrations/<name> with npm pack into a temporary folder and reads the plan from that file. Nothing in the task changes before you answer y.", "The plan shows every task.yaml change, then what you add yourself: secret values and hosts that differ per task.", "After y (or with --yes), it runs npm install @ignitify-integrations/<name>@<that version> in the task folder (a normal dependency, with --ignore-scripts as the build uses), then writes task.yaml. If the install fails, task.yaml is not written.", "An N, --dry-run or a refusal changes nothing: no package.json, lockfile, node_modules or task.yaml change.", "A setting that conflicts with task.yaml, or more egress hosts than the platform allows, is refused and nothing is written.", "Adding the same integration again changes nothing. To upgrade, add it again. To remove it, run npm uninstall; the settings it added stay yours to delete."], examples: ["ignitify integration:add s3-storage --task launch-event", "ignitify integration:add stream --task launch-event --dry-run"] }, [COMMANDS.SCHEDULE_LIST]: { summary: "List runs that wait for a time, soonest first.", usage: ["ignitify schedule:list"] }, [COMMANDS.SCHEDULE_CANCEL]: { summary: "Cancel one scheduled run so that it never fires.", usage: ["ignitify schedule:cancel <sch-id> [--yes]"], args: { "sch-id": "The schedule id, from task:run --at or schedule:list." }, flags: YES2, notes: ['"0 rows" means it is already firing or fired.'] }, [COMMANDS.HOOK_CREATE]: { summary: "Create a webhook that starts a run of one task.", usage: ["ignitify hook:create <deployment-id> --task-name <name>"], args: { "deployment-id": "The deployment the webhook belongs to." }, flags: { "task-name": { text: "The task that each run starts. Required." } }, notes: ["The reply carries a `secret` shown ONCE: hook:list never returns it."] }, [COMMANDS.HOOK_LIST]: { summary: "List the webhooks of a deployment.", usage: ["ignitify hook:list <deployment-id> [--limit N] [--after-id <id>] [--after <iso>]"], args: { "deployment-id": "The deployment id." }, flags: PAGE2 }, [COMMANDS.HOOK_DELETE]: { summary: "Delete a webhook.", usage: ["ignitify hook:delete <hook-resource-id> [--yes]"], args: { "hook-resource-id": "The HOOK's id (hok_\u2026), not the deployment's." }, flags: YES2 }, [COMMANDS.NOTIFY_SET]: { summary: "Set or clear the callback URL of a deployment.", usage: ["ignitify notify:set <deployment-id> --url <https://\u2026> --secret-stdin", "ignitify notify:set <deployment-id> --clear"], args: { "deployment-id": "The deployment id." }, flags: { url: { text: "The HTTPS address to call. Needs --secret-stdin." }, "secret-stdin": { text: "Read the signing secret from stdin. Needed with --url." }, clear: { text: "Remove the callback URL. Cannot be used with --url." } }, notes: ["There is no --secret flag: a value on argv is in `ps` and in your shell history."] }, [COMMANDS.USAGE]: { summary: "Show what you used in one month, by axis.", usage: [`ignitify usage [--period YYYY-MM] [--axis ${AXES}] [--vm <vm-id>] [--run <run-id>] [--runs|--vms] [--json]`], flags: { period: { text: "The month to show, as YYYY-MM.", default: "this month" }, axis: { text: "Show one axis only." }, vm: { text: "Only the usage of this VM." }, run: { text: "Only the usage of this run." }, runs: { text: "Add the lines behind the totals, one per run." }, vms: { text: "Add the lines behind the totals, one per VM." }, json: { text: "Print the report as JSON." } } }, [COMMANDS.USAGE_EXPORT]: { summary: "Export the usage lines of a month as JSON or CSV.", usage: [`ignitify usage:export [--period YYYY-MM] [--axis ${AXES}] [--vm <vm-id>] [--run <run-id>] (--json|--csv)`], flags: { period: { text: "The month to export, as YYYY-MM.", default: "this month" }, axis: { text: "Export one axis only." }, vm: { text: "Only the lines of this VM." }, run: { text: "Only the lines of this run." }, json: { text: "Print the lines as a JSON array." }, csv: { text: "Print the lines as CSV." } }, notes: ["Name exactly one format: --json or --csv."] }, [COMMANDS.USAGE_SERIES]: { summary: "Show your usage per day: runs, run durations, compute and egress.", usage: ["ignitify usage:series [--days N] [--json]"], flags: { ...SERIES_DAYS, json: { text: "Print the series as JSON." } }, notes: ["Days are UTC. A run counts on the day it ended. Compute counts when the VM closes, so a running VM shows none yet."], examples: ["ignitify usage:series", "ignitify usage:series --days 7 --json"] }, [COMMANDS.PERMISSION_LIST]: { summary: "List every permission a group can grant, and what it allows.", usage: ["ignitify permission:list [--json]"], notes: ["Needs no key and no server: the list is built into the CLI.", ...PERMISSION_NOTES] }, [COMMANDS.USER_CREATE]: { summary: "Create a user: a name that holds keys and is in groups.", usage: ["ignitify user:create <name> [--json]"], args: { name: "1 to 63 lower case letters, digits and -, unique in your account." }, notes: ["A user has no password and cannot sign in. Add it to a group to give it permissions.", OWNER_ONLY], examples: ["ignitify user:create github-ci"] }, [COMMANDS.USER_LIST]: { summary: "List your users.", usage: ["ignitify user:list [--json]"], notes: [OWNER_ONLY] }, [COMMANDS.USER_GET]: { summary: "Show one user: its groups, permissions and live keys.", usage: ["ignitify user:get <name> [--json]"], args: { name: "The user name." }, notes: [OWNER_ONLY] }, [COMMANDS.USER_REMOVE]: { summary: "Remove a user and revoke all of its keys.", usage: ["ignitify user:remove <name> [--yes]"], args: { name: "The user name." }, flags: YES2, notes: ["Every key of the user stops working at once. The name can be used again.", OWNER_ONLY] }, [COMMANDS.GROUP_CREATE]: { summary: "Create a group with a set of permissions.", usage: ["ignitify group:create <name> --permissions <p1,p2,\u2026> [--json]"], args: { name: "1 to 63 lower case letters, digits and -, unique in your account." }, flags: { permissions: { text: "The permissions the group grants, comma-separated. Required. See permission:list." } }, notes: [...PERMISSION_NOTES, OWNER_ONLY], examples: ["ignitify group:create readers --permissions tasks.read,deployments.read,runs.read,usage.read", "ignitify group:create ci --permissions tasks.read,deployments.read,deployments.write,runs.read,runs.write"] }, [COMMANDS.GROUP_LIST]: { summary: "List your groups and their permissions.", usage: ["ignitify group:list [--json]"], notes: [OWNER_ONLY] }, [COMMANDS.GROUP_GET]: { summary: "Show one group: its permissions and users.", usage: ["ignitify group:get <name> [--json]"], args: { name: "The group name." }, notes: [OWNER_ONLY] }, [COMMANDS.GROUP_GRANT]: { summary: "Add one permission to a group.", usage: ["ignitify group:grant <name> <permission>"], args: { name: "The group name.", permission: "One permission from permission:list." }, notes: [...PERMISSION_NOTES, OWNER_ONLY], examples: ["ignitify group:grant readers secrets.read"] }, [COMMANDS.GROUP_REVOKE]: { summary: "Remove one permission from a group.", usage: ["ignitify group:revoke <name> <permission>"], args: { name: "The group name.", permission: "The permission to remove." }, notes: ["The users of the group lose it at their next request.", OWNER_ONLY] }, [COMMANDS.GROUP_ADD_USER]: { summary: "Put a user in a group.", usage: ["ignitify group:add-user <group> <user>"], args: { group: "The group name.", user: "The user name." }, notes: [OWNER_ONLY], examples: ["ignitify group:add-user ci github-ci"] }, [COMMANDS.GROUP_REMOVE_USER]: { summary: "Take a user out of a group.", usage: ["ignitify group:remove-user <group> <user>"], args: { group: "The group name.", user: "The user name." }, notes: ["The user and its keys stay; they lose what the group granted.", OWNER_ONLY] }, [COMMANDS.GROUP_DELETE]: { summary: "Delete a group. Its users and keys stay.", usage: ["ignitify group:delete <name> [--yes]"], args: { name: "The group name." }, flags: YES2, notes: ["The users of the group lose the permissions it granted.", OWNER_ONLY] }, [COMMANDS.KEY_CREATE]: { summary: "Create an API key for a user.", usage: ["ignitify key:create --user <name> --label <text> [--out <file>] [--json]"], flags: { user: { text: "The user the key belongs to. Required." }, label: { text: "A name for the key, such as where it is used. Required." }, out: { text: "Write the key to this new file (mode 0600) and print only its id. Fails when the file exists." } }, notes: ["The key is shown once. Without --out it is printed; hand it over by hand and do not keep a copy.", "Owner keys come from ignitify login. This command makes user keys only.", OWNER_ONLY], examples: ["ignitify key:create --user github-ci --label github --out ./github-ci.key"] }, [COMMANDS.KEY_LIST]: { summary: "List the live keys of your account. Never a raw key.", usage: ["ignitify key:list [--user <name>] [--json]"], flags: { user: { text: "Only the keys of this user." } }, notes: ["The user column says owner for an owner key.", OWNER_ONLY] }, [COMMANDS.KEY_REVOKE]: { summary: "Revoke a key. It stops working at once.", usage: ["ignitify key:revoke <key-resource-id> [--yes]"], args: { "key-resource-id": "The key id, from key:list." }, flags: YES2, notes: [OWNER_ONLY] } }, HELP_PAGE = { TITLE: "ignitify", TAGLINE: "create, deploy and run tasks", USAGE: "ignitify <command> [arguments] [flags]", USAGE_NOTE: "Every command is <resource>:<verb>.", QUICK_START: [{ command: "ignitify login", text: "Sign this machine in." }, { command: "ignitify task:create my-task", text: "Register a task and write its files." }, { command: "ignitify task:deploy my-task", text: "Build it on the platform." }, { command: "ignitify task:run my-task --wait", text: "Run it and print the result." }], GROUPS: [{ title: "Tasks", resources: ["task"] }, { title: "Deployments", resources: ["deployment"] }, { title: "Runs", resources: ["run"] }, { title: "VMs", resources: ["vm"] }, { title: "Secrets", resources: ["secret"] }, { title: "Integrations", resources: ["integration"] }, { title: "Schedules", resources: ["schedule"] }, { title: "Webhooks", resources: ["hook", "notify"] }, { title: "Access", resources: ["permission", "user", "group", "key"] }, { title: "Account and usage", resources: ["login", "logout", "whoami", "quota", "usage", "notification", "help"] }], GLOBAL_FLAGS: [{ flag: "--json", text: "Print the result as one JSON document on stdout." }, { flag: "-h, --help", text: "Print help for the command." }, { flag: "-y, --yes", text: "Answer yes to a delete's question (for scripts)." }, { flag: "-v, --version", text: "Print the client and API version (first word only)." }], ENV: [{ name: ENV.KEY, text: "Your API key, for CI. Wins over the saved login." }, { name: ENV.TASKS_DIR, text: `Folder that holds your task folders (default: ${DEFAULT_TASKS_DIR}).` }, { name: "NO_COLOR", text: "Set to any value to turn colour off." }], NOTES: ["Delete commands always ask first; --force unlocks a refusal, it does not skip the question.", "A flag or argument a command does not take is refused, not ignored.", "On error the CLI prints a clean message and exits non-zero."], DOCS: SITE_LINKS.DOCS, MORE: "Run 'ignitify <command> --help' for the flags of one command.", H: { USAGE: "Usage", QUICK_START: "Quick start", GLOBAL_FLAGS: "Global flags", ENV: "Environment", NOTES: "Good to know", DOCS: "Docs", DESCRIPTION: "Description", ARGUMENTS: "Arguments", FLAGS: "Flags", EXAMPLES: "Examples" }, COLUMNS: { COMMAND: "COMMAND", WHAT: "WHAT IT DOES", FLAG: "FLAG", VALUE: "VALUE", DEFAULT: "DEFAULT", DESCRIPTION: "DESCRIPTION", NAME: "NAME", ARG: "ARGUMENT" }, SWITCH: "switch", DEFAULT: (value) => `Default: ${value}.`, REQUIRED: "required" };
1900
2065
  } });
1901
2066
  function entryOf(name) {
1902
2067
  if (name === VERSION_NAME) return { help: VERSION_HELP, meta: VERSION_META };
@@ -1937,7 +2102,7 @@ function placeholderOf(forms, flag) {
1937
2102
  }
1938
2103
  function flagRows(help, meta) {
1939
2104
  let words = help.flags ?? {}, known = { ...meta.flags, ...GLOBAL_FLAGS }, shortOf = Object.fromEntries(Object.entries(SHORT_FLAGS).map(([s, l]) => [l, s]));
1940
- return Object.entries(words).filter(([flag]) => Object.hasOwn(known, flag) && !HIDDEN_FLAGS.includes(flag)).map(([flag, w]) => {
2105
+ return Object.entries(words).filter(([flag]) => Object.hasOwn(known, flag)).map(([flag, w]) => {
1941
2106
  let short = shortOf[flag], value = known[flag] === "value" ? placeholderOf(help.usage, flag) : HELP_PAGE.SWITCH, text = w.default === void 0 ? w.text : `${w.text} ${HELP_PAGE.DEFAULT(w.default)}`;
1942
2107
  return [short === void 0 ? `--${flag}` : `-${short}, --${flag}`, value, text];
1943
2108
  });
@@ -2057,17 +2222,23 @@ function explainRunRefusal(e) {
2057
2222
  `);
2058
2223
  }
2059
2224
  function explainLimitRefusal(e) {
2060
- let refused = httpErrorJson(e);
2061
- if (!refused || refused.status !== 429) return null;
2062
- let { summary, reason } = refused.body;
2225
+ let refused2 = httpErrorJson(e);
2226
+ if (!refused2 || refused2.status !== 429) return null;
2227
+ let { summary, reason } = refused2.body;
2063
2228
  return typeof summary != "string" || summary === "" ? null : [`\u2717 Run refused \u2014 a monthly limit is reached (${typeof reason == "string" ? reason : "429"}).`, ` ${summary}`].join(`
2064
2229
  `);
2065
2230
  }
2066
- var isPayloadTooLarge, init_run_refusal = __esm({ "src/output/run-refusal.ts"() {
2231
+ function idempotencyRefusal(e) {
2232
+ let refused2 = httpErrorJson(e), hint = refused2 ? IDEMPOTENCY_REFUSAL_HINTS[refused2.status] : void 0, error = refused2?.body.error;
2233
+ return !refused2 || hint === void 0 || typeof error != "string" || error === "" ? null : { error, hint };
2234
+ }
2235
+ var IDEMPOTENCY_REFUSAL_HINTS, isPayloadTooLarge, init_run_refusal = __esm({ "src/output/run-refusal.ts"() {
2067
2236
  "use strict";
2068
2237
  init_define_IGNITIFY_CLIENT_FILES();
2069
2238
  init_http_client();
2239
+ init_constants();
2070
2240
  init_tenant();
2241
+ IDEMPOTENCY_REFUSAL_HINTS = { 409: MESSAGES.IDEMPOTENCY_IN_PROGRESS_HINT, 422: MESSAGES.IDEMPOTENCY_KEY_REUSED_HINT };
2071
2242
  isPayloadTooLarge = (e) => e instanceof HttpError && e.status === 413;
2072
2243
  } });
2073
2244
  function renderUsageReport(st, r, opts = { lines: false }) {
@@ -2091,6 +2262,77 @@ var init_usage2 = __esm({ "src/output/usage.ts"() {
2091
2262
  init_constants2();
2092
2263
  init_table();
2093
2264
  } });
2265
+ function attrText(value) {
2266
+ return value === null || typeof value != "object" ? typeof value == "string" && !/^[\w.:/@+-]+$/.test(value) ? JSON.stringify(value) : String(value) : JSON.stringify(value.text);
2267
+ }
2268
+ function timelineLine(event) {
2269
+ let attrs = Object.entries(event.attrs).filter(([key, value]) => key !== CAUSE_ATTR && value !== null).map(([key, value]) => `${key}=${attrText(value)}`), line = [event.at, event.label, ...attrs.length > 0 ? [attrs.join(" ")] : []].join(" ");
2270
+ return terminalSafe(line, false).replace(/[\n\t]/g, " ");
2271
+ }
2272
+ var CAUSE_ATTR, init_timeline = __esm({ "src/output/timeline.ts"() {
2273
+ "use strict";
2274
+ init_define_IGNITIFY_CLIENT_FILES();
2275
+ init_style();
2276
+ CAUSE_ATTR = "cause";
2277
+ } });
2278
+ function renderUsageSeries(st, r) {
2279
+ let I2 = LAYOUT.INDENT, statusColumns = TERMINAL_RUN_STATUSES.map((s) => ({ header: s, keep: true })), table = renderTable(st, [{ header: "DAY", keep: true }, ...statusColumns, { header: "P50", keep: true }, { header: "P95", keep: true }, { header: "COMPUTE", keep: true }, { header: "EGRESS", keep: true }], r.series.map((d) => [d.day, ...TERMINAL_RUN_STATUSES.map((s) => runsIn(d, s)), durationText(st, d.duration_ms_p50), durationText(st, d.duration_ms_p95), formatUsageQuantity(d.compute_ms, AXIS_UNIT.compute), formatUsageQuantity(d.egress_bytes, AXIS_UNIT.network)]), { indent: I2 });
2280
+ return [heading(st, `usage per day, ${windowText(r.days)}`), "", table, "", st.dim(`${I2}note: runs count on the day they ended; P50 and P95 are the run durations of that day.`), st.dim(`${I2} \`compute\` = VM time, counted when the VM closes. The egress of a past day can still grow.`)].join(`
2281
+ `);
2282
+ }
2283
+ function renderFailures(st, r) {
2284
+ let I2 = LAYOUT.INDENT, out2 = [heading(st, `failed and cancelled runs, ${windowText(r.days)}`), ""];
2285
+ return out2.push(renderTable(st, [{ header: "CLASS", keep: true }, { header: "RUNS", keep: true }, { header: "MEANING" }], FAILURE_CLASSES.map((c) => [c, r.by_class[c], FAILURE_CLASS_TEXT[c].hint]), { indent: I2 }), ""), r.top_tasks.length === 0 ? (out2.push(st.dim(`${I2}No task failed in this window.`)), out2.join(`
2286
+ `)) : (out2.push(renderTable(st, [{ header: "TASK" }, { header: "FAILURES", keep: true }], r.top_tasks.map((t) => [t.task_name === null ? NO_TASK_NAME_TEXT : terminalSafe(t.task_name, false), t.failures]), { indent: I2 }), "", st.dim(`${I2}note: the task list leaves out cancelled runs.`)), out2.join(`
2287
+ `));
2288
+ }
2289
+ var windowText, runsIn, durationText, init_reports = __esm({ "src/output/reports.ts"() {
2290
+ "use strict";
2291
+ init_define_IGNITIFY_CLIENT_FILES();
2292
+ init_tenant();
2293
+ init_http_client();
2294
+ init_blocks();
2295
+ init_constants2();
2296
+ init_style();
2297
+ init_table();
2298
+ windowText = (days) => `last ${days} ${days === 1 ? "day" : "days"} (UTC)`, runsIn = (day, status) => day.runs[status] ?? 0, durationText = (st, ms) => ms === null ? st.glyphs.dash : formatUsageQuantity(ms, AXIS_UNIT.compute);
2299
+ } });
2300
+ function severityWord(st, s) {
2301
+ let word = s.toUpperCase();
2302
+ return s === "critical" ? st.red(word) : s === "warning" ? st.yellow(word) : st.dim(word);
2303
+ }
2304
+ function factsOf(n) {
2305
+ let facts = [];
2306
+ return n.read || facts.push("unread"), n.state === "open" && facts.push("open"), n.state === "resolved" && n.resolved_at !== null && facts.push(`resolved ${terminalSafe(n.resolved_at, false)}`), n.occurrences > 1 && facts.push(`${n.occurrences} times`), facts;
2307
+ }
2308
+ function commandOf(a) {
2309
+ return a.type === "open-run" ? `ignitify ${COMMANDS.RUN_GET} ${terminalSafe(a.run_id, false)}` : a.type === "usage" ? `ignitify ${COMMANDS.QUOTA}` : null;
2310
+ }
2311
+ function card(st, n) {
2312
+ let I2 = LAYOUT.INDENT, title = terminalSafe(n.title, false), facts = factsOf(n), head = `${I2}${severityWord(st, n.severity)} ${n.read ? title : st.bold(title)}${facts.length > 0 ? st.dim(` (${facts.join(", ")})`) : ""}`, text = wrapText(terminalSafe(n.text, false), st.width - 2 * I2.length).map((l) => `${I2}${I2}${l}`), ids = [n.id, n.last_at, ...n.subject === null ? [] : [`${n.subject.type} ${n.subject.id}`]].map((s) => terminalSafe(s, false)), next = (n.actions ?? []).flatMap((a) => {
2313
+ let cmd = commandOf(a);
2314
+ return cmd === null ? [] : [`${I2}${I2}next: ${cmd}`];
2315
+ });
2316
+ return [head, ...text, st.dim(`${I2}${I2}${ids.join(" ")}`), ...next].join(`
2317
+ `);
2318
+ }
2319
+ function renderNotifications(st, r) {
2320
+ let I2 = LAYOUT.INDENT;
2321
+ return r.items.length === 0 ? `${heading(st, "notifications")}
2322
+
2323
+ ${st.dim(`${I2}No notifications.`)}` : [heading(st, "notifications, newest first"), "", r.items.map((n) => card(st, n)).join(`
2324
+
2325
+ `)].join(`
2326
+ `);
2327
+ }
2328
+ var init_notifications = __esm({ "src/output/notifications.ts"() {
2329
+ "use strict";
2330
+ init_define_IGNITIFY_CLIENT_FILES();
2331
+ init_constants();
2332
+ init_blocks();
2333
+ init_constants2();
2334
+ init_style();
2335
+ } });
2094
2336
  var init_output = __esm({ "src/output/index.ts"() {
2095
2337
  "use strict";
2096
2338
  init_define_IGNITIFY_CLIENT_FILES();
@@ -2108,6 +2350,10 @@ var init_output = __esm({ "src/output/index.ts"() {
2108
2350
  init_deletion_plan();
2109
2351
  init_run_refusal();
2110
2352
  init_usage2();
2353
+ init_timeline();
2354
+ init_reports();
2355
+ init_notifications();
2356
+ init_access2();
2111
2357
  } });
2112
2358
  function planAdvice(config) {
2113
2359
  let declared = config.build?.system_packages ?? [];
@@ -2127,127 +2373,31 @@ var init_package_advice3 = __esm({ "src/core/package-advice.ts"() {
2127
2373
  init_constants();
2128
2374
  } });
2129
2375
  var version, init_package = __esm({ "package.json"() {
2130
- version = "1.2.1";
2376
+ version = "2.0.0";
2131
2377
  } });
2132
- var byCreatedAtDesc, init_sort = __esm({ "src/utils/sort.ts"() {
2133
- "use strict";
2134
- init_define_IGNITIFY_CLIENT_FILES();
2135
- byCreatedAtDesc = (rows) => [...rows].sort((a, b) => (b.created_at ?? "").localeCompare(a.created_at ?? ""));
2136
- } });
2137
- function apiUrlOf(args) {
2138
- return strOpt(args, "api") ?? DEFAULTS.API_URL;
2378
+ function apiUrlFor(env, release = RELEASE_BUILD) {
2379
+ return release ? DEFAULTS.API_URL : env[ENV.DEV_API_URL] || DEFAULTS.API_URL;
2139
2380
  }
2140
- function boolFlag(args, key) {
2141
- return args.options[key] === true;
2142
- }
2143
- function requiredArg(args) {
2144
- return args.positionals[0];
2145
- }
2146
- function requireArg(args, label) {
2147
- let id = requiredArg(args);
2148
- return id || (fail(MESSAGES.ARG_REQUIRED(label)), null);
2149
- }
2150
- var init_args2 = __esm({ "src/utils/args.ts"() {
2151
- "use strict";
2152
- init_define_IGNITIFY_CLIENT_FILES();
2153
- init_constants();
2154
- init_output();
2155
- init_http_client();
2156
- init_http_client();
2157
- } });
2158
- function traceLine(e) {
2159
- return e instanceof HttpError && e.traceId ? MESSAGES.SERVER_TRACE_ID(e.traceId) : null;
2160
- }
2161
- function keyExpiredHint(e) {
2162
- let refused = httpErrorJson(e);
2163
- return refused?.status === 401 && refused.body.error === KEY_EXPIRED_ERROR ? MESSAGES.KEY_EXPIRED_HINT : null;
2164
- }
2165
- function printError(e) {
2166
- fail(errText(e), { hint: keyExpiredHint(e), trace: traceLine(e) });
2167
- }
2168
- async function guard(body) {
2169
- return await guardValue(body) ?? 1;
2170
- }
2171
- async function guardValue(body) {
2172
- try {
2173
- return await body();
2174
- } catch (e) {
2175
- printError(e);
2176
- return;
2381
+ function apiUrlRefusal(url) {
2382
+ switch (keyUrlRefusal(url)) {
2383
+ case "not-url":
2384
+ return MESSAGES.API_URL_NOT_URL(url);
2385
+ case "insecure":
2386
+ return MESSAGES.API_URL_NOT_HTTPS(url);
2387
+ case null:
2388
+ return null;
2177
2389
  }
2178
2390
  }
2179
- var init_guard = __esm({ "src/utils/guard.ts"() {
2180
- "use strict";
2181
- init_define_IGNITIFY_CLIENT_FILES();
2182
- init_http_client();
2183
- init_tenant();
2184
- init_constants();
2185
- init_output();
2186
- } });
2187
- var import_node_readline, ttyPrompter, init_prompt = __esm({ "src/io/prompt.ts"() {
2188
- "use strict";
2189
- init_define_IGNITIFY_CLIENT_FILES();
2190
- import_node_readline = __toESM(require("node:readline"), 1);
2191
- init_output();
2192
- ttyPrompter = { async confirm(question) {
2193
- if (!process.stdin.isTTY) return fail("Refusing to proceed: not a TTY. Re-run with --yes to confirm non-interactively."), false;
2194
- let rl = import_node_readline.default.createInterface({ input: process.stdin, output: process.stderr });
2195
- try {
2196
- let answer = await new Promise((resolve) => rl.question(`${question} [y/N] `, resolve));
2197
- return /^y(es)?$/i.test(answer.trim());
2198
- } finally {
2199
- rl.close();
2200
- }
2201
- } };
2202
- } });
2203
- async function confirmOrAbort(args, prompter = ttyPrompter, question = MESSAGES.CONFIRM_PROCEED) {
2204
- return boolFlag(args, "yes") || await prompter.confirm(question) ? true : (say(MESSAGES.ABORTED), false);
2205
- }
2206
- var init_prompt_flow = __esm({ "src/utils/prompt-flow.ts"() {
2207
- "use strict";
2208
- init_define_IGNITIFY_CLIENT_FILES();
2209
- init_prompt();
2210
- init_constants();
2211
- init_args2();
2212
- init_manager();
2213
- } });
2214
- var REAL_CLOCK, init_clock = __esm({ "src/utils/clock.ts"() {
2215
- "use strict";
2216
- init_define_IGNITIFY_CLIENT_FILES();
2217
- REAL_CLOCK = { sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)), now: () => Date.now() };
2218
- } });
2219
- function snakeCaseKeys(value) {
2220
- return Array.isArray(value) ? value.map(snakeCaseKeys) : typeof value != "object" || value === null ? value : Object.fromEntries(Object.entries(value).map(([k, v]) => [k.replace(/([a-z0-9])([A-Z])/g, (_, a, b) => `${a}_${b.toLowerCase()}`), snakeCaseKeys(v)]));
2221
- }
2222
- var init_snake_case = __esm({ "src/utils/snake-case.ts"() {
2223
- "use strict";
2224
- init_define_IGNITIFY_CLIENT_FILES();
2225
- } });
2226
- function nextPageNoteFor2(args, list2, rows) {
2227
- return nextPageNoteFor(PROGRAM, args, { ...list2, flags: [...Object.keys(list2.flags), ...REPEATED_GLOBAL_FLAGS] }, rows, effectivePageLimit(strOpt(args, "limit")));
2228
- }
2229
- function limitRefusal(args) {
2230
- let raw = args.options.limit;
2231
- return typeof raw == "string" ? pageLimitRefusal(raw) : null;
2391
+ function assertApiUrl(url) {
2392
+ let refusal = apiUrlRefusal(url);
2393
+ if (refusal !== null) throw new Error(refusal);
2394
+ return url;
2232
2395
  }
2233
- var PROGRAM, REPEATED_GLOBAL_FLAGS, init_page2 = __esm({ "src/utils/page.ts"() {
2396
+ var init_api_url = __esm({ "src/core/api-url.ts"() {
2234
2397
  "use strict";
2235
2398
  init_define_IGNITIFY_CLIENT_FILES();
2236
- init_tenant();
2237
2399
  init_http_client();
2238
- init_args2();
2239
- PROGRAM = "ignitify", REPEATED_GLOBAL_FLAGS = ["api"];
2240
- } });
2241
- var init_utils = __esm({ "src/utils/index.ts"() {
2242
- "use strict";
2243
- init_define_IGNITIFY_CLIENT_FILES();
2244
- init_sort();
2245
- init_args2();
2246
- init_guard();
2247
- init_prompt_flow();
2248
- init_clock();
2249
- init_snake_case();
2250
- init_page2();
2400
+ init_constants();
2251
2401
  } });
2252
2402
  function floorWarning(client, floor) {
2253
2403
  if (!floor) return null;
@@ -2275,8 +2425,8 @@ async function describeServer(baseUrl, fetchImpl = fetch, check = noteServerVers
2275
2425
  let floor = res.headers.get(CLIENT_FLOOR_HEADER);
2276
2426
  return `API: ${api} at ${baseUrl}${floor ? ` (minimum client ${floor})` : ""}`;
2277
2427
  }
2278
- async function runVersion(args, fetchImpl = fetch) {
2279
- let baseUrl = apiUrlOf(args), st = outStyle();
2428
+ async function runVersion(fetchImpl = fetch, env = process.env) {
2429
+ let baseUrl = apiUrlFor(env), st = outStyle();
2280
2430
  return out(`${st.bold(`ignitify ${CLIENT_VERSION}`)} ${st.dim(`(built for API ${API_VERSION})`)}`), out(st.dim(await describeServer(baseUrl, fetchImpl))), 0;
2281
2431
  }
2282
2432
  var CLIENT_VERSION, PROBE_TIMEOUT_MS, noteServerVersion, init_version = __esm({ "src/io/version.ts"() {
@@ -2286,7 +2436,7 @@ var CLIENT_VERSION, PROBE_TIMEOUT_MS, noteServerVersion, init_version = __esm({
2286
2436
  init_tenant();
2287
2437
  init_constants();
2288
2438
  init_semver();
2289
- init_utils();
2439
+ init_api_url();
2290
2440
  init_output();
2291
2441
  CLIENT_VERSION = version, PROBE_TIMEOUT_MS = 3e3;
2292
2442
  noteServerVersion = createStalenessCheck(CLIENT_VERSION, (msg) => warn(msg));
@@ -2355,16 +2505,25 @@ function readCredentials(file = credentialsPath(), fsx = import_node_fs2.default
2355
2505
  fsx.closeSync(fd);
2356
2506
  }
2357
2507
  }
2358
- function writeCredentialsAtomic(creds, file = credentialsPath(), fsx = import_node_fs2.default) {
2359
- secureCredentialsDir(import_node_path.default.dirname(file), fsx);
2360
- let temp = `${file}.${(0, import_node_crypto.randomBytes)(6).toString("hex")}.tmp`, fd = fsx.openSync(temp, "wx", CREDENTIALS.FILE_MODE);
2508
+ function createPrivateFile(file, fsx = import_node_fs2.default) {
2509
+ return fsx.openSync(file, "wx", CREDENTIALS.FILE_MODE);
2510
+ }
2511
+ function discardPrivateFile(fd, file, fsx = import_node_fs2.default) {
2512
+ fsx.closeSync(fd), fsx.unlinkSync(file);
2513
+ }
2514
+ function fillPrivateFile(fd, file, text, fsx = import_node_fs2.default) {
2361
2515
  try {
2362
- fsx.writeSync(fd, `${JSON.stringify(creds, null, 2)}
2363
- `), fsx.fsyncSync(fd);
2516
+ fsx.writeSync(fd, text), fsx.fsyncSync(fd);
2364
2517
  } catch (e) {
2365
- throw fsx.closeSync(fd), fsx.unlinkSync(temp), e;
2518
+ throw discardPrivateFile(fd, file, fsx), e;
2366
2519
  }
2367
2520
  fsx.closeSync(fd);
2521
+ }
2522
+ function writeCredentialsAtomic(creds, file = credentialsPath(), fsx = import_node_fs2.default) {
2523
+ secureCredentialsDir(import_node_path.default.dirname(file), fsx);
2524
+ let temp = `${file}.${(0, import_node_crypto.randomBytes)(6).toString("hex")}.tmp`;
2525
+ fillPrivateFile(createPrivateFile(temp, fsx), temp, `${JSON.stringify(creds, null, 2)}
2526
+ `, fsx);
2368
2527
  try {
2369
2528
  fsx.renameSync(temp, file);
2370
2529
  } catch (e) {
@@ -2435,29 +2594,8 @@ var UnreachableError, init_unreachable = __esm({ "src/core/unreachable.ts"() {
2435
2594
  }
2436
2595
  };
2437
2596
  } });
2438
- function apiUrlRefusal(url) {
2439
- switch (keyUrlRefusal(url)) {
2440
- case "not-url":
2441
- return MESSAGES.API_URL_NOT_URL(url);
2442
- case "insecure":
2443
- return MESSAGES.API_URL_NOT_HTTPS(url);
2444
- case null:
2445
- return null;
2446
- }
2447
- }
2448
- function assertApiUrl(url) {
2449
- let refusal = apiUrlRefusal(url);
2450
- if (refusal !== null) throw new Error(refusal);
2451
- return url;
2452
- }
2453
- var init_api_url = __esm({ "src/core/api-url.ts"() {
2454
- "use strict";
2455
- init_define_IGNITIFY_CLIENT_FILES();
2456
- init_http_client();
2457
- init_constants();
2458
- } });
2459
- function resolveApiConfig(apiOverride, env = process.env, read = () => readCredentials(), note = noteEnvOverride) {
2460
- let baseUrl = assertApiUrl(apiOverride ?? DEFAULTS.API_URL), envKey = env[ENV.KEY];
2597
+ function resolveApiConfig(env = process.env, read = () => readCredentials(), note = noteEnvOverride) {
2598
+ let baseUrl = assertApiUrl(apiUrlFor(env)), envKey = env[ENV.KEY];
2461
2599
  if (envKey) return envOverridesLogin(baseUrl, readOrNone(read)) && note(MESSAGES.ENV_KEY_OVERRIDES_LOGIN), { baseUrl, token: envKey };
2462
2600
  let saved = read();
2463
2601
  if (saved.kind === "none") throw new Error(MESSAGES.NOT_SIGNED_IN);
@@ -2516,9 +2654,9 @@ async function pollDeviceLogin(cfg, deviceCode, fetchImpl) {
2516
2654
  return { kind: "key", key };
2517
2655
  }
2518
2656
  function slowDownOf(e) {
2519
- let refused = httpErrorJson(e);
2520
- if (refused?.status !== 429 || refused.body.status !== "slow_down") return null;
2521
- let interval = refused.body.interval;
2657
+ let refused2 = httpErrorJson(e);
2658
+ if (refused2?.status !== 429 || refused2.body.status !== "slow_down") return null;
2659
+ let interval = refused2.body.interval;
2522
2660
  return typeof interval == "number" ? interval : null;
2523
2661
  }
2524
2662
  function revokeOwnKey(cfg, fetchImpl) {
@@ -2531,9 +2669,11 @@ async function postDeployment(cfg, taskId, manifest, tar, fetchImpl) {
2531
2669
  let form = new FormData();
2532
2670
  return form.set("task_id", taskId), form.set("manifest", JSON.stringify(manifest)), form.set("bundle", new Blob([new Uint8Array(tar)], { type: "application/x-tar" }), "bundle.tar"), await request(`${cfg.baseUrl}${TENANT_PATHS.DEPLOYMENTS}`, { method: "POST", headers: authHeaders(cfg), body: form, fetchImpl: viaApi(fetchImpl), timeoutMs: 3e5, ...readHeaders });
2533
2671
  }
2534
- function postRun(cfg, run2, fetchImpl) {
2535
- let body = { deployment_id: run2.deploymentId, task_name: run2.taskName, payload: run2.payload, preset: run2.preset, timeout_sec: run2.timeoutSec, execution: run2.execution, at: run2.at };
2536
- return apiPost(cfg, TENANT_PATHS.RUNS, body, fetchImpl);
2672
+ async function postRun(cfg, run2, fetchImpl) {
2673
+ let body = { deployment_id: run2.deploymentId, task_name: run2.taskName, payload: run2.payload, preset: run2.preset, timeout_sec: run2.timeoutSec, execution: run2.execution, at: run2.at }, replayed = false;
2674
+ return { answer: await apiPost(cfg, TENANT_PATHS.RUNS, body, fetchImpl, void 0, { headers: idempotencyHeaders(run2.idempotencyKey), onHeaders: (headers) => {
2675
+ replayed = isReplayedAnswer(headers);
2676
+ } }), replayed };
2537
2677
  }
2538
2678
  async function listSchedules(cfg, fetchImpl) {
2539
2679
  return apiGet(cfg, TENANT_PATHS.SCHEDULES, fetchImpl);
@@ -2544,8 +2684,10 @@ function deleteSchedule(cfg, scheduleId, fetchImpl) {
2544
2684
  function apiGet(cfg, path12, fetchImpl) {
2545
2685
  return request(`${cfg.baseUrl}${path12}`, { headers: authHeaders(cfg), fetchImpl: viaApi(fetchImpl), ...readHeaders });
2546
2686
  }
2547
- function apiPost(cfg, path12, body, fetchImpl, timeoutMs) {
2548
- return request(`${cfg.baseUrl}${path12}`, { method: "POST", headers: { ...authHeaders(cfg), "content-type": "application/json" }, body, fetchImpl: viaApi(fetchImpl), timeoutMs, ...readHeaders });
2687
+ function apiPost(cfg, path12, body, fetchImpl, timeoutMs, extras = {}) {
2688
+ return request(`${cfg.baseUrl}${path12}`, { method: "POST", headers: { ...authHeaders(cfg), "content-type": "application/json", ...extras.headers }, body, fetchImpl: viaApi(fetchImpl), timeoutMs, onHeaders: (headers) => {
2689
+ readHeaders.onHeaders(headers), extras.onHeaders?.(headers);
2690
+ } });
2549
2691
  }
2550
2692
  function apiDelete(cfg, path12, fetchImpl) {
2551
2693
  return request(`${cfg.baseUrl}${path12}`, { method: "DELETE", headers: authHeaders(cfg), fetchImpl: viaApi(fetchImpl), ...readHeaders });
@@ -2559,6 +2701,15 @@ function getWhoami(cfg, fetchImpl) {
2559
2701
  function getUsage(cfg, filters2 = {}, fetchImpl) {
2560
2702
  return apiGet(cfg, `${TENANT_PATHS.USAGE}${buildQuery(filters2)}`, fetchImpl);
2561
2703
  }
2704
+ function getUsageSeries(cfg, days, fetchImpl) {
2705
+ return apiGet(cfg, `${TENANT_PATHS.USAGE_SERIES}${daysQuery(days)}`, fetchImpl);
2706
+ }
2707
+ function getRunFailures(cfg, days, fetchImpl) {
2708
+ return apiGet(cfg, `${TENANT_PATHS.RUN_FAILURES}${daysQuery(days)}`, fetchImpl);
2709
+ }
2710
+ function listNotifications(cfg, params, fetchImpl) {
2711
+ return apiGet(cfg, `${TENANT_PATHS.NOTIFICATIONS}${buildQuery(params)}`, fetchImpl);
2712
+ }
2562
2713
  function setSecret(cfg, name, value, fetchImpl) {
2563
2714
  return apiPost(cfg, TENANT_PATHS.SECRETS, { name, value }, fetchImpl);
2564
2715
  }
@@ -2580,6 +2731,52 @@ function deleteHook(cfg, hookId, fetchImpl) {
2580
2731
  function setNotify(cfg, deploymentId, body, fetchImpl) {
2581
2732
  return apiPut(cfg, TENANT_PATHS.DEPLOYMENT_NOTIFY(deploymentId), body, fetchImpl);
2582
2733
  }
2734
+ function createUser(cfg, name, fetchImpl) {
2735
+ return apiPost(cfg, TENANT_PATHS.USERS, { name }, fetchImpl);
2736
+ }
2737
+ function listUsers(cfg, fetchImpl) {
2738
+ return apiGet(cfg, TENANT_PATHS.USERS, fetchImpl);
2739
+ }
2740
+ function getUser(cfg, name, fetchImpl) {
2741
+ return apiGet(cfg, TENANT_PATHS.USER_BY_ID(name), fetchImpl);
2742
+ }
2743
+ function deleteUser(cfg, name, fetchImpl) {
2744
+ return apiDelete(cfg, TENANT_PATHS.USER_BY_ID(name), fetchImpl);
2745
+ }
2746
+ function createGroup(cfg, name, permissions, fetchImpl) {
2747
+ return apiPost(cfg, TENANT_PATHS.GROUPS, { name, permissions }, fetchImpl);
2748
+ }
2749
+ function listGroups(cfg, fetchImpl) {
2750
+ return apiGet(cfg, TENANT_PATHS.GROUPS, fetchImpl);
2751
+ }
2752
+ function getGroup(cfg, name, fetchImpl) {
2753
+ return apiGet(cfg, TENANT_PATHS.GROUP_BY_ID(name), fetchImpl);
2754
+ }
2755
+ function deleteGroup(cfg, name, fetchImpl) {
2756
+ return apiDelete(cfg, TENANT_PATHS.GROUP_BY_ID(name), fetchImpl);
2757
+ }
2758
+ function grantGroupPermission(cfg, name, permission, fetchImpl) {
2759
+ return apiPut(cfg, TENANT_PATHS.GROUP_PERMISSION(name, permission), void 0, fetchImpl);
2760
+ }
2761
+ function revokeGroupPermission(cfg, name, permission, fetchImpl) {
2762
+ return apiDelete(cfg, TENANT_PATHS.GROUP_PERMISSION(name, permission), fetchImpl);
2763
+ }
2764
+ function addGroupUser(cfg, name, user, fetchImpl) {
2765
+ return apiPut(cfg, TENANT_PATHS.GROUP_USER(name, user), void 0, fetchImpl);
2766
+ }
2767
+ function removeGroupUser(cfg, name, user, fetchImpl) {
2768
+ return apiDelete(cfg, TENANT_PATHS.GROUP_USER(name, user), fetchImpl);
2769
+ }
2770
+ function createKey(cfg, body, fetchImpl) {
2771
+ return apiPost(cfg, TENANT_PATHS.KEYS, body, fetchImpl);
2772
+ }
2773
+ function listKeys(cfg, user, fetchImpl) {
2774
+ let q = buildQuery({ [KEY_LIST_QUERY.USER]: user });
2775
+ return apiGet(cfg, `${TENANT_PATHS.KEYS}${q}`, fetchImpl);
2776
+ }
2777
+ function deleteKey(cfg, keyId, fetchImpl) {
2778
+ return apiDelete(cfg, TENANT_PATHS.KEY_BY_ID(keyId), fetchImpl);
2779
+ }
2583
2780
  async function postPackageAdvice(cfg, body, fetchImpl) {
2584
2781
  try {
2585
2782
  return { kind: "ok", response: await apiPost(cfg, TENANT_PATHS.PACKAGE_ADVICE, body, fetchImpl, ADVICE.TIMEOUT_MS) };
@@ -2627,6 +2824,29 @@ function getApiRun(cfg, runId, fetchImpl) {
2627
2824
  function getApiRunLogs(cfg, runId, fetchImpl) {
2628
2825
  return apiGet(cfg, TENANT_PATHS.RUN_LOGS(runId), fetchImpl);
2629
2826
  }
2827
+ async function apiFollowGet(cfg, path12, fetchImpl) {
2828
+ let retryAfter = null;
2829
+ try {
2830
+ return { ok: true, data: await request(`${cfg.baseUrl}${path12}`, { headers: authHeaders(cfg), fetchImpl: viaApi(fetchImpl), onHeaders: (headers) => {
2831
+ readHeaders.onHeaders(headers), retryAfter = headers.get(RETRY_AFTER_HEADER);
2832
+ } }) };
2833
+ } catch (error) {
2834
+ return { ok: false, error, retryAfterMs: retryAfterMs(retryAfter, Date.now()) };
2835
+ }
2836
+ }
2837
+ function readRunTimeline(cfg, runId, query, fetchImpl) {
2838
+ let q = buildQuery({ [OBS_QUERY.CURSOR]: query.cursor ?? void 0, [OBS_QUERY.WAIT_SEC]: query.waitSec === void 0 ? void 0 : String(query.waitSec) });
2839
+ return apiFollowGet(cfg, `${TENANT_PATHS.RUN_TIMELINE(runId)}${q}`, fetchImpl);
2840
+ }
2841
+ function readRunOutput(cfg, runId, fromOffset, fetchImpl) {
2842
+ return apiFollowGet(cfg, `${TENANT_PATHS.RUN_LOGS(runId)}${buildQuery({ [OBS_QUERY.FROM_OFFSET]: String(fromOffset) })}`, fetchImpl);
2843
+ }
2844
+ function readRunList(cfg, params = {}, fetchImpl) {
2845
+ return apiFollowGet(cfg, `${TENANT_PATHS.RUNS}${buildQuery(params)}`, fetchImpl);
2846
+ }
2847
+ function readRunForFollow(cfg, runId, fetchImpl) {
2848
+ return apiFollowGet(cfg, TENANT_PATHS.RUN_BY_ID(runId), fetchImpl);
2849
+ }
2630
2850
  function deleteRun(cfg, runId, fetchImpl) {
2631
2851
  return apiDelete(cfg, TENANT_PATHS.RUN_BY_ID(runId), fetchImpl);
2632
2852
  }
@@ -2645,28 +2865,151 @@ async function getApiVm(cfg, vmId, fetchImpl) {
2645
2865
  function deleteVm(cfg, vmId, force = false, fetchImpl) {
2646
2866
  return apiDelete(cfg, `${TENANT_PATHS.VM_BY_ID(vmId)}${forceQuery(force)}`, fetchImpl);
2647
2867
  }
2648
- var readHeaders, noteEnvOverride, versionHeader, BadAnswerError, init_api = __esm({ "src/io/api.ts"() {
2868
+ var readHeaders, idempotencyHeaders, isReplayedAnswer, noteEnvOverride, versionHeader, BadAnswerError, daysQuery, init_api = __esm({ "src/io/api.ts"() {
2869
+ "use strict";
2870
+ init_define_IGNITIFY_CLIENT_FILES();
2871
+ init_http_client();
2872
+ init_output();
2873
+ init_constants();
2874
+ init_package_advice3();
2875
+ init_version();
2876
+ init_credentials();
2877
+ init_unreachable();
2878
+ init_api_url();
2879
+ init_tenant();
2880
+ readHeaders = { onHeaders: noteServerVersion }, idempotencyHeaders = (key) => key === void 0 ? {} : { [IDEMPOTENCY_KEY_HEADER]: key }, isReplayedAnswer = (headers) => headers.get(IDEMPOTENT_REPLAYED_HEADER) === "true";
2881
+ noteEnvOverride = /* @__PURE__ */ (() => {
2882
+ let noted = false;
2883
+ return (msg) => {
2884
+ noted || (noted = true, warn(msg));
2885
+ };
2886
+ })();
2887
+ versionHeader = { [CLI_VERSION_HEADER]: CLIENT_VERSION };
2888
+ BadAnswerError = class extends Error {
2889
+ };
2890
+ daysQuery = (days) => buildQuery({ [OBS_QUERY.DAYS]: days === null ? void 0 : String(days) });
2891
+ } });
2892
+ var byCreatedAtDesc, init_sort = __esm({ "src/utils/sort.ts"() {
2893
+ "use strict";
2894
+ init_define_IGNITIFY_CLIENT_FILES();
2895
+ byCreatedAtDesc = (rows) => [...rows].sort((a, b) => (b.created_at ?? "").localeCompare(a.created_at ?? ""));
2896
+ } });
2897
+ function parseWholeCount(raw) {
2898
+ if (!/^[1-9][0-9]*$/.test(raw)) return null;
2899
+ let n = Number(raw);
2900
+ return Number.isSafeInteger(n) ? n : null;
2901
+ }
2902
+ function boolFlag(args, key) {
2903
+ return args.options[key] === true;
2904
+ }
2905
+ function requiredArg(args) {
2906
+ return args.positionals[0];
2907
+ }
2908
+ function requireArg(args, label) {
2909
+ let id = requiredArg(args);
2910
+ return id || (fail(MESSAGES.ARG_REQUIRED(label)), null);
2911
+ }
2912
+ var init_args2 = __esm({ "src/utils/args.ts"() {
2913
+ "use strict";
2914
+ init_define_IGNITIFY_CLIENT_FILES();
2915
+ init_constants();
2916
+ init_output();
2917
+ init_http_client();
2918
+ } });
2919
+ function traceLine(e) {
2920
+ return e instanceof HttpError && e.traceId ? MESSAGES.SERVER_TRACE_ID(e.traceId) : null;
2921
+ }
2922
+ function keyExpiredHint(e) {
2923
+ let refused2 = httpErrorJson(e);
2924
+ return refused2?.status === 401 && refused2.body.error === KEY_EXPIRED_ERROR ? MESSAGES.KEY_EXPIRED_HINT : null;
2925
+ }
2926
+ function printError(e) {
2927
+ fail(accessRefusalText(e) ?? errText(e), { hint: keyExpiredHint(e), trace: traceLine(e) });
2928
+ }
2929
+ async function guard(body) {
2930
+ return await guardValue(body) ?? 1;
2931
+ }
2932
+ async function guardValue(body) {
2933
+ try {
2934
+ return await body();
2935
+ } catch (e) {
2936
+ printError(e);
2937
+ return;
2938
+ }
2939
+ }
2940
+ var init_guard = __esm({ "src/utils/guard.ts"() {
2649
2941
  "use strict";
2650
2942
  init_define_IGNITIFY_CLIENT_FILES();
2651
2943
  init_http_client();
2944
+ init_tenant();
2945
+ init_constants();
2652
2946
  init_output();
2947
+ init_access();
2948
+ } });
2949
+ var import_node_readline, ttyPrompter, init_prompt = __esm({ "src/io/prompt.ts"() {
2950
+ "use strict";
2951
+ init_define_IGNITIFY_CLIENT_FILES();
2952
+ import_node_readline = __toESM(require("node:readline"), 1);
2953
+ init_output();
2954
+ ttyPrompter = { async confirm(question) {
2955
+ if (!process.stdin.isTTY) return fail("Refusing to proceed: not a TTY. Re-run with --yes to confirm non-interactively."), false;
2956
+ let rl = import_node_readline.default.createInterface({ input: process.stdin, output: process.stderr });
2957
+ try {
2958
+ let answer = await new Promise((resolve) => rl.question(`${question} [y/N] `, resolve));
2959
+ return /^y(es)?$/i.test(answer.trim());
2960
+ } finally {
2961
+ rl.close();
2962
+ }
2963
+ } };
2964
+ } });
2965
+ async function confirmOrAbort(args, prompter = ttyPrompter, question = MESSAGES.CONFIRM_PROCEED) {
2966
+ return boolFlag(args, "yes") || await prompter.confirm(question) ? true : (say(MESSAGES.ABORTED), false);
2967
+ }
2968
+ var init_prompt_flow = __esm({ "src/utils/prompt-flow.ts"() {
2969
+ "use strict";
2970
+ init_define_IGNITIFY_CLIENT_FILES();
2971
+ init_prompt();
2653
2972
  init_constants();
2654
- init_package_advice3();
2655
- init_version();
2656
- init_credentials();
2657
- init_unreachable();
2658
- init_api_url();
2973
+ init_args2();
2974
+ init_manager();
2975
+ } });
2976
+ var REAL_CLOCK, init_clock = __esm({ "src/utils/clock.ts"() {
2977
+ "use strict";
2978
+ init_define_IGNITIFY_CLIENT_FILES();
2979
+ REAL_CLOCK = { sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)), now: () => Date.now() };
2980
+ } });
2981
+ function snakeCaseKeys(value) {
2982
+ return Array.isArray(value) ? value.map(snakeCaseKeys) : typeof value != "object" || value === null ? value : Object.fromEntries(Object.entries(value).map(([k, v]) => [k.replace(/([a-z0-9])([A-Z])/g, (_, a, b) => `${a}_${b.toLowerCase()}`), snakeCaseKeys(v)]));
2983
+ }
2984
+ var init_snake_case = __esm({ "src/utils/snake-case.ts"() {
2985
+ "use strict";
2986
+ init_define_IGNITIFY_CLIENT_FILES();
2987
+ } });
2988
+ function nextPageNoteFor2(args, list2, rows) {
2989
+ return nextPageNoteFor(PROGRAM, args, { ...list2, flags: Object.keys(list2.flags) }, rows, effectivePageLimit(strOpt(args, "limit")));
2990
+ }
2991
+ function limitRefusal(args) {
2992
+ let raw = args.options.limit;
2993
+ return typeof raw == "string" ? pageLimitRefusal(raw) : null;
2994
+ }
2995
+ var PROGRAM, init_page2 = __esm({ "src/utils/page.ts"() {
2996
+ "use strict";
2997
+ init_define_IGNITIFY_CLIENT_FILES();
2659
2998
  init_tenant();
2660
- readHeaders = { onHeaders: noteServerVersion };
2661
- noteEnvOverride = /* @__PURE__ */ (() => {
2662
- let noted = false;
2663
- return (msg) => {
2664
- noted || (noted = true, warn(msg));
2665
- };
2666
- })();
2667
- versionHeader = { [CLI_VERSION_HEADER]: CLIENT_VERSION };
2668
- BadAnswerError = class extends Error {
2669
- };
2999
+ init_http_client();
3000
+ init_args2();
3001
+ PROGRAM = "ignitify";
3002
+ } });
3003
+ var init_utils = __esm({ "src/utils/index.ts"() {
3004
+ "use strict";
3005
+ init_define_IGNITIFY_CLIENT_FILES();
3006
+ init_sort();
3007
+ init_args2();
3008
+ init_guard();
3009
+ init_prompt_flow();
3010
+ init_clock();
3011
+ init_snake_case();
3012
+ init_page2();
2670
3013
  } });
2671
3014
  function payloadRefusal(payload, limit) {
2672
3015
  let bytes = payloadBytes(payload);
@@ -2680,8 +3023,19 @@ var payloadBytes, limitOrFallback, formatLimit, limitsNote, init_payload_limit =
2680
3023
  payloadBytes = (payload) => Buffer.byteLength(JSON.stringify(payload) ?? "", "utf8"), limitOrFallback = (limit, fallback) => typeof limit == "number" && Number.isFinite(limit) && limit > 0 ? limit : fallback;
2681
3024
  formatLimit = (bytes) => formatBytes(bytes).replace(/\.0 /, " "), limitsNote = () => MESSAGES.TASK_LIMITS(formatLimit(PAYLOAD_LIMIT_FALLBACK_BYTES), formatLimit(RESULT_LIMIT_FALLBACK_BYTES));
2682
3025
  } });
2683
- function apiConfig(args) {
2684
- return resolveApiConfig(strOpt(args, "api"));
3026
+ function apiConfig() {
3027
+ return resolveApiConfig();
3028
+ }
3029
+ function accessNameArg(raw, kind, label) {
3030
+ if (raw === void 0 || raw === "") return fail(MESSAGES.ARG_REQUIRED(label)), null;
3031
+ let checked = checkAccessName(kind, raw);
3032
+ return checked.ok ? checked.value : (fail(checked.message), null);
3033
+ }
3034
+ function daysOption(args) {
3035
+ let raw = strOpt(args, "days");
3036
+ if (raw === void 0) return { ok: true, days: null };
3037
+ let days = parseWholeCount(raw);
3038
+ return days === null ? (fail(MESSAGES.DAYS_INVALID(raw)), { ok: false }) : { ok: true, days };
2685
3039
  }
2686
3040
  async function payloadLimit(cfg) {
2687
3041
  let whoami = await getWhoami(cfg).catch(() => null);
@@ -2691,6 +3045,10 @@ function consoleLogText(bytes, out2) {
2691
3045
  return out2.raw ? bytes : terminalSafe(bytes, out2.colour);
2692
3046
  }
2693
3047
  function printConsoleLog(data, raw, colour = outStyle().colour) {
3048
+ if (isJsonOutput()) {
3049
+ emit(data);
3050
+ return;
3051
+ }
2694
3052
  if (writeRaw(consoleLogText(typeof data?.bytes == "string" ? data.bytes : "", { raw, colour })), data?.truncated === true) {
2695
3053
  let lines = typeof data.lines == "number" ? data.lines : 0;
2696
3054
  tell(`
@@ -2704,7 +3062,7 @@ function noteNextPage(args, list2, rows) {
2704
3062
  async function runPagedList(args, verb) {
2705
3063
  let badLimit = limitRefusal(args);
2706
3064
  return badLimit !== null ? (fail(badLimit), 1) : guard(async () => {
2707
- let data = await verb.fetchPage(apiConfig(args), { ...flagParams(args, verb.list.flags), ...verb.extra });
3065
+ let data = await verb.fetchPage(apiConfig(), { ...flagParams(args, verb.list.flags), ...verb.extra });
2708
3066
  return verb.show(data), noteNextPage(args, verb.list, verb.rowsOf(data)), 0;
2709
3067
  });
2710
3068
  }
@@ -2713,19 +3071,20 @@ var init_shared = __esm({ "src/commands/shared.ts"() {
2713
3071
  init_define_IGNITIFY_CLIENT_FILES();
2714
3072
  init_api();
2715
3073
  init_payload_limit();
3074
+ init_access();
2716
3075
  init_constants();
2717
3076
  init_utils();
2718
3077
  init_output();
2719
3078
  } });
2720
3079
  async function runWhoami(args) {
2721
3080
  return guard(async () => {
2722
- let cfg = apiConfig(args);
3081
+ let cfg = apiConfig();
2723
3082
  return CliOutputManager.render("whoami", await getWhoami(cfg)), 0;
2724
3083
  });
2725
3084
  }
2726
3085
  async function runUsage(args) {
2727
3086
  return guard(async () => {
2728
- let cfg = apiConfig(args);
3087
+ let cfg = apiConfig();
2729
3088
  return CliOutputManager.render("quota", await getWhoami(cfg)), 0;
2730
3089
  });
2731
3090
  }
@@ -2747,14 +3106,16 @@ function decidePollError(e, failuresInARow, failingForMs) {
2747
3106
  return isTransientError(e) ? failuresInARow >= POLL.ERROR.MIN_TRIES && failingForMs >= POLL.ERROR.GRACE_MS ? "give-up" : "retry" : "give-up";
2748
3107
  }
2749
3108
  async function pollUntil(loop) {
2750
- let sleep = loop.clock?.sleep ?? REAL_CLOCK.sleep, now = loop.clock?.now ?? REAL_CLOCK.now, startedAt = now(), failures = 0, firstFailureAt = 0;
3109
+ let sleep = loop.clock?.sleep ?? REAL_CLOCK.sleep, now = loop.clock?.now ?? REAL_CLOCK.now, startedAt = now(), decideError = loop.decideError === void 0 ? fixedRetry(loop.retryDelayMs) : loop.decideError, failures = 0, firstFailureAt = 0;
2751
3110
  for (let attempt = 0; ; ) {
2752
3111
  let view;
2753
3112
  try {
2754
3113
  view = await loop.fetch();
2755
3114
  } catch (error) {
2756
- if (failures === 0 && (firstFailureAt = now()), failures += 1, decidePollError(error, failures, now() - firstFailureAt) === "give-up") return { kind: "lost", error };
2757
- loop.onRetry?.(error), await sleep(loop.retryDelayMs);
3115
+ failures === 0 && (firstFailureAt = now()), failures += 1;
3116
+ let next = decideError(error, failures, now() - firstFailureAt);
3117
+ if (next.kind === "give-up") return { kind: "lost", error };
3118
+ next.counted || (failures = 0), loop.onRetry?.(error, next.delayMs), await sleep(next.delayMs);
2758
3119
  continue;
2759
3120
  }
2760
3121
  failures = 0, loop.onView?.(view);
@@ -2763,7 +3124,7 @@ async function pollUntil(loop) {
2763
3124
  loop.onWait?.(view, attempt), await sleep(action.delayMs), attempt += 1;
2764
3125
  }
2765
3126
  }
2766
- var isWait, isLost, init_poll = __esm({ "src/core/poll.ts"() {
3127
+ var isWait, isLost, fixedRetry, init_poll = __esm({ "src/core/poll.ts"() {
2767
3128
  "use strict";
2768
3129
  init_define_IGNITIFY_CLIENT_FILES();
2769
3130
  init_http_client();
@@ -2771,6 +3132,7 @@ var isWait, isLost, init_poll = __esm({ "src/core/poll.ts"() {
2771
3132
  init_constants();
2772
3133
  init_utils();
2773
3134
  isWait = (action) => action.kind === "wait", isLost = (end) => "kind" in end && end.kind === "lost";
3135
+ fixedRetry = (delayMs) => (error, failuresInARow, failingForMs) => decidePollError(error, failuresInARow, failingForMs) === "give-up" ? { kind: "give-up" } : { kind: "retry", delayMs, counted: true };
2774
3136
  } });
2775
3137
  function shortenHome(file, home) {
2776
3138
  if (home === "" || !file.startsWith(home)) return file;
@@ -2862,7 +3224,7 @@ async function pollForKey(baseUrl, started, deadline, deps) {
2862
3224
  }
2863
3225
  async function runLogin(args, deps = {}) {
2864
3226
  return guard(async () => {
2865
- let clock = deps.clock ?? REAL_CLOCK, baseUrl = assertApiUrl(apiUrlOf(args)), label = strOpt(args, "name") ?? (deps.hostname ?? import_node_os2.default.hostname)(), file = deps.file ?? credentialsPath(deps.env), started = await withRetries(baseUrl, clock, START_RETRY_MS, () => startDeviceLogin({ baseUrl }, { label, cli_version: CLIENT_VERSION }, deps.fetchImpl)).catch((e) => {
3227
+ let clock = deps.clock ?? REAL_CLOCK, baseUrl = assertApiUrl(apiUrlFor(deps.env ?? process.env)), label = strOpt(args, "name") ?? (deps.hostname ?? import_node_os2.default.hostname)(), file = deps.file ?? credentialsPath(deps.env), started = await withRetries(baseUrl, clock, START_RETRY_MS, () => startDeviceLogin({ baseUrl }, { label, cli_version: CLIENT_VERSION }, deps.fetchImpl)).catch((e) => {
2866
3228
  throw e instanceof HttpError && e.status === 429 ? new Error(MESSAGES.LOGIN_TOO_MANY, { cause: e }) : e;
2867
3229
  }), env = deps.env ?? process.env, st = screenStyle(deps.screen, env), url = started.verification_uri_complete;
2868
3230
  if (say(renderLoginStart(st, { code: formatUserCode(started.user_code), url })), say(""), url !== null) {
@@ -2930,7 +3292,7 @@ function selectLines(lines, runs, vms) {
2930
3292
  }
2931
3293
  async function runUsageShow(args) {
2932
3294
  return guard(async () => {
2933
- let report = await getUsage(apiConfig(args), filters(args));
3295
+ let report = await getUsage(apiConfig(), filters(args));
2934
3296
  if (boolFlag(args, "json")) return emit(report), 0;
2935
3297
  let runs = boolFlag(args, "runs"), vms = boolFlag(args, "vms"), shown = { ...report, lines: selectLines(report.lines, runs, vms) };
2936
3298
  return out(renderUsageReport(outStyle(), shown, { lines: runs || vms })), 0;
@@ -2940,10 +3302,18 @@ async function runUsageExport(args) {
2940
3302
  return guard(async () => {
2941
3303
  let json2 = boolFlag(args, "json"), csv = boolFlag(args, "csv");
2942
3304
  if (json2 === csv) return tell(MESSAGES.USAGE_EXPORT_USAGE), 1;
2943
- let report = await getUsage(apiConfig(args), filters(args));
3305
+ let report = await getUsage(apiConfig(), filters(args));
2944
3306
  return out(json2 ? JSON.stringify(report.lines, null, 2) : toCsv(report)), 0;
2945
3307
  });
2946
3308
  }
3309
+ async function runUsageSeries(args) {
3310
+ return guard(async () => {
3311
+ let days = daysOption(args);
3312
+ if (!days.ok) return 1;
3313
+ let series = await getUsageSeries(apiConfig(), days.days);
3314
+ return emit(series, (st) => renderUsageSeries(st, series)), 0;
3315
+ });
3316
+ }
2947
3317
  var filters, init_usage_report = __esm({ "src/commands/usage-report.ts"() {
2948
3318
  "use strict";
2949
3319
  init_define_IGNITIFY_CLIENT_FILES();
@@ -2988,7 +3358,7 @@ var init_resolve_deployment = __esm({ "src/core/resolve-deployment.ts"() {
2988
3358
  function parseRunOptions(args, config) {
2989
3359
  let bare = bareValueFlag(args, VALUE_FLAGS);
2990
3360
  if (bare !== void 0) return { ok: false, error: needsValueMessage(bare) };
2991
- let payloadArg = strOpt(args, "payload"), payload = payloadArg === void 0 ? { ok: true, value: config.run?.payload ?? {} } : parseJson2(payloadArg);
3361
+ let payloadArg = strOpt(args, "payload"), payload = payloadArg === void 0 ? { ok: true, value: config.run?.payload ?? {} } : parseJsonText(payloadArg);
2992
3362
  if (!payload.ok) return { ok: false, error: `--payload is not valid JSON: ${payloadArg}` };
2993
3363
  let timeoutArg = strOpt(args, "timeout-sec"), timeoutOverride = timeoutArg === void 0 ? void 0 : Number(timeoutArg);
2994
3364
  if (timeoutOverride !== void 0 && !(Number.isFinite(timeoutOverride) && timeoutOverride > 0)) return { ok: false, error: `--timeout-sec must be a positive number, got: ${timeoutArg}` };
@@ -2996,24 +3366,27 @@ function parseRunOptions(args, config) {
2996
3366
  if (onBusy !== void 0 && onBusy !== "queue" && onBusy !== "reject") return { ok: false, error: `--on-busy must be 'queue' or 'reject', got: ${onBusy}` };
2997
3367
  let at = strOpt(args, "at");
2998
3368
  if (at !== void 0 && Number.isNaN(new Date(at).getTime())) return { ok: false, error: `--at is not a valid ISO-8601 timestamp: ${at}` };
3369
+ let idempotencyKey = strOpt(args, "idempotency-key");
3370
+ if (idempotencyKey !== void 0 && !isValidIdempotencyKey(idempotencyKey)) return { ok: false, error: MESSAGES.IDEMPOTENCY_KEY_INVALID(idempotencyKey) };
2999
3371
  let wait = boolFlag(args, "wait");
3000
- return at !== void 0 && wait ? { ok: false, error: MESSAGES.RUN_AT_WITH_WAIT } : { ok: true, deploymentFlag: strOpt(args, "deployment"), wait, run: { payload: payload.value, preset: config.run?.preset, timeoutSec: timeoutOverride ?? config.run?.timeout_sec, execution: onBusy === void 0 ? config.execution : { ...config.execution ?? {}, on_busy: onBusy }, at } };
3001
- }
3002
- function parseJson2(text) {
3003
- try {
3004
- return { ok: true, value: JSON.parse(text) };
3005
- } catch {
3006
- return { ok: false };
3007
- }
3372
+ return at !== void 0 && wait ? { ok: false, error: MESSAGES.RUN_AT_WITH_WAIT } : { ok: true, deploymentFlag: strOpt(args, "deployment"), wait, run: { payload: payload.value, preset: config.run?.preset, timeoutSec: timeoutOverride ?? config.run?.timeout_sec, execution: onBusy === void 0 ? config.execution : { ...config.execution ?? {}, on_busy: onBusy }, at, idempotencyKey } };
3008
3373
  }
3009
3374
  var VALUE_FLAGS, init_run_options = __esm({ "src/core/run-options.ts"() {
3010
3375
  "use strict";
3011
3376
  init_define_IGNITIFY_CLIENT_FILES();
3377
+ init_tenant();
3012
3378
  init_http_client();
3013
3379
  init_constants();
3014
3380
  init_utils();
3015
3381
  VALUE_FLAGS = Object.entries(COMMAND_META[COMMANDS.TASK_RUN].flags).filter(([, kind]) => kind === "value").map(([flag]) => flag);
3016
3382
  } });
3383
+ function classifyRunAnswer(res, at, wait) {
3384
+ return at !== void 0 ? res.schedule_id ? { kind: "scheduled", scheduleId: res.schedule_id, firesAt: res.fires_at ?? at } : res.run_id ? { kind: "skew-ran-now", runId: res.run_id } : { kind: "skew-no-schedule" } : wait && res.run_id ? { kind: "wait", runId: res.run_id } : { kind: "submitted" };
3385
+ }
3386
+ var init_run_answer = __esm({ "src/core/run-answer.ts"() {
3387
+ "use strict";
3388
+ init_define_IGNITIFY_CLIENT_FILES();
3389
+ } });
3017
3390
  function writeFileAtomic(file, text) {
3018
3391
  let exists = import_node_fs3.default.existsSync(file), target = exists ? import_node_fs3.default.realpathSync(file) : file, mode = exists ? import_node_fs3.default.statSync(target).mode & 511 : NEW_FILE_MODE, name = `.${import_node_path2.default.basename(target)}.${process.pid}.${(0, import_node_crypto2.randomBytes)(6).toString("hex")}.tmp`, tmp = import_node_path2.default.join(import_node_path2.default.dirname(target), name);
3019
3392
  try {
@@ -3073,7 +3446,7 @@ function buildTaskReport(inputs) {
3073
3446
  }
3074
3447
  function formatTaskReport(r) {
3075
3448
  let lines = [];
3076
- if (lines.push(`Task report: ${r.slug}`), lines.push(""), lines.push(`Deployed: ${r.deployed.yes === "unknown" ? "UNKNOWN" : r.deployed.yes ? "YES" : "NO"} \u2014 ${r.deployed.detail}`), lines.push(""), lines.push("Resources:"), lines.push(` task images on disk: ${r.resources.taskImageBytes === "unknown" ? "unknown (server unreachable)" : formatBytes(r.resources.taskImageBytes)}`), r.resources.tenant) {
3449
+ if (lines.push(`Task report: ${r.slug}`), lines.push(""), lines.push(`Deployed: ${yesNoUnknown(r.deployed.yes)} \u2014 ${r.deployed.detail}`), lines.push(""), lines.push("Resources:"), lines.push(` task images on disk: ${r.resources.taskImageBytes === "unknown" ? "unknown (server unreachable)" : formatBytes(r.resources.taskImageBytes)}`), r.resources.tenant) {
3077
3450
  let u = r.resources.tenant;
3078
3451
  lines.push(` tenant-wide (whoami): tasks ${u.task_count ?? "?"}, active runs ${u.active_runs ?? "?"}, deployments ${u.deployment_count ?? "?"}, images ${formatBytes(u.total_image_bytes ?? 0)}, egress this month ${formatBytes(u.net_egress_bytes ?? 0)}`), lines.push(" more: ignitify quota");
3079
3452
  }
@@ -3096,14 +3469,14 @@ function formatTaskReport(r) {
3096
3469
  }
3097
3470
  lines.push("");
3098
3471
  }
3099
- lines.push(`New deployment needed: ${verdictLine(r.newDeployment)}`);
3472
+ lines.push(`New deployment needed: ${yesNoUnknown(r.newDeployment.needed)}`);
3100
3473
  for (let reason of r.newDeployment.reasons) lines.push(` - ${reason}`);
3101
- lines.push(""), lines.push(`New VM on next run: ${verdictLine(r.newVm)}`);
3474
+ lines.push(""), lines.push(`New VM on next run: ${yesNoUnknown(r.newVm.needed)}`);
3102
3475
  for (let reason of r.newVm.reasons) lines.push(` - ${reason}`);
3103
3476
  return lines.join(`
3104
3477
  `);
3105
3478
  }
3106
- var FINGERPRINT_AXES, resolveOrNull, DEFAULT_NATURE, runNature, fingerprintDiffs, presetIndeterminate, decideNewDeployment, decideNewVm, decideInbound, verdictLine, init_report = __esm({ "src/core/report.ts"() {
3479
+ var FINGERPRINT_AXES, resolveOrNull, DEFAULT_NATURE, runNature, fingerprintDiffs, presetIndeterminate, decideNewDeployment, decideNewVm, decideInbound, yesNoUnknown, init_report = __esm({ "src/core/report.ts"() {
3107
3480
  "use strict";
3108
3481
  init_define_IGNITIFY_CLIENT_FILES();
3109
3482
  init_execution();
@@ -3147,7 +3520,7 @@ var FINGERPRINT_AXES, resolveOrNull, DEFAULT_NATURE, runNature, fingerprintDiffs
3147
3520
  let serving = (runs ?? []).some((r) => ACTIVE_RUN_STATUSES.has(r.status ?? "")), routes = taskDeployments === null ? "unknown" : taskDeployments.flatMap((d) => d.id ? [{ deploymentId: d.id, routeId: deriveRouteId(d.id) }] : []);
3148
3521
  return { port: nature.inbound_port, serving, routes };
3149
3522
  };
3150
- verdictLine = (v) => v.needed === "unknown" ? "UNKNOWN" : v.needed ? "YES" : "NO";
3523
+ yesNoUnknown = (answer) => answer === "unknown" ? "UNKNOWN" : answer ? "YES" : "NO";
3151
3524
  } });
3152
3525
  function getDefaultExportFromCjs(x) {
3153
3526
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
@@ -4406,13 +4779,13 @@ function requireJsYaml() {
4406
4779
  }
4407
4780
  return jsYaml.Type = requireType(), jsYaml.Schema = requireSchema(), jsYaml.FAILSAFE_SCHEMA = requireFailsafe(), jsYaml.JSON_SCHEMA = requireJson(), jsYaml.CORE_SCHEMA = requireCore(), jsYaml.DEFAULT_SCHEMA = require_default(), jsYaml.load = loader2.load, jsYaml.loadAll = loader2.loadAll, jsYaml.dump = dumper2.dump, jsYaml.YAMLException = requireException(), jsYaml.types = { binary: requireBinary(), float: requireFloat(), map: requireMap(), null: require_null(), pairs: requirePairs(), set: requireSet(), timestamp: requireTimestamp(), bool: requireBool(), int: requireInt(), merge: requireMerge(), omap: requireOmap(), seq: requireSeq(), str: requireStr() }, jsYaml.safeLoad = renamed("safeLoad", "load"), jsYaml.safeLoadAll = renamed("safeLoadAll", "loadAll"), jsYaml.safeDump = renamed("safeDump", "dump"), jsYaml;
4408
4781
  }
4409
- var jsYaml, loader, common, hasRequiredCommon, exception, hasRequiredException, snippet, hasRequiredSnippet, type, hasRequiredType, schema, hasRequiredSchema, str2, hasRequiredStr, seq, hasRequiredSeq, map, hasRequiredMap, failsafe, hasRequiredFailsafe, _null, hasRequired_null, bool, hasRequiredBool, int, hasRequiredInt, float, hasRequiredFloat, json, hasRequiredJson, core, hasRequiredCore, timestamp, hasRequiredTimestamp, merge, hasRequiredMerge, binary, hasRequiredBinary, omap, hasRequiredOmap, pairs2, hasRequiredPairs, set, hasRequiredSet, _default, hasRequired_default, hasRequiredLoader, dumper, hasRequiredDumper, hasRequiredJsYaml, jsYamlExports, yaml, Type, Schema, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, load, loadAll, dump, YAMLException, types, safeLoad, safeLoadAll, safeDump, init_js_yaml = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/js-yaml/dist/js-yaml.mjs"() {
4782
+ var jsYaml, loader, common, hasRequiredCommon, exception, hasRequiredException, snippet, hasRequiredSnippet, type, hasRequiredType, schema, hasRequiredSchema, str2, hasRequiredStr, seq, hasRequiredSeq, map, hasRequiredMap, failsafe, hasRequiredFailsafe, _null, hasRequired_null, bool, hasRequiredBool, int, hasRequiredInt, float, hasRequiredFloat, json, hasRequiredJson, core, hasRequiredCore, timestamp, hasRequiredTimestamp, merge, hasRequiredMerge, binary, hasRequiredBinary, omap, hasRequiredOmap, pairs2, hasRequiredPairs, set, hasRequiredSet, _default, hasRequired_default, hasRequiredLoader, dumper, hasRequiredDumper, hasRequiredJsYaml, jsYamlExports, yaml, Type, Schema, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, load, loadAll, dump, YAMLException, types, safeLoad, safeLoadAll, safeDump, init_js_yaml = __esm({ "../../node_modules/js-yaml/dist/js-yaml.mjs"() {
4410
4783
  init_define_IGNITIFY_CLIENT_FILES();
4411
4784
  jsYaml = {}, loader = {}, common = {};
4412
4785
  dumper = {};
4413
4786
  jsYamlExports = requireJsYaml(), yaml = getDefaultExportFromCjs(jsYamlExports), { Type, Schema, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, load, loadAll, dump, YAMLException, types, safeLoad, safeLoadAll, safeDump } = yaml;
4414
4787
  } });
4415
- var require_code = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/codegen/code.js"(exports2) {
4788
+ var require_code = __commonJS({ "../../node_modules/ajv/dist/compile/codegen/code.js"(exports2) {
4416
4789
  "use strict";
4417
4790
  init_define_IGNITIFY_CLIENT_FILES();
4418
4791
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -4526,7 +4899,7 @@ var require_code = __commonJS({ "../../../../../../../../../Users/saeed/Projects
4526
4899
  }
4527
4900
  exports2.regexpCode = regexpCode;
4528
4901
  } });
4529
- var require_scope = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/codegen/scope.js"(exports2) {
4902
+ var require_scope = __commonJS({ "../../node_modules/ajv/dist/compile/codegen/scope.js"(exports2) {
4530
4903
  "use strict";
4531
4904
  init_define_IGNITIFY_CLIENT_FILES();
4532
4905
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -4631,7 +5004,7 @@ var require_scope = __commonJS({ "../../../../../../../../../Users/saeed/Project
4631
5004
  };
4632
5005
  exports2.ValueScope = ValueScope;
4633
5006
  } });
4634
- var require_codegen = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/codegen/index.js"(exports2) {
5007
+ var require_codegen = __commonJS({ "../../node_modules/ajv/dist/compile/codegen/index.js"(exports2) {
4635
5008
  "use strict";
4636
5009
  init_define_IGNITIFY_CLIENT_FILES();
4637
5010
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5120,7 +5493,7 @@ var require_codegen = __commonJS({ "../../../../../../../../../Users/saeed/Proje
5120
5493
  return x instanceof code_1.Name ? x : (0, code_1._)`(${x})`;
5121
5494
  }
5122
5495
  } });
5123
- var require_util = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/util.js"(exports2) {
5496
+ var require_util = __commonJS({ "../../node_modules/ajv/dist/compile/util.js"(exports2) {
5124
5497
  "use strict";
5125
5498
  init_define_IGNITIFY_CLIENT_FILES();
5126
5499
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5230,14 +5603,14 @@ var require_util = __commonJS({ "../../../../../../../../../Users/saeed/Projects
5230
5603
  }
5231
5604
  exports2.checkStrictMode = checkStrictMode;
5232
5605
  } });
5233
- var require_names = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/names.js"(exports2) {
5606
+ var require_names = __commonJS({ "../../node_modules/ajv/dist/compile/names.js"(exports2) {
5234
5607
  "use strict";
5235
5608
  init_define_IGNITIFY_CLIENT_FILES();
5236
5609
  Object.defineProperty(exports2, "__esModule", { value: true });
5237
5610
  var codegen_1 = require_codegen(), names = { data: new codegen_1.Name("data"), valCxt: new codegen_1.Name("valCxt"), instancePath: new codegen_1.Name("instancePath"), parentData: new codegen_1.Name("parentData"), parentDataProperty: new codegen_1.Name("parentDataProperty"), rootData: new codegen_1.Name("rootData"), dynamicAnchors: new codegen_1.Name("dynamicAnchors"), vErrors: new codegen_1.Name("vErrors"), errors: new codegen_1.Name("errors"), this: new codegen_1.Name("this"), self: new codegen_1.Name("self"), scope: new codegen_1.Name("scope"), json: new codegen_1.Name("json"), jsonPos: new codegen_1.Name("jsonPos"), jsonLen: new codegen_1.Name("jsonLen"), jsonPart: new codegen_1.Name("jsonPart") };
5238
5611
  exports2.default = names;
5239
5612
  } });
5240
- var require_errors = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/errors.js"(exports2) {
5613
+ var require_errors = __commonJS({ "../../node_modules/ajv/dist/compile/errors.js"(exports2) {
5241
5614
  "use strict";
5242
5615
  init_define_IGNITIFY_CLIENT_FILES();
5243
5616
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5297,7 +5670,7 @@ var require_errors = __commonJS({ "../../../../../../../../../Users/saeed/Projec
5297
5670
  keyValues.push([E.keyword, keyword], [E.params, typeof params == "function" ? params(cxt) : params || (0, codegen_1._)`{}`]), opts.messages && keyValues.push([E.message, typeof message == "function" ? message(cxt) : message]), opts.verbose && keyValues.push([E.schema, schemaValue], [E.parentSchema, (0, codegen_1._)`${topSchemaRef}${schemaPath}`], [names_1.default.data, data]), propertyName && keyValues.push([E.propertyName, propertyName]);
5298
5671
  }
5299
5672
  } });
5300
- var require_boolSchema = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/boolSchema.js"(exports2) {
5673
+ var require_boolSchema = __commonJS({ "../../node_modules/ajv/dist/compile/validate/boolSchema.js"(exports2) {
5301
5674
  "use strict";
5302
5675
  init_define_IGNITIFY_CLIENT_FILES();
5303
5676
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5318,7 +5691,7 @@ var require_boolSchema = __commonJS({ "../../../../../../../../../Users/saeed/Pr
5318
5691
  (0, errors_1.reportError)(cxt, boolError, void 0, overrideAllErrors);
5319
5692
  }
5320
5693
  } });
5321
- var require_rules = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/rules.js"(exports2) {
5694
+ var require_rules = __commonJS({ "../../node_modules/ajv/dist/compile/rules.js"(exports2) {
5322
5695
  "use strict";
5323
5696
  init_define_IGNITIFY_CLIENT_FILES();
5324
5697
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5334,7 +5707,7 @@ var require_rules = __commonJS({ "../../../../../../../../../Users/saeed/Project
5334
5707
  }
5335
5708
  exports2.getRules = getRules;
5336
5709
  } });
5337
- var require_applicability = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/applicability.js"(exports2) {
5710
+ var require_applicability = __commonJS({ "../../node_modules/ajv/dist/compile/validate/applicability.js"(exports2) {
5338
5711
  "use strict";
5339
5712
  init_define_IGNITIFY_CLIENT_FILES();
5340
5713
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5354,7 +5727,7 @@ var require_applicability = __commonJS({ "../../../../../../../../../Users/saeed
5354
5727
  }
5355
5728
  exports2.shouldUseRule = shouldUseRule;
5356
5729
  } });
5357
- var require_dataType = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/dataType.js"(exports2) {
5730
+ var require_dataType = __commonJS({ "../../node_modules/ajv/dist/compile/validate/dataType.js"(exports2) {
5358
5731
  "use strict";
5359
5732
  init_define_IGNITIFY_CLIENT_FILES();
5360
5733
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5479,7 +5852,7 @@ var require_dataType = __commonJS({ "../../../../../../../../../Users/saeed/Proj
5479
5852
  return { gen, keyword: "type", data, schema: schema2.type, schemaCode, schemaValue: schemaCode, parentSchema: schema2, params: {}, it };
5480
5853
  }
5481
5854
  } });
5482
- var require_defaults = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/defaults.js"(exports2) {
5855
+ var require_defaults = __commonJS({ "../../node_modules/ajv/dist/compile/validate/defaults.js"(exports2) {
5483
5856
  "use strict";
5484
5857
  init_define_IGNITIFY_CLIENT_FILES();
5485
5858
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5503,7 +5876,7 @@ var require_defaults = __commonJS({ "../../../../../../../../../Users/saeed/Proj
5503
5876
  opts.useDefaults === "empty" && (condition = (0, codegen_1._)`${condition} || ${childData} === null || ${childData} === ""`), gen.if(condition, (0, codegen_1._)`${childData} = ${(0, codegen_1.stringify)(defaultValue)}`);
5504
5877
  }
5505
5878
  } });
5506
- var require_code2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/code.js"(exports2) {
5879
+ var require_code2 = __commonJS({ "../../node_modules/ajv/dist/vocabularies/code.js"(exports2) {
5507
5880
  "use strict";
5508
5881
  init_define_IGNITIFY_CLIENT_FILES();
5509
5882
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5590,7 +5963,7 @@ var require_code2 = __commonJS({ "../../../../../../../../../Users/saeed/Project
5590
5963
  }
5591
5964
  exports2.validateUnion = validateUnion;
5592
5965
  } });
5593
- var require_keyword = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/keyword.js"(exports2) {
5966
+ var require_keyword = __commonJS({ "../../node_modules/ajv/dist/compile/validate/keyword.js"(exports2) {
5594
5967
  "use strict";
5595
5968
  init_define_IGNITIFY_CLIENT_FILES();
5596
5969
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5667,7 +6040,7 @@ var require_keyword = __commonJS({ "../../../../../../../../../Users/saeed/Proje
5667
6040
  }
5668
6041
  exports2.validateKeywordUsage = validateKeywordUsage;
5669
6042
  } });
5670
- var require_subschema = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/subschema.js"(exports2) {
6043
+ var require_subschema = __commonJS({ "../../node_modules/ajv/dist/compile/validate/subschema.js"(exports2) {
5671
6044
  "use strict";
5672
6045
  init_define_IGNITIFY_CLIENT_FILES();
5673
6046
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5708,7 +6081,7 @@ var require_subschema = __commonJS({ "../../../../../../../../../Users/saeed/Pro
5708
6081
  }
5709
6082
  exports2.extendSubschemaMode = extendSubschemaMode;
5710
6083
  } });
5711
- var require_fast_deep_equal = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/fast-deep-equal/index.js"(exports2, module2) {
6084
+ var require_fast_deep_equal = __commonJS({ "../../node_modules/fast-deep-equal/index.js"(exports2, module2) {
5712
6085
  "use strict";
5713
6086
  init_define_IGNITIFY_CLIENT_FILES();
5714
6087
  module2.exports = function equal(a, b) {
@@ -5735,7 +6108,7 @@ var require_fast_deep_equal = __commonJS({ "../../../../../../../../../Users/sae
5735
6108
  return a !== a && b !== b;
5736
6109
  };
5737
6110
  } });
5738
- var require_json_schema_traverse = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/json-schema-traverse/index.js"(exports2, module2) {
6111
+ var require_json_schema_traverse = __commonJS({ "../../node_modules/json-schema-traverse/index.js"(exports2, module2) {
5739
6112
  "use strict";
5740
6113
  init_define_IGNITIFY_CLIENT_FILES();
5741
6114
  var traverse = module2.exports = function(schema2, opts, cb) {
@@ -5767,7 +6140,7 @@ var require_json_schema_traverse = __commonJS({ "../../../../../../../../../User
5767
6140
  return str3.replace(/~/g, "~0").replace(/\//g, "~1");
5768
6141
  }
5769
6142
  } });
5770
- var require_resolve = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/resolve.js"(exports2) {
6143
+ var require_resolve = __commonJS({ "../../node_modules/ajv/dist/compile/resolve.js"(exports2) {
5771
6144
  "use strict";
5772
6145
  init_define_IGNITIFY_CLIENT_FILES();
5773
6146
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -5844,7 +6217,7 @@ var require_resolve = __commonJS({ "../../../../../../../../../Users/saeed/Proje
5844
6217
  }
5845
6218
  exports2.getSchemaRefs = getSchemaRefs;
5846
6219
  } });
5847
- var require_validate = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/validate/index.js"(exports2) {
6220
+ var require_validate = __commonJS({ "../../node_modules/ajv/dist/compile/validate/index.js"(exports2) {
5848
6221
  "use strict";
5849
6222
  init_define_IGNITIFY_CLIENT_FILES();
5850
6223
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -6134,7 +6507,7 @@ var require_validate = __commonJS({ "../../../../../../../../../Users/saeed/Proj
6134
6507
  }
6135
6508
  exports2.getData = getData;
6136
6509
  } });
6137
- var require_validation_error = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/runtime/validation_error.js"(exports2) {
6510
+ var require_validation_error = __commonJS({ "../../node_modules/ajv/dist/runtime/validation_error.js"(exports2) {
6138
6511
  "use strict";
6139
6512
  init_define_IGNITIFY_CLIENT_FILES();
6140
6513
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -6145,7 +6518,7 @@ var require_validation_error = __commonJS({ "../../../../../../../../../Users/sa
6145
6518
  };
6146
6519
  exports2.default = ValidationError;
6147
6520
  } });
6148
- var require_ref_error = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/ref_error.js"(exports2) {
6521
+ var require_ref_error = __commonJS({ "../../node_modules/ajv/dist/compile/ref_error.js"(exports2) {
6149
6522
  "use strict";
6150
6523
  init_define_IGNITIFY_CLIENT_FILES();
6151
6524
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -6156,7 +6529,7 @@ var require_ref_error = __commonJS({ "../../../../../../../../../Users/saeed/Pro
6156
6529
  };
6157
6530
  exports2.default = MissingRefError;
6158
6531
  } });
6159
- var require_compile = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/compile/index.js"(exports2) {
6532
+ var require_compile = __commonJS({ "../../node_modules/ajv/dist/compile/index.js"(exports2) {
6160
6533
  "use strict";
6161
6534
  init_define_IGNITIFY_CLIENT_FILES();
6162
6535
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -6261,10 +6634,10 @@ var require_compile = __commonJS({ "../../../../../../../../../Users/saeed/Proje
6261
6634
  if (env = env || new SchemaEnv({ schema: schema2, schemaId, root, baseId }), env.schema !== env.root.schema) return env;
6262
6635
  }
6263
6636
  } });
6264
- var require_data = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/data.json"(exports2, module2) {
6637
+ var require_data = __commonJS({ "../../node_modules/ajv/dist/refs/data.json"(exports2, module2) {
6265
6638
  module2.exports = { $id: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#", description: "Meta-schema for $data reference (JSON AnySchema extension proposal)", type: "object", required: ["$data"], properties: { $data: { type: "string", anyOf: [{ format: "relative-json-pointer" }, { format: "json-pointer" }] } }, additionalProperties: false };
6266
6639
  } });
6267
- var require_utils = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/fast-uri/lib/utils.js"(exports2, module2) {
6640
+ var require_utils = __commonJS({ "../../node_modules/fast-uri/lib/utils.js"(exports2, module2) {
6268
6641
  "use strict";
6269
6642
  init_define_IGNITIFY_CLIENT_FILES();
6270
6643
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu), isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u), isPort = RegExp.prototype.test.bind(/^\d*$/u), isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu), isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu), isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u), isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u), isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u), BYTE_HEX = new Array(256);
@@ -6577,7 +6950,7 @@ var require_utils = __commonJS({ "../../../../../../../../../Users/saeed/Project
6577
6950
  }
6578
6951
  module2.exports = { nonSimpleDomain, recomposeAuthority, reescapeHostDelimiters, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeUserinfo, encodeQuery, encodeFragment, escapePreservingEscapes, removeDotSegments, removeDotSegmentsRelative, isIPv4, isUUID, normalizeIPv6, stringArrayToHexStripped };
6579
6952
  } });
6580
- var require_schemes = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/fast-uri/lib/schemes.js"(exports2, module2) {
6953
+ var require_schemes = __commonJS({ "../../node_modules/fast-uri/lib/schemes.js"(exports2, module2) {
6581
6954
  "use strict";
6582
6955
  init_define_IGNITIFY_CLIENT_FILES();
6583
6956
  var { isUUID } = require_utils(), URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu, supportedSchemeNames = ["http", "https", "ws", "wss", "urn", "urn:uuid"];
@@ -6637,7 +7010,7 @@ var require_schemes = __commonJS({ "../../../../../../../../../Users/saeed/Proje
6637
7010
  }
6638
7011
  module2.exports = { wsIsSecure, SCHEMES, isValidSchemeName, getSchemeHandler };
6639
7012
  } });
6640
- var require_fast_uri = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/fast-uri/index.js"(exports2, module2) {
7013
+ var require_fast_uri = __commonJS({ "../../node_modules/fast-uri/index.js"(exports2, module2) {
6641
7014
  "use strict";
6642
7015
  init_define_IGNITIFY_CLIENT_FILES();
6643
7016
  var { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils(), { SCHEMES, getSchemeHandler } = require_schemes(), VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u, MALFORMED_SCHEME_ERROR = "URI scheme is malformed.", MALFORMED_HOST_ERROR = "URI host is malformed.", FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u;
@@ -6793,7 +7166,7 @@ var require_fast_uri = __commonJS({ "../../../../../../../../../Users/saeed/Proj
6793
7166
  module2.exports.default = fastUri;
6794
7167
  module2.exports.fastUri = fastUri;
6795
7168
  } });
6796
- var require_uri = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/runtime/uri.js"(exports2) {
7169
+ var require_uri = __commonJS({ "../../node_modules/ajv/dist/runtime/uri.js"(exports2) {
6797
7170
  "use strict";
6798
7171
  init_define_IGNITIFY_CLIENT_FILES();
6799
7172
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -6801,7 +7174,7 @@ var require_uri = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
6801
7174
  uri.code = 'require("ajv/dist/runtime/uri").default';
6802
7175
  exports2.default = uri;
6803
7176
  } });
6804
- var require_core = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/core.js"(exports2) {
7177
+ var require_core = __commonJS({ "../../node_modules/ajv/dist/core.js"(exports2) {
6805
7178
  "use strict";
6806
7179
  init_define_IGNITIFY_CLIENT_FILES();
6807
7180
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7126,7 +7499,7 @@ var require_core = __commonJS({ "../../../../../../../../../Users/saeed/Projects
7126
7499
  return { anyOf: [schema2, $dataRef] };
7127
7500
  }
7128
7501
  } });
7129
- var require_id = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/core/id.js"(exports2) {
7502
+ var require_id = __commonJS({ "../../node_modules/ajv/dist/vocabularies/core/id.js"(exports2) {
7130
7503
  "use strict";
7131
7504
  init_define_IGNITIFY_CLIENT_FILES();
7132
7505
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7135,7 +7508,7 @@ var require_id = __commonJS({ "../../../../../../../../../Users/saeed/Projects/r
7135
7508
  } };
7136
7509
  exports2.default = def;
7137
7510
  } });
7138
- var require_ref = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/core/ref.js"(exports2) {
7511
+ var require_ref = __commonJS({ "../../node_modules/ajv/dist/vocabularies/core/ref.js"(exports2) {
7139
7512
  "use strict";
7140
7513
  init_define_IGNITIFY_CLIENT_FILES();
7141
7514
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7204,14 +7577,14 @@ var require_ref = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
7204
7577
  exports2.callRef = callRef;
7205
7578
  exports2.default = def;
7206
7579
  } });
7207
- var require_core2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/core/index.js"(exports2) {
7580
+ var require_core2 = __commonJS({ "../../node_modules/ajv/dist/vocabularies/core/index.js"(exports2) {
7208
7581
  "use strict";
7209
7582
  init_define_IGNITIFY_CLIENT_FILES();
7210
7583
  Object.defineProperty(exports2, "__esModule", { value: true });
7211
7584
  var id_1 = require_id(), ref_1 = require_ref(), core2 = ["$schema", "$id", "$defs", "$vocabulary", { keyword: "$comment" }, "definitions", id_1.default, ref_1.default];
7212
7585
  exports2.default = core2;
7213
7586
  } });
7214
- var require_limitNumber = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/limitNumber.js"(exports2) {
7587
+ var require_limitNumber = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/limitNumber.js"(exports2) {
7215
7588
  "use strict";
7216
7589
  init_define_IGNITIFY_CLIENT_FILES();
7217
7590
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7221,7 +7594,7 @@ var require_limitNumber = __commonJS({ "../../../../../../../../../Users/saeed/P
7221
7594
  } };
7222
7595
  exports2.default = def;
7223
7596
  } });
7224
- var require_multipleOf = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/multipleOf.js"(exports2) {
7597
+ var require_multipleOf = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/multipleOf.js"(exports2) {
7225
7598
  "use strict";
7226
7599
  init_define_IGNITIFY_CLIENT_FILES();
7227
7600
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7231,7 +7604,7 @@ var require_multipleOf = __commonJS({ "../../../../../../../../../Users/saeed/Pr
7231
7604
  } };
7232
7605
  exports2.default = def;
7233
7606
  } });
7234
- var require_ucs2length = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/runtime/ucs2length.js"(exports2) {
7607
+ var require_ucs2length = __commonJS({ "../../node_modules/ajv/dist/runtime/ucs2length.js"(exports2) {
7235
7608
  "use strict";
7236
7609
  init_define_IGNITIFY_CLIENT_FILES();
7237
7610
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7243,7 +7616,7 @@ var require_ucs2length = __commonJS({ "../../../../../../../../../Users/saeed/Pr
7243
7616
  exports2.default = ucs2length;
7244
7617
  ucs2length.code = 'require("ajv/dist/runtime/ucs2length").default';
7245
7618
  } });
7246
- var require_limitLength = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/limitLength.js"(exports2) {
7619
+ var require_limitLength = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/limitLength.js"(exports2) {
7247
7620
  "use strict";
7248
7621
  init_define_IGNITIFY_CLIENT_FILES();
7249
7622
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7256,7 +7629,7 @@ var require_limitLength = __commonJS({ "../../../../../../../../../Users/saeed/P
7256
7629
  } };
7257
7630
  exports2.default = def;
7258
7631
  } });
7259
- var require_pattern = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/pattern.js"(exports2) {
7632
+ var require_pattern = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/pattern.js"(exports2) {
7260
7633
  "use strict";
7261
7634
  init_define_IGNITIFY_CLIENT_FILES();
7262
7635
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7272,7 +7645,7 @@ var require_pattern = __commonJS({ "../../../../../../../../../Users/saeed/Proje
7272
7645
  } };
7273
7646
  exports2.default = def;
7274
7647
  } });
7275
- var require_limitProperties = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/limitProperties.js"(exports2) {
7648
+ var require_limitProperties = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/limitProperties.js"(exports2) {
7276
7649
  "use strict";
7277
7650
  init_define_IGNITIFY_CLIENT_FILES();
7278
7651
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7285,7 +7658,7 @@ var require_limitProperties = __commonJS({ "../../../../../../../../../Users/sae
7285
7658
  } };
7286
7659
  exports2.default = def;
7287
7660
  } });
7288
- var require_required = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/required.js"(exports2) {
7661
+ var require_required = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/required.js"(exports2) {
7289
7662
  "use strict";
7290
7663
  init_define_IGNITIFY_CLIENT_FILES();
7291
7664
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7326,7 +7699,7 @@ var require_required = __commonJS({ "../../../../../../../../../Users/saeed/Proj
7326
7699
  } };
7327
7700
  exports2.default = def;
7328
7701
  } });
7329
- var require_limitItems = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/limitItems.js"(exports2) {
7702
+ var require_limitItems = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/limitItems.js"(exports2) {
7330
7703
  "use strict";
7331
7704
  init_define_IGNITIFY_CLIENT_FILES();
7332
7705
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7339,7 +7712,7 @@ var require_limitItems = __commonJS({ "../../../../../../../../../Users/saeed/Pr
7339
7712
  } };
7340
7713
  exports2.default = def;
7341
7714
  } });
7342
- var require_equal = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/runtime/equal.js"(exports2) {
7715
+ var require_equal = __commonJS({ "../../node_modules/ajv/dist/runtime/equal.js"(exports2) {
7343
7716
  "use strict";
7344
7717
  init_define_IGNITIFY_CLIENT_FILES();
7345
7718
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7347,7 +7720,7 @@ var require_equal = __commonJS({ "../../../../../../../../../Users/saeed/Project
7347
7720
  equal.code = 'require("ajv/dist/runtime/equal").default';
7348
7721
  exports2.default = equal;
7349
7722
  } });
7350
- var require_uniqueItems = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js"(exports2) {
7723
+ var require_uniqueItems = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/uniqueItems.js"(exports2) {
7351
7724
  "use strict";
7352
7725
  init_define_IGNITIFY_CLIENT_FILES();
7353
7726
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7380,7 +7753,7 @@ var require_uniqueItems = __commonJS({ "../../../../../../../../../Users/saeed/P
7380
7753
  } };
7381
7754
  exports2.default = def;
7382
7755
  } });
7383
- var require_const = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/const.js"(exports2) {
7756
+ var require_const = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/const.js"(exports2) {
7384
7757
  "use strict";
7385
7758
  init_define_IGNITIFY_CLIENT_FILES();
7386
7759
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7390,7 +7763,7 @@ var require_const = __commonJS({ "../../../../../../../../../Users/saeed/Project
7390
7763
  } };
7391
7764
  exports2.default = def;
7392
7765
  } });
7393
- var require_enum = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/enum.js"(exports2) {
7766
+ var require_enum = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/enum.js"(exports2) {
7394
7767
  "use strict";
7395
7768
  init_define_IGNITIFY_CLIENT_FILES();
7396
7769
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7415,14 +7788,14 @@ var require_enum = __commonJS({ "../../../../../../../../../Users/saeed/Projects
7415
7788
  } };
7416
7789
  exports2.default = def;
7417
7790
  } });
7418
- var require_validation = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/index.js"(exports2) {
7791
+ var require_validation = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/index.js"(exports2) {
7419
7792
  "use strict";
7420
7793
  init_define_IGNITIFY_CLIENT_FILES();
7421
7794
  Object.defineProperty(exports2, "__esModule", { value: true });
7422
7795
  var limitNumber_1 = require_limitNumber(), multipleOf_1 = require_multipleOf(), limitLength_1 = require_limitLength(), pattern_1 = require_pattern(), limitProperties_1 = require_limitProperties(), required_1 = require_required(), limitItems_1 = require_limitItems(), uniqueItems_1 = require_uniqueItems(), const_1 = require_const(), enum_1 = require_enum(), validation = [limitNumber_1.default, multipleOf_1.default, limitLength_1.default, pattern_1.default, limitProperties_1.default, required_1.default, limitItems_1.default, uniqueItems_1.default, { keyword: "type", schemaType: ["string", "array"] }, { keyword: "nullable", schemaType: "boolean" }, const_1.default, enum_1.default];
7423
7796
  exports2.default = validation;
7424
7797
  } });
7425
- var require_additionalItems = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js"(exports2) {
7798
+ var require_additionalItems = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/additionalItems.js"(exports2) {
7426
7799
  "use strict";
7427
7800
  init_define_IGNITIFY_CLIENT_FILES();
7428
7801
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7453,7 +7826,7 @@ var require_additionalItems = __commonJS({ "../../../../../../../../../Users/sae
7453
7826
  exports2.validateAdditionalItems = validateAdditionalItems;
7454
7827
  exports2.default = def;
7455
7828
  } });
7456
- var require_items = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/items.js"(exports2) {
7829
+ var require_items = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/items.js"(exports2) {
7457
7830
  "use strict";
7458
7831
  init_define_IGNITIFY_CLIENT_FILES();
7459
7832
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7481,14 +7854,14 @@ var require_items = __commonJS({ "../../../../../../../../../Users/saeed/Project
7481
7854
  exports2.validateTuple = validateTuple;
7482
7855
  exports2.default = def;
7483
7856
  } });
7484
- var require_prefixItems = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js"(exports2) {
7857
+ var require_prefixItems = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/prefixItems.js"(exports2) {
7485
7858
  "use strict";
7486
7859
  init_define_IGNITIFY_CLIENT_FILES();
7487
7860
  Object.defineProperty(exports2, "__esModule", { value: true });
7488
7861
  var items_1 = require_items(), def = { keyword: "prefixItems", type: "array", schemaType: ["array"], before: "uniqueItems", code: (cxt) => (0, items_1.validateTuple)(cxt, "items") };
7489
7862
  exports2.default = def;
7490
7863
  } });
7491
- var require_items2020 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/items2020.js"(exports2) {
7864
+ var require_items2020 = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/items2020.js"(exports2) {
7492
7865
  "use strict";
7493
7866
  init_define_IGNITIFY_CLIENT_FILES();
7494
7867
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7498,7 +7871,7 @@ var require_items2020 = __commonJS({ "../../../../../../../../../Users/saeed/Pro
7498
7871
  } };
7499
7872
  exports2.default = def;
7500
7873
  } });
7501
- var require_contains = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/contains.js"(exports2) {
7874
+ var require_contains = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/contains.js"(exports2) {
7502
7875
  "use strict";
7503
7876
  init_define_IGNITIFY_CLIENT_FILES();
7504
7877
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7537,7 +7910,7 @@ var require_contains = __commonJS({ "../../../../../../../../../Users/saeed/Proj
7537
7910
  } };
7538
7911
  exports2.default = def;
7539
7912
  } });
7540
- var require_dependencies = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/dependencies.js"(exports2) {
7913
+ var require_dependencies = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/dependencies.js"(exports2) {
7541
7914
  "use strict";
7542
7915
  init_define_IGNITIFY_CLIENT_FILES();
7543
7916
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7587,7 +7960,7 @@ var require_dependencies = __commonJS({ "../../../../../../../../../Users/saeed/
7587
7960
  exports2.validateSchemaDeps = validateSchemaDeps;
7588
7961
  exports2.default = def;
7589
7962
  } });
7590
- var require_propertyNames = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js"(exports2) {
7963
+ var require_propertyNames = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/propertyNames.js"(exports2) {
7591
7964
  "use strict";
7592
7965
  init_define_IGNITIFY_CLIENT_FILES();
7593
7966
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7603,7 +7976,7 @@ var require_propertyNames = __commonJS({ "../../../../../../../../../Users/saeed
7603
7976
  } };
7604
7977
  exports2.default = def;
7605
7978
  } });
7606
- var require_additionalProperties = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js"(exports2) {
7979
+ var require_additionalProperties = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js"(exports2) {
7607
7980
  "use strict";
7608
7981
  init_define_IGNITIFY_CLIENT_FILES();
7609
7982
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7653,7 +8026,7 @@ var require_additionalProperties = __commonJS({ "../../../../../../../../../User
7653
8026
  } };
7654
8027
  exports2.default = def;
7655
8028
  } });
7656
- var require_properties = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/properties.js"(exports2) {
8029
+ var require_properties = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/properties.js"(exports2) {
7657
8030
  "use strict";
7658
8031
  init_define_IGNITIFY_CLIENT_FILES();
7659
8032
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7676,7 +8049,7 @@ var require_properties = __commonJS({ "../../../../../../../../../Users/saeed/Pr
7676
8049
  } };
7677
8050
  exports2.default = def;
7678
8051
  } });
7679
- var require_patternProperties = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js"(exports2) {
8052
+ var require_patternProperties = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/patternProperties.js"(exports2) {
7680
8053
  "use strict";
7681
8054
  init_define_IGNITIFY_CLIENT_FILES();
7682
8055
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7704,7 +8077,7 @@ var require_patternProperties = __commonJS({ "../../../../../../../../../Users/s
7704
8077
  } };
7705
8078
  exports2.default = def;
7706
8079
  } });
7707
- var require_not = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/not.js"(exports2) {
8080
+ var require_not = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/not.js"(exports2) {
7708
8081
  "use strict";
7709
8082
  init_define_IGNITIFY_CLIENT_FILES();
7710
8083
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7719,14 +8092,14 @@ var require_not = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
7719
8092
  }, error: { message: "must NOT be valid" } };
7720
8093
  exports2.default = def;
7721
8094
  } });
7722
- var require_anyOf = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/anyOf.js"(exports2) {
8095
+ var require_anyOf = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/anyOf.js"(exports2) {
7723
8096
  "use strict";
7724
8097
  init_define_IGNITIFY_CLIENT_FILES();
7725
8098
  Object.defineProperty(exports2, "__esModule", { value: true });
7726
8099
  var code_1 = require_code2(), def = { keyword: "anyOf", schemaType: "array", trackErrors: true, code: code_1.validateUnion, error: { message: "must match a schema in anyOf" } };
7727
8100
  exports2.default = def;
7728
8101
  } });
7729
- var require_oneOf = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/oneOf.js"(exports2) {
8102
+ var require_oneOf = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/oneOf.js"(exports2) {
7730
8103
  "use strict";
7731
8104
  init_define_IGNITIFY_CLIENT_FILES();
7732
8105
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7747,7 +8120,7 @@ var require_oneOf = __commonJS({ "../../../../../../../../../Users/saeed/Project
7747
8120
  } };
7748
8121
  exports2.default = def;
7749
8122
  } });
7750
- var require_allOf = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/allOf.js"(exports2) {
8123
+ var require_allOf = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/allOf.js"(exports2) {
7751
8124
  "use strict";
7752
8125
  init_define_IGNITIFY_CLIENT_FILES();
7753
8126
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7763,7 +8136,7 @@ var require_allOf = __commonJS({ "../../../../../../../../../Users/saeed/Project
7763
8136
  } };
7764
8137
  exports2.default = def;
7765
8138
  } });
7766
- var require_if = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/if.js"(exports2) {
8139
+ var require_if = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/if.js"(exports2) {
7767
8140
  "use strict";
7768
8141
  init_define_IGNITIFY_CLIENT_FILES();
7769
8142
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7795,7 +8168,7 @@ var require_if = __commonJS({ "../../../../../../../../../Users/saeed/Projects/r
7795
8168
  }
7796
8169
  exports2.default = def;
7797
8170
  } });
7798
- var require_thenElse = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/thenElse.js"(exports2) {
8171
+ var require_thenElse = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/thenElse.js"(exports2) {
7799
8172
  "use strict";
7800
8173
  init_define_IGNITIFY_CLIENT_FILES();
7801
8174
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7804,7 +8177,7 @@ var require_thenElse = __commonJS({ "../../../../../../../../../Users/saeed/Proj
7804
8177
  } };
7805
8178
  exports2.default = def;
7806
8179
  } });
7807
- var require_applicator = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/index.js"(exports2) {
8180
+ var require_applicator = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/index.js"(exports2) {
7808
8181
  "use strict";
7809
8182
  init_define_IGNITIFY_CLIENT_FILES();
7810
8183
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7815,7 +8188,7 @@ var require_applicator = __commonJS({ "../../../../../../../../../Users/saeed/Pr
7815
8188
  }
7816
8189
  exports2.default = getApplicator;
7817
8190
  } });
7818
- var require_dynamicAnchor = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js"(exports2) {
8191
+ var require_dynamicAnchor = __commonJS({ "../../node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js"(exports2) {
7819
8192
  "use strict";
7820
8193
  init_define_IGNITIFY_CLIENT_FILES();
7821
8194
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7834,7 +8207,7 @@ var require_dynamicAnchor = __commonJS({ "../../../../../../../../../Users/saeed
7834
8207
  }
7835
8208
  exports2.default = def;
7836
8209
  } });
7837
- var require_dynamicRef = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js"(exports2) {
8210
+ var require_dynamicRef = __commonJS({ "../../node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js"(exports2) {
7838
8211
  "use strict";
7839
8212
  init_define_IGNITIFY_CLIENT_FILES();
7840
8213
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7864,7 +8237,7 @@ var require_dynamicRef = __commonJS({ "../../../../../../../../../Users/saeed/Pr
7864
8237
  exports2.dynamicRef = dynamicRef;
7865
8238
  exports2.default = def;
7866
8239
  } });
7867
- var require_recursiveAnchor = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js"(exports2) {
8240
+ var require_recursiveAnchor = __commonJS({ "../../node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js"(exports2) {
7868
8241
  "use strict";
7869
8242
  init_define_IGNITIFY_CLIENT_FILES();
7870
8243
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7873,35 +8246,35 @@ var require_recursiveAnchor = __commonJS({ "../../../../../../../../../Users/sae
7873
8246
  } };
7874
8247
  exports2.default = def;
7875
8248
  } });
7876
- var require_recursiveRef = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js"(exports2) {
8249
+ var require_recursiveRef = __commonJS({ "../../node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js"(exports2) {
7877
8250
  "use strict";
7878
8251
  init_define_IGNITIFY_CLIENT_FILES();
7879
8252
  Object.defineProperty(exports2, "__esModule", { value: true });
7880
8253
  var dynamicRef_1 = require_dynamicRef(), def = { keyword: "$recursiveRef", schemaType: "string", code: (cxt) => (0, dynamicRef_1.dynamicRef)(cxt, cxt.schema) };
7881
8254
  exports2.default = def;
7882
8255
  } });
7883
- var require_dynamic = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/dynamic/index.js"(exports2) {
8256
+ var require_dynamic = __commonJS({ "../../node_modules/ajv/dist/vocabularies/dynamic/index.js"(exports2) {
7884
8257
  "use strict";
7885
8258
  init_define_IGNITIFY_CLIENT_FILES();
7886
8259
  Object.defineProperty(exports2, "__esModule", { value: true });
7887
8260
  var dynamicAnchor_1 = require_dynamicAnchor(), dynamicRef_1 = require_dynamicRef(), recursiveAnchor_1 = require_recursiveAnchor(), recursiveRef_1 = require_recursiveRef(), dynamic = [dynamicAnchor_1.default, dynamicRef_1.default, recursiveAnchor_1.default, recursiveRef_1.default];
7888
8261
  exports2.default = dynamic;
7889
8262
  } });
7890
- var require_dependentRequired = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js"(exports2) {
8263
+ var require_dependentRequired = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/dependentRequired.js"(exports2) {
7891
8264
  "use strict";
7892
8265
  init_define_IGNITIFY_CLIENT_FILES();
7893
8266
  Object.defineProperty(exports2, "__esModule", { value: true });
7894
8267
  var dependencies_1 = require_dependencies(), def = { keyword: "dependentRequired", type: "object", schemaType: "object", error: dependencies_1.error, code: (cxt) => (0, dependencies_1.validatePropertyDeps)(cxt) };
7895
8268
  exports2.default = def;
7896
8269
  } });
7897
- var require_dependentSchemas = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js"(exports2) {
8270
+ var require_dependentSchemas = __commonJS({ "../../node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js"(exports2) {
7898
8271
  "use strict";
7899
8272
  init_define_IGNITIFY_CLIENT_FILES();
7900
8273
  Object.defineProperty(exports2, "__esModule", { value: true });
7901
8274
  var dependencies_1 = require_dependencies(), def = { keyword: "dependentSchemas", type: "object", schemaType: "object", code: (cxt) => (0, dependencies_1.validateSchemaDeps)(cxt) };
7902
8275
  exports2.default = def;
7903
8276
  } });
7904
- var require_limitContains = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/validation/limitContains.js"(exports2) {
8277
+ var require_limitContains = __commonJS({ "../../node_modules/ajv/dist/vocabularies/validation/limitContains.js"(exports2) {
7905
8278
  "use strict";
7906
8279
  init_define_IGNITIFY_CLIENT_FILES();
7907
8280
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7910,14 +8283,14 @@ var require_limitContains = __commonJS({ "../../../../../../../../../Users/saeed
7910
8283
  } };
7911
8284
  exports2.default = def;
7912
8285
  } });
7913
- var require_next = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/next.js"(exports2) {
8286
+ var require_next = __commonJS({ "../../node_modules/ajv/dist/vocabularies/next.js"(exports2) {
7914
8287
  "use strict";
7915
8288
  init_define_IGNITIFY_CLIENT_FILES();
7916
8289
  Object.defineProperty(exports2, "__esModule", { value: true });
7917
8290
  var dependentRequired_1 = require_dependentRequired(), dependentSchemas_1 = require_dependentSchemas(), limitContains_1 = require_limitContains(), next = [dependentRequired_1.default, dependentSchemas_1.default, limitContains_1.default];
7918
8291
  exports2.default = next;
7919
8292
  } });
7920
- var require_unevaluatedProperties = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js"(exports2) {
8293
+ var require_unevaluatedProperties = __commonJS({ "../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js"(exports2) {
7921
8294
  "use strict";
7922
8295
  init_define_IGNITIFY_CLIENT_FILES();
7923
8296
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7947,7 +8320,7 @@ var require_unevaluatedProperties = __commonJS({ "../../../../../../../../../Use
7947
8320
  } };
7948
8321
  exports2.default = def;
7949
8322
  } });
7950
- var require_unevaluatedItems = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js"(exports2) {
8323
+ var require_unevaluatedItems = __commonJS({ "../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js"(exports2) {
7951
8324
  "use strict";
7952
8325
  init_define_IGNITIFY_CLIENT_FILES();
7953
8326
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7969,14 +8342,14 @@ var require_unevaluatedItems = __commonJS({ "../../../../../../../../../Users/sa
7969
8342
  } };
7970
8343
  exports2.default = def;
7971
8344
  } });
7972
- var require_unevaluated = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/unevaluated/index.js"(exports2) {
8345
+ var require_unevaluated = __commonJS({ "../../node_modules/ajv/dist/vocabularies/unevaluated/index.js"(exports2) {
7973
8346
  "use strict";
7974
8347
  init_define_IGNITIFY_CLIENT_FILES();
7975
8348
  Object.defineProperty(exports2, "__esModule", { value: true });
7976
8349
  var unevaluatedProperties_1 = require_unevaluatedProperties(), unevaluatedItems_1 = require_unevaluatedItems(), unevaluated = [unevaluatedProperties_1.default, unevaluatedItems_1.default];
7977
8350
  exports2.default = unevaluated;
7978
8351
  } });
7979
- var require_format = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/format/format.js"(exports2) {
8352
+ var require_format = __commonJS({ "../../node_modules/ajv/dist/vocabularies/format/format.js"(exports2) {
7980
8353
  "use strict";
7981
8354
  init_define_IGNITIFY_CLIENT_FILES();
7982
8355
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -8029,14 +8402,14 @@ var require_format = __commonJS({ "../../../../../../../../../Users/saeed/Projec
8029
8402
  } };
8030
8403
  exports2.default = def;
8031
8404
  } });
8032
- var require_format2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/format/index.js"(exports2) {
8405
+ var require_format2 = __commonJS({ "../../node_modules/ajv/dist/vocabularies/format/index.js"(exports2) {
8033
8406
  "use strict";
8034
8407
  init_define_IGNITIFY_CLIENT_FILES();
8035
8408
  Object.defineProperty(exports2, "__esModule", { value: true });
8036
8409
  var format_1 = require_format(), format = [format_1.default];
8037
8410
  exports2.default = format;
8038
8411
  } });
8039
- var require_metadata = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/metadata.js"(exports2) {
8412
+ var require_metadata = __commonJS({ "../../node_modules/ajv/dist/vocabularies/metadata.js"(exports2) {
8040
8413
  "use strict";
8041
8414
  init_define_IGNITIFY_CLIENT_FILES();
8042
8415
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -8044,14 +8417,14 @@ var require_metadata = __commonJS({ "../../../../../../../../../Users/saeed/Proj
8044
8417
  exports2.metadataVocabulary = ["title", "description", "default", "deprecated", "readOnly", "writeOnly", "examples"];
8045
8418
  exports2.contentVocabulary = ["contentMediaType", "contentEncoding", "contentSchema"];
8046
8419
  } });
8047
- var require_draft2020 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/draft2020.js"(exports2) {
8420
+ var require_draft2020 = __commonJS({ "../../node_modules/ajv/dist/vocabularies/draft2020.js"(exports2) {
8048
8421
  "use strict";
8049
8422
  init_define_IGNITIFY_CLIENT_FILES();
8050
8423
  Object.defineProperty(exports2, "__esModule", { value: true });
8051
8424
  var core_1 = require_core2(), validation_1 = require_validation(), applicator_1 = require_applicator(), dynamic_1 = require_dynamic(), next_1 = require_next(), unevaluated_1 = require_unevaluated(), format_1 = require_format2(), metadata_1 = require_metadata(), draft2020Vocabularies = [dynamic_1.default, core_1.default, validation_1.default, (0, applicator_1.default)(true), format_1.default, metadata_1.metadataVocabulary, metadata_1.contentVocabulary, next_1.default, unevaluated_1.default];
8052
8425
  exports2.default = draft2020Vocabularies;
8053
8426
  } });
8054
- var require_types = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/discriminator/types.js"(exports2) {
8427
+ var require_types = __commonJS({ "../../node_modules/ajv/dist/vocabularies/discriminator/types.js"(exports2) {
8055
8428
  "use strict";
8056
8429
  init_define_IGNITIFY_CLIENT_FILES();
8057
8430
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -8061,7 +8434,7 @@ var require_types = __commonJS({ "../../../../../../../../../Users/saeed/Project
8061
8434
  DiscrError2.Tag = "tag", DiscrError2.Mapping = "mapping";
8062
8435
  })(DiscrError || (exports2.DiscrError = DiscrError = {}));
8063
8436
  } });
8064
- var require_discriminator = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/vocabularies/discriminator/index.js"(exports2) {
8437
+ var require_discriminator = __commonJS({ "../../node_modules/ajv/dist/vocabularies/discriminator/index.js"(exports2) {
8065
8438
  "use strict";
8066
8439
  init_define_IGNITIFY_CLIENT_FILES();
8067
8440
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -8115,31 +8488,31 @@ var require_discriminator = __commonJS({ "../../../../../../../../../Users/saeed
8115
8488
  } };
8116
8489
  exports2.default = def;
8117
8490
  } });
8118
- var require_schema = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/schema.json"(exports2, module2) {
8491
+ var require_schema = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/schema.json"(exports2, module2) {
8119
8492
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/schema", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/core": true, "https://json-schema.org/draft/2020-12/vocab/applicator": true, "https://json-schema.org/draft/2020-12/vocab/unevaluated": true, "https://json-schema.org/draft/2020-12/vocab/validation": true, "https://json-schema.org/draft/2020-12/vocab/meta-data": true, "https://json-schema.org/draft/2020-12/vocab/format-annotation": true, "https://json-schema.org/draft/2020-12/vocab/content": true }, $dynamicAnchor: "meta", title: "Core and Validation specifications meta-schema", allOf: [{ $ref: "meta/core" }, { $ref: "meta/applicator" }, { $ref: "meta/unevaluated" }, { $ref: "meta/validation" }, { $ref: "meta/meta-data" }, { $ref: "meta/format-annotation" }, { $ref: "meta/content" }], type: ["object", "boolean"], $comment: "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", properties: { definitions: { $comment: '"definitions" has been replaced by "$defs".', type: "object", additionalProperties: { $dynamicRef: "#meta" }, deprecated: true, default: {} }, dependencies: { $comment: '"dependencies" has been split and replaced by "dependentSchemas" and "dependentRequired" in order to serve their differing semantics.', type: "object", additionalProperties: { anyOf: [{ $dynamicRef: "#meta" }, { $ref: "meta/validation#/$defs/stringArray" }] }, deprecated: true, default: {} }, $recursiveAnchor: { $comment: '"$recursiveAnchor" has been replaced by "$dynamicAnchor".', $ref: "meta/core#/$defs/anchorString", deprecated: true }, $recursiveRef: { $comment: '"$recursiveRef" has been replaced by "$dynamicRef".', $ref: "meta/core#/$defs/uriReferenceString", deprecated: true } } };
8120
8493
  } });
8121
- var require_applicator2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.json"(exports2, module2) {
8494
+ var require_applicator2 = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.json"(exports2, module2) {
8122
8495
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/applicator", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/applicator": true }, $dynamicAnchor: "meta", title: "Applicator vocabulary meta-schema", type: ["object", "boolean"], properties: { prefixItems: { $ref: "#/$defs/schemaArray" }, items: { $dynamicRef: "#meta" }, contains: { $dynamicRef: "#meta" }, additionalProperties: { $dynamicRef: "#meta" }, properties: { type: "object", additionalProperties: { $dynamicRef: "#meta" }, default: {} }, patternProperties: { type: "object", additionalProperties: { $dynamicRef: "#meta" }, propertyNames: { format: "regex" }, default: {} }, dependentSchemas: { type: "object", additionalProperties: { $dynamicRef: "#meta" }, default: {} }, propertyNames: { $dynamicRef: "#meta" }, if: { $dynamicRef: "#meta" }, then: { $dynamicRef: "#meta" }, else: { $dynamicRef: "#meta" }, allOf: { $ref: "#/$defs/schemaArray" }, anyOf: { $ref: "#/$defs/schemaArray" }, oneOf: { $ref: "#/$defs/schemaArray" }, not: { $dynamicRef: "#meta" } }, $defs: { schemaArray: { type: "array", minItems: 1, items: { $dynamicRef: "#meta" } } } };
8123
8496
  } });
8124
- var require_unevaluated2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.json"(exports2, module2) {
8497
+ var require_unevaluated2 = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.json"(exports2, module2) {
8125
8498
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/unevaluated", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/unevaluated": true }, $dynamicAnchor: "meta", title: "Unevaluated applicator vocabulary meta-schema", type: ["object", "boolean"], properties: { unevaluatedItems: { $dynamicRef: "#meta" }, unevaluatedProperties: { $dynamicRef: "#meta" } } };
8126
8499
  } });
8127
- var require_content = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.json"(exports2, module2) {
8500
+ var require_content = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.json"(exports2, module2) {
8128
8501
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/content", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/content": true }, $dynamicAnchor: "meta", title: "Content vocabulary meta-schema", type: ["object", "boolean"], properties: { contentEncoding: { type: "string" }, contentMediaType: { type: "string" }, contentSchema: { $dynamicRef: "#meta" } } };
8129
8502
  } });
8130
- var require_core3 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.json"(exports2, module2) {
8503
+ var require_core3 = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.json"(exports2, module2) {
8131
8504
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/core", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/core": true }, $dynamicAnchor: "meta", title: "Core vocabulary meta-schema", type: ["object", "boolean"], properties: { $id: { $ref: "#/$defs/uriReferenceString", $comment: "Non-empty fragments not allowed.", pattern: "^[^#]*#?$" }, $schema: { $ref: "#/$defs/uriString" }, $ref: { $ref: "#/$defs/uriReferenceString" }, $anchor: { $ref: "#/$defs/anchorString" }, $dynamicRef: { $ref: "#/$defs/uriReferenceString" }, $dynamicAnchor: { $ref: "#/$defs/anchorString" }, $vocabulary: { type: "object", propertyNames: { $ref: "#/$defs/uriString" }, additionalProperties: { type: "boolean" } }, $comment: { type: "string" }, $defs: { type: "object", additionalProperties: { $dynamicRef: "#meta" } } }, $defs: { anchorString: { type: "string", pattern: "^[A-Za-z_][-A-Za-z0-9._]*$" }, uriString: { type: "string", format: "uri" }, uriReferenceString: { type: "string", format: "uri-reference" } } };
8132
8505
  } });
8133
- var require_format_annotation = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.json"(exports2, module2) {
8506
+ var require_format_annotation = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.json"(exports2, module2) {
8134
8507
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/format-annotation", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/format-annotation": true }, $dynamicAnchor: "meta", title: "Format vocabulary meta-schema for annotation results", type: ["object", "boolean"], properties: { format: { type: "string" } } };
8135
8508
  } });
8136
- var require_meta_data = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.json"(exports2, module2) {
8509
+ var require_meta_data = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.json"(exports2, module2) {
8137
8510
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/meta-data", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/meta-data": true }, $dynamicAnchor: "meta", title: "Meta-data vocabulary meta-schema", type: ["object", "boolean"], properties: { title: { type: "string" }, description: { type: "string" }, default: true, deprecated: { type: "boolean", default: false }, readOnly: { type: "boolean", default: false }, writeOnly: { type: "boolean", default: false }, examples: { type: "array", items: true } } };
8138
8511
  } });
8139
- var require_validation2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json"(exports2, module2) {
8512
+ var require_validation2 = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json"(exports2, module2) {
8140
8513
  module2.exports = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://json-schema.org/draft/2020-12/meta/validation", $vocabulary: { "https://json-schema.org/draft/2020-12/vocab/validation": true }, $dynamicAnchor: "meta", title: "Validation vocabulary meta-schema", type: ["object", "boolean"], properties: { type: { anyOf: [{ $ref: "#/$defs/simpleTypes" }, { type: "array", items: { $ref: "#/$defs/simpleTypes" }, minItems: 1, uniqueItems: true }] }, const: true, enum: { type: "array", items: true }, multipleOf: { type: "number", exclusiveMinimum: 0 }, maximum: { type: "number" }, exclusiveMaximum: { type: "number" }, minimum: { type: "number" }, exclusiveMinimum: { type: "number" }, maxLength: { $ref: "#/$defs/nonNegativeInteger" }, minLength: { $ref: "#/$defs/nonNegativeIntegerDefault0" }, pattern: { type: "string", format: "regex" }, maxItems: { $ref: "#/$defs/nonNegativeInteger" }, minItems: { $ref: "#/$defs/nonNegativeIntegerDefault0" }, uniqueItems: { type: "boolean", default: false }, maxContains: { $ref: "#/$defs/nonNegativeInteger" }, minContains: { $ref: "#/$defs/nonNegativeInteger", default: 1 }, maxProperties: { $ref: "#/$defs/nonNegativeInteger" }, minProperties: { $ref: "#/$defs/nonNegativeIntegerDefault0" }, required: { $ref: "#/$defs/stringArray" }, dependentRequired: { type: "object", additionalProperties: { $ref: "#/$defs/stringArray" } } }, $defs: { nonNegativeInteger: { type: "integer", minimum: 0 }, nonNegativeIntegerDefault0: { $ref: "#/$defs/nonNegativeInteger", default: 0 }, simpleTypes: { enum: ["array", "boolean", "integer", "null", "number", "object", "string"] }, stringArray: { type: "array", items: { type: "string" }, uniqueItems: true, default: [] } } };
8141
8514
  } });
8142
- var require_json_schema_2020_12 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/refs/json-schema-2020-12/index.js"(exports2) {
8515
+ var require_json_schema_2020_12 = __commonJS({ "../../node_modules/ajv/dist/refs/json-schema-2020-12/index.js"(exports2) {
8143
8516
  "use strict";
8144
8517
  init_define_IGNITIFY_CLIENT_FILES();
8145
8518
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -8152,7 +8525,7 @@ var require_json_schema_2020_12 = __commonJS({ "../../../../../../../../../Users
8152
8525
  }
8153
8526
  exports2.default = addMetaSchema2020;
8154
8527
  } });
8155
- var require__ = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/ajv/dist/2020.js"(exports2, module2) {
8528
+ var require__ = __commonJS({ "../../node_modules/ajv/dist/2020.js"(exports2, module2) {
8156
8529
  "use strict";
8157
8530
  init_define_IGNITIFY_CLIENT_FILES();
8158
8531
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -8484,7 +8857,8 @@ function scanSourceTree(root, maxBytes = UPLOAD_MAX_BYTES, ignoreRules = []) {
8484
8857
  return walk(root), { entries, data, errors, warnings, ignored, totalBytes, truncated: over };
8485
8858
  }
8486
8859
  function computeSourceHash(entries, config) {
8487
- return `sha256:${import_node_crypto3.default.createHash("sha256").update(sourceManifest(entries, config), "utf8").digest("hex")}`;
8860
+ let manifest = checkSourceManifest(entries, config);
8861
+ return manifest.ok ? { ok: true, hash: `sha256:${import_node_crypto3.default.createHash("sha256").update(manifest.text, "utf8").digest("hex")}` } : manifest;
8488
8862
  }
8489
8863
  function checkLockfile(entries, runtime) {
8490
8864
  let required = RUNTIME_REGISTRY[runtime].lockfile;
@@ -8607,13 +8981,8 @@ function checkSourceUpload(taskDir) {
8607
8981
  scan.entries.some((e) => e.path === entry) || errors.push(`the entry file "${entry}" is not in the upload.`);
8608
8982
  }
8609
8983
  if (errors.length > 0) return { ok: false, errors, warnings };
8610
- let contentHash;
8611
- try {
8612
- contentHash = computeSourceHash(scan.entries, { name: import_node_path5.default.basename(read.file ?? ""), value: config });
8613
- } catch (e) {
8614
- return { ok: false, errors: [errText(e).replace(/^source manifest: /, "")], warnings };
8615
- }
8616
- return { ok: true, source: { config, entries: scan.entries, data: scan.data, totalBytes: scan.totalBytes, ignored: scan.ignored, contentHash }, warnings };
8984
+ let key = computeSourceHash(scan.entries, { name: import_node_path5.default.basename(read.file ?? ""), value: config });
8985
+ return key.ok ? { ok: true, source: { config, entries: scan.entries, data: scan.data, totalBytes: scan.totalBytes, ignored: scan.ignored, contentHash: key.hash }, warnings } : { ok: false, errors: [key.reason], warnings };
8617
8986
  }
8618
8987
  function prepareSourceUpload(taskDir) {
8619
8988
  let check = checkSourceUpload(taskDir);
@@ -9013,6 +9382,71 @@ var import_fs3, import_path3, init_scaffold = __esm({ "src/scaffold/index.ts"()
9013
9382
  init_templates();
9014
9383
  init_vendor();
9015
9384
  } });
9385
+ function replyOrThrow(reply) {
9386
+ if (!reply.ok) throw new FollowReadError(reply.error, reply.retryAfterMs);
9387
+ return reply.data;
9388
+ }
9389
+ function followStopOf(e) {
9390
+ let code = refusalCode(e);
9391
+ return code === OBS_REFUSAL.AGENT_OUTDATED_CURSOR.error ? "agent-outdated" : code === OBS_REFUSAL.NEVER_RAN.error ? "not-started" : "error";
9392
+ }
9393
+ function decidePacedRetry(e, retryAfterMs2, failuresInARow, failingForMs, fallbackMs) {
9394
+ return decidePollError(e, failuresInARow, failingForMs) === "give-up" ? { kind: "give-up" } : { kind: "retry", delayMs: isBusyAnswer(e) ? retryAfterMs2 ?? fallbackMs : fallbackMs, counted: true };
9395
+ }
9396
+ function decideBusyReadError(e, retryAfterMs2, failuresInARow, failingForMs) {
9397
+ return !isBusyAnswer(e) || failuresInARow > BUSY_READ.MAX_RETRIES ? { kind: "give-up" } : decidePacedRetry(e, retryAfterMs2, failuresInARow, failingForMs, FOLLOW.RETRY_FALLBACK_MS);
9398
+ }
9399
+ function decideFollowError(e, retryAfterMs2, failuresInARow, failingForMs) {
9400
+ return followStopOf(e) !== "error" ? { kind: "give-up" } : isWaitRefused(e) ? { kind: "retry", delayMs: retryAfterMs2 ?? FOLLOW.RETRY_FALLBACK_MS, counted: false } : decidePacedRetry(e, retryAfterMs2, failuresInARow, failingForMs, FOLLOW.RETRY_FALLBACK_MS);
9401
+ }
9402
+ function placeOutputPage(fromOffset, reply) {
9403
+ let next = reply.next_offset, bytes = typeof reply.bytes == "string" ? reply.bytes : "";
9404
+ return !isOffset(next) || next < fromOffset || bytes !== "" && next === fromOffset ? { kind: "no-cursor" } : { kind: "page", bytes, nextOffset: next, full: reply.truncated === true && next > fromOffset };
9405
+ }
9406
+ function decideOutputStep(page, endedAt, readAt) {
9407
+ return page.full ? "read-now" : page.bytes === "" && endedAt !== null && readAt - endedAt >= FOLLOW.IDLE_MS ? "stop" : "wait";
9408
+ }
9409
+ function timelineDone(reply, follow, held) {
9410
+ return reply.complete ? true : !follow && nextCursor(held, reply) === held;
9411
+ }
9412
+ function eventsToPrint(page, printedTail) {
9413
+ let fresh = (e) => !printedTail.has(e.id), tail = page.tail.filter(fresh), settledIds = new Set(page.events.map((e) => e.id));
9414
+ return { print: [...page.events.filter(fresh), ...tail], printedTail: new Set([...printedTail, ...tail.map((e) => e.id)].filter((id) => !settledIds.has(id))) };
9415
+ }
9416
+ function lastLines(text, n) {
9417
+ if (n <= 0) return "";
9418
+ let at = text.endsWith(`
9419
+ `) ? text.length - 1 : text.length;
9420
+ for (let seen = 0; seen < n; seen += 1) {
9421
+ let nl = at > 0 ? text.lastIndexOf(`
9422
+ `, at - 1) : -1;
9423
+ if (nl < 0) return text;
9424
+ at = nl;
9425
+ }
9426
+ return text.slice(at + 1);
9427
+ }
9428
+ var FollowReadError, isOffset, refusalCode, isWaitRefused, isBusyAnswer, nextCursor, idleRestMs, init_follow = __esm({ "src/core/follow.ts"() {
9429
+ "use strict";
9430
+ init_define_IGNITIFY_CLIENT_FILES();
9431
+ init_http_client();
9432
+ init_tenant();
9433
+ init_constants();
9434
+ init_poll();
9435
+ FollowReadError = class extends Error {
9436
+ error;
9437
+ retryAfterMs;
9438
+ constructor(error, retryAfterMs2) {
9439
+ super(error instanceof Error ? error.message : String(error)), this.name = "FollowReadError", this.error = error, this.retryAfterMs = retryAfterMs2;
9440
+ }
9441
+ };
9442
+ isOffset = (v) => typeof v == "number" && Number.isSafeInteger(v) && v >= 0, refusalCode = (e) => {
9443
+ let code = httpErrorJson(e)?.body.error;
9444
+ return typeof code == "string" ? code : null;
9445
+ }, isWaitRefused = (e) => refusalCode(e) === OBS_REFUSAL.WAIT_REFUSED.error;
9446
+ isBusyAnswer = (e) => e instanceof HttpError && (e.status === 429 || e.status === 503);
9447
+ nextCursor = (held, reply) => reply.cursor ?? held;
9448
+ idleRestMs = (startedAt, now) => Math.max(0, FOLLOW.IDLE_MS - (now - startedAt));
9449
+ } });
9016
9450
  function decidePoll(status, elapsedMs, attempt, failureReason) {
9017
9451
  return status === READY ? { kind: "ready" } : status === FAILED ? { kind: "failed", reason: failureReason ?? "the build failed without recording a reason" } : status !== BUILDING ? { kind: "failed", reason: `deployment entered an unexpected status: ${status}` } : elapsedMs >= POLL.DEPLOY.TIMEOUT_MS ? { kind: "timeout" } : { kind: "wait", delayMs: nextDelayMs(attempt) };
9018
9452
  }
@@ -9039,14 +9473,19 @@ var BUILDING, READY, FAILED, init_deploy_poll = __esm({ "src/core/deploy-poll.ts
9039
9473
  function decideRunPoll(status, elapsedMs, attempt) {
9040
9474
  return isTerminalRunStatus(status) ? { kind: "settled", status } : elapsedMs >= POLL.RUN.TIMEOUT_MS ? { kind: "timeout", status } : { kind: "wait", delayMs: backoffDelayMs(attempt, POLL.RUN) };
9041
9475
  }
9476
+ function decideRunPollError(e, failuresInARow, failingForMs) {
9477
+ let [error, retryAfterMs2] = e instanceof FollowReadError ? [e.error, e.retryAfterMs] : [e, null];
9478
+ return decidePacedRetry(error, retryAfterMs2, failuresInARow, failingForMs, POLL.RUN.MAX_MS);
9479
+ }
9042
9480
  async function pollUntilSettled(deps) {
9043
- let statusOf = (run2) => run2.status ?? "UNKNOWN", end = await pollUntil({ fetch: deps.fetchRun, retryDelayMs: POLL.RUN.MAX_MS, onRetry: deps.onRetry, decide: (run2, elapsedMs, attempt) => decideRunPoll(statusOf(run2), elapsedMs, attempt), onView: (run2) => deps.onStatus?.(statusOf(run2)), clock: deps });
9044
- return isLost(end) ? end : { action: end.action, run: end.view };
9481
+ let statusOf = (run2) => run2.status ?? "UNKNOWN", end = await pollUntil({ fetch: deps.fetchRun, decideError: decideRunPollError, onRetry: deps.onRetry, decide: (run2, elapsedMs, attempt) => decideRunPoll(statusOf(run2), elapsedMs, attempt), onView: (run2) => deps.onStatus?.(statusOf(run2)), clock: deps });
9482
+ return isLost(end) ? end.error instanceof FollowReadError ? { kind: "lost", error: end.error.error } : end : { action: end.action, run: end.view };
9045
9483
  }
9046
9484
  var init_run_poll = __esm({ "src/core/run-poll.ts"() {
9047
9485
  "use strict";
9048
9486
  init_define_IGNITIFY_CLIENT_FILES();
9049
9487
  init_constants();
9488
+ init_follow();
9050
9489
  init_poll();
9051
9490
  } });
9052
9491
  async function waitForBuild(cfg, deploymentId, progress, reused = false) {
@@ -9074,7 +9513,7 @@ ${st.bold(LABELS.BUILD_LOG)}
9074
9513
  return built.kind === "timeout" ? (progress.fail(WAIT.BUILD_TIMEOUT), fail(WAIT.BUILD_TIMEOUT_DETAIL(deploymentId)), 1) : (progress.succeed(reused && !building ? WAIT.REUSED : WAIT.BUILT), 0);
9075
9514
  }
9076
9515
  async function waitForRun(cfg, runId) {
9077
- let progress = startProgress(WAIT.RUN_SUBMITTED(runId)), lastStatus, settled = await withInterruptNotice(progress, () => WAIT.INTERRUPTED_RUN(runId), () => pollUntilSettled({ fetchRun: () => getApiRun(cfg, runId), onStatus: (status) => {
9516
+ let progress = startProgress(WAIT.RUN_SUBMITTED(runId)), lastStatus, settled = await withInterruptNotice(progress, () => WAIT.INTERRUPTED_RUN(runId), () => pollUntilSettled({ fetchRun: async () => replyOrThrow(await readRunForFollow(cfg, runId)), onStatus: (status) => {
9078
9517
  lastStatus = status, progress.update(WAIT.RUN(runId, status), WAIT.HINT_RUN);
9079
9518
  }, onRetry: () => progress.update(lastStatus === void 0 ? WAIT.RUN_SUBMITTED(runId) : WAIT.RUN(runId, lastStatus), WAIT.HINT_RETRYING) }));
9080
9519
  if (isLost(settled)) return progress.fail(WAIT.LOST), fail(WAIT.LOST_RUN_DETAIL(runId, errText(settled.error))), 1;
@@ -9087,6 +9526,7 @@ var init_wait = __esm({ "src/commands/wait.ts"() {
9087
9526
  "use strict";
9088
9527
  init_define_IGNITIFY_CLIENT_FILES();
9089
9528
  init_api();
9529
+ init_follow();
9090
9530
  init_deploy_poll();
9091
9531
  init_run_poll();
9092
9532
  init_poll();
@@ -9094,11 +9534,11 @@ var init_wait = __esm({ "src/commands/wait.ts"() {
9094
9534
  init_constants();
9095
9535
  init_tenant();
9096
9536
  } });
9097
- var MANIFEST_FILE, PACKAGE_SCOPE, RUNTIMES, NETWORK_TYPES, PRESETS, DURATIONS, INTERACTIONS, NAME_PATTERN, CALLBACK_ROUTE_PREFIX, EGRESS_HINT_PATTERN, DNS_LABEL, HOST_PATTERN, HOST_MAX_LENGTH, init_constants3 = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/constants.js"() {
9537
+ var MANIFEST_FILE, PACKAGE_SCOPE, RUNTIMES, NETWORK_TYPES, PRESETS, DURATIONS, INTERACTIONS, NAME_PATTERN, CALLBACK_ROUTE_PREFIX, EGRESS_HINT_PATTERN, DNS_LABEL, HOST_PATTERN, HOST_MAX_LENGTH, init_constants3 = __esm({ "../../node_modules/@ignitify-integrations/core/dist/constants.js"() {
9098
9538
  init_define_IGNITIFY_CLIENT_FILES();
9099
9539
  MANIFEST_FILE = "integration.yaml", PACKAGE_SCOPE = "@ignitify-integrations", RUNTIMES = ["node"], NETWORK_TYPES = ["none", "egress", "bidirectional"], PRESETS = ["std.micro", "std.small", "std.medium", "std.large", "std.xlarge"], DURATIONS = ["short", "long"], INTERACTIONS = ["boundary-only", "continuous"], NAME_PATTERN = "^[a-z][a-z0-9-]*[a-z0-9]$", CALLBACK_ROUTE_PREFIX = "/__callback/", EGRESS_HINT_PATTERN = "^[^\\r\\n]*$", DNS_LABEL = "[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?", HOST_PATTERN = new RegExp(`^${DNS_LABEL}(?:\\.${DNS_LABEL})+$`), HOST_MAX_LENGTH = 253;
9100
9540
  } });
9101
- var require_identity = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/identity.js"(exports2) {
9541
+ var require_identity = __commonJS({ "../../node_modules/yaml/dist/nodes/identity.js"(exports2) {
9102
9542
  "use strict";
9103
9543
  init_define_IGNITIFY_CLIENT_FILES();
9104
9544
  var ALIAS = /* @__PURE__ */ Symbol.for("yaml.alias"), DOC = /* @__PURE__ */ Symbol.for("yaml.document"), MAP = /* @__PURE__ */ Symbol.for("yaml.map"), PAIR = /* @__PURE__ */ Symbol.for("yaml.pair"), SCALAR = /* @__PURE__ */ Symbol.for("yaml.scalar"), SEQ = /* @__PURE__ */ Symbol.for("yaml.seq"), NODE_TYPE = /* @__PURE__ */ Symbol.for("yaml.node.type"), isAlias = (node) => !!node && typeof node == "object" && node[NODE_TYPE] === ALIAS, isDocument = (node) => !!node && typeof node == "object" && node[NODE_TYPE] === DOC, isMap2 = (node) => !!node && typeof node == "object" && node[NODE_TYPE] === MAP, isPair = (node) => !!node && typeof node == "object" && node[NODE_TYPE] === PAIR, isScalar2 = (node) => !!node && typeof node == "object" && node[NODE_TYPE] === SCALAR, isSeq2 = (node) => !!node && typeof node == "object" && node[NODE_TYPE] === SEQ;
@@ -9138,7 +9578,7 @@ var require_identity = __commonJS({ "../../../../../../../../../Users/saeed/Proj
9138
9578
  exports2.isScalar = isScalar2;
9139
9579
  exports2.isSeq = isSeq2;
9140
9580
  } });
9141
- var require_visit = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/visit.js"(exports2) {
9581
+ var require_visit = __commonJS({ "../../node_modules/yaml/dist/visit.js"(exports2) {
9142
9582
  "use strict";
9143
9583
  init_define_IGNITIFY_CLIENT_FILES();
9144
9584
  var identity = require_identity(), BREAK = /* @__PURE__ */ Symbol("break visit"), SKIP = /* @__PURE__ */ Symbol("skip children"), REMOVE = /* @__PURE__ */ Symbol("remove node");
@@ -9232,7 +9672,7 @@ var require_visit = __commonJS({ "../../../../../../../../../Users/saeed/Project
9232
9672
  exports2.visit = visit;
9233
9673
  exports2.visitAsync = visitAsync;
9234
9674
  } });
9235
- var require_directives = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/doc/directives.js"(exports2) {
9675
+ var require_directives = __commonJS({ "../../node_modules/yaml/dist/doc/directives.js"(exports2) {
9236
9676
  "use strict";
9237
9677
  init_define_IGNITIFY_CLIENT_FILES();
9238
9678
  var identity = require_identity(), visit = require_visit(), escapeChars = { "!": "%21", ",": "%2C", "[": "%5B", "]": "%5D", "{": "%7B", "}": "%7D" }, escapeTagName = (tn) => tn.replace(/[!,[\]{}]/g, (ch) => escapeChars[ch]), Directives = class _Directives {
@@ -9315,7 +9755,7 @@ var require_directives = __commonJS({ "../../../../../../../../../Users/saeed/Pr
9315
9755
  Directives.defaultTags = { "!!": "tag:yaml.org,2002:" };
9316
9756
  exports2.Directives = Directives;
9317
9757
  } });
9318
- var require_anchors = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/doc/anchors.js"(exports2) {
9758
+ var require_anchors = __commonJS({ "../../node_modules/yaml/dist/doc/anchors.js"(exports2) {
9319
9759
  "use strict";
9320
9760
  init_define_IGNITIFY_CLIENT_FILES();
9321
9761
  var identity = require_identity(), visit = require_visit();
@@ -9360,7 +9800,7 @@ var require_anchors = __commonJS({ "../../../../../../../../../Users/saeed/Proje
9360
9800
  exports2.createNodeAnchors = createNodeAnchors;
9361
9801
  exports2.findNewAnchor = findNewAnchor;
9362
9802
  } });
9363
- var require_applyReviver = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/doc/applyReviver.js"(exports2) {
9803
+ var require_applyReviver = __commonJS({ "../../node_modules/yaml/dist/doc/applyReviver.js"(exports2) {
9364
9804
  "use strict";
9365
9805
  init_define_IGNITIFY_CLIENT_FILES();
9366
9806
  function applyReviver(reviver, obj, key, val) {
@@ -9384,7 +9824,7 @@ var require_applyReviver = __commonJS({ "../../../../../../../../../Users/saeed/
9384
9824
  }
9385
9825
  exports2.applyReviver = applyReviver;
9386
9826
  } });
9387
- var require_toJS = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/toJS.js"(exports2) {
9827
+ var require_toJS = __commonJS({ "../../node_modules/yaml/dist/nodes/toJS.js"(exports2) {
9388
9828
  "use strict";
9389
9829
  init_define_IGNITIFY_CLIENT_FILES();
9390
9830
  var identity = require_identity();
@@ -9403,7 +9843,7 @@ var require_toJS = __commonJS({ "../../../../../../../../../Users/saeed/Projects
9403
9843
  }
9404
9844
  exports2.toJS = toJS;
9405
9845
  } });
9406
- var require_Node = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/Node.js"(exports2) {
9846
+ var require_Node = __commonJS({ "../../node_modules/yaml/dist/nodes/Node.js"(exports2) {
9407
9847
  "use strict";
9408
9848
  init_define_IGNITIFY_CLIENT_FILES();
9409
9849
  var applyReviver = require_applyReviver(), identity = require_identity(), toJS = require_toJS(), NodeBase = class {
@@ -9423,7 +9863,7 @@ var require_Node = __commonJS({ "../../../../../../../../../Users/saeed/Projects
9423
9863
  };
9424
9864
  exports2.NodeBase = NodeBase;
9425
9865
  } });
9426
- var require_Alias = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/Alias.js"(exports2) {
9866
+ var require_Alias = __commonJS({ "../../node_modules/yaml/dist/nodes/Alias.js"(exports2) {
9427
9867
  "use strict";
9428
9868
  init_define_IGNITIFY_CLIENT_FILES();
9429
9869
  var anchors = require_anchors(), visit = require_visit(), identity = require_identity(), Node = require_Node(), toJS = require_toJS(), Alias = class extends Node.NodeBase {
@@ -9496,7 +9936,7 @@ var require_Alias = __commonJS({ "../../../../../../../../../Users/saeed/Project
9496
9936
  }
9497
9937
  exports2.Alias = Alias;
9498
9938
  } });
9499
- var require_Scalar = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/Scalar.js"(exports2) {
9939
+ var require_Scalar = __commonJS({ "../../node_modules/yaml/dist/nodes/Scalar.js"(exports2) {
9500
9940
  "use strict";
9501
9941
  init_define_IGNITIFY_CLIENT_FILES();
9502
9942
  var identity = require_identity(), Node = require_Node(), toJS = require_toJS(), isScalarValue = (value) => !value || typeof value != "function" && typeof value != "object", Scalar = class extends Node.NodeBase {
@@ -9518,7 +9958,7 @@ var require_Scalar = __commonJS({ "../../../../../../../../../Users/saeed/Projec
9518
9958
  exports2.Scalar = Scalar;
9519
9959
  exports2.isScalarValue = isScalarValue;
9520
9960
  } });
9521
- var require_createNode = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/doc/createNode.js"(exports2) {
9961
+ var require_createNode = __commonJS({ "../../node_modules/yaml/dist/doc/createNode.js"(exports2) {
9522
9962
  "use strict";
9523
9963
  init_define_IGNITIFY_CLIENT_FILES();
9524
9964
  var Alias = require_Alias(), identity = require_identity(), Scalar = require_Scalar(), defaultTagPrefix = "tag:yaml.org,2002:";
@@ -9557,7 +9997,7 @@ var require_createNode = __commonJS({ "../../../../../../../../../Users/saeed/Pr
9557
9997
  }
9558
9998
  exports2.createNode = createNode;
9559
9999
  } });
9560
- var require_Collection = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/Collection.js"(exports2) {
10000
+ var require_Collection = __commonJS({ "../../node_modules/yaml/dist/nodes/Collection.js"(exports2) {
9561
10001
  "use strict";
9562
10002
  init_define_IGNITIFY_CLIENT_FILES();
9563
10003
  var createNode = require_createNode(), identity = require_identity(), Node = require_Node();
@@ -9630,7 +10070,7 @@ var require_Collection = __commonJS({ "../../../../../../../../../Users/saeed/Pr
9630
10070
  exports2.collectionFromPath = collectionFromPath;
9631
10071
  exports2.isEmptyPath = isEmptyPath;
9632
10072
  } });
9633
- var require_stringifyComment = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringifyComment.js"(exports2) {
10073
+ var require_stringifyComment = __commonJS({ "../../node_modules/yaml/dist/stringify/stringifyComment.js"(exports2) {
9634
10074
  "use strict";
9635
10075
  init_define_IGNITIFY_CLIENT_FILES();
9636
10076
  var stringifyComment = (str3) => str3.replace(/^(?!$)(?: $)?/gm, "#");
@@ -9645,7 +10085,7 @@ var require_stringifyComment = __commonJS({ "../../../../../../../../../Users/sa
9645
10085
  exports2.lineComment = lineComment;
9646
10086
  exports2.stringifyComment = stringifyComment;
9647
10087
  } });
9648
- var require_foldFlowLines = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/foldFlowLines.js"(exports2) {
10088
+ var require_foldFlowLines = __commonJS({ "../../node_modules/yaml/dist/stringify/foldFlowLines.js"(exports2) {
9649
10089
  "use strict";
9650
10090
  init_define_IGNITIFY_CLIENT_FILES();
9651
10091
  var FOLD_FLOW = "flow", FOLD_BLOCK = "block", FOLD_QUOTED = "quoted";
@@ -9722,7 +10162,7 @@ ${indent}${text.slice(fold + 1, end2)}`);
9722
10162
  exports2.FOLD_QUOTED = FOLD_QUOTED;
9723
10163
  exports2.foldFlowLines = foldFlowLines;
9724
10164
  } });
9725
- var require_stringifyString = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringifyString.js"(exports2) {
10165
+ var require_stringifyString = __commonJS({ "../../node_modules/yaml/dist/stringify/stringifyString.js"(exports2) {
9726
10166
  "use strict";
9727
10167
  init_define_IGNITIFY_CLIENT_FILES();
9728
10168
  var Scalar = require_Scalar(), foldFlowLines = require_foldFlowLines(), getFoldOptions = (ctx, isBlock) => ({ indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart, lineWidth: ctx.options.lineWidth, minContentWidth: ctx.options.minContentWidth }), containsDocumentMarker = (str3) => /^(%|---|\.\.\.)/m.test(str3);
@@ -9904,7 +10344,7 @@ ${indent}`);
9904
10344
  }
9905
10345
  exports2.stringifyString = stringifyString;
9906
10346
  } });
9907
- var require_stringify = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringify.js"(exports2) {
10347
+ var require_stringify = __commonJS({ "../../node_modules/yaml/dist/stringify/stringify.js"(exports2) {
9908
10348
  "use strict";
9909
10349
  init_define_IGNITIFY_CLIENT_FILES();
9910
10350
  var anchors = require_anchors(), identity = require_identity(), stringifyComment = require_stringifyComment(), stringifyString = require_stringifyString();
@@ -9968,7 +10408,7 @@ ${ctx.indent}${str3}` : str3;
9968
10408
  exports2.createStringifyContext = createStringifyContext;
9969
10409
  exports2.stringify = stringify;
9970
10410
  } });
9971
- var require_stringifyPair = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringifyPair.js"(exports2) {
10411
+ var require_stringifyPair = __commonJS({ "../../node_modules/yaml/dist/stringify/stringifyPair.js"(exports2) {
9972
10412
  "use strict";
9973
10413
  init_define_IGNITIFY_CLIENT_FILES();
9974
10414
  var identity = require_identity(), Scalar = require_Scalar(), stringify = require_stringify(), stringifyComment = require_stringifyComment();
@@ -10026,7 +10466,7 @@ ${ctx.indent}`);
10026
10466
  }
10027
10467
  exports2.stringifyPair = stringifyPair;
10028
10468
  } });
10029
- var require_log = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/log.js"(exports2) {
10469
+ var require_log = __commonJS({ "../../node_modules/yaml/dist/log.js"(exports2) {
10030
10470
  "use strict";
10031
10471
  init_define_IGNITIFY_CLIENT_FILES();
10032
10472
  var node_process = require("process");
@@ -10039,7 +10479,7 @@ var require_log = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
10039
10479
  exports2.debug = debug;
10040
10480
  exports2.warn = warn2;
10041
10481
  } });
10042
- var require_merge = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/merge.js"(exports2) {
10482
+ var require_merge = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/merge.js"(exports2) {
10043
10483
  "use strict";
10044
10484
  init_define_IGNITIFY_CLIENT_FILES();
10045
10485
  var identity = require_identity(), Scalar = require_Scalar(), MERGE_KEY = "<<", merge2 = { identify: (value) => value === MERGE_KEY || typeof value == "symbol" && value.description === MERGE_KEY, default: "key", tag: "tag:yaml.org,2002:merge", test: /^<<$/, resolve: () => Object.assign(new Scalar.Scalar(Symbol(MERGE_KEY)), { addToJSMap: addMergeToJSMap }), stringify: () => MERGE_KEY }, isMergeKey = (ctx, key) => (merge2.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge2.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge2.tag && tag.default);
@@ -10063,7 +10503,7 @@ var require_merge = __commonJS({ "../../../../../../../../../Users/saeed/Project
10063
10503
  exports2.isMergeKey = isMergeKey;
10064
10504
  exports2.merge = merge2;
10065
10505
  } });
10066
- var require_addPairToJSMap = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/addPairToJSMap.js"(exports2) {
10506
+ var require_addPairToJSMap = __commonJS({ "../../node_modules/yaml/dist/nodes/addPairToJSMap.js"(exports2) {
10067
10507
  "use strict";
10068
10508
  init_define_IGNITIFY_CLIENT_FILES();
10069
10509
  var log = require_log(), merge2 = require_merge(), stringify = require_stringify(), identity = require_identity(), toJS = require_toJS();
@@ -10100,7 +10540,7 @@ var require_addPairToJSMap = __commonJS({ "../../../../../../../../../Users/saee
10100
10540
  }
10101
10541
  exports2.addPairToJSMap = addPairToJSMap;
10102
10542
  } });
10103
- var require_Pair = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/Pair.js"(exports2) {
10543
+ var require_Pair = __commonJS({ "../../node_modules/yaml/dist/nodes/Pair.js"(exports2) {
10104
10544
  "use strict";
10105
10545
  init_define_IGNITIFY_CLIENT_FILES();
10106
10546
  var createNode = require_createNode(), stringifyPair = require_stringifyPair(), addPairToJSMap = require_addPairToJSMap(), identity = require_identity();
@@ -10127,7 +10567,7 @@ var require_Pair = __commonJS({ "../../../../../../../../../Users/saeed/Projects
10127
10567
  exports2.Pair = Pair;
10128
10568
  exports2.createPair = createPair;
10129
10569
  } });
10130
- var require_stringifyCollection = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringifyCollection.js"(exports2) {
10570
+ var require_stringifyCollection = __commonJS({ "../../node_modules/yaml/dist/stringify/stringifyCollection.js"(exports2) {
10131
10571
  "use strict";
10132
10572
  init_define_IGNITIFY_CLIENT_FILES();
10133
10573
  var identity = require_identity(), stringify = require_stringify(), stringifyComment = require_stringifyComment();
@@ -10202,7 +10642,7 @@ ${indent}${end}`;
10202
10642
  }
10203
10643
  exports2.stringifyCollection = stringifyCollection;
10204
10644
  } });
10205
- var require_YAMLMap = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/YAMLMap.js"(exports2) {
10645
+ var require_YAMLMap = __commonJS({ "../../node_modules/yaml/dist/nodes/YAMLMap.js"(exports2) {
10206
10646
  "use strict";
10207
10647
  init_define_IGNITIFY_CLIENT_FILES();
10208
10648
  var stringifyCollection = require_stringifyCollection(), addPairToJSMap = require_addPairToJSMap(), Collection = require_Collection(), identity = require_identity(), Pair = require_Pair(), Scalar = require_Scalar();
@@ -10268,7 +10708,7 @@ var require_YAMLMap = __commonJS({ "../../../../../../../../../Users/saeed/Proje
10268
10708
  exports2.YAMLMap = YAMLMap;
10269
10709
  exports2.findPair = findPair;
10270
10710
  } });
10271
- var require_map = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/common/map.js"(exports2) {
10711
+ var require_map = __commonJS({ "../../node_modules/yaml/dist/schema/common/map.js"(exports2) {
10272
10712
  "use strict";
10273
10713
  init_define_IGNITIFY_CLIENT_FILES();
10274
10714
  var identity = require_identity(), YAMLMap = require_YAMLMap(), map2 = { collection: "map", default: true, nodeClass: YAMLMap.YAMLMap, tag: "tag:yaml.org,2002:map", resolve(map3, onError) {
@@ -10276,7 +10716,7 @@ var require_map = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
10276
10716
  }, createNode: (schema2, obj, ctx) => YAMLMap.YAMLMap.from(schema2, obj, ctx) };
10277
10717
  exports2.map = map2;
10278
10718
  } });
10279
- var require_YAMLSeq = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/nodes/YAMLSeq.js"(exports2) {
10719
+ var require_YAMLSeq = __commonJS({ "../../node_modules/yaml/dist/nodes/YAMLSeq.js"(exports2) {
10280
10720
  "use strict";
10281
10721
  init_define_IGNITIFY_CLIENT_FILES();
10282
10722
  var createNode = require_createNode(), stringifyCollection = require_stringifyCollection(), Collection = require_Collection(), identity = require_identity(), Scalar = require_Scalar(), toJS = require_toJS(), YAMLSeq = class extends Collection.Collection {
@@ -10340,7 +10780,7 @@ var require_YAMLSeq = __commonJS({ "../../../../../../../../../Users/saeed/Proje
10340
10780
  }
10341
10781
  exports2.YAMLSeq = YAMLSeq;
10342
10782
  } });
10343
- var require_seq = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/common/seq.js"(exports2) {
10783
+ var require_seq = __commonJS({ "../../node_modules/yaml/dist/schema/common/seq.js"(exports2) {
10344
10784
  "use strict";
10345
10785
  init_define_IGNITIFY_CLIENT_FILES();
10346
10786
  var identity = require_identity(), YAMLSeq = require_YAMLSeq(), seq2 = { collection: "seq", default: true, nodeClass: YAMLSeq.YAMLSeq, tag: "tag:yaml.org,2002:seq", resolve(seq3, onError) {
@@ -10348,7 +10788,7 @@ var require_seq = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
10348
10788
  }, createNode: (schema2, obj, ctx) => YAMLSeq.YAMLSeq.from(schema2, obj, ctx) };
10349
10789
  exports2.seq = seq2;
10350
10790
  } });
10351
- var require_string = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/common/string.js"(exports2) {
10791
+ var require_string = __commonJS({ "../../node_modules/yaml/dist/schema/common/string.js"(exports2) {
10352
10792
  "use strict";
10353
10793
  init_define_IGNITIFY_CLIENT_FILES();
10354
10794
  var stringifyString = require_stringifyString(), string = { identify: (value) => typeof value == "string", default: true, tag: "tag:yaml.org,2002:str", resolve: (str3) => str3, stringify(item, ctx, onComment, onChompKeep) {
@@ -10356,13 +10796,13 @@ var require_string = __commonJS({ "../../../../../../../../../Users/saeed/Projec
10356
10796
  } };
10357
10797
  exports2.string = string;
10358
10798
  } });
10359
- var require_null2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/common/null.js"(exports2) {
10799
+ var require_null2 = __commonJS({ "../../node_modules/yaml/dist/schema/common/null.js"(exports2) {
10360
10800
  "use strict";
10361
10801
  init_define_IGNITIFY_CLIENT_FILES();
10362
10802
  var Scalar = require_Scalar(), nullTag = { identify: (value) => value == null, createNode: () => new Scalar.Scalar(null), default: true, tag: "tag:yaml.org,2002:null", test: /^(?:~|[Nn]ull|NULL)?$/, resolve: () => new Scalar.Scalar(null), stringify: ({ source }, ctx) => typeof source == "string" && nullTag.test.test(source) ? source : ctx.options.nullStr };
10363
10803
  exports2.nullTag = nullTag;
10364
10804
  } });
10365
- var require_bool = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/core/bool.js"(exports2) {
10805
+ var require_bool = __commonJS({ "../../node_modules/yaml/dist/schema/core/bool.js"(exports2) {
10366
10806
  "use strict";
10367
10807
  init_define_IGNITIFY_CLIENT_FILES();
10368
10808
  var Scalar = require_Scalar(), boolTag = { identify: (value) => typeof value == "boolean", default: true, tag: "tag:yaml.org,2002:bool", test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/, resolve: (str3) => new Scalar.Scalar(str3[0] === "t" || str3[0] === "T"), stringify({ source, value }, ctx) {
@@ -10374,7 +10814,7 @@ var require_bool = __commonJS({ "../../../../../../../../../Users/saeed/Projects
10374
10814
  } };
10375
10815
  exports2.boolTag = boolTag;
10376
10816
  } });
10377
- var require_stringifyNumber = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringifyNumber.js"(exports2) {
10817
+ var require_stringifyNumber = __commonJS({ "../../node_modules/yaml/dist/stringify/stringifyNumber.js"(exports2) {
10378
10818
  "use strict";
10379
10819
  init_define_IGNITIFY_CLIENT_FILES();
10380
10820
  function stringifyNumber({ format, minFractionDigits, tag, value }) {
@@ -10392,7 +10832,7 @@ var require_stringifyNumber = __commonJS({ "../../../../../../../../../Users/sae
10392
10832
  }
10393
10833
  exports2.stringifyNumber = stringifyNumber;
10394
10834
  } });
10395
- var require_float = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/core/float.js"(exports2) {
10835
+ var require_float = __commonJS({ "../../node_modules/yaml/dist/schema/core/float.js"(exports2) {
10396
10836
  "use strict";
10397
10837
  init_define_IGNITIFY_CLIENT_FILES();
10398
10838
  var Scalar = require_Scalar(), stringifyNumber = require_stringifyNumber(), floatNaN = { identify: (value) => typeof value == "number", default: true, tag: "tag:yaml.org,2002:float", test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/, resolve: (str3) => str3.slice(-3).toLowerCase() === "nan" ? NaN : str3[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, stringify: stringifyNumber.stringifyNumber }, floatExp = { identify: (value) => typeof value == "number", default: true, tag: "tag:yaml.org,2002:float", format: "EXP", test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/, resolve: (str3) => parseFloat(str3), stringify(node) {
@@ -10406,7 +10846,7 @@ var require_float = __commonJS({ "../../../../../../../../../Users/saeed/Project
10406
10846
  exports2.floatExp = floatExp;
10407
10847
  exports2.floatNaN = floatNaN;
10408
10848
  } });
10409
- var require_int = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/core/int.js"(exports2) {
10849
+ var require_int = __commonJS({ "../../node_modules/yaml/dist/schema/core/int.js"(exports2) {
10410
10850
  "use strict";
10411
10851
  init_define_IGNITIFY_CLIENT_FILES();
10412
10852
  var stringifyNumber = require_stringifyNumber(), intIdentify = (value) => typeof value == "bigint" || Number.isInteger(value), intResolve = (str3, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str3) : parseInt(str3.substring(offset), radix);
@@ -10419,13 +10859,13 @@ var require_int = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
10419
10859
  exports2.intHex = intHex;
10420
10860
  exports2.intOct = intOct;
10421
10861
  } });
10422
- var require_schema2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/core/schema.js"(exports2) {
10862
+ var require_schema2 = __commonJS({ "../../node_modules/yaml/dist/schema/core/schema.js"(exports2) {
10423
10863
  "use strict";
10424
10864
  init_define_IGNITIFY_CLIENT_FILES();
10425
10865
  var map2 = require_map(), _null2 = require_null2(), seq2 = require_seq(), string = require_string(), bool2 = require_bool(), float2 = require_float(), int2 = require_int(), schema2 = [map2.map, seq2.seq, string.string, _null2.nullTag, bool2.boolTag, int2.intOct, int2.int, int2.intHex, float2.floatNaN, float2.floatExp, float2.float];
10426
10866
  exports2.schema = schema2;
10427
10867
  } });
10428
- var require_schema3 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/json/schema.js"(exports2) {
10868
+ var require_schema3 = __commonJS({ "../../node_modules/yaml/dist/schema/json/schema.js"(exports2) {
10429
10869
  "use strict";
10430
10870
  init_define_IGNITIFY_CLIENT_FILES();
10431
10871
  var Scalar = require_Scalar(), map2 = require_map(), seq2 = require_seq();
@@ -10437,7 +10877,7 @@ var require_schema3 = __commonJS({ "../../../../../../../../../Users/saeed/Proje
10437
10877
  } }, schema2 = [map2.map, seq2.seq].concat(jsonScalars, jsonError);
10438
10878
  exports2.schema = schema2;
10439
10879
  } });
10440
- var require_binary = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/binary.js"(exports2) {
10880
+ var require_binary = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/binary.js"(exports2) {
10441
10881
  "use strict";
10442
10882
  init_define_IGNITIFY_CLIENT_FILES();
10443
10883
  var node_buffer = require("buffer"), Scalar = require_Scalar(), stringifyString = require_stringifyString(), binary2 = { identify: (value) => value instanceof Uint8Array, default: false, tag: "tag:yaml.org,2002:binary", resolve(src, onError) {
@@ -10466,7 +10906,7 @@ var require_binary = __commonJS({ "../../../../../../../../../Users/saeed/Projec
10466
10906
  } };
10467
10907
  exports2.binary = binary2;
10468
10908
  } });
10469
- var require_pairs = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/pairs.js"(exports2) {
10909
+ var require_pairs = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/pairs.js"(exports2) {
10470
10910
  "use strict";
10471
10911
  init_define_IGNITIFY_CLIENT_FILES();
10472
10912
  var identity = require_identity(), Pair = require_Pair(), Scalar = require_Scalar(), YAMLSeq = require_YAMLSeq();
@@ -10514,7 +10954,7 @@ ${cn.comment}` : item.comment;
10514
10954
  exports2.pairs = pairs3;
10515
10955
  exports2.resolvePairs = resolvePairs;
10516
10956
  } });
10517
- var require_omap = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/omap.js"(exports2) {
10957
+ var require_omap = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/omap.js"(exports2) {
10518
10958
  "use strict";
10519
10959
  init_define_IGNITIFY_CLIENT_FILES();
10520
10960
  var identity = require_identity(), toJS = require_toJS(), YAMLMap = require_YAMLMap(), YAMLSeq = require_YAMLSeq(), pairs3 = require_pairs(), YAMLOMap = class _YAMLOMap extends YAMLSeq.YAMLSeq {
@@ -10546,7 +10986,7 @@ var require_omap = __commonJS({ "../../../../../../../../../Users/saeed/Projects
10546
10986
  exports2.YAMLOMap = YAMLOMap;
10547
10987
  exports2.omap = omap2;
10548
10988
  } });
10549
- var require_bool2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/bool.js"(exports2) {
10989
+ var require_bool2 = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/bool.js"(exports2) {
10550
10990
  "use strict";
10551
10991
  init_define_IGNITIFY_CLIENT_FILES();
10552
10992
  var Scalar = require_Scalar();
@@ -10557,7 +10997,7 @@ var require_bool2 = __commonJS({ "../../../../../../../../../Users/saeed/Project
10557
10997
  exports2.falseTag = falseTag;
10558
10998
  exports2.trueTag = trueTag;
10559
10999
  } });
10560
- var require_float2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/float.js"(exports2) {
11000
+ var require_float2 = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/float.js"(exports2) {
10561
11001
  "use strict";
10562
11002
  init_define_IGNITIFY_CLIENT_FILES();
10563
11003
  var Scalar = require_Scalar(), stringifyNumber = require_stringifyNumber(), floatNaN = { identify: (value) => typeof value == "number", default: true, tag: "tag:yaml.org,2002:float", test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/, resolve: (str3) => str3.slice(-3).toLowerCase() === "nan" ? NaN : str3[0] === "-" ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, stringify: stringifyNumber.stringifyNumber }, floatExp = { identify: (value) => typeof value == "number", default: true, tag: "tag:yaml.org,2002:float", format: "EXP", test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/, resolve: (str3) => parseFloat(str3.replace(/_/g, "")), stringify(node) {
@@ -10575,7 +11015,7 @@ var require_float2 = __commonJS({ "../../../../../../../../../Users/saeed/Projec
10575
11015
  exports2.floatExp = floatExp;
10576
11016
  exports2.floatNaN = floatNaN;
10577
11017
  } });
10578
- var require_int2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/int.js"(exports2) {
11018
+ var require_int2 = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/int.js"(exports2) {
10579
11019
  "use strict";
10580
11020
  init_define_IGNITIFY_CLIENT_FILES();
10581
11021
  var stringifyNumber = require_stringifyNumber(), intIdentify = (value) => typeof value == "bigint" || Number.isInteger(value);
@@ -10613,7 +11053,7 @@ var require_int2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects
10613
11053
  exports2.intHex = intHex;
10614
11054
  exports2.intOct = intOct;
10615
11055
  } });
10616
- var require_set = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/set.js"(exports2) {
11056
+ var require_set = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/set.js"(exports2) {
10617
11057
  "use strict";
10618
11058
  init_define_IGNITIFY_CLIENT_FILES();
10619
11059
  var identity = require_identity(), Pair = require_Pair(), YAMLMap = require_YAMLMap(), YAMLSet = class _YAMLSet extends YAMLMap.YAMLMap {
@@ -10658,7 +11098,7 @@ var require_set = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
10658
11098
  exports2.YAMLSet = YAMLSet;
10659
11099
  exports2.set = set2;
10660
11100
  } });
10661
- var require_timestamp = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js"(exports2) {
11101
+ var require_timestamp = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/timestamp.js"(exports2) {
10662
11102
  "use strict";
10663
11103
  init_define_IGNITIFY_CLIENT_FILES();
10664
11104
  var stringifyNumber = require_stringifyNumber();
@@ -10689,13 +11129,13 @@ var require_timestamp = __commonJS({ "../../../../../../../../../Users/saeed/Pro
10689
11129
  exports2.intTime = intTime;
10690
11130
  exports2.timestamp = timestamp2;
10691
11131
  } });
10692
- var require_schema4 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/yaml-1.1/schema.js"(exports2) {
11132
+ var require_schema4 = __commonJS({ "../../node_modules/yaml/dist/schema/yaml-1.1/schema.js"(exports2) {
10693
11133
  "use strict";
10694
11134
  init_define_IGNITIFY_CLIENT_FILES();
10695
11135
  var map2 = require_map(), _null2 = require_null2(), seq2 = require_seq(), string = require_string(), binary2 = require_binary(), bool2 = require_bool2(), float2 = require_float2(), int2 = require_int2(), merge2 = require_merge(), omap2 = require_omap(), pairs3 = require_pairs(), set2 = require_set(), timestamp2 = require_timestamp(), schema2 = [map2.map, seq2.seq, string.string, _null2.nullTag, bool2.trueTag, bool2.falseTag, int2.intBin, int2.intOct, int2.int, int2.intHex, float2.floatNaN, float2.floatExp, float2.float, binary2.binary, merge2.merge, omap2.omap, pairs3.pairs, set2.set, timestamp2.intTime, timestamp2.floatTime, timestamp2.timestamp];
10696
11136
  exports2.schema = schema2;
10697
11137
  } });
10698
- var require_tags = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/tags.js"(exports2) {
11138
+ var require_tags = __commonJS({ "../../node_modules/yaml/dist/schema/tags.js"(exports2) {
10699
11139
  "use strict";
10700
11140
  init_define_IGNITIFY_CLIENT_FILES();
10701
11141
  var map2 = require_map(), _null2 = require_null2(), seq2 = require_seq(), string = require_string(), bool2 = require_bool(), float2 = require_float(), int2 = require_int(), schema2 = require_schema2(), schema$1 = require_schema3(), binary2 = require_binary(), merge2 = require_merge(), omap2 = require_omap(), pairs3 = require_pairs(), schema$2 = require_schema4(), set2 = require_set(), timestamp2 = require_timestamp(), schemas = /* @__PURE__ */ new Map([["core", schema2.schema], ["failsafe", [map2.map, seq2.seq, string.string]], ["json", schema$1.schema], ["yaml11", schema$2.schema], ["yaml-1.1", schema$2.schema]]), tagsByName = { binary: binary2.binary, bool: bool2.boolTag, float: float2.float, floatExp: float2.floatExp, floatNaN: float2.floatNaN, floatTime: timestamp2.floatTime, int: int2.int, intHex: int2.intHex, intOct: int2.intOct, intTime: timestamp2.intTime, map: map2.map, merge: merge2.merge, null: _null2.nullTag, omap: omap2.omap, pairs: pairs3.pairs, seq: seq2.seq, set: set2.set, timestamp: timestamp2.timestamp }, coreKnownTags = { "tag:yaml.org,2002:binary": binary2.binary, "tag:yaml.org,2002:merge": merge2.merge, "tag:yaml.org,2002:omap": omap2.omap, "tag:yaml.org,2002:pairs": pairs3.pairs, "tag:yaml.org,2002:set": set2.set, "tag:yaml.org,2002:timestamp": timestamp2.timestamp };
@@ -10722,7 +11162,7 @@ var require_tags = __commonJS({ "../../../../../../../../../Users/saeed/Projects
10722
11162
  exports2.coreKnownTags = coreKnownTags;
10723
11163
  exports2.getTags = getTags;
10724
11164
  } });
10725
- var require_Schema = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/schema/Schema.js"(exports2) {
11165
+ var require_Schema = __commonJS({ "../../node_modules/yaml/dist/schema/Schema.js"(exports2) {
10726
11166
  "use strict";
10727
11167
  init_define_IGNITIFY_CLIENT_FILES();
10728
11168
  var identity = require_identity(), map2 = require_map(), seq2 = require_seq(), string = require_string(), tags = require_tags(), sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0, Schema2 = class _Schema {
@@ -10736,7 +11176,7 @@ var require_Schema = __commonJS({ "../../../../../../../../../Users/saeed/Projec
10736
11176
  };
10737
11177
  exports2.Schema = Schema2;
10738
11178
  } });
10739
- var require_stringifyDocument = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/stringify/stringifyDocument.js"(exports2) {
11179
+ var require_stringifyDocument = __commonJS({ "../../node_modules/yaml/dist/stringify/stringifyDocument.js"(exports2) {
10740
11180
  "use strict";
10741
11181
  init_define_IGNITIFY_CLIENT_FILES();
10742
11182
  var identity = require_identity(), stringify = require_stringify(), stringifyComment = require_stringifyComment();
@@ -10780,7 +11220,7 @@ var require_stringifyDocument = __commonJS({ "../../../../../../../../../Users/s
10780
11220
  }
10781
11221
  exports2.stringifyDocument = stringifyDocument;
10782
11222
  } });
10783
- var require_Document = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/doc/Document.js"(exports2) {
11223
+ var require_Document = __commonJS({ "../../node_modules/yaml/dist/doc/Document.js"(exports2) {
10784
11224
  "use strict";
10785
11225
  init_define_IGNITIFY_CLIENT_FILES();
10786
11226
  var Alias = require_Alias(), Collection = require_Collection(), identity = require_identity(), Pair = require_Pair(), toJS = require_toJS(), Schema2 = require_Schema(), stringifyDocument = require_stringifyDocument(), anchors = require_anchors(), applyReviver = require_applyReviver(), createNode = require_createNode(), directives = require_directives(), Document = class _Document {
@@ -10894,7 +11334,7 @@ var require_Document = __commonJS({ "../../../../../../../../../Users/saeed/Proj
10894
11334
  }
10895
11335
  exports2.Document = Document;
10896
11336
  } });
10897
- var require_errors2 = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/errors.js"(exports2) {
11337
+ var require_errors2 = __commonJS({ "../../node_modules/yaml/dist/errors.js"(exports2) {
10898
11338
  "use strict";
10899
11339
  init_define_IGNITIFY_CLIENT_FILES();
10900
11340
  var YAMLError = class extends Error {
@@ -10940,7 +11380,7 @@ ${pointer}
10940
11380
  exports2.YAMLWarning = YAMLWarning;
10941
11381
  exports2.prettifyError = prettifyError;
10942
11382
  } });
10943
- var require_resolve_props = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-props.js"(exports2) {
11383
+ var require_resolve_props = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-props.js"(exports2) {
10944
11384
  "use strict";
10945
11385
  init_define_IGNITIFY_CLIENT_FILES();
10946
11386
  function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
@@ -10981,7 +11421,7 @@ var require_resolve_props = __commonJS({ "../../../../../../../../../Users/saeed
10981
11421
  }
10982
11422
  exports2.resolveProps = resolveProps;
10983
11423
  } });
10984
- var require_util_contains_newline = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/util-contains-newline.js"(exports2) {
11424
+ var require_util_contains_newline = __commonJS({ "../../node_modules/yaml/dist/compose/util-contains-newline.js"(exports2) {
10985
11425
  "use strict";
10986
11426
  init_define_IGNITIFY_CLIENT_FILES();
10987
11427
  function containsNewline(key) {
@@ -11012,7 +11452,7 @@ var require_util_contains_newline = __commonJS({ "../../../../../../../../../Use
11012
11452
  }
11013
11453
  exports2.containsNewline = containsNewline;
11014
11454
  } });
11015
- var require_util_flow_indent_check = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/util-flow-indent-check.js"(exports2) {
11455
+ var require_util_flow_indent_check = __commonJS({ "../../node_modules/yaml/dist/compose/util-flow-indent-check.js"(exports2) {
11016
11456
  "use strict";
11017
11457
  init_define_IGNITIFY_CLIENT_FILES();
11018
11458
  var utilContainsNewline = require_util_contains_newline();
@@ -11024,7 +11464,7 @@ var require_util_flow_indent_check = __commonJS({ "../../../../../../../../../Us
11024
11464
  }
11025
11465
  exports2.flowIndentCheck = flowIndentCheck;
11026
11466
  } });
11027
- var require_util_map_includes = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/util-map-includes.js"(exports2) {
11467
+ var require_util_map_includes = __commonJS({ "../../node_modules/yaml/dist/compose/util-map-includes.js"(exports2) {
11028
11468
  "use strict";
11029
11469
  init_define_IGNITIFY_CLIENT_FILES();
11030
11470
  var identity = require_identity();
@@ -11036,7 +11476,7 @@ var require_util_map_includes = __commonJS({ "../../../../../../../../../Users/s
11036
11476
  }
11037
11477
  exports2.mapIncludes = mapIncludes;
11038
11478
  } });
11039
- var require_resolve_block_map = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-block-map.js"(exports2) {
11479
+ var require_resolve_block_map = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-block-map.js"(exports2) {
11040
11480
  "use strict";
11041
11481
  init_define_IGNITIFY_CLIENT_FILES();
11042
11482
  var Pair = require_Pair(), YAMLMap = require_YAMLMap(), resolveProps = require_resolve_props(), utilContainsNewline = require_util_contains_newline(), utilFlowIndentCheck = require_util_flow_indent_check(), utilMapIncludes = require_util_map_includes(), startColMsg = "All mapping items must start at the same column";
@@ -11075,7 +11515,7 @@ var require_resolve_block_map = __commonJS({ "../../../../../../../../../Users/s
11075
11515
  }
11076
11516
  exports2.resolveBlockMap = resolveBlockMap;
11077
11517
  } });
11078
- var require_resolve_block_seq = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-block-seq.js"(exports2) {
11518
+ var require_resolve_block_seq = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-block-seq.js"(exports2) {
11079
11519
  "use strict";
11080
11520
  init_define_IGNITIFY_CLIENT_FILES();
11081
11521
  var YAMLSeq = require_YAMLSeq(), resolveProps = require_resolve_props(), utilFlowIndentCheck = require_util_flow_indent_check();
@@ -11097,7 +11537,7 @@ var require_resolve_block_seq = __commonJS({ "../../../../../../../../../Users/s
11097
11537
  }
11098
11538
  exports2.resolveBlockSeq = resolveBlockSeq;
11099
11539
  } });
11100
- var require_resolve_end = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-end.js"(exports2) {
11540
+ var require_resolve_end = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-end.js"(exports2) {
11101
11541
  "use strict";
11102
11542
  init_define_IGNITIFY_CLIENT_FILES();
11103
11543
  function resolveEnd(end, offset, reqSpace, onError) {
@@ -11129,7 +11569,7 @@ var require_resolve_end = __commonJS({ "../../../../../../../../../Users/saeed/P
11129
11569
  }
11130
11570
  exports2.resolveEnd = resolveEnd;
11131
11571
  } });
11132
- var require_resolve_flow_collection = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-flow-collection.js"(exports2) {
11572
+ var require_resolve_flow_collection = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-flow-collection.js"(exports2) {
11133
11573
  "use strict";
11134
11574
  init_define_IGNITIFY_CLIENT_FILES();
11135
11575
  var identity = require_identity(), Pair = require_Pair(), YAMLMap = require_YAMLMap(), YAMLSeq = require_YAMLSeq(), resolveEnd = require_resolve_end(), resolveProps = require_resolve_props(), utilContainsNewline = require_util_contains_newline(), utilMapIncludes = require_util_map_includes(), blockMsg = "Block collections are not allowed within flow collections", isBlock = (token) => token && (token.type === "block-map" || token.type === "block-seq");
@@ -11219,7 +11659,7 @@ var require_resolve_flow_collection = __commonJS({ "../../../../../../../../../U
11219
11659
  }
11220
11660
  exports2.resolveFlowCollection = resolveFlowCollection;
11221
11661
  } });
11222
- var require_compose_collection = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/compose-collection.js"(exports2) {
11662
+ var require_compose_collection = __commonJS({ "../../node_modules/yaml/dist/compose/compose-collection.js"(exports2) {
11223
11663
  "use strict";
11224
11664
  init_define_IGNITIFY_CLIENT_FILES();
11225
11665
  var identity = require_identity(), Scalar = require_Scalar(), YAMLMap = require_YAMLMap(), YAMLSeq = require_YAMLSeq(), resolveBlockMap = require_resolve_block_map(), resolveBlockSeq = require_resolve_block_seq(), resolveFlowCollection = require_resolve_flow_collection();
@@ -11246,7 +11686,7 @@ var require_compose_collection = __commonJS({ "../../../../../../../../../Users/
11246
11686
  }
11247
11687
  exports2.composeCollection = composeCollection;
11248
11688
  } });
11249
- var require_resolve_block_scalar = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-block-scalar.js"(exports2) {
11689
+ var require_resolve_block_scalar = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-block-scalar.js"(exports2) {
11250
11690
  "use strict";
11251
11691
  init_define_IGNITIFY_CLIENT_FILES();
11252
11692
  var Scalar = require_Scalar();
@@ -11358,7 +11798,7 @@ var require_resolve_block_scalar = __commonJS({ "../../../../../../../../../User
11358
11798
  }
11359
11799
  exports2.resolveBlockScalar = resolveBlockScalar;
11360
11800
  } });
11361
- var require_resolve_flow_scalar = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/resolve-flow-scalar.js"(exports2) {
11801
+ var require_resolve_flow_scalar = __commonJS({ "../../node_modules/yaml/dist/compose/resolve-flow-scalar.js"(exports2) {
11362
11802
  "use strict";
11363
11803
  init_define_IGNITIFY_CLIENT_FILES();
11364
11804
  var Scalar = require_Scalar(), resolveEnd = require_resolve_end();
@@ -11482,7 +11922,7 @@ var require_resolve_flow_scalar = __commonJS({ "../../../../../../../../../Users
11482
11922
  }
11483
11923
  exports2.resolveFlowScalar = resolveFlowScalar;
11484
11924
  } });
11485
- var require_compose_scalar = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/compose-scalar.js"(exports2) {
11925
+ var require_compose_scalar = __commonJS({ "../../node_modules/yaml/dist/compose/compose-scalar.js"(exports2) {
11486
11926
  "use strict";
11487
11927
  init_define_IGNITIFY_CLIENT_FILES();
11488
11928
  var identity = require_identity(), Scalar = require_Scalar(), resolveBlockScalar = require_resolve_block_scalar(), resolveFlowScalar = require_resolve_flow_scalar();
@@ -11521,7 +11961,7 @@ var require_compose_scalar = __commonJS({ "../../../../../../../../../Users/saee
11521
11961
  }
11522
11962
  exports2.composeScalar = composeScalar;
11523
11963
  } });
11524
- var require_util_empty_scalar_position = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/util-empty-scalar-position.js"(exports2) {
11964
+ var require_util_empty_scalar_position = __commonJS({ "../../node_modules/yaml/dist/compose/util-empty-scalar-position.js"(exports2) {
11525
11965
  "use strict";
11526
11966
  init_define_IGNITIFY_CLIENT_FILES();
11527
11967
  function emptyScalarPosition(offset, before, pos) {
@@ -11544,7 +11984,7 @@ var require_util_empty_scalar_position = __commonJS({ "../../../../../../../../.
11544
11984
  }
11545
11985
  exports2.emptyScalarPosition = emptyScalarPosition;
11546
11986
  } });
11547
- var require_compose_node = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/compose-node.js"(exports2) {
11987
+ var require_compose_node = __commonJS({ "../../node_modules/yaml/dist/compose/compose-node.js"(exports2) {
11548
11988
  "use strict";
11549
11989
  init_define_IGNITIFY_CLIENT_FILES();
11550
11990
  var Alias = require_Alias(), identity = require_identity(), composeCollection = require_compose_collection(), composeScalar = require_compose_scalar(), resolveEnd = require_resolve_end(), utilEmptyScalarPosition = require_util_empty_scalar_position(), CN = { composeNode, composeEmptyNode };
@@ -11590,7 +12030,7 @@ var require_compose_node = __commonJS({ "../../../../../../../../../Users/saeed/
11590
12030
  exports2.composeEmptyNode = composeEmptyNode;
11591
12031
  exports2.composeNode = composeNode;
11592
12032
  } });
11593
- var require_compose_doc = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/compose-doc.js"(exports2) {
12033
+ var require_compose_doc = __commonJS({ "../../node_modules/yaml/dist/compose/compose-doc.js"(exports2) {
11594
12034
  "use strict";
11595
12035
  init_define_IGNITIFY_CLIENT_FILES();
11596
12036
  var Document = require_Document(), composeNode = require_compose_node(), resolveEnd = require_resolve_end(), resolveProps = require_resolve_props();
@@ -11602,7 +12042,7 @@ var require_compose_doc = __commonJS({ "../../../../../../../../../Users/saeed/P
11602
12042
  }
11603
12043
  exports2.composeDoc = composeDoc;
11604
12044
  } });
11605
- var require_composer = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/compose/composer.js"(exports2) {
12045
+ var require_composer = __commonJS({ "../../node_modules/yaml/dist/compose/composer.js"(exports2) {
11606
12046
  "use strict";
11607
12047
  init_define_IGNITIFY_CLIENT_FILES();
11608
12048
  var node_process = require("process"), directives = require_directives(), Document = require_Document(), errors = require_errors2(), identity = require_identity(), composeDoc = require_compose_doc(), resolveEnd = require_resolve_end();
@@ -11726,7 +12166,7 @@ ${end.comment}` : end.comment;
11726
12166
  };
11727
12167
  exports2.Composer = Composer;
11728
12168
  } });
11729
- var require_cst_scalar = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/cst-scalar.js"(exports2) {
12169
+ var require_cst_scalar = __commonJS({ "../../node_modules/yaml/dist/parse/cst-scalar.js"(exports2) {
11730
12170
  "use strict";
11731
12171
  init_define_IGNITIFY_CLIENT_FILES();
11732
12172
  var resolveBlockScalar = require_resolve_block_scalar(), resolveFlowScalar = require_resolve_flow_scalar(), errors = require_errors2(), stringifyString = require_stringifyString();
@@ -11861,7 +12301,7 @@ var require_cst_scalar = __commonJS({ "../../../../../../../../../Users/saeed/Pr
11861
12301
  exports2.resolveAsScalar = resolveAsScalar;
11862
12302
  exports2.setScalarValue = setScalarValue;
11863
12303
  } });
11864
- var require_cst_stringify = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/cst-stringify.js"(exports2) {
12304
+ var require_cst_stringify = __commonJS({ "../../node_modules/yaml/dist/parse/cst-stringify.js"(exports2) {
11865
12305
  "use strict";
11866
12306
  init_define_IGNITIFY_CLIENT_FILES();
11867
12307
  var stringify = (cst) => "type" in cst ? stringifyToken(cst) : stringifyItem(cst);
@@ -11904,7 +12344,7 @@ var require_cst_stringify = __commonJS({ "../../../../../../../../../Users/saeed
11904
12344
  }
11905
12345
  exports2.stringify = stringify;
11906
12346
  } });
11907
- var require_cst_visit = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/cst-visit.js"(exports2) {
12347
+ var require_cst_visit = __commonJS({ "../../node_modules/yaml/dist/parse/cst-visit.js"(exports2) {
11908
12348
  "use strict";
11909
12349
  init_define_IGNITIFY_CLIENT_FILES();
11910
12350
  var BREAK = /* @__PURE__ */ Symbol("break visit"), SKIP = /* @__PURE__ */ Symbol("skip children"), REMOVE = /* @__PURE__ */ Symbol("remove item");
@@ -11949,7 +12389,7 @@ var require_cst_visit = __commonJS({ "../../../../../../../../../Users/saeed/Pro
11949
12389
  }
11950
12390
  exports2.visit = visit;
11951
12391
  } });
11952
- var require_cst = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/cst.js"(exports2) {
12392
+ var require_cst = __commonJS({ "../../node_modules/yaml/dist/parse/cst.js"(exports2) {
11953
12393
  "use strict";
11954
12394
  init_define_IGNITIFY_CLIENT_FILES();
11955
12395
  var cstScalar = require_cst_scalar(), cstStringify = require_cst_stringify(), cstVisit = require_cst_visit(), BOM = "\uFEFF", DOCUMENT = "", FLOW_END = "", SCALAR = "", isCollection = (token) => !!token && "items" in token, isScalar2 = (token) => !!token && (token.type === "scalar" || token.type === "single-quoted-scalar" || token.type === "double-quoted-scalar" || token.type === "block-scalar");
@@ -12042,7 +12482,7 @@ var require_cst = __commonJS({ "../../../../../../../../../Users/saeed/Projects/
12042
12482
  exports2.prettyToken = prettyToken;
12043
12483
  exports2.tokenType = tokenType;
12044
12484
  } });
12045
- var require_lexer = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/lexer.js"(exports2) {
12485
+ var require_lexer = __commonJS({ "../../node_modules/yaml/dist/parse/lexer.js"(exports2) {
12046
12486
  "use strict";
12047
12487
  init_define_IGNITIFY_CLIENT_FILES();
12048
12488
  var cst = require_cst();
@@ -12419,7 +12859,7 @@ var require_lexer = __commonJS({ "../../../../../../../../../Users/saeed/Project
12419
12859
  };
12420
12860
  exports2.Lexer = Lexer;
12421
12861
  } });
12422
- var require_line_counter = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/line-counter.js"(exports2) {
12862
+ var require_line_counter = __commonJS({ "../../node_modules/yaml/dist/parse/line-counter.js"(exports2) {
12423
12863
  "use strict";
12424
12864
  init_define_IGNITIFY_CLIENT_FILES();
12425
12865
  var LineCounter = class {
@@ -12439,7 +12879,7 @@ var require_line_counter = __commonJS({ "../../../../../../../../../Users/saeed/
12439
12879
  };
12440
12880
  exports2.LineCounter = LineCounter;
12441
12881
  } });
12442
- var require_parser = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/parse/parser.js"(exports2) {
12882
+ var require_parser = __commonJS({ "../../node_modules/yaml/dist/parse/parser.js"(exports2) {
12443
12883
  "use strict";
12444
12884
  init_define_IGNITIFY_CLIENT_FILES();
12445
12885
  var node_process = require("process"), cst = require_cst(), lexer = require_lexer();
@@ -12943,7 +13383,7 @@ var require_parser = __commonJS({ "../../../../../../../../../Users/saeed/Projec
12943
13383
  };
12944
13384
  exports2.Parser = Parser;
12945
13385
  } });
12946
- var require_public_api = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/public-api.js"(exports2) {
13386
+ var require_public_api = __commonJS({ "../../node_modules/yaml/dist/public-api.js"(exports2) {
12947
13387
  "use strict";
12948
13388
  init_define_IGNITIFY_CLIENT_FILES();
12949
13389
  var composer = require_composer(), Document = require_Document(), errors = require_errors2(), log = require_log(), identity = require_identity(), lineCounter = require_line_counter(), parser = require_parser();
@@ -12993,7 +13433,7 @@ var require_public_api = __commonJS({ "../../../../../../../../../Users/saeed/Pr
12993
13433
  exports2.parseDocument = parseDocument2;
12994
13434
  exports2.stringify = stringify;
12995
13435
  } });
12996
- var require_dist = __commonJS({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/node_modules/yaml/dist/index.js"(exports2) {
13436
+ var require_dist = __commonJS({ "../../node_modules/yaml/dist/index.js"(exports2) {
12997
13437
  "use strict";
12998
13438
  init_define_IGNITIFY_CLIENT_FILES();
12999
13439
  var composer = require_composer(), Document = require_Document(), Schema2 = require_Schema(), errors = require_errors2(), Alias = require_Alias(), identity = require_identity(), Pair = require_Pair(), Scalar = require_Scalar(), YAMLMap = require_YAMLMap(), YAMLSeq = require_YAMLSeq(), cst = require_cst(), lexer = require_lexer(), lineCounter = require_line_counter(), parser = require_parser(), publicApi = require_public_api(), visit = require_visit();
@@ -13027,41 +13467,45 @@ var require_dist = __commonJS({ "../../../../../../../../../Users/saeed/Projects
13027
13467
  exports2.visit = visit.visit;
13028
13468
  exports2.visitAsync = visit.visitAsync;
13029
13469
  } });
13030
- var ok, err, init_result2 = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/runtime/dist/result.js"() {
13470
+ var ok, err, init_result2 = __esm({ "../../node_modules/@ignitify-integrations/runtime/dist/result.js"() {
13031
13471
  init_define_IGNITIFY_CLIENT_FILES();
13032
13472
  ok = (value) => ({ ok: true, value }), err = (error) => ({ ok: false, error });
13033
13473
  } });
13034
- var init_ctx = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/runtime/dist/ctx.js"() {
13474
+ var init_ctx = __esm({ "../../node_modules/@ignitify-integrations/runtime/dist/ctx.js"() {
13035
13475
  init_define_IGNITIFY_CLIENT_FILES();
13036
13476
  } });
13037
- var SECRET_NAME_MAX_LENGTH, SECRET_NAME_PATTERN, init_secrets = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/runtime/dist/secrets.js"() {
13477
+ var SECRET_NAME_MAX_LENGTH, SECRET_NAME_PATTERN, init_secrets = __esm({ "../../node_modules/@ignitify-integrations/runtime/dist/secrets.js"() {
13038
13478
  init_define_IGNITIFY_CLIENT_FILES();
13039
13479
  init_result2();
13040
13480
  SECRET_NAME_MAX_LENGTH = 64, SECRET_NAME_PATTERN = new RegExp(`^[A-Z][A-Z0-9_]{0,${SECRET_NAME_MAX_LENGTH - 1}}$`);
13041
13481
  } });
13042
- var ROUTE_PREFIX_PATTERN, init_platform = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/runtime/dist/platform.js"() {
13482
+ var ROUTE_PREFIX_PATTERN, init_platform = __esm({ "../../node_modules/@ignitify-integrations/runtime/dist/platform.js"() {
13043
13483
  init_define_IGNITIFY_CLIENT_FILES();
13044
13484
  ROUTE_PREFIX_PATTERN = "^/[a-z0-9._~-]+(/[a-z0-9._~-]+)*/$";
13045
13485
  } });
13046
- var init_dist = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/runtime/dist/index.js"() {
13486
+ var init_stop = __esm({ "../../node_modules/@ignitify-integrations/runtime/dist/stop.js"() {
13487
+ init_define_IGNITIFY_CLIENT_FILES();
13488
+ } });
13489
+ var init_dist = __esm({ "../../node_modules/@ignitify-integrations/runtime/dist/index.js"() {
13047
13490
  init_define_IGNITIFY_CLIENT_FILES();
13048
13491
  init_result2();
13049
13492
  init_ctx();
13050
13493
  init_secrets();
13051
13494
  init_platform();
13495
+ init_stop();
13052
13496
  } });
13053
- var list, MANIFEST_MESSAGES, PLAN_MESSAGES, COVERAGE_MESSAGES, init_messages = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/messages.js"() {
13497
+ var list, MANIFEST_MESSAGES, PLAN_MESSAGES, COVERAGE_MESSAGES, init_messages = __esm({ "../../node_modules/@ignitify-integrations/core/dist/messages.js"() {
13054
13498
  init_define_IGNITIFY_CLIENT_FILES();
13055
13499
  init_constants3();
13056
13500
  list = (items) => items.join(", "), MANIFEST_MESSAGES = { yaml: (reason) => `not valid YAML: ${reason}`, schema: (path12, message) => `${path12}: ${message}`, badHost: (host) => `network.egress_allow: "${host}" is not a lower-case DNS name with at least two labels and no wildcard (hosts that vary go in network.egress_hint)`, egressNeedsNic: (key) => `network.${key}: needs network.type "egress" or "bidirectional"`, inboundNeedsBidirectional: (key) => `network.${key}: needs network.type "bidirectional"`, shadowsCallback: (prefix) => `network.inbound_routes: "${prefix}" would shadow the platform callback route ${CALLBACK_ROUTE_PREFIX}` }, PLAN_MESSAGES = { settingsOnly: "settings only", settingsAndCode: "settings + code", runs: (packages) => `runs ${list(packages)}`, conflict: (field, current, wanted, label) => `${field} is ${String(current)} but ${label} needs ${String(wanted)}: change it by hand or use another task`, tooManyHosts: (count) => `execution.network.egress_allow would list ${count} hosts; the platform allows at most ${32}`, networkRaised: (from, to) => `execution.network.type: ${from} -> ${to}`, egressAnywhere: (hosts) => `execution.network.egress_allow is absent (any host), so it stays absent; this integration needs: ${list(hosts)}`, presetRaised: (from, to) => `run.preset: ${from ?? "(default)"} -> ${to}`, presetUnknown: (preset, min) => `run.preset ${preset} is not a known preset; left as is (this integration needs at least ${min})`, setSecret: (name, isNew) => `secret ${name}${isNew ? " (new)" : ""}: ignitify secret:set ${name} --stdin`, addHost: (hint) => `egress host: ${hint}` }, COVERAGE_MESSAGES = { secretMissing: (label, name) => `${label}: secret ${name} is missing from secrets`, hostMissing: (label, host) => `${label}: host ${host} is missing from execution.network.egress_allow`, networkTooSmall: (label, have, need) => `${label}: execution.network.type is ${have}, needs ${need}`, fieldMismatch: (label, field, have, need) => `${label}: ${field} is ${have === void 0 ? "(absent)" : String(have)}, needs ${String(need)}`, packageMissing: (label, name) => `${label}: system package ${name} is missing from build.system_packages`, presetTooSmall: (label, have, need) => `${label}: run.preset is ${have ?? "(default)"}, needs at least ${need}`, routeMissing: (label, prefix) => `${label}: route ${prefix} is missing from execution.network.inbound_routes` };
13057
13501
  } });
13058
- var nonEmptyString, uniqueStrings, closed, network, MANIFEST_SCHEMA, init_schema = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/schema.js"() {
13502
+ var nonEmptyString, uniqueStrings, closed, network, MANIFEST_SCHEMA, init_schema = __esm({ "../../node_modules/@ignitify-integrations/core/dist/schema.js"() {
13059
13503
  init_define_IGNITIFY_CLIENT_FILES();
13060
13504
  init_dist();
13061
13505
  init_constants3();
13062
13506
  nonEmptyString = { type: "string", minLength: 1 }, uniqueStrings = { type: "array", items: nonEmptyString, uniqueItems: true }, closed = (properties, required = []) => ({ type: "object", additionalProperties: false, properties, required }), network = closed({ type: { enum: NETWORK_TYPES }, egress_allow: { type: "array", items: { type: "string", minLength: 1, maxLength: HOST_MAX_LENGTH }, uniqueItems: true, maxItems: 32 }, egress_hint: { type: "string", minLength: 1, maxLength: 200, pattern: EGRESS_HINT_PATTERN }, inbound_port: { type: "integer", minimum: 1024, maximum: 65535 }, inbound_routes: { type: "array", minItems: 1, maxItems: 32, items: closed({ prefix: { type: "string", maxLength: 256, pattern: ROUTE_PREFIX_PATTERN } }, ["prefix"]) }, inbound_max_concurrent: { type: "integer", minimum: 1 } }, ["type"]), MANIFEST_SCHEMA = { $schema: "https://json-schema.org/draft/2020-12/schema", title: "ignitify integration manifest", ...closed({ schema_version: { const: 1 }, name: { type: "string", pattern: NAME_PATTERN }, runtimes: { type: "array", items: { enum: RUNTIMES }, minItems: 1, uniqueItems: true }, secrets: { type: "array", items: { type: "string", maxLength: SECRET_NAME_MAX_LENGTH, pattern: SECRET_NAME_PATTERN.source }, uniqueItems: true }, network, execution: closed({ duration: { enum: DURATIONS }, interaction: { enum: INTERACTIONS } }), system_packages: uniqueStrings, min_preset: { enum: PRESETS } }, ["schema_version", "name", "runtimes"]) };
13063
13507
  } });
13064
- var import__2, import_yaml, INBOUND_KEYS, EGRESS_KEYS, ROOT_PATH, NUMERIC_LABEL, validate, isHostName, loadYaml, formatError, semanticIssues, parseManifest, init_manifest = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/manifest.js"() {
13508
+ var import__2, import_yaml, INBOUND_KEYS, EGRESS_KEYS, ROOT_PATH, NUMERIC_LABEL, validate, isHostName, loadYaml, formatError, semanticIssues, parseManifest, init_manifest = __esm({ "../../node_modules/@ignitify-integrations/core/dist/manifest.js"() {
13065
13509
  init_define_IGNITIFY_CLIENT_FILES();
13066
13510
  import__2 = __toESM(require__(), 1), import_yaml = __toESM(require_dist(), 1);
13067
13511
  init_dist();
@@ -13089,12 +13533,12 @@ var import__2, import_yaml, INBOUND_KEYS, EGRESS_KEYS, ROOT_PATH, NUMERIC_LABEL,
13089
13533
  return issues.length > 0 ? err(issues) : ok(data);
13090
13534
  };
13091
13535
  } });
13092
- var packageName, hasCode, rank, maxOf, union, optional, init_utils2 = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/utils.js"() {
13536
+ var packageName, hasCode, rank, maxOf, union, optional, init_utils2 = __esm({ "../../node_modules/@ignitify-integrations/core/dist/utils.js"() {
13093
13537
  init_define_IGNITIFY_CLIENT_FILES();
13094
13538
  init_constants3();
13095
13539
  packageName = (name) => `${PACKAGE_SCOPE}/${name}`, hasCode = (packageJson) => typeof packageJson == "object" && packageJson !== null && "exports" in packageJson, rank = (order, value) => order.indexOf(value), maxOf = (order, a, b) => rank(order, a) >= rank(order, b) ? a : b, union = (a, b) => [.../* @__PURE__ */ new Set([...a, ...b])], optional = (key, value) => value === void 0 ? {} : { [key]: value };
13096
13540
  } });
13097
- var EXECUTION_FIELDS, INBOUND_FIELDS, needsOf, planHeadline, pick, unionRoutes, egressFor, networkFor, presetFor, planAdd, coverageIssues, checkCoverage, init_plan = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/plan.js"() {
13541
+ var EXECUTION_FIELDS, INBOUND_FIELDS, needsOf, planHeadline, pick, prefixOf, unionRoutes, egressFor, networkFor, presetFor, planAdd, coverageIssues, checkCoverage, init_plan = __esm({ "../../node_modules/@ignitify-integrations/core/dist/plan.js"() {
13098
13542
  init_define_IGNITIFY_CLIENT_FILES();
13099
13543
  init_dist();
13100
13544
  init_constants3();
@@ -13103,7 +13547,7 @@ var EXECUTION_FIELDS, INBOUND_FIELDS, needsOf, planHeadline, pick, unionRoutes,
13103
13547
  EXECUTION_FIELDS = ["duration", "interaction"], INBOUND_FIELDS = ["inbound_port", "inbound_max_concurrent"], needsOf = (manifest) => ({ hosts: manifest.network?.egress_allow ?? [], secrets: manifest.secrets ?? [], networkType: manifest.network?.type ?? "none", inbound_port: manifest.network?.inbound_port, inbound_max_concurrent: manifest.network?.inbound_max_concurrent, inboundRoutes: manifest.network?.inbound_routes ?? [], execution: manifest.execution ?? {}, systemPackages: manifest.system_packages ?? [], minPreset: manifest.min_preset }), planHeadline = (manifest, version2, hasCode2) => {
13104
13548
  let packages = manifest.system_packages ?? [];
13105
13549
  return [`${packageName(manifest.name)}@${version2}`, hasCode2 ? PLAN_MESSAGES.settingsAndCode : PLAN_MESSAGES.settingsOnly, ...packages.length > 0 ? [PLAN_MESSAGES.runs(packages)] : []].join(" \xB7 ");
13106
- }, pick = (field, current, wanted, label) => wanted === void 0 || current === wanted ? { value: current } : current === void 0 ? { value: wanted } : { value: current, conflict: PLAN_MESSAGES.conflict(field, current, wanted, label) }, unionRoutes = (current, wanted) => [...current, ...wanted.filter((route2) => !current.some((have) => have.prefix === route2.prefix))], egressFor = (current, needs, notes) => {
13550
+ }, pick = (field, current, wanted, label) => wanted === void 0 || current === wanted ? { value: current } : current === void 0 ? { value: wanted } : { value: current, conflict: PLAN_MESSAGES.conflict(field, current, wanted, label) }, prefixOf = (route2) => "prefix" in route2 ? route2.prefix : void 0, unionRoutes = (current, wanted) => [...current, ...wanted.filter((route2) => !current.some((have) => prefixOf(have) === route2.prefix))], egressFor = (current, needs, notes) => {
13107
13551
  if (current?.egress_allow !== void 0) return union(current.egress_allow, needs.hosts);
13108
13552
  if ((current?.type ?? "none") !== "none") {
13109
13553
  needs.hosts.length > 0 && notes.push(PLAN_MESSAGES.egressAnywhere(needs.hosts));
@@ -13141,10 +13585,10 @@ var EXECUTION_FIELDS, INBOUND_FIELDS, needsOf, planHeadline, pick, unionRoutes,
13141
13585
  }), ...INBOUND_FIELDS.flatMap((field) => {
13142
13586
  let need = needs[field];
13143
13587
  return need === void 0 || network2?.[field] === need ? [] : [COVERAGE_MESSAGES.fieldMismatch(label, `execution.network.${field}`, network2?.[field], need)];
13144
- }), ...needs.inboundRoutes.filter((route2) => !routes.some((present) => present.prefix === route2.prefix)).map((route2) => COVERAGE_MESSAGES.routeMissing(label, route2.prefix)), ...needs.systemPackages.filter((name) => !packages.includes(name)).map((name) => COVERAGE_MESSAGES.packageMissing(label, name)), ...needs.minPreset !== void 0 && (preset === void 0 || presetRank >= 0 && presetRank < rank(PRESETS, needs.minPreset)) ? [COVERAGE_MESSAGES.presetTooSmall(label, preset, needs.minPreset)] : []];
13588
+ }), ...needs.inboundRoutes.filter((route2) => !routes.some((present) => prefixOf(present) === route2.prefix)).map((route2) => COVERAGE_MESSAGES.routeMissing(label, route2.prefix)), ...needs.systemPackages.filter((name) => !packages.includes(name)).map((name) => COVERAGE_MESSAGES.packageMissing(label, name)), ...needs.minPreset !== void 0 && (preset === void 0 || presetRank >= 0 && presetRank < rank(PRESETS, needs.minPreset)) ? [COVERAGE_MESSAGES.presetTooSmall(label, preset, needs.minPreset)] : []];
13145
13589
  }, checkCoverage = (config, manifests) => manifests.flatMap((manifest) => coverageIssues(config, packageName(manifest.name), needsOf(manifest)));
13146
13590
  } });
13147
- var init_dist2 = __esm({ "../../../../../../../../../Users/saeed/Projects/repos/mitra/apps/cli/node_modules/@ignitify-integrations/core/dist/index.js"() {
13591
+ var init_dist2 = __esm({ "../../node_modules/@ignitify-integrations/core/dist/index.js"() {
13148
13592
  init_define_IGNITIFY_CLIENT_FILES();
13149
13593
  init_constants3();
13150
13594
  init_manifest();
@@ -13167,23 +13611,29 @@ function diffLines(before, after, path12 = []) {
13167
13611
  return [...newScalars.length > 0 ? [`+ ${here}: ${newScalars.join(", ")}`] : [], ...nested];
13168
13612
  }
13169
13613
  function planIntegrationAdd(config, manifest, version2, hasCode2) {
13170
- let before = asCoreConfig(config), headline = planHeadline(manifest, version2, hasCode2), outcome = planAdd(before, manifest);
13614
+ let headline = planHeadline(manifest, version2, hasCode2), outcome = planAdd(config, manifest);
13171
13615
  if (!outcome.ok) return { ok: false, headline, refusals: outcome.error };
13172
13616
  let after = outcome.value.config;
13173
- return { ok: true, headline, changes: [...outcome.value.notes, ...diffLines(before, after)], youAdd: outcome.value.youAdd, config: after, changed: !(0, import_node_util.isDeepStrictEqual)(before, after) };
13617
+ return { ok: true, headline, changes: [...outcome.value.notes, ...diffLines(config, after)], youAdd: outcome.value.youAdd, config: after, changed: !(0, import_node_util.isDeepStrictEqual)(config, after) };
13174
13618
  }
13175
13619
  function renderAddPlan(plan) {
13176
13620
  return [plan.headline, ...plan.changes.map((line) => ` ${line}`), ...plan.youAdd.length > 0 ? [INTEGRATION.YOU_ADD, ...plan.youAdd.map((line) => ` ${line}`)] : []];
13177
13621
  }
13178
- var import_node_util, asCoreConfig, itemText, init_integration_plan = __esm({ "src/core/integration-plan.ts"() {
13622
+ var import_node_util, itemText, init_integration_plan = __esm({ "src/core/integration-plan.ts"() {
13179
13623
  "use strict";
13180
13624
  init_define_IGNITIFY_CLIENT_FILES();
13181
13625
  import_node_util = require("node:util");
13182
13626
  init_dist2();
13183
13627
  init_tenant();
13184
13628
  init_constants();
13185
- asCoreConfig = (config) => config, itemText = (item) => isRecord(item) && typeof item.prefix == "string" ? item.prefix : typeof item == "string" ? item : JSON.stringify(item);
13629
+ itemText = (item) => isRecord(item) && typeof item.prefix == "string" ? item.prefix : isRecord(item) && typeof item.path == "string" ? item.path : typeof item == "string" ? item : JSON.stringify(item);
13186
13630
  } });
13631
+ function assessIntegrations(installed, config) {
13632
+ let missing = installed.filter((entry) => entry.read.kind === "missing").map((entry) => entry.pkg);
13633
+ if (missing.length > 0) return { ok: false, missing };
13634
+ let integrations = installed.flatMap(({ pkg, read }) => read.kind === "installed" ? [{ pkg, version: read.version, manifest: parseManifest(read.manifestText) }] : []), manifests = integrations.flatMap(({ manifest }) => manifest.ok ? [manifest.value] : []);
13635
+ return { ok: true, errors: [...integrations.flatMap(({ pkg, manifest }) => manifest.ok ? [] : manifest.error.map((issue) => INTEGRATION.BAD_MANIFEST(pkg, issue))), ...checkCoverage(config, manifests)], versions: integrations.map(({ pkg, version: version2 }) => ({ pkg, version: version2 })) };
13636
+ }
13187
13637
  function integrationDeps(packageJson) {
13188
13638
  let deps = packageJson?.dependencies;
13189
13639
  return typeof deps != "object" || deps === null ? [] : Object.keys(deps).filter((name) => name.startsWith(`${PACKAGE_SCOPE}/`));
@@ -13305,9 +13755,10 @@ async function runIntegrationAdd(args, cwd = process.cwd(), deps = REAL_INTEGRAT
13305
13755
  let task = await prepareTask(args, cwd, slug2);
13306
13756
  if (!task) return 1;
13307
13757
  if (printWarnings([...task.warnings]), task.config.runtime !== INTEGRATION.RUNTIME) return fail(INTEGRATION.NOT_NODE(task.config.runtime)), 1;
13308
- if (readTaskPackageJson(task.taskDir) === null) return fail(INTEGRATION.NO_PACKAGE_JSON(task.taskDir)), 1;
13758
+ let taskDir = import_node_fs9.default.realpathSync(task.taskDir);
13759
+ if (readTaskPackageJson(taskDir) === null) return fail(INTEGRATION.NO_PACKAGE_JSON(task.taskDir)), 1;
13309
13760
  let pkg = packageName(name);
13310
- return guard(() => withPackDir((packDir) => addIntegration(args, task.taskDir, task.config, pkg, packDir, dryRun, deps)));
13761
+ return guard(() => withPackDir((packDir) => addIntegration(args, taskDir, task.config, pkg, packDir, dryRun, deps)));
13311
13762
  }
13312
13763
  async function withPackDir(fn) {
13313
13764
  let packDir = import_node_fs9.default.mkdtempSync(import_node_path8.default.join(import_node_os3.default.tmpdir(), INTEGRATION.PACK_TMP_PREFIX));
@@ -13350,15 +13801,8 @@ function taskConfigEdit(taskDir, config, planned) {
13350
13801
  async function checkIntegrations(taskDir, config, fetchImpl) {
13351
13802
  let pkgs = integrationDeps(readTaskPackageJson(taskDir));
13352
13803
  if (pkgs.length === 0) return true;
13353
- let installed = pkgs.map((pkg) => ({ pkg, read: readInstalledPackage(taskDir, pkg) })), missing = installed.filter((entry) => entry.read.kind === "missing").map((entry) => entry.pkg);
13354
- if (missing.length > 0) return fail(INTEGRATION.NOT_INSTALLED(missing)), false;
13355
- let manifests = [], errors = [], versions = [];
13356
- for (let { pkg, read } of installed) {
13357
- if (read.kind !== "installed") continue;
13358
- let manifest = parseManifest(read.manifestText);
13359
- manifest.ok ? manifests.push(manifest.value) : errors.push(...manifest.error.map((issue) => INTEGRATION.BAD_MANIFEST(pkg, issue))), versions.push({ pkg, version: read.version });
13360
- }
13361
- return await warnObsolete(versions, fetchImpl), errors.push(...checkCoverage(asCoreConfig(config), manifests)), printErrors(errors), errors.length === 0;
13804
+ let installed = pkgs.map((pkg) => ({ pkg, read: readInstalledPackage(taskDir, pkg) })), assessed = assessIntegrations(installed, config);
13805
+ return assessed.ok ? (await warnObsolete(assessed.versions, fetchImpl), printErrors(assessed.errors), assessed.errors.length === 0) : (fail(INTEGRATION.NOT_INSTALLED(assessed.missing)), false);
13362
13806
  }
13363
13807
  async function warnObsolete(versions, fetchImpl) {
13364
13808
  let lookups = await Promise.all(versions.map(async (entry) => ({ ...entry, lookup: await fetchPackument(entry.pkg, fetchImpl) }))), skipped = /* @__PURE__ */ new Set();
@@ -13394,7 +13838,7 @@ async function printPackageAdvice(args, config, fetchImpl) {
13394
13838
  let plan = planAdvice(config);
13395
13839
  if (plan.kind === "skip") return say(ADVICE.SKIPPED(plan.reason));
13396
13840
  try {
13397
- let outcome = await postPackageAdvice(apiConfig(args), plan.request, fetchImpl), { lines, fault } = renderAdvice(outcome, screenStyle());
13841
+ let outcome = await postPackageAdvice(apiConfig(), plan.request, fetchImpl), { lines, fault } = renderAdvice(outcome, screenStyle());
13398
13842
  for (let line of lines) (fault ? tell : say)(line);
13399
13843
  } catch (e) {
13400
13844
  fail(errText(e));
@@ -13407,12 +13851,12 @@ async function runTaskValidate(args, cwd = process.cwd(), fetchImpl) {
13407
13851
  async function runTaskGet(args, cwd = process.cwd()) {
13408
13852
  let task = await prepareTask(args, cwd);
13409
13853
  if (!task) return 1;
13410
- let { slug: slug2 } = task, state = readState(task.taskDir), check = checkSourceUpload(task.taskDir), localContentHash = check.ok ? check.source.contentHash : null, cfg = offlineTolerantConfig(args), orNull = (p) => p.catch(() => null), [whoami, deploymentsRes, runsRes] = cfg ? await Promise.all([orNull(getWhoami(cfg)), orNull(listApiDeploymentsForTask(cfg, slug2, void 0, { limit: TASK_REPORT_PAGE })), orNull(listApiRuns(cfg, { task_name: slug2, limit: String(TASK_REPORT_PAGE) }))]) : [null, null, null], report = buildTaskReport({ slug: slug2, declared: task.config.execution, declaredPreset: task.config.run?.preset, stateDeploymentId: state.deployment_id ?? null, localContentHash, deployments: deploymentsRes?.deployments ?? null, runs: runsRes?.runs ?? null, pageLimit: TASK_REPORT_PAGE, usage: whoami?.usage ?? null });
13854
+ let { slug: slug2 } = task, state = readState(task.taskDir), check = checkSourceUpload(task.taskDir), localContentHash = check.ok ? check.source.contentHash : null, cfg = offlineTolerantConfig(), orNull = (p) => p.catch(() => null), [whoami, deploymentsRes, runsRes] = cfg ? await Promise.all([orNull(getWhoami(cfg)), orNull(listApiDeploymentsForTask(cfg, slug2, void 0, { limit: TASK_REPORT_PAGE })), orNull(listApiRuns(cfg, { task_name: slug2, limit: String(TASK_REPORT_PAGE) }))]) : [null, null, null], report = buildTaskReport({ slug: slug2, declared: task.config.execution, declaredPreset: task.config.run?.preset, stateDeploymentId: state.deployment_id ?? null, localContentHash, deployments: deploymentsRes?.deployments ?? null, runs: runsRes?.runs ?? null, pageLimit: TASK_REPORT_PAGE, usage: whoami?.usage ?? null });
13411
13855
  return emit(snakeCaseKeys(report), () => formatTaskReport(report)), 0;
13412
13856
  }
13413
- function offlineTolerantConfig(args) {
13857
+ function offlineTolerantConfig() {
13414
13858
  try {
13415
- return apiConfig(args);
13859
+ return apiConfig();
13416
13860
  } catch (e) {
13417
13861
  return warn(RESULT_MESSAGES.TASK_GET_OFFLINE(errText(e))), null;
13418
13862
  }
@@ -13430,8 +13874,8 @@ async function runTaskPack(args, cwd = process.cwd()) {
13430
13874
  return CliOutputManager.render("task:pack", { task_id: config.slug, files: entries.map((e) => ({ path: e.path, size: e.size })), total_bytes: totalBytes, ignored, content_hash: contentHash }), 0;
13431
13875
  }
13432
13876
  async function runTaskDeploy(args, cwd = process.cwd()) {
13433
- let taskDir = getTaskDir(args, cwd);
13434
- if (!taskDir) return 1;
13877
+ let taskDir = getTaskDir(args, cwd), { taskId, dirFlag } = getTaskPath(args, cwd);
13878
+ if (!taskDir || !taskId) return 1;
13435
13879
  let prep = args.options.check ? checkSourceUpload(taskDir) : prepareSourceUpload(taskDir);
13436
13880
  if (printWarnings([...prep.warnings]), !prep.ok) return printErrors([...prep.errors]), 1;
13437
13881
  let left = "upload" in prep ? prep.upload.ignored : prep.source.ignored;
@@ -13440,9 +13884,9 @@ async function runTaskDeploy(args, cwd = process.cwd()) {
13440
13884
  return emit({ task_id: config.slug, valid: true, total_bytes: totalBytes, content_hash: contentHash }, (st) => successLine(st, VALIDATE.VALID)), 0;
13441
13885
  }
13442
13886
  let state = readState(taskDir);
13443
- if (!state.task_id) return fail("task_id not found in .ignitify/state.json \u2014 run `ignitify task:create <task-id>` first"), 1;
13887
+ if (!state.task_id) return fail(MESSAGES.TASK_NOT_REGISTERED(taskId, dirFlag)), 1;
13444
13888
  let { upload } = prep;
13445
- return uploadAndWait(apiConfig(args), taskDir, state.task_id, upload.manifest, upload.tar, upload.slug);
13889
+ return uploadAndWait(apiConfig(), taskDir, state.task_id, upload.manifest, upload.tar, upload.slug);
13446
13890
  }
13447
13891
  async function uploadAndWait(cfg, taskDir, taskId, manifest, tar, slug2) {
13448
13892
  let progress = startProgress(WAIT.UPLOADING(slug2, formatBytes(tar.length))), res, whoami;
@@ -13461,7 +13905,7 @@ async function runTaskRun(args, cwd = process.cwd()) {
13461
13905
  printWarnings([...task.warnings]);
13462
13906
  let opts = parseRunOptions(args, task.config);
13463
13907
  if (!opts.ok) return fail(opts.error), 1;
13464
- let { run: run2 } = opts, taskName = task.slug, cfg = apiConfig(args);
13908
+ let { run: run2 } = opts, taskName = task.slug, cfg = apiConfig();
13465
13909
  if (payloadBytes(run2.payload) > PAYLOAD_LIMIT_FALLBACK_BYTES) {
13466
13910
  let refusal = payloadRefusal(run2.payload, await payloadLimit(cfg));
13467
13911
  if (refusal !== null) return fail(refusal), 1;
@@ -13474,32 +13918,47 @@ async function runTaskRun(args, cwd = process.cwd()) {
13474
13918
  if (refusal !== null) return fail(refusal), 1;
13475
13919
  }
13476
13920
  return resolved.source === "server" && say(`Using deployment ${deploymentId} (resolved from the server \u2014 no local state).`), await guard(async () => {
13477
- let res;
13921
+ let posted;
13478
13922
  try {
13479
- res = await postRun(cfg, { deploymentId, taskName, ...run2 });
13923
+ posted = await postRun(cfg, { deploymentId, taskName, ...run2 });
13480
13924
  } catch (e) {
13481
13925
  if (isJsonOutput()) throw e;
13482
13926
  let trace = traceLine(e);
13483
13927
  if (isPayloadTooLarge(e)) return fail(MESSAGES.PAYLOAD_REFUSED_BY_SERVER(await payloadLimit(cfg)), { trace }), 1;
13928
+ let keyed = run2.idempotencyKey === void 0 ? null : idempotencyRefusal(e);
13929
+ if (keyed) return fail(keyed.error, { hint: keyed.hint, trace }), 1;
13484
13930
  let explained = explainRunRefusal(e) ?? explainLimitRefusal(e);
13485
13931
  if (!explained) throw e;
13486
13932
  return tell(explained), trace !== null && tell(errStyle().dim(trace)), 1;
13487
13933
  }
13488
- if (run2.at !== void 0) {
13489
- if (!res.schedule_id) return fail(res.run_id ? `this server does not support scheduling \u2014 it IGNORED --at and ran the job NOW (run ${res.run_id}). Cancel it with 'ignitify run:cancel ${res.run_id}' if that is not what you wanted.` : "this server does not support scheduling (no schedule_id in the response)."), 1;
13490
- if (isJsonOutput()) return emit(res), 0;
13491
- let st = outStyle();
13492
- out(successLine(st, `Scheduled: ${res.schedule_id} fires at ${res.fires_at ?? run2.at}`)), out(st.dim(`No run exists until it fires. List with 'ignitify schedule:list'; cancel with 'ignitify schedule:cancel ${res.schedule_id}'.`));
13493
- let scheduledNotices = renderRunNotices(res.notices);
13494
- scheduledNotices && out(st.yellow(scheduledNotices));
13495
- let capacity2 = renderCapacity(res.capacity, st);
13496
- return capacity2 && out(capacity2), 0;
13497
- }
13498
- if (!opts.wait || !res.run_id) return CliOutputManager.render("task:run", { ...res }), 0;
13499
- let notices = isJsonOutput() ? "" : renderRunNotices(res.notices);
13500
- notices && out(outStyle().yellow(notices));
13501
- let capacity = isJsonOutput() ? "" : renderCapacity(res.capacity, outStyle());
13502
- return capacity && out(capacity), waitForRun(cfg, res.run_id);
13934
+ let res = posted.answer;
13935
+ posted.replayed && warn(MESSAGES.RUN_REPLAYED);
13936
+ let answer = classifyRunAnswer(res, run2.at, opts.wait);
13937
+ switch (answer.kind) {
13938
+ case "skew-ran-now":
13939
+ return fail(`this server does not support scheduling \u2014 it IGNORED --at and ran the job NOW (run ${answer.runId}). Cancel it with 'ignitify run:cancel ${answer.runId}' if that is not what you wanted.`), 1;
13940
+ case "skew-no-schedule":
13941
+ return fail("this server does not support scheduling (no schedule_id in the response)."), 1;
13942
+ case "scheduled": {
13943
+ if (isJsonOutput()) return emit(res), 0;
13944
+ let st = outStyle();
13945
+ out(successLine(st, `Scheduled: ${answer.scheduleId} fires at ${answer.firesAt}`)), out(st.dim(`No run exists until it fires. List with 'ignitify schedule:list'; cancel with 'ignitify schedule:cancel ${answer.scheduleId}'.`));
13946
+ let scheduledNotices = renderRunNotices(res.notices);
13947
+ scheduledNotices && out(st.yellow(scheduledNotices));
13948
+ let capacity = renderCapacity(res.capacity, st);
13949
+ return capacity && out(capacity), 0;
13950
+ }
13951
+ case "submitted":
13952
+ return CliOutputManager.render("task:run", { ...res }), 0;
13953
+ case "wait": {
13954
+ let notices = isJsonOutput() ? "" : renderRunNotices(res.notices);
13955
+ notices && out(outStyle().yellow(notices));
13956
+ let capacity = isJsonOutput() ? "" : renderCapacity(res.capacity, outStyle());
13957
+ return capacity && out(capacity), waitForRun(cfg, answer.runId);
13958
+ }
13959
+ default:
13960
+ return answer;
13961
+ }
13503
13962
  });
13504
13963
  }
13505
13964
  async function runTaskCreate(args, cwd = process.cwd()) {
@@ -13515,7 +13974,7 @@ async function runTaskCreate(args, cwd = process.cwd()) {
13515
13974
  return err2 ? (fail(err2), 1) : (emit({ slug: taskId, runtime: lang, local_dir: taskDir, registered: false }, (st) => successLine(st, RESULT_MESSAGES.TASK_CREATED_LOCAL(lang, taskId, taskDir))), say(screenStyle().dim(limitsNote())), 0);
13516
13975
  }
13517
13976
  return guard(async () => {
13518
- let cfg = apiConfig(args), res = await createTask(cfg, taskId);
13977
+ let cfg = apiConfig(), res = await createTask(cfg, taskId);
13519
13978
  writeState(taskDir, { task_id: res.task_id, task_resource_id: res.resource_id });
13520
13979
  let local_dir;
13521
13980
  if (!args.options["no-scaffold"]) {
@@ -13532,11 +13991,11 @@ async function runTaskDelete(args, cwd = process.cwd(), prompter = ttyPrompter)
13532
13991
  let id = requiredArg(args);
13533
13992
  if (!id) return fail(MESSAGES.TASK_ID_REQUIRED), 1;
13534
13993
  let plan = await guardValue(async () => {
13535
- let baseDir = tasksBaseDir(args, cwd), cfg = apiConfig(args), { taskId, runs, deploymentCount, runCount } = await surveyTaskContents(cfg, id), folders = readTaskFolders(baseDir);
13994
+ let baseDir = tasksBaseDir(args, cwd), cfg = apiConfig(), { taskId, runs, deploymentCount, runCount } = await surveyTaskContents(cfg, id), folders = readTaskFolders(baseDir);
13536
13995
  return planTaskDeletion({ taskSlug: id, taskId, runs, deploymentCount, runCount, folders });
13537
13996
  });
13538
13997
  return plan === void 0 || (printDeletionPlan(plan), !await confirmOrAbort(args, prompter)) ? 1 : guard(async () => {
13539
- let cfg = apiConfig(args), d = (await deleteTask(cfg, id)).deleted;
13998
+ let cfg = apiConfig(), d = (await deleteTask(cfg, id)).deleted;
13540
13999
  d ? sayOk(`${MESSAGES.TASK_DELETED}: ${d.task_id} (${deletedCounts([["deployments", d.deployments], ["runs", d.runs], ["vms", d.vms], ["forfeited pins", d.forfeited_pins]])})`) : sayOk(MESSAGES.TASK_DELETED);
13541
14000
  for (let dir of plan.unlinkDirs) {
13542
14001
  let link = taskLinkPath(dir);
@@ -13558,6 +14017,7 @@ var import_fs4, TASK_REPORT_PAGE, init_task = __esm({ "src/commands/task.ts"() {
13558
14017
  init_plan_task_delete();
13559
14018
  init_resolve_deployment();
13560
14019
  init_run_options();
14020
+ init_run_answer();
13561
14021
  init_state();
13562
14022
  init_constants();
13563
14023
  init_payload_limit();
@@ -13581,18 +14041,18 @@ function runDeploymentList(args) {
13581
14041
  async function runDeploymentGet(args) {
13582
14042
  let id = requireArg(args, "deployment-id");
13583
14043
  return id ? guard(async () => {
13584
- let cfg = apiConfig(args);
14044
+ let cfg = apiConfig();
13585
14045
  return CliOutputManager.render("deployment:get", await getApiDeployment(cfg, id)), 0;
13586
14046
  }) : 1;
13587
14047
  }
13588
14048
  async function runDeploymentLogs(args) {
13589
14049
  let id = requireArg(args, "deployment-id");
13590
- return id ? guard(async () => (printConsoleLog(await getApiDeploymentLogs(apiConfig(args), id), boolFlag(args, "raw")), 0)) : 1;
14050
+ return id ? guard(async () => (printConsoleLog(await getApiDeploymentLogs(apiConfig(), id), boolFlag(args, "raw")), 0)) : 1;
13591
14051
  }
13592
14052
  async function runDeploymentDelete(args, prompter = ttyPrompter) {
13593
14053
  let id = requireArg(args, "deployment-id");
13594
14054
  return id ? guard(async () => {
13595
- let cfg = apiConfig(args);
14055
+ let cfg = apiConfig();
13596
14056
  if (say(RESULT_MESSAGES.DEPLOYMENT_DELETE_PREVIEW(id)), !await confirmOrAbort(args, prompter)) return 1;
13597
14057
  let res = await deleteDeployment(cfg, id);
13598
14058
  emit(res);
@@ -13621,27 +14081,122 @@ var WHOLE_MS, init_grace = __esm({ "src/core/grace.ts"() {
13621
14081
  init_constants();
13622
14082
  WHOLE_MS = /^\d+$/;
13623
14083
  } });
14084
+ async function readWithRetry(read, clock) {
14085
+ let wait = true, end = await pollUntil({ fetch: async () => replyOrThrow(await read(wait)), decideError: (e, failures, failingForMs) => e instanceof FollowReadError ? decideFollowError(e.error, e.retryAfterMs, failures, failingForMs) : { kind: "give-up" }, onRetry: (e) => {
14086
+ e instanceof FollowReadError && isWaitRefused(e.error) && (wait = false);
14087
+ }, decide: () => ({ kind: "read" }), clock });
14088
+ if (!isLost(end)) return { ok: true, data: end.view };
14089
+ let error = end.error instanceof FollowReadError ? end.error.error : end.error, stop = followStopOf(error);
14090
+ return { ok: false, failure: stop === "agent-outdated" ? { kind: stop } : { kind: stop, error } };
14091
+ }
14092
+ async function readBusyRetried(read, clock, onRetry = () => {
14093
+ }) {
14094
+ let end = await pollUntil({ fetch: async () => replyOrThrow(await read()), decideError: (e, failures, failingForMs) => e instanceof FollowReadError ? decideBusyReadError(e.error, e.retryAfterMs, failures, failingForMs) : { kind: "give-up" }, onRetry: (_e, delayMs) => onRetry(delayMs), decide: () => ({ kind: "read" }), clock });
14095
+ if (!isLost(end)) return end.view;
14096
+ throw end.error instanceof FollowReadError ? end.error.error : end.error;
14097
+ }
14098
+ async function readTimeline(loop) {
14099
+ let cursor = null;
14100
+ for (; ; ) {
14101
+ let held = cursor, startedAt = loop.clock.now(), read = await readWithRetry((wait) => loop.read(held, loop.follow && wait), loop.clock);
14102
+ if (!read.ok) return { ok: false, failure: read.failure };
14103
+ if (loop.onPage(read.data), cursor = nextCursor(held, read.data), timelineDone(read.data, loop.follow, held)) return { ok: true, last: read.data };
14104
+ if (loop.follow && read.data.events.length === 0) {
14105
+ let rest = idleRestMs(startedAt, loop.clock.now());
14106
+ rest > 0 && await loop.clock.sleep(rest);
14107
+ }
14108
+ }
14109
+ }
14110
+ async function readOutput(loop) {
14111
+ let offset = 0, held = loop.tail === null ? null : "", runId = "", checkRun = loop.follow, endedAt = null;
14112
+ for (; ; ) {
14113
+ if (checkRun && endedAt === null) {
14114
+ let run2 = await readWithRetry(loop.readRun, loop.clock);
14115
+ if (!run2.ok) return { ok: false, failure: run2.failure };
14116
+ isTerminalRunStatus(run2.data.status) && (endedAt = loop.clock.now());
14117
+ }
14118
+ let from = offset, readAt = loop.clock.now(), read = await readWithRetry(() => loop.readPage(from), loop.clock);
14119
+ if (!read.ok && !(loop.follow && read.failure.kind === "not-started")) return { ok: false, failure: read.failure };
14120
+ let placed = read.ok ? placeOutputPage(from, read.data) : { kind: "page", bytes: "", nextOffset: from, full: false };
14121
+ if (placed.kind === "no-cursor") return { ok: false, failure: { kind: "no-cursor" } };
14122
+ if (read.ok && (runId = read.data.run_id), offset = placed.nextOffset, held !== null && loop.tail !== null ? (held = lastLines(held + placed.bytes, loop.tail), placed.full || (held !== "" && loop.onChunk({ runId, bytes: held, nextOffset: offset }), held = null)) : placed.bytes !== "" && loop.onChunk({ runId, bytes: placed.bytes, nextOffset: offset }), !loop.follow) {
14123
+ if (placed.full) continue;
14124
+ return { ok: true };
14125
+ }
14126
+ let step = decideOutputStep(placed, endedAt, readAt);
14127
+ if (step === "stop") return { ok: true };
14128
+ checkRun = step === "wait", step === "wait" && await loop.clock.sleep(FOLLOW.IDLE_MS);
14129
+ }
14130
+ }
14131
+ var init_run_follow = __esm({ "src/commands/run-follow.ts"() {
14132
+ "use strict";
14133
+ init_define_IGNITIFY_CLIENT_FILES();
14134
+ init_constants();
14135
+ init_follow();
14136
+ init_poll();
14137
+ } });
13624
14138
  function runRunList(args) {
13625
- return runPagedList(args, { list: { command: COMMANDS.RUN_LIST, flags: RUN_LIST_FLAG_PARAMS }, fetchPage: listApiRuns, rowsOf: (data) => data.runs, show: (data) => CliOutputManager.render("run:list", data.runs) });
14139
+ return runPagedList(args, { list: { command: COMMANDS.RUN_LIST, flags: RUN_LIST_FLAG_PARAMS }, fetchPage: (cfg, params) => readBusyRetried(() => readRunList(cfg, params), REAL_CLOCK, noteBusyRetry), rowsOf: (data) => data.runs, show: (data) => CliOutputManager.render("run:list", data.runs) });
13626
14140
  }
13627
14141
  async function runRunGet(args) {
13628
14142
  let id = requireArg(args, "run-id");
13629
14143
  return id ? guard(async () => {
13630
- let cfg = apiConfig(args), data = await getApiRun(cfg, id);
14144
+ let cfg = apiConfig(), data = await readBusyRetried(() => readRunForFollow(cfg, id), REAL_CLOCK, noteBusyRetry);
13631
14145
  return boolFlag(args, "full") ? out(JSON.stringify(data, null, 2)) : CliOutputManager.render("run:get", data), 0;
13632
14146
  }) : 1;
13633
14147
  }
13634
14148
  async function runRunLogs(args) {
13635
14149
  let id = requireArg(args, "run-id");
13636
- return id ? guard(async () => {
13637
- let cfg = apiConfig(args);
13638
- return printConsoleLog(await getApiRunLogs(cfg, id), boolFlag(args, "raw")), 0;
13639
- }) : 1;
14150
+ if (!id) return 1;
14151
+ let follow = boolFlag(args, "follow"), raw = boolFlag(args, "raw");
14152
+ return guard(async () => {
14153
+ let tailRaw = strOpt(args, "tail"), tail = tailRaw === void 0 ? null : parseWholeCount(tailRaw);
14154
+ if (tailRaw !== void 0 && tail === null) return fail(FOLLOW_MESSAGES.TAIL_INVALID(tailRaw)), 1;
14155
+ let cfg = apiConfig(), json2 = isJsonOutput();
14156
+ if (!follow && tail === null) return printConsoleLog(await getApiRunLogs(cfg, id), raw), 0;
14157
+ let colour = outStyle().colour, read = () => readOutput({ readPage: (fromOffset) => readRunOutput(cfg, id, fromOffset), readRun: () => readRunForFollow(cfg, id), onChunk: (chunk) => json2 ? out(JSON.stringify(outputDocument(chunk))) : writeRaw(consoleLogText(chunk.bytes, { raw, colour })), follow, tail, clock: REAL_CLOCK }), end = follow ? await withInterruptNotice(NO_PROGRESS, () => FOLLOW_MESSAGES.INTERRUPTED(id), read) : await read();
14158
+ return end.ok ? 0 : failFollow(end.failure);
14159
+ });
14160
+ }
14161
+ function failFollow(failure) {
14162
+ if (failure.kind === "agent-outdated") fail(FOLLOW_MESSAGES.AGENT_OUTDATED);
14163
+ else if (failure.kind === "no-cursor") fail(FOLLOW_MESSAGES.API_NO_CURSOR);
14164
+ else throw failure.error;
14165
+ return 1;
14166
+ }
14167
+ async function runRunTimeline(args) {
14168
+ let id = requireArg(args, "run-id");
14169
+ if (!id) return 1;
14170
+ let follow = boolFlag(args, "follow");
14171
+ return guard(async () => {
14172
+ let cfg = apiConfig(), json2 = isJsonOutput(), events = [], printedTail = /* @__PURE__ */ new Set(), onPage = (page) => {
14173
+ if (json2 && follow) (page.events.length > 0 || page.complete) && out(JSON.stringify(page));
14174
+ else if (json2) events.push(...page.events);
14175
+ else {
14176
+ let next = eventsToPrint(page, printedTail);
14177
+ printedTail = next.printedTail;
14178
+ for (let event of next.print) out(timelineLine(event));
14179
+ }
14180
+ }, read = () => readTimeline({ read: (cursor, wait) => readRunTimeline(cfg, id, { cursor, waitSec: wait ? FOLLOW.WAIT_SEC : void 0 }), onPage, follow, clock: REAL_CLOCK }), end = follow ? await withInterruptNotice(NO_PROGRESS, () => FOLLOW_MESSAGES.INTERRUPTED(id), read) : await read();
14181
+ if (!end.ok) return failFollow(end.failure);
14182
+ let { run: run2 } = end.last;
14183
+ json2 && !follow && emit({ ...end.last, events });
14184
+ let ended = isTerminalRunStatus(run2.status), status = terminalSafe(run2.status, false);
14185
+ return json2 || out(ended ? WAIT.RUN_ENDED(status) : FOLLOW_MESSAGES.STILL_LIVE(status)), !ended || run2.status === RUN_STATUS.COMPLETED ? 0 : 1;
14186
+ });
14187
+ }
14188
+ async function runRunFailures(args) {
14189
+ return guard(async () => {
14190
+ let days = daysOption(args);
14191
+ if (!days.ok) return 1;
14192
+ let report = await getRunFailures(apiConfig(), days.days);
14193
+ return emit(report, (st) => renderFailures(st, report)), 0;
14194
+ });
13640
14195
  }
13641
14196
  async function runRunDelete(args, prompter = ttyPrompter) {
13642
14197
  let id = requireArg(args, "run-id");
13643
14198
  return id ? guard(async () => {
13644
- let cfg = apiConfig(args);
14199
+ let cfg = apiConfig();
13645
14200
  return say(RESULT_MESSAGES.RUN_DELETE_PREVIEW(id)), await confirmOrAbort(args, prompter) ? (emit(await deleteRun(cfg, id)), sayOk(`${MESSAGES.RUN_DELETED}: ${id}`), 0) : 1;
13646
14201
  }) : 1;
13647
14202
  }
@@ -13652,7 +14207,10 @@ async function runRunCancel(args, prompter = ttyPrompter) {
13652
14207
  return guard(async () => {
13653
14208
  let grace = parseGraceMs(strOpt(args, "grace"), force);
13654
14209
  if (!grace.ok) return fail(grace.error), 1;
13655
- let graceMs = grace.graceMs, cfg = apiConfig(args), run2 = await getApiRun(cfg, id);
14210
+ let graceMs = grace.graceMs, cfg = apiConfig(), run2 = await getApiRun(cfg, id).catch((e) => {
14211
+ if (isTransientError(e)) return null;
14212
+ throw e;
14213
+ });
13656
14214
  if (run2?.status && isTerminalRunStatus(run2.status)) return emit({ run_id: id, outcome: RUN_CANCEL_OUTCOME.ALREADY_TERMINAL, status: run2.status }), say(RESULT_MESSAGES.RUN_ALREADY_OVER(id, run2.status)), 0;
13657
14215
  if (say(RESULT_MESSAGES.RUN_CANCEL_PREVIEW(id, force)), !await confirmOrAbort(args, prompter)) return 1;
13658
14216
  let res = await cancelApiRun(cfg, id, force, graceMs);
@@ -13665,7 +14223,7 @@ async function runRunCancel(args, prompter = ttyPrompter) {
13665
14223
  return sayOk(RESULT_MESSAGES.RUN_CANCELLED(id, was)), 0;
13666
14224
  });
13667
14225
  }
13668
- var init_run = __esm({ "src/commands/run.ts"() {
14226
+ var noteBusyRetry, outputDocument, init_run = __esm({ "src/commands/run.ts"() {
13669
14227
  "use strict";
13670
14228
  init_define_IGNITIFY_CLIENT_FILES();
13671
14229
  init_prompt();
@@ -13674,7 +14232,15 @@ var init_run = __esm({ "src/commands/run.ts"() {
13674
14232
  init_utils();
13675
14233
  init_output();
13676
14234
  init_grace();
14235
+ init_follow();
14236
+ init_poll();
13677
14237
  init_shared();
14238
+ init_run_follow();
14239
+ noteBusyRetry = (delayMs) => {
14240
+ tell(BUSY_READ.NOTE(Math.ceil(delayMs / MS_PER_SECOND)));
14241
+ };
14242
+ outputDocument = (chunk) => ({ run_id: chunk.runId, bytes: chunk.bytes, lines: chunk.bytes.split(`
14243
+ `).length - 1, truncated: false, next_offset: chunk.nextOffset });
13678
14244
  } });
13679
14245
  function decideVmDelete(vm, force, vmId) {
13680
14246
  if (vm.residency === "pinned" && !force) {
@@ -13696,7 +14262,7 @@ function runVmList(args) {
13696
14262
  async function runVmGet(args) {
13697
14263
  let id = requireArg(args, "vm-id");
13698
14264
  return id ? guard(async () => {
13699
- let cfg = apiConfig(args), data = await getApiVm(cfg, id);
14265
+ let cfg = apiConfig(), data = await getApiVm(cfg, id);
13700
14266
  return CliOutputManager.render("vm:get", { ...data }), 0;
13701
14267
  }) : 1;
13702
14268
  }
@@ -13705,7 +14271,7 @@ async function runVmDelete(args, prompter = ttyPrompter) {
13705
14271
  if (!id) return 1;
13706
14272
  let force = boolFlag(args, "force");
13707
14273
  return guard(async () => {
13708
- let cfg = apiConfig(args), vm = await getApiVm(cfg, id), decision = decideVmDelete(vm, force, id);
14274
+ let cfg = apiConfig(), vm = await getApiVm(cfg, id), decision = decideVmDelete(vm, force, id);
13709
14275
  if (decision.refuse) return fail(decision.message), 1;
13710
14276
  if (say(decision.notice), !await confirmOrAbort(args, prompter)) return 1;
13711
14277
  let res = await deleteVm(cfg, id, force);
@@ -13733,20 +14299,20 @@ async function runSecretSet(args) {
13733
14299
  if (args.options.stdin !== true) return tell(MESSAGES.SECRET_SET_USAGE), 1;
13734
14300
  let value = import_fs5.default.readFileSync(0, "utf8").replace(/\n$/, "");
13735
14301
  return value === "" ? (fail(MESSAGES.SECRET_VALUE_EMPTY), 1) : guard(async () => {
13736
- let cfg = apiConfig(args), res = await setSecret(cfg, name, value);
14302
+ let cfg = apiConfig(), res = await setSecret(cfg, name, value);
13737
14303
  return emit(res), sayOk(MESSAGES.SECRET_STORED(name)), 0;
13738
14304
  });
13739
14305
  }
13740
14306
  async function runSecretList(args) {
13741
14307
  return guard(async () => {
13742
- let cfg = apiConfig(args), data = await listSecrets(cfg);
14308
+ let cfg = apiConfig(), data = await listSecrets(cfg);
13743
14309
  return emit(data, (st) => data.secrets.length === 0 ? emptyState(st, RESULT_MESSAGES.NO_SECRETS, RESULT_MESSAGES.NO_SECRETS_NEXT) : renderTable(st, [{ header: "name", keep: true }, { header: "updated_at", keep: true }], data.secrets.map((x) => [x.name, x.updated_at]))), 0;
13744
14310
  });
13745
14311
  }
13746
14312
  async function runSecretDelete(args, prompter = ttyPrompter) {
13747
14313
  let name = args.positionals[0];
13748
14314
  return name ? guard(async () => {
13749
- let cfg = apiConfig(args);
14315
+ let cfg = apiConfig();
13750
14316
  if (tell(RESULT_MESSAGES.SECRET_DELETE_PREVIEW(name)), !await confirmOrAbort(args, prompter)) return 1;
13751
14317
  let res = await rmSecret(cfg, name);
13752
14318
  return emit(res), sayOk(MESSAGES.SECRET_REMOVED(name)), 0;
@@ -13766,14 +14332,14 @@ var import_fs5, secretValueOnArgv, init_secret = __esm({ "src/commands/secret.ts
13766
14332
  } });
13767
14333
  async function runScheduleList(args) {
13768
14334
  return guard(async () => {
13769
- let cfg = apiConfig(args), res = await listSchedules(cfg);
14335
+ let cfg = apiConfig(), res = await listSchedules(cfg);
13770
14336
  return CliOutputManager.render("schedule:list", res.schedules.map((row) => ({ ...row }))), 0;
13771
14337
  });
13772
14338
  }
13773
14339
  async function runScheduleCancel(args, prompter = ttyPrompter) {
13774
14340
  let id = requireArg(args, "schedule-id");
13775
14341
  return id ? guard(async () => {
13776
- let cfg = apiConfig(args);
14342
+ let cfg = apiConfig();
13777
14343
  if (say(RESULT_MESSAGES.SCHEDULE_CANCEL_PREVIEW(id)), !await confirmOrAbort(args, prompter)) return 1;
13778
14344
  try {
13779
14345
  await deleteSchedule(cfg, id);
@@ -13794,12 +14360,37 @@ var init_schedule = __esm({ "src/commands/schedule.ts"() {
13794
14360
  init_output();
13795
14361
  init_shared();
13796
14362
  } });
14363
+ function notificationView(unread, open) {
14364
+ return unread && open ? null : unread ? "unread" : open ? "open" : "all";
14365
+ }
14366
+ function notificationMoreNote(rawLimit) {
14367
+ return (rawLimit === void 0 ? NOTIFICATION_PAGE_DEFAULT : Number(rawLimit)) < NOTIFICATION_PAGE_MAX ? MESSAGES.NOTIFICATION_MORE(NOTIFICATION_PAGE_MAX) : MESSAGES.NOTIFICATION_MORE_IN_APP;
14368
+ }
14369
+ async function runNotificationList(args) {
14370
+ let view = notificationView(boolFlag(args, "unread"), boolFlag(args, "open"));
14371
+ if (view === null) return fail(MESSAGES.NOTIFICATION_ONE_VIEW), 1;
14372
+ let badLimit = limitRefusal(args);
14373
+ return badLimit !== null ? (fail(badLimit), 1) : guard(async () => {
14374
+ let page = await listNotifications(apiConfig(), { ...flagParams(args, NOTIFICATION_LIST_FLAG_PARAMS), [NOTIFICATION_QUERY.FILTER]: view });
14375
+ return emit(page, (st) => renderNotifications(st, page)), page.next_cursor !== null && warn(notificationMoreNote(strOpt(args, "limit"))), 0;
14376
+ });
14377
+ }
14378
+ var init_notification = __esm({ "src/commands/notification.ts"() {
14379
+ "use strict";
14380
+ init_define_IGNITIFY_CLIENT_FILES();
14381
+ init_tenant();
14382
+ init_api();
14383
+ init_utils();
14384
+ init_output();
14385
+ init_constants();
14386
+ init_shared();
14387
+ } });
13797
14388
  function withAbsoluteUrl(created, baseUrl) {
13798
14389
  let { url } = created;
13799
14390
  return typeof url != "string" || !url.startsWith("/") ? created : { ...created, url: `${baseUrl.replace(/\/+$/, "")}${url}` };
13800
14391
  }
13801
14392
  function renderHookCreated(st, created) {
13802
- let { secret, ...rest } = created, rows = { ...rest, [RESULT_MESSAGES.HOOK_SECRET_KEY]: secret }, paint2 = { [RESULT_MESSAGES.HOOK_SECRET_KEY]: (s) => st.bold(st.yellow(s)) };
14393
+ let { secret, secret_redacted: _redacted, ...rest } = created, rows = { ...rest, [RESULT_MESSAGES.HOOK_SECRET_KEY]: secret }, paint2 = { [RESULT_MESSAGES.HOOK_SECRET_KEY]: (s) => st.bold(st.yellow(s)) };
13803
14394
  return `
13804
14395
  ${heading(st, RESULT_MESSAGES.HOOK_CREATED_TITLE, true)}
13805
14396
  ${renderFields(st, rows, void 0, paint2)}
@@ -13810,8 +14401,8 @@ async function runHookCreate(args) {
13810
14401
  if (!deploymentId) return tell(MESSAGES.HOOK_CREATE_USAGE), 1;
13811
14402
  let taskName = args.options["task-name"];
13812
14403
  return typeof taskName != "string" || taskName.trim() === "" ? (fail(MESSAGES.HOOK_TASK_NAME_REQUIRED), 1) : guard(async () => {
13813
- let cfg = apiConfig(args), created = withAbsoluteUrl(await createHook(cfg, deploymentId, { task_name: taskName }), cfg.baseUrl);
13814
- return warn(MESSAGES.HOOK_SECRET_SHOWN_ONCE), tell(MESSAGES.HOOK_PAYLOAD_LIMIT(formatLimit(await payloadLimit(cfg)))), emit(created, (st) => renderHookCreated(st, created)), 0;
14404
+ let cfg = apiConfig(), created = withAbsoluteUrl(await createHook(cfg, deploymentId, { task_name: taskName }), cfg.baseUrl);
14405
+ return created.secret === null ? (fail(MESSAGES.HOOK_SECRET_REDACTED(created.resource_id)), emit(created), 1) : (warn(MESSAGES.HOOK_SECRET_SHOWN_ONCE), tell(MESSAGES.HOOK_PAYLOAD_LIMIT(formatLimit(await payloadLimit(cfg)))), emit(created, (st) => renderHookCreated(st, created)), 0);
13815
14406
  });
13816
14407
  }
13817
14408
  async function runHookList(args) {
@@ -13819,14 +14410,14 @@ async function runHookList(args) {
13819
14410
  if (!deploymentId) return tell(MESSAGES.HOOK_LIST_USAGE), 1;
13820
14411
  let badLimit = limitRefusal(args);
13821
14412
  return badLimit !== null ? (fail(badLimit), 1) : guard(async () => {
13822
- let cfg = apiConfig(args), res = await listHooks(cfg, deploymentId, flagParams(args, PAGE_FLAG_PARAMS)), hooks = Array.isArray(res.hooks) ? res.hooks : [];
14413
+ let cfg = apiConfig(), res = await listHooks(cfg, deploymentId, flagParams(args, PAGE_FLAG_PARAMS)), hooks = Array.isArray(res.hooks) ? res.hooks : [];
13823
14414
  return emit(res, (st) => renderList(hooks.map((h) => ({ ...h })), st, EMPTY_LISTS.HOOKS)), noteNextPage(args, { command: COMMANDS.HOOK_LIST, flags: PAGE_FLAG_PARAMS }, hooks), 0;
13824
14415
  });
13825
14416
  }
13826
14417
  async function runHookDelete(args, prompter = ttyPrompter) {
13827
14418
  let hookId = args.positionals[0];
13828
14419
  return hookId ? guard(async () => {
13829
- let cfg = apiConfig(args);
14420
+ let cfg = apiConfig();
13830
14421
  return tell(RESULT_MESSAGES.HOOK_DELETE_PREVIEW(hookId)), await confirmOrAbort(args, prompter) ? (emit(await deleteHook(cfg, hookId)), sayOk(RESULT_MESSAGES.HOOK_DELETED(hookId)), 0) : 1;
13831
14422
  }) : (tell(MESSAGES.HOOK_DELETE_USAGE), 1);
13832
14423
  }
@@ -13838,7 +14429,7 @@ async function runNotifySet(args) {
13838
14429
  if (refusal !== null) return refuseNotifySet(refusal);
13839
14430
  let secret = args.options["secret-stdin"] === true ? import_fs6.default.readFileSync(0, "utf8").replace(/\n$/, "") : void 0;
13840
14431
  return secret === "" ? refuseNotifySet(MESSAGES.NOTIFY_SECRET_EMPTY) : guard(async () => {
13841
- let cfg = apiConfig(args), target = clear || typeof url != "string" ? null : url;
14432
+ let cfg = apiConfig(), target = clear || typeof url != "string" ? null : url;
13842
14433
  return emit(await setNotify(cfg, deploymentId, { url: target, ...secret !== void 0 ? { secret } : {} })), sayOk(target === null ? RESULT_MESSAGES.NOTIFY_CLEARED(deploymentId) : RESULT_MESSAGES.NOTIFY_SET(deploymentId, target)), 0;
13843
14434
  });
13844
14435
  }
@@ -13861,6 +14452,198 @@ var import_fs6, init_hook = __esm({ "src/commands/hook.ts"() {
13861
14452
  init_shared();
13862
14453
  init_output();
13863
14454
  } });
14455
+ async function runPermissionList(_args) {
14456
+ let permissions = permissionRows();
14457
+ return emit({ permissions }, (st) => renderPermissions(st, permissions)), 0;
14458
+ }
14459
+ var init_permission = __esm({ "src/commands/permission.ts"() {
14460
+ "use strict";
14461
+ init_define_IGNITIFY_CLIENT_FILES();
14462
+ init_access();
14463
+ init_output();
14464
+ } });
14465
+ async function runUserCreate(args) {
14466
+ let name = accessNameArg(args.positionals[0], ACCESS.USER, "name");
14467
+ return name === null ? 1 : guard(async () => {
14468
+ let created = await createUser(apiConfig(), name);
14469
+ return emit(created, (st) => renderFields(st, { ...created })), sayOk(MESSAGES.USER_CREATED(created.name)), 0;
14470
+ });
14471
+ }
14472
+ async function runUserList(_args) {
14473
+ return guard(async () => {
14474
+ let data = await listUsers(apiConfig());
14475
+ return emit(data, (st) => renderUsers(st, data.users)), 0;
14476
+ });
14477
+ }
14478
+ async function runUserGet(args) {
14479
+ let name = accessNameArg(args.positionals[0], ACCESS.USER, "name");
14480
+ return name === null ? 1 : guard(async () => {
14481
+ let user = await getUser(apiConfig(), name);
14482
+ return emit(user, (st) => renderUser(st, user)), 0;
14483
+ });
14484
+ }
14485
+ async function runUserRemove(args, prompter = ttyPrompter) {
14486
+ let name = accessNameArg(args.positionals[0], ACCESS.USER, "name");
14487
+ return name === null ? 1 : guard(async () => {
14488
+ let cfg = apiConfig();
14489
+ if (tell(RESULT_MESSAGES.USER_REMOVE_PREVIEW(name)), !await confirmOrAbort(args, prompter)) return 1;
14490
+ let res = await deleteUser(cfg, name);
14491
+ return emit(res), sayOk(MESSAGES.USER_REMOVED(res.removed, res.revoked_keys.length)), 0;
14492
+ });
14493
+ }
14494
+ var init_user = __esm({ "src/commands/user.ts"() {
14495
+ "use strict";
14496
+ init_define_IGNITIFY_CLIENT_FILES();
14497
+ init_api();
14498
+ init_prompt();
14499
+ init_constants();
14500
+ init_utils();
14501
+ init_output();
14502
+ init_shared();
14503
+ } });
14504
+ async function groupWrite(write, done) {
14505
+ return guard(async () => {
14506
+ let group = await write(apiConfig());
14507
+ return emit(group, (st) => renderGroup(st, group)), sayOk(done), 0;
14508
+ });
14509
+ }
14510
+ function permissionArg(raw) {
14511
+ if (raw === void 0 || raw === "") return fail(MESSAGES.ARG_REQUIRED("permission")), null;
14512
+ let checked = checkPermission(raw);
14513
+ return checked.ok ? checked.value : (fail(checked.message), null);
14514
+ }
14515
+ async function runGroupCreate(args) {
14516
+ let name = accessNameArg(args.positionals[0], ACCESS.GROUP, "name");
14517
+ if (name === null) return 1;
14518
+ let permissions = parsePermissions(strOpt(args, "permissions"));
14519
+ return permissions.ok ? groupWrite((cfg) => createGroup(cfg, name, permissions.value), MESSAGES.GROUP_CREATED(name)) : (fail(permissions.message), 1);
14520
+ }
14521
+ async function runGroupList(_args) {
14522
+ return guard(async () => {
14523
+ let data = await listGroups(apiConfig());
14524
+ return emit(data, (st) => renderGroups(st, data.groups)), 0;
14525
+ });
14526
+ }
14527
+ async function runGroupGet(args) {
14528
+ let name = accessNameArg(args.positionals[0], ACCESS.GROUP, "name");
14529
+ return name === null ? 1 : guard(async () => {
14530
+ let group = await getGroup(apiConfig(), name);
14531
+ return emit(group, (st) => renderGroup(st, group)), 0;
14532
+ });
14533
+ }
14534
+ async function runGroupGrant(args) {
14535
+ let name = accessNameArg(args.positionals[0], ACCESS.GROUP, "name");
14536
+ if (name === null) return 1;
14537
+ let permission = permissionArg(args.positionals[1]);
14538
+ return permission === null ? 1 : groupWrite((cfg) => grantGroupPermission(cfg, name, permission), MESSAGES.GROUP_GRANTED(name, permission));
14539
+ }
14540
+ async function runGroupRevoke(args) {
14541
+ let name = accessNameArg(args.positionals[0], ACCESS.GROUP, "name");
14542
+ if (name === null) return 1;
14543
+ let permission = permissionArg(args.positionals[1]);
14544
+ return permission === null ? 1 : groupWrite((cfg) => revokeGroupPermission(cfg, name, permission), MESSAGES.GROUP_REVOKED(name, permission));
14545
+ }
14546
+ async function runGroupAddUser(args) {
14547
+ let group = accessNameArg(args.positionals[0], ACCESS.GROUP, "group");
14548
+ if (group === null) return 1;
14549
+ let user = accessNameArg(args.positionals[1], ACCESS.USER, "user");
14550
+ return user === null ? 1 : groupWrite((cfg) => addGroupUser(cfg, group, user), MESSAGES.GROUP_USER_ADDED(group, user));
14551
+ }
14552
+ async function runGroupRemoveUser(args) {
14553
+ let group = accessNameArg(args.positionals[0], ACCESS.GROUP, "group");
14554
+ if (group === null) return 1;
14555
+ let user = accessNameArg(args.positionals[1], ACCESS.USER, "user");
14556
+ return user === null ? 1 : groupWrite((cfg) => removeGroupUser(cfg, group, user), MESSAGES.GROUP_USER_REMOVED(group, user));
14557
+ }
14558
+ async function runGroupDelete(args, prompter = ttyPrompter) {
14559
+ let name = accessNameArg(args.positionals[0], ACCESS.GROUP, "name");
14560
+ return name === null ? 1 : guard(async () => {
14561
+ let cfg = apiConfig();
14562
+ if (tell(RESULT_MESSAGES.GROUP_DELETE_PREVIEW(name)), !await confirmOrAbort(args, prompter)) return 1;
14563
+ let res = await deleteGroup(cfg, name);
14564
+ return emit(res), sayOk(MESSAGES.GROUP_DELETED(res.deleted)), 0;
14565
+ });
14566
+ }
14567
+ var init_group = __esm({ "src/commands/group.ts"() {
14568
+ "use strict";
14569
+ init_define_IGNITIFY_CLIENT_FILES();
14570
+ init_api();
14571
+ init_prompt();
14572
+ init_constants();
14573
+ init_access();
14574
+ init_utils();
14575
+ init_output();
14576
+ init_shared();
14577
+ } });
14578
+ function keyFileDocument(created, out2) {
14579
+ let { raw_key: _raw, ...rest } = created;
14580
+ return { ...rest, out: out2 };
14581
+ }
14582
+ function openOutFile(out2) {
14583
+ try {
14584
+ return { fd: createPrivateFile(out2), path: out2 };
14585
+ } catch (e) {
14586
+ return fail(errCode(e) === "EEXIST" ? MESSAGES.KEY_OUT_EXISTS(out2) : MESSAGES.KEY_OUT_FAILED(out2, errText(e))), null;
14587
+ }
14588
+ }
14589
+ async function runKeyCreate(args) {
14590
+ let rawUser = strOpt(args, "user");
14591
+ if (rawUser === void 0 || rawUser === "") return fail(MESSAGES.KEY_USER_REQUIRED), 1;
14592
+ let user = accessNameArg(rawUser, ACCESS.USER, "--user");
14593
+ if (user === null) return 1;
14594
+ let label = strOpt(args, "label")?.trim() ?? "";
14595
+ if (label === "") return fail(MESSAGES.KEY_LABEL_REQUIRED), 1;
14596
+ let out2 = strOpt(args, "out");
14597
+ return guard(async () => {
14598
+ let cfg = apiConfig(), file = null;
14599
+ if (out2 !== void 0 && (file = openOutFile(out2), file === null)) return 1;
14600
+ let created;
14601
+ try {
14602
+ created = await createKey(cfg, { user, label });
14603
+ } catch (e) {
14604
+ throw file !== null && discardPrivateFile(file.fd, file.path), e;
14605
+ }
14606
+ if (created.raw_key === null) return file !== null && discardPrivateFile(file.fd, file.path), fail(MESSAGES.KEY_REDACTED(created.resource_id)), 1;
14607
+ if (file !== null) {
14608
+ try {
14609
+ fillPrivateFile(file.fd, file.path, `${created.raw_key}
14610
+ `);
14611
+ } catch (e) {
14612
+ return fail(MESSAGES.KEY_OUT_WRITE_FAILED(file.path, errText(e), created.resource_id)), 1;
14613
+ }
14614
+ return emit(keyFileDocument(created, file.path)), sayOk(MESSAGES.KEY_WRITTEN(created.resource_id, file.path)), 0;
14615
+ }
14616
+ return warn(MESSAGES.KEY_SHOWN_ONCE), emit(created, (st) => renderKeyCreated(st, created)), 0;
14617
+ });
14618
+ }
14619
+ async function runKeyList(args) {
14620
+ let rawUser = strOpt(args, "user"), user = rawUser === void 0 ? void 0 : accessNameArg(rawUser, ACCESS.USER, "--user");
14621
+ return user === null ? 1 : guard(async () => {
14622
+ let data = await listKeys(apiConfig(), user);
14623
+ return emit(data, (st) => renderKeys(st, data.keys)), 0;
14624
+ });
14625
+ }
14626
+ async function runKeyRevoke(args, prompter = ttyPrompter) {
14627
+ let id = requireArg(args, "key-resource-id");
14628
+ return id ? guard(async () => {
14629
+ let cfg = apiConfig();
14630
+ if (tell(RESULT_MESSAGES.KEY_REVOKE_PREVIEW(id)), !await confirmOrAbort(args, prompter)) return 1;
14631
+ let res = await deleteKey(cfg, id);
14632
+ return emit(res), sayOk(MESSAGES.KEY_REVOKED(res.revoked)), 0;
14633
+ }) : 1;
14634
+ }
14635
+ var init_key = __esm({ "src/commands/key.ts"() {
14636
+ "use strict";
14637
+ init_define_IGNITIFY_CLIENT_FILES();
14638
+ init_tenant();
14639
+ init_api();
14640
+ init_credentials();
14641
+ init_prompt();
14642
+ init_constants();
14643
+ init_utils();
14644
+ init_output();
14645
+ init_shared();
14646
+ } });
13864
14647
  var init_commands = __esm({ "src/commands/index.ts"() {
13865
14648
  "use strict";
13866
14649
  init_define_IGNITIFY_CLIENT_FILES();
@@ -13874,7 +14657,12 @@ var init_commands = __esm({ "src/commands/index.ts"() {
13874
14657
  init_secret();
13875
14658
  init_schedule();
13876
14659
  init_integration();
14660
+ init_notification();
13877
14661
  init_hook();
14662
+ init_permission();
14663
+ init_user();
14664
+ init_group();
14665
+ init_key();
13878
14666
  init_decide_vm_delete();
13879
14667
  } });
13880
14668
  function metaFor(command) {
@@ -13884,7 +14672,7 @@ function allowedFlags(meta) {
13884
14672
  return { ...meta.flags, ...GLOBAL_FLAGS };
13885
14673
  }
13886
14674
  function parserSpec(meta) {
13887
- return boolFlagSpec(meta === void 0 || meta.secretArgv === true ? GLOBAL_FLAGS : { ...meta.flags, ...GLOBAL_FLAGS });
14675
+ return boolFlagSpec(meta === void 0 || meta.secretArgv === true ? GLOBAL_FLAGS : allowedFlags(meta));
13888
14676
  }
13889
14677
  function parseInvocation(argv) {
13890
14678
  return parseArgs([...argv], parserSpec(metaFor(argv[0] ?? "")));
@@ -13906,7 +14694,7 @@ function checkInvocation(command, meta, pass) {
13906
14694
  for (let key of Object.keys(args.options)) {
13907
14695
  if (Object.hasOwn(flags, key)) continue;
13908
14696
  let short = typed[key];
13909
- return short !== void 0 ? MESSAGES.UNKNOWN_SHORT_FLAG(short, key, command) : unknownFlagRefusal(key, command, Object.keys(meta.flags), Object.keys(GLOBAL_FLAGS), HIDDEN_FLAGS);
14697
+ return short !== void 0 ? MESSAGES.UNKNOWN_SHORT_FLAG(short, key, command) : unknownFlagRefusal(key, command, Object.keys(meta.flags), Object.keys(GLOBAL_FLAGS));
13910
14698
  }
13911
14699
  let badShort = pass.unknown[0];
13912
14700
  return badShort !== void 0 ? unknownFlagText(badShort, command) : meta.secretArgv === true ? null : shapeRefusal(command, args, flags, meta.positionals);
@@ -13944,7 +14732,7 @@ async function dispatch(plan) {
13944
14732
  case "unknown":
13945
14733
  return fail(`${MESSAGES.UNKNOWN_COMMAND}: ${plan.command}`, { hint: MESSAGES.SEE_HELP }), 1;
13946
14734
  case "version":
13947
- return runVersion(plan.args);
14735
+ return runVersion();
13948
14736
  case "run":
13949
14737
  return route(plan.command, plan.args);
13950
14738
  }
@@ -13975,6 +14763,8 @@ function route(command, args) {
13975
14763
  return runUsageShow(args);
13976
14764
  case COMMANDS.USAGE_EXPORT:
13977
14765
  return runUsageExport(args);
14766
+ case COMMANDS.USAGE_SERIES:
14767
+ return runUsageSeries(args);
13978
14768
  case COMMANDS.TASK_CREATE:
13979
14769
  return runTaskCreate(args);
13980
14770
  case COMMANDS.TASK_LIST:
@@ -13995,6 +14785,10 @@ function route(command, args) {
13995
14785
  return runRunGet(args);
13996
14786
  case COMMANDS.RUN_LOGS:
13997
14787
  return runRunLogs(args);
14788
+ case COMMANDS.RUN_TIMELINE:
14789
+ return runRunTimeline(args);
14790
+ case COMMANDS.RUN_FAILURES:
14791
+ return runRunFailures(args);
13998
14792
  case COMMANDS.RUN_DELETE:
13999
14793
  return runRunDelete(args);
14000
14794
  case COMMANDS.RUN_CANCEL:
@@ -14025,6 +14819,40 @@ function route(command, args) {
14025
14819
  return runNotifySet(args);
14026
14820
  case COMMANDS.INTEGRATION_ADD:
14027
14821
  return runIntegrationAdd(args);
14822
+ case COMMANDS.NOTIFICATION_LIST:
14823
+ return runNotificationList(args);
14824
+ case COMMANDS.PERMISSION_LIST:
14825
+ return runPermissionList(args);
14826
+ case COMMANDS.USER_CREATE:
14827
+ return runUserCreate(args);
14828
+ case COMMANDS.USER_LIST:
14829
+ return runUserList(args);
14830
+ case COMMANDS.USER_GET:
14831
+ return runUserGet(args);
14832
+ case COMMANDS.USER_REMOVE:
14833
+ return runUserRemove(args);
14834
+ case COMMANDS.GROUP_CREATE:
14835
+ return runGroupCreate(args);
14836
+ case COMMANDS.GROUP_LIST:
14837
+ return runGroupList(args);
14838
+ case COMMANDS.GROUP_GET:
14839
+ return runGroupGet(args);
14840
+ case COMMANDS.GROUP_GRANT:
14841
+ return runGroupGrant(args);
14842
+ case COMMANDS.GROUP_REVOKE:
14843
+ return runGroupRevoke(args);
14844
+ case COMMANDS.GROUP_ADD_USER:
14845
+ return runGroupAddUser(args);
14846
+ case COMMANDS.GROUP_REMOVE_USER:
14847
+ return runGroupRemoveUser(args);
14848
+ case COMMANDS.GROUP_DELETE:
14849
+ return runGroupDelete(args);
14850
+ case COMMANDS.KEY_CREATE:
14851
+ return runKeyCreate(args);
14852
+ case COMMANDS.KEY_LIST:
14853
+ return runKeyList(args);
14854
+ case COMMANDS.KEY_REVOKE:
14855
+ return runKeyRevoke(args);
14028
14856
  }
14029
14857
  }
14030
14858
  async function main(argv) {