@dashai/cli 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Status
8
8
 
9
- `0.1.x` — full author workflow + **Query Plane v1 author tooling** + **P7 cross-module-action observability** (shipped 2026-05-20). Commands: `login`, `logout`, `profile`, `workspace`, `module init` (incl. `--custom`) / `connect-git` / `generate` / `dev` / `validate` / `list` / `publish` / `diff` / `pull-data` / `clone` / `query-log` / `action-log`, plus `query` (run AST queries against the local module) and `deps add` / `list` / `remove` / `check`.
9
+ `0.5.x` — full author workflow + **Query Plane v1 author tooling** + **P7 cross-module-action observability** (shipped 2026-05-20) + **BaaS Phase 1 deploy loop** (`api-keys`, `env export`, `--deploy-target`; shipped 2026-05-24). Commands: `login`, `logout`, `profile`, `workspace`, `init` / `module init` (incl. `--custom`, `--deploy-target railway|vercel|fly`) / `connect-git` / `generate` / `dev` / `validate` / `list` / `publish` / `diff` / `pull-data` / `clone` / `query-log` / `action-log`, plus `query` (run AST queries against the local module), `pull` (sync canonical manifest from backend), `api-keys list|create|revoke`, `env export`, and `deps add` / `list` / `remove` / `check`.
10
10
 
11
11
  ## Install
12
12
 
@@ -103,23 +103,25 @@ Flags:
103
103
 
104
104
  Requires `dashwise login` first — the command refuses to start if no token is resolvable. The runtime-token injection requires `dashwise init <slug>` (LDI-6); the dev session SSO setup works without it.
105
105
 
106
- ### `dashwise module init [slug]`
106
+ ### `dashwise init [slug]` / `dashwise module init [slug]`
107
107
 
108
- Scaffold a new DashWise module in a fresh directory. Two flavors:
108
+ Scaffold a new DashWise module in a fresh directory. `dashwise init` is a top-level alias for `dashwise module init` — both accept the same flags. Two flavors:
109
109
 
110
- **Hand-authored** (default) — simple module-runtime app (isolate runtime). 10 files: `module.json`, `package.json`, `tsconfig.json`, `next.config.mjs`, `next-env.d.ts`, `.gitignore`, `.env.local.example`, `app/layout.tsx`, `app/page.tsx`, `README.md`.
110
+ **Custom** (default since 2026-05-18) — full Next.js App Router app with SDK auth wired in (machine runtime, lands on Fly Machines once P7 ships). Files: `module.json`, `package.json`, `tsconfig.json`, `next.config.mjs`, `next-env.d.ts`, `middleware.ts` (uses `@dashai/sdk/auth/middleware`), `app/layout.tsx`, `app/page.tsx`, `app/dashboard/page.tsx` (auth-gated Server Component example), three `app/api/auth/*` route handlers, shadcn primitives + a `globals.css`, plus `CLAUDE.md` / `spec.md` / `agent-log.md` agent-facing docs. `module.json` carries `module_kind: 'custom'` + `runtime.kind: 'machine'`.
111
111
 
112
- **Custom** (`--custom`) — full Next.js App Router app with SDK auth wired in (machine runtime, lands on Fly Machines once P7 ships). Adds 5 files on top of the hand-authored set: `middleware.ts` (uses `@dashai/sdk/auth/middleware`), `app/dashboard/page.tsx` (auth-gated Server Component example), and three `app/api/auth/*` route handlers (`sign-in`, `callback`, `sign-out`). `module.json` carries `module_kind: 'custom'` + `runtime.kind: 'machine'`.
112
+ **Hand-authored** (`--simple`) — the legacy simple module-runtime app (isolate runtime). 10 files total: no middleware, no `/api/auth/*`, no dashboard. Suitable for public viewers / demo modules that don't need SSO.
113
113
 
114
114
  Flags:
115
115
  - `--dir <path>` — Target directory (default `./<slug>`).
116
116
  - `--name <name>` — Human-readable module name (default: derived from slug).
117
117
  - `--force` — Overwrite an existing non-empty directory.
118
- - `--custom` — Use the full Next.js custom-module scaffold.
118
+ - `--simple` — Use the legacy minimal scaffold (hand-authored, no Next.js auth wiring).
119
+ - `--custom` — *[Deprecated alias — kept for back-compat.]* Equivalent to the default. Will be removed in a future major version.
119
120
  - `--git <url>` — Initial Git repository URL. Written to `module.json#repository.url`.
120
121
  - `--description <text>` — Module description forwarded to the backend when provisioning the dev installation (HH-CC-LDI-6). No effect under `--no-provision`.
121
122
  - `--workspace <slug-or-id>` — Target workspace for the dev installation (HH-CC-LDI-6). When omitted in a TTY, the CLI prompts; auto-picked if your account has one workspace; in non-interactive mode with multiple workspaces, errors with the list.
122
123
  - `--no-provision` — Skip the `POST /api/installations/dev` step (HH-CC-LDI-6). Local scaffold is still written, but the module won't have a backing dev installation — `dashwise dev` data-plane calls will fail with `UnauthenticatedError` until you re-run `dashwise init --force` or (once it ships) `dashwise module provision-dev-install`.
124
+ - `--deploy-target railway|vercel|fly` (HH-CC-P1-D2) — Emit a platform deploy config file alongside the scaffold (`railway.json`, `vercel.json`, or `fly.toml`). Default: none (clean repo). Pair with `dashwise env export --format <platform>` to push env vars after provisioning. See [`docs/deploying.md`](../../docs/deploying.md) for the full deploy walkthrough.
123
125
 
124
126
  **Provisioning behavior (HH-CC-LDI-6):** by default, after the local scaffold is written, `dashwise init` provisions a real local-dev installation by calling `POST /api/installations/dev`. The returned runtime token (90-day JWT) is cached in `~/.config/dashwise/auth.json#modules[<slug>]` where `@dashai/sdk`'s `createDevClient({ moduleSlug })` reads it on every dev-server boot. Provisioning failures are surfaced as warnings; the local scaffold remains usable so you can retry later.
125
127
 
@@ -297,6 +299,76 @@ Flags:
297
299
 
298
300
  Pre-reqs: `dashwise module generate` must have run (the SDK reads `node_modules/@dashai/generated`). `DASHWISE_API_URL`, `DASHWISE_INSTALLATION_ID`, `DASHWISE_API_TOKEN` must be set (the scaffold's `.env.local` is loaded automatically).
299
301
 
302
+ ### `dashwise pull` (HH-CC-P1-E2)
303
+
304
+ Fetch the canonical manifest from the backend and write it to local `module.json`. The inverse of `dashwise table create` / `field add` — useful after dashboard-side schema edits, DashAI mutations, or teammate-driven changes.
305
+
306
+ The backend (`GET /api/installations/:id/schema`) is the source of truth; `pull` materializes that locally. `dashwise dev`'s watcher polls this endpoint automatically, so most authors don't need to invoke `pull` manually.
307
+
308
+ ```
309
+ $ dashwise pull
310
+ ℹ Backend at ab12cd34 — local at 9f8e7d6c. Writing module.json…
311
+ ✓ module.json updated (3 tables, 18 fields).
312
+ ```
313
+
314
+ Flags:
315
+ - `--dir <path>` — Project root (default: current directory).
316
+ - `--dry-run` — Print the diff but don't write.
317
+
318
+ ### `dashwise api-keys list|create|revoke` (HH-CC-P1-C4)
319
+
320
+ Mint long-lived production credentials for a `production` install. Used by self-hosted deploys (Railway / Vercel / Fly / your own infra) instead of the per-CLI-session runtime token. The key format is `dwk_<43-char-base64url>`; the backend stores only a `sha256` hash so the plaintext is shown exactly once at `create`.
321
+
322
+ ```sh
323
+ # Mint a key. Plaintext appears on stdout — copy it now.
324
+ dashwise api-keys create production
325
+
326
+ # Script-friendly: capture the raw key with no other chatter.
327
+ KEY=$(dashwise api-keys create ci --raw-only)
328
+
329
+ # List all keys for the current install.
330
+ dashwise api-keys list
331
+
332
+ # Revoke. Irreversible. Effective on the next request.
333
+ dashwise api-keys revoke <key-id>
334
+ ```
335
+
336
+ The install is resolved from the cached entry in `~/.config/dashwise/auth.json#modules[<slug>]` (keyed by `module.json#module.slug`). Run from inside the module directory, or pass `--dir <path>`.
337
+
338
+ Pairs with `dashwise env export --key dwk_...` to push the key into a deploy platform without ever copy-pasting it through a shell history.
339
+
340
+ ### `dashwise env export` (HH-CC-P1-D1)
341
+
342
+ Emit the four env vars every self-hosted deploy needs:
343
+
344
+ | Var | Source |
345
+ |---|---|
346
+ | `DASHWISE_API_URL` | CLI config (`apiUrl`). |
347
+ | `NEXT_PUBLIC_DASHWISE_API_URL` | Same. |
348
+ | `DASHWISE_INSTALLATION_ID` | `~/.config/dashwise/auth.json#modules[<slug>].installationId` (the dev install cached at `dashwise init`). |
349
+ | `DASHWISE_API_KEY` | Placeholder by default; pass `--key dwk_...` to inline an existing key, or `--new-key <name>` to mint one in-flight. |
350
+
351
+ Five output formats — `env`, `json`, `railway`, `vercel`, `fly`. The platform-specific ones wrap each var in the matching CLI invocation (`railway variables set …`, `vercel env add …`, `fly secrets set …`) so the output is directly pipeable into `sh`.
352
+
353
+ ```sh
354
+ # .env syntax — copy/paste into a host that reads .env files.
355
+ dashwise env export --format env > .env.production
356
+
357
+ # Push straight into Railway.
358
+ dashwise env export --key dwk_... --format railway | sh
359
+
360
+ # Mint and inline a new key in one step.
361
+ dashwise env export --new-key prod --format vercel | sh
362
+ ```
363
+
364
+ Stdout carries only the env block (clean for piping); status chatter goes to stderr.
365
+
366
+ Flags:
367
+ - `--format env|json|railway|vercel|fly` — Output format. Default: `env`.
368
+ - `--key dwk_<...>` — Inline an existing API key.
369
+ - `--new-key <name>` — Mint a new API key and inline its plaintext.
370
+ - `--dir <path>` — Project root.
371
+
300
372
  ### `dashwise module query-log`
301
373
 
302
374
  Read the per-module SDK query log (each cross-module / `.execute()` / `.stream()` / `.explain()` dispatch writes a row to `module_query_log` server-side). Workspace-member-scoped on the backend.
package/dist/bin.js CHANGED
@@ -4,7 +4,7 @@ import { tmpdir, platform, homedir } from 'os';
4
4
  import { resolve, join, dirname, relative } from 'path';
5
5
  import pc from 'picocolors';
6
6
  import { intro, log, select, isCancel, cancel, spinner, outro, text, multiselect, confirm } from '@clack/prompts';
7
- import { Command } from 'commander';
7
+ import { Command, Option } from 'commander';
8
8
  import { spawn, spawnSync } from 'child_process';
9
9
  import open from 'open';
10
10
  import * as tar from 'tar';
@@ -394,6 +394,9 @@ var init_output = __esm({
394
394
  });
395
395
 
396
396
  // src/lib/scaffold.ts
397
+ function isDeployTarget(value) {
398
+ return DEPLOY_TARGETS.includes(value);
399
+ }
397
400
  function manifestJson(opts) {
398
401
  const kind = opts.kind ?? "hand_authored";
399
402
  const manifest = {
@@ -1017,6 +1020,7 @@ function appApiAuthSignInTs() {
1017
1020
  // the DashWise FE \`/login?return_to=...\` automatically \u2014 you don't
1018
1021
  // need to handle the "user not logged in" case here.
1019
1022
  import { NextResponse } from 'next/server';
1023
+ import { getPublicOrigin } from '@/lib/request-origin';
1020
1024
 
1021
1025
  export function GET(request: Request) {
1022
1026
  const url = new URL(request.url);
@@ -1042,8 +1046,10 @@ export function GET(request: Request) {
1042
1046
 
1043
1047
  // Absolute URL for return_to so the backend knows which host to
1044
1048
  // bounce back to (the callback path is fixed at /api/auth/callback
1045
- // by SDK convention).
1046
- const moduleOrigin = url.origin;
1049
+ // by SDK convention). \`getPublicOrigin\` reads \`X-Forwarded-Host\`
1050
+ // when present so the redirect URL points at the public domain,
1051
+ // not the internal Node origin behind reverse proxies.
1052
+ const moduleOrigin = getPublicOrigin(request);
1047
1053
  const absoluteReturnTo = \`\${moduleOrigin}\${returnTo}\`;
1048
1054
 
1049
1055
  let ssoStart;
@@ -1077,12 +1083,17 @@ function appApiAuthCallbackTs() {
1077
1083
  // (e.g. \`access_denied\`, \`server_error\`, \`invalid_request\`).
1078
1084
  import { NextResponse } from 'next/server';
1079
1085
  import { exchangeCode } from '@dashai/sdk/auth/server';
1086
+ import { getPublicOrigin } from '@/lib/request-origin';
1080
1087
 
1081
1088
  export async function GET(request: Request) {
1082
1089
  const url = new URL(request.url);
1090
+ // Resolve the public origin once \u2014 all redirects below are
1091
+ // back to this module, and behind a reverse proxy url.origin is
1092
+ // the internal Node origin (localhost:<PORT>), not the public host.
1093
+ const publicOrigin = getPublicOrigin(request);
1083
1094
  const error = url.searchParams.get('error');
1084
1095
  if (error) {
1085
- const target = new URL('/sign-in-error', url.origin);
1096
+ const target = new URL('/sign-in-error', publicOrigin);
1086
1097
  target.searchParams.set('code', error);
1087
1098
  const description = url.searchParams.get('error_description');
1088
1099
  if (description) target.searchParams.set('description', description);
@@ -1091,19 +1102,19 @@ export async function GET(request: Request) {
1091
1102
  const code = url.searchParams.get('code');
1092
1103
  const returnTo = url.searchParams.get('return_to') ?? '/';
1093
1104
  if (!code) {
1094
- const target = new URL('/sign-in-error', url.origin);
1105
+ const target = new URL('/sign-in-error', publicOrigin);
1095
1106
  target.searchParams.set('code', 'missing_code');
1096
1107
  return NextResponse.redirect(target);
1097
1108
  }
1098
1109
  try {
1099
1110
  await exchangeCode(code); // sets the dashwise.session cookie
1100
1111
  } catch (err) {
1101
- const target = new URL('/sign-in-error', url.origin);
1112
+ const target = new URL('/sign-in-error', publicOrigin);
1102
1113
  target.searchParams.set('code', 'exchange_failed');
1103
1114
  target.searchParams.set('description', (err as Error).message);
1104
1115
  return NextResponse.redirect(target);
1105
1116
  }
1106
- return NextResponse.redirect(new URL(returnTo, url.origin));
1117
+ return NextResponse.redirect(new URL(returnTo, publicOrigin));
1107
1118
  }
1108
1119
  `;
1109
1120
  }
@@ -1116,10 +1127,14 @@ function appApiAuthSignOutTs() {
1116
1127
  // to follow with GET (not re-POST), landing on the public '/' page.
1117
1128
  import { NextResponse } from 'next/server';
1118
1129
  import { signOut } from '@dashai/sdk/auth/server';
1130
+ import { getPublicOrigin } from '@/lib/request-origin';
1119
1131
 
1120
1132
  export async function POST(request: Request) {
1121
1133
  await signOut();
1122
- return NextResponse.redirect(new URL('/', request.url), 303);
1134
+ // Build the redirect against the public origin so we don't land
1135
+ // the user on \`http://localhost:<PORT>/\` when running behind a
1136
+ // reverse proxy (Railway/Vercel/Fly).
1137
+ return NextResponse.redirect(new URL('/', getPublicOrigin(request)), 303);
1123
1138
  }
1124
1139
  `;
1125
1140
  }
@@ -1293,6 +1308,36 @@ export function cn(...inputs: ClassValue[]) {
1293
1308
  }
1294
1309
  `;
1295
1310
  }
1311
+ function libRequestOriginTs() {
1312
+ return `/**
1313
+ * Resolve the **public** origin of an incoming request.
1314
+ *
1315
+ * Behind a reverse proxy (Railway, Vercel, Fly, Cloudflare, an
1316
+ * nginx in front of a Node container, etc.) \`new URL(request.url)\`
1317
+ * reports the *internal* origin the Node process is bound to \u2014
1318
+ * usually \`http://localhost:<PORT>\` \u2014 not the public URL the
1319
+ * browser hit. The proxy preserves the public origin in
1320
+ * \`X-Forwarded-*\` headers; we read those first.
1321
+ *
1322
+ * Falls back to \`new URL(request.url).origin\` for local dev where
1323
+ * there's no proxy in front of Next.js.
1324
+ *
1325
+ * Both \`x-forwarded-proto\` and \`x-forwarded-host\` can be
1326
+ * comma-separated when multiple proxies chain; the leftmost entry
1327
+ * is the original client-facing one per RFC 7239 conventions.
1328
+ */
1329
+ export function getPublicOrigin(request: Request): string {
1330
+ const forwardedProto = request.headers.get('x-forwarded-proto');
1331
+ const forwardedHost = request.headers.get('x-forwarded-host');
1332
+ if (forwardedProto && forwardedHost) {
1333
+ const proto = forwardedProto.split(',')[0].trim();
1334
+ const host = forwardedHost.split(',')[0].trim();
1335
+ return \`\${proto}://\${host}\`;
1336
+ }
1337
+ return new URL(request.url).origin;
1338
+ }
1339
+ `;
1340
+ }
1296
1341
  function componentsUiButtonTsx() {
1297
1342
  return `import * as React from "react";
1298
1343
  import { cva, type VariantProps } from "class-variance-authority";
@@ -1750,9 +1795,63 @@ Format (reverse chronological, newest first):
1750
1795
  schema mutation.
1751
1796
  `;
1752
1797
  }
1753
- var SCAFFOLD_DEFAULT_API_URL;
1798
+ function railwayJson(_opts) {
1799
+ return JSON.stringify(
1800
+ {
1801
+ $schema: "https://railway.com/railway.schema.json",
1802
+ build: {
1803
+ builder: "NIXPACKS"
1804
+ },
1805
+ deploy: {
1806
+ restartPolicyType: "ON_FAILURE",
1807
+ restartPolicyMaxRetries: 3
1808
+ }
1809
+ },
1810
+ null,
1811
+ 2
1812
+ ) + "\n";
1813
+ }
1814
+ function vercelJson(_opts) {
1815
+ return JSON.stringify(
1816
+ {
1817
+ $schema: "https://openapi.vercel.sh/vercel.json",
1818
+ framework: "nextjs"
1819
+ },
1820
+ null,
1821
+ 2
1822
+ ) + "\n";
1823
+ }
1824
+ function flyToml(opts) {
1825
+ return `# fly.toml \u2014 generated by \`dashwise init --deploy-target fly\`.
1826
+ # Run \`fly launch --no-deploy --copy-config\` to register this app with
1827
+ # Fly; the launcher will read this file and prompt for anything missing.
1828
+ #
1829
+ # Edit \`app\` if the slug is already taken globally on fly.io.
1830
+ # Edit \`primary_region\` for non-US-East deploys (https://fly.io/docs/reference/regions/).
1831
+
1832
+ app = "${opts.slug}"
1833
+ primary_region = "iad"
1834
+
1835
+ [build]
1836
+
1837
+ [http_service]
1838
+ internal_port = 3000
1839
+ force_https = true
1840
+ auto_stop_machines = "stop"
1841
+ auto_start_machines = true
1842
+ min_machines_running = 0
1843
+ processes = ["app"]
1844
+
1845
+ [[vm]]
1846
+ cpu_kind = "shared"
1847
+ cpus = 1
1848
+ memory_mb = 256
1849
+ `;
1850
+ }
1851
+ var DEPLOY_TARGETS, SCAFFOLD_DEFAULT_API_URL;
1754
1852
  var init_scaffold = __esm({
1755
1853
  "src/lib/scaffold.ts"() {
1854
+ DEPLOY_TARGETS = ["railway", "vercel", "fly"];
1756
1855
  SCAFFOLD_DEFAULT_API_URL = "http://localhost:3000";
1757
1856
  }
1758
1857
  });
@@ -1854,6 +1953,12 @@ async function moduleInitCommand(slugArg, options) {
1854
1953
  );
1855
1954
  return 1;
1856
1955
  }
1956
+ if (options.deployTarget !== void 0 && !isDeployTarget(options.deployTarget)) {
1957
+ fail(
1958
+ `Invalid --deploy-target ${code(options.deployTarget)} \u2014 must be one of ${DEPLOY_TARGETS.map((t) => code(t)).join(", ")}.`
1959
+ );
1960
+ return 1;
1961
+ }
1857
1962
  const kind = options.simple ? "hand_authored" : "custom";
1858
1963
  const scaffoldOpts = {
1859
1964
  slug,
@@ -1886,6 +1991,7 @@ async function moduleInitCommand(slugArg, options) {
1886
1991
  ["postcss.config.mjs", postcssConfigMjs()],
1887
1992
  ["app/globals.css", globalsCss()],
1888
1993
  ["lib/utils.ts", libUtilsTs()],
1994
+ ["lib/request-origin.ts", libRequestOriginTs()],
1889
1995
  ["components/theme-provider.tsx", componentsThemeProviderTsx()],
1890
1996
  ["components/ui/button.tsx", componentsUiButtonTsx()],
1891
1997
  ["components/ui/card.tsx", componentsUiCardTsx()],
@@ -1904,6 +2010,19 @@ async function moduleInitCommand(slugArg, options) {
1904
2010
  ["app/page.tsx", appPageTsx(scaffoldOpts)]
1905
2011
  );
1906
2012
  }
2013
+ if (options.deployTarget !== void 0) {
2014
+ switch (options.deployTarget) {
2015
+ case "railway":
2016
+ files.push(["railway.json", railwayJson()]);
2017
+ break;
2018
+ case "vercel":
2019
+ files.push(["vercel.json", vercelJson()]);
2020
+ break;
2021
+ case "fly":
2022
+ files.push(["fly.toml", flyToml(scaffoldOpts)]);
2023
+ break;
2024
+ }
2025
+ }
1907
2026
  for (const [relPath, content] of files) {
1908
2027
  const absPath = join(dir, relPath);
1909
2028
  const parentDir = join(absPath, "..");
@@ -5243,6 +5362,9 @@ function surfacePullFailure(err) {
5243
5362
  return 1;
5244
5363
  }
5245
5364
 
5365
+ // src/bin.ts
5366
+ init_scaffold();
5367
+
5246
5368
  // src/commands/api-keys.ts
5247
5369
  init_api_client();
5248
5370
  init_config();
@@ -6253,6 +6375,11 @@ var initOptions = (cmd) => cmd.option("--dir <path>", "Override the target direc
6253
6375
  ).option(
6254
6376
  "--no-provision",
6255
6377
  "Skip the `POST /api/installations/dev` step. Local scaffold is still written; you can provision later by re-running `dashwise init --force` (or, once it ships, `dashwise module provision-dev-install`)."
6378
+ ).addOption(
6379
+ new Option(
6380
+ "--deploy-target <platform>",
6381
+ "Emit a platform deploy config file alongside the scaffold (railway.json | vercel.json | fly.toml). Default: none (clean repo). Pair with `dashwise env export --format <platform>` to push env vars after provisioning."
6382
+ ).choices([...DEPLOY_TARGETS])
6256
6383
  );
6257
6384
  var initAction = async (slugArg, cmdOpts) => {
6258
6385
  process.exitCode = await moduleInitCommand(slugArg, {
@@ -6264,7 +6391,8 @@ var initAction = async (slugArg, cmdOpts) => {
6264
6391
  ...cmdOpts.git !== void 0 ? { git: cmdOpts.git } : {},
6265
6392
  ...cmdOpts.description !== void 0 ? { description: cmdOpts.description } : {},
6266
6393
  ...cmdOpts.workspace !== void 0 ? { workspace: cmdOpts.workspace } : {},
6267
- ...cmdOpts.provision !== void 0 ? { provision: cmdOpts.provision } : {}
6394
+ ...cmdOpts.provision !== void 0 ? { provision: cmdOpts.provision } : {},
6395
+ ...cmdOpts.deployTarget !== void 0 ? { deployTarget: cmdOpts.deployTarget } : {}
6268
6396
  });
6269
6397
  };
6270
6398
  initOptions(
@@ -6651,7 +6779,7 @@ fieldCmd.command("set-type <table-slug> <field-slug> <new-type>").description(
6651
6779
  }
6652
6780
  })();
6653
6781
  function getVersion() {
6654
- return "0.5.0";
6782
+ return "0.5.1";
6655
6783
  }
6656
6784
  function parseIntOption(value) {
6657
6785
  const n = Number.parseInt(value, 10);