openlimiter 1.2.0 → 1.3.2

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.
Files changed (55) hide show
  1. package/README.md +45 -16
  2. package/dist/bin.js +53 -4
  3. package/dist/bin.js.map +1 -1
  4. package/dist/cli.d.ts +110 -11
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +1064 -64
  7. package/dist/cli.js.map +1 -1
  8. package/dist/codex-device-login.d.ts +87 -0
  9. package/dist/codex-device-login.d.ts.map +1 -0
  10. package/dist/codex-device-login.js +291 -0
  11. package/dist/codex-device-login.js.map +1 -0
  12. package/dist/config.d.ts +44 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +129 -7
  15. package/dist/config.js.map +1 -1
  16. package/dist/hub-auth.d.ts +137 -0
  17. package/dist/hub-auth.d.ts.map +1 -0
  18. package/dist/hub-auth.js +280 -0
  19. package/dist/hub-auth.js.map +1 -0
  20. package/dist/hub-sync.d.ts +144 -0
  21. package/dist/hub-sync.d.ts.map +1 -0
  22. package/dist/hub-sync.js +370 -0
  23. package/dist/hub-sync.js.map +1 -0
  24. package/dist/hub.d.ts +60 -0
  25. package/dist/hub.d.ts.map +1 -0
  26. package/dist/hub.js +178 -0
  27. package/dist/hub.js.map +1 -0
  28. package/dist/index.d.ts +6 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6 -2
  31. package/dist/index.js.map +1 -1
  32. package/dist/ingest.d.ts +26 -0
  33. package/dist/ingest.d.ts.map +1 -1
  34. package/dist/ingest.js +116 -1
  35. package/dist/ingest.js.map +1 -1
  36. package/dist/qr.d.ts.map +1 -1
  37. package/dist/qr.js +1 -0
  38. package/dist/qr.js.map +1 -1
  39. package/dist/session.d.ts +46 -0
  40. package/dist/session.d.ts.map +1 -0
  41. package/dist/session.js +158 -0
  42. package/dist/session.js.map +1 -0
  43. package/dist/statusline.d.ts +14 -0
  44. package/dist/statusline.d.ts.map +1 -1
  45. package/dist/statusline.js +258 -19
  46. package/dist/statusline.js.map +1 -1
  47. package/dist/terminal.d.ts +109 -0
  48. package/dist/terminal.d.ts.map +1 -0
  49. package/dist/terminal.js +974 -0
  50. package/dist/terminal.js.map +1 -0
  51. package/package.json +4 -4
  52. package/dist/serve.d.ts +0 -170
  53. package/dist/serve.d.ts.map +0 -1
  54. package/dist/serve.js +0 -533
  55. package/dist/serve.js.map +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `openlimiter`
2
2
 
3
- A local command line meter for AI quota, usage, and reset times.
3
+ A local terminal quota meter for AI coding subscriptions: bars in your terminal, an account free of charge, and an account that syncs the same bars to the hub and your phone.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,13 +8,37 @@ A local command line meter for AI quota, usage, and reset times.
8
8
  npm install --global openlimiter
9
9
  ```
10
10
 
11
- ## First command
11
+ ## First run
12
12
 
13
13
  ```bash
14
- openlimiter demo
14
+ npx openlimiter
15
15
  ```
16
16
 
17
- The demo uses synthetic data and does not read a provider account.
17
+ With nothing after it, or once installed, `openlimiter` on its own walks the same three steps every time: sign in (skippable), connect the agent CLIs already on this machine, then show bars in. It prints the bars once at the end.
18
+
19
+ ## Terminal bars
20
+
21
+ Claude Code, Grok Build and the Antigravity CLI draw bars through their own status line. Codex draws its own built in items instead. Gemini CLI, OpenCode, Kimi and any other terminal read a shell prompt segment.
22
+
23
+ ```bash
24
+ openlimiter terminal
25
+ openlimiter terminal install claude
26
+ openlimiter terminal status
27
+ openlimiter terminal uninstall claude
28
+ openlimiter terminal show codex
29
+ openlimiter terminal hide codex
30
+ ```
31
+
32
+ ## Account and sync
33
+
34
+ ```bash
35
+ openlimiter login # device code sign in, approved at openlimiter.com/app/cli
36
+ openlimiter whoami
37
+ openlimiter sync # uploads one round of cached bars to the hub
38
+ openlimiter logout
39
+ ```
40
+
41
+ Bars never require this. An account only syncs the current percentage on every window between your devices.
18
42
 
19
43
  ## Agent context hooks
20
44
 
@@ -27,25 +51,30 @@ openlimiter hooks status codex
27
51
  openlimiter hooks repair codex
28
52
  ```
29
53
 
30
- Installation preserves unrelated agent configuration, writes a recoverable backup, performs no network request, and refuses a version below the tested minimum or an unsafe configuration path. A newer version remains enabled and `hooks status` prints one warning line. Hook execution reads only the short lived local snapshot and the protected desktop trust bridge, then fails open with no context on any invalid or missing input.
54
+ Installation preserves unrelated agent configuration, writes a recoverable backup, performs no network request, and refuses a version below the tested minimum or an unsafe configuration path. Hook execution reads only the short lived local snapshot and the protected desktop trust bridge, then fails open with no context on any invalid or missing input.
31
55
 
32
56
  Antigravity CLI injection is excluded because `agy 1.1.23` did not fire the IDE hook shapes in a real prompt fixture. Kimi Code CLI installation stays gated because `1.50.0` fired `UserPromptSubmit` but discarded successful hook stdout instead of adding it to model context.
33
57
 
34
- Grok Build does not currently expose a documented dynamic context surface. Its `UserPromptSubmit` hook discards successful stdout, so OpenLimiter does not install a Grok hook or claim injection support. Use the explicit command instead:
58
+ Grok Build does not currently expose a documented dynamic context surface. Use the explicit command instead:
35
59
 
36
60
  ```bash
37
61
  openlimiter status --agent-context
38
62
  ```
39
63
 
40
- ## Provider inputs
41
-
42
- | Provider | How data reaches OpenLimiter |
43
- |---|---|
44
- | Claude | Claude Code sends its native statusline JSON to standard input |
45
- | OpenRouter | You supply an explicit API response with `openlimiter ingest --provider openrouter` |
46
- | Codex | You supply an explicit payload with `openlimiter ingest --provider codex` |
47
- | Antigravity | You supply an explicit payload with `openlimiter ingest --provider antigravity` |
48
- | OpenCode | You supply an explicit payload with `openlimiter ingest --provider opencode` |
49
- | Manual | You create `manual.json` in the OpenLimiter state directory or use `openlimiter ingest --provider manual` |
64
+ ## How each provider connects
65
+
66
+ | Provider | Connects by | Reads |
67
+ |---|---|---|
68
+ | Claude | Nothing to do | The Claude Code status line automatically; an opt in poll of Anthropic's usage endpoint (`providers.claude.poll`) covers the gap when Claude Code is closed |
69
+ | Codex | Use the login already there, or sign in from inside OpenLimiter | The login the Codex CLI stored |
70
+ | Gemini CLI | Read only, from the login already there | The login the Gemini CLI stored |
71
+ | Antigravity | Read only, from the credential already there | The credential the Antigravity CLI stored |
72
+ | Grok | Use the login already there | The login the Grok CLI stored |
73
+ | Kimi | Use the login already there | The usage response the Kimi CLI defines |
74
+ | OpenRouter | Real OAuth from the hub, or your own key | OpenRouter's documented key and usage report |
75
+ | OpenCode | Import only | `openlimiter ingest --provider opencode` |
76
+ | Manual | You write the numbers | `manual.json` in the OpenLimiter state directory, or `openlimiter ingest --provider manual` |
77
+
78
+ `openlimiter refresh` is what reaches the network, at most once every fifteen minutes per provider: it reads the logins your provider tools already stored and asks each provider for its own usage. It stands down while the desktop app is running, and `statusline`, `snapshot` and `setup` all start it in the background on their own. OpenLimiter never asks for a vendor password, never impersonates a vendor tool, and never uploads a token.
50
79
 
51
80
  Read the [documentation](https://openlimiter.com/docs) or browse the [repository](https://github.com/lucaswebsystems/openlimiter).
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createInterface } from "node:readline/promises";
3
3
  import { HOOK_INPUT_MAX_BYTES } from "@openlimiter/adapters";
4
- import { runCli } from "./cli.js";
4
+ import { runCli, runtimeDependencies } from "./cli.js";
5
5
  import { readStandardInputBuffer, readStandardInputText } from "./ingest.js";
6
6
  import { decodeWrappedStatuslineCommand, runStatuslineWrapper } from "./statusline-wrapper.js";
7
7
  async function promptForSecret() {
@@ -18,10 +18,36 @@ async function promptForSecret() {
18
18
  interfaceHandle.close();
19
19
  }
20
20
  }
21
+ async function promptChoice(question) {
22
+ if (!process.stdin.isTTY || !process.stdout.isTTY)
23
+ return "";
24
+ const interfaceHandle = createInterface({
25
+ input: process.stdin,
26
+ output: process.stdout
27
+ });
28
+ try {
29
+ return await interfaceHandle.question(question);
30
+ }
31
+ finally {
32
+ interfaceHandle.close();
33
+ }
34
+ }
35
+ /**
36
+ * Everything that reaches the world, built once and used by BOTH entry paths.
37
+ *
38
+ * The wrapped status line is the configuration most people end up with, because
39
+ * it is what the installer writes for anyone who already had a status line of
40
+ * their own. It used to call the command line tool with only a standard input
41
+ * reader, so it rendered bars from the cache and never started the refresh that
42
+ * keeps them true: the one path that most needed acquisition was the one path
43
+ * that had none.
44
+ */
45
+ const runtime = runtimeDependencies();
21
46
  const argumentsList = process.argv.slice(2);
22
- const wrapperRequested = argumentsList[0] === "statusline" && argumentsList[1] === "--wrap";
47
+ const wrapIndex = argumentsList.indexOf("--wrap");
48
+ const wrapperRequested = argumentsList[0] === "statusline" && wrapIndex !== -1;
23
49
  const wrapped = wrapperRequested
24
- ? decodeWrappedStatuslineCommand(argumentsList[2] ?? "")
50
+ ? decodeWrappedStatuslineCommand(argumentsList[wrapIndex + 1] ?? "")
25
51
  : null;
26
52
  if (wrapperRequested && wrapped === null) {
27
53
  /* A damaged wrapper command must fail invisibly, never fall through to the
@@ -29,10 +55,15 @@ if (wrapperRequested && wrapped === null) {
29
55
  process.exitCode = 0;
30
56
  }
31
57
  else if (wrapped !== null) {
58
+ const hostIndex = argumentsList.indexOf("--host");
59
+ const hostArgs = hostIndex !== -1 && argumentsList[hostIndex + 1]
60
+ ? ["--host", argumentsList[hostIndex + 1]]
61
+ : [];
32
62
  const payload = await readStandardInputBuffer();
33
63
  const result = await runStatuslineWrapper(payload, wrapped, {
34
64
  ingest: async (buffer) => {
35
- await runCli(["statusline"], {
65
+ await runCli(["statusline", ...hostArgs], {
66
+ ...runtime,
36
67
  readStandardInput: async () => buffer.toString("utf8")
37
68
  });
38
69
  }
@@ -44,12 +75,30 @@ else if (wrapped !== null) {
44
75
  process.exitCode = result.exitCode;
45
76
  }
46
77
  else {
78
+ /*
79
+ * Ctrl C is wired to an abort signal only for the commands that poll for
80
+ * somebody else's action: signing in, and the first run wizard's sign in
81
+ * step. Every other command keeps Node's ordinary SIGINT behaviour, which
82
+ * this listener would otherwise silently replace by existing at all.
83
+ */
84
+ const pollsForApproval = argumentsList[0] === "login" ||
85
+ argumentsList[0] === "setup" ||
86
+ argumentsList.length === 0;
87
+ const controller = pollsForApproval ? new AbortController() : null;
88
+ const onInterrupt = () => controller?.abort();
89
+ if (controller !== null)
90
+ process.on("SIGINT", onInterrupt);
47
91
  const result = await runCli(argumentsList, {
92
+ ...runtime,
48
93
  promptForSecret,
94
+ promptChoice,
95
+ ...(controller === null ? {} : { interruptSignal: controller.signal }),
49
96
  readStandardInput: (signal) => argumentsList[0] === "hook"
50
97
  ? readStandardInputText(process.stdin, HOOK_INPUT_MAX_BYTES, undefined, signal)
51
98
  : readStandardInputText()
52
99
  });
100
+ if (controller !== null)
101
+ process.off("SIGINT", onInterrupt);
53
102
  if (result.stdout !== "")
54
103
  process.stdout.write(result.stdout + "\n");
55
104
  if (result.stderr !== "")
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { type ProviderFailure, type Snapshot } from "@openlimiter/core";
1
+ import { type AntigravityProbeOptions, type AntigravityProbeResult, type AcquisitionSpec, type AcquisitionTransport, type CredentialCommandRunner, type DetachedSpawn, type ProviderFailure, type Snapshot } from "@openlimiter/core";
2
2
  import { type AgentId, type AgentInstallation, type HostedContextTrust, type HostedTrustLoadOptions } from "@openlimiter/adapters";
3
+ import { type ProvidersConfig } from "./config.js";
3
4
  import { type CredentialStore } from "./credentials.js";
4
- import { type QuotaServerHandle } from "./serve.js";
5
+ import { type HubTransport } from "./hub.js";
6
+ import { type DeviceLoginRunner } from "./codex-device-login.js";
5
7
  export interface CliDependencies {
6
8
  environment: Readonly<Record<string, string | undefined>>;
7
9
  stateDirectory?: string;
@@ -20,11 +22,9 @@ export interface CliDependencies {
20
22
  /**
21
23
  * Whether output may carry terminal colour.
22
24
  *
23
- * Two surfaces depend on it. The QR symbol the serve command prints has to
24
- * state its own black and white, because a dark themed terminal would
25
- * otherwise invert it and no camera would read it. The meter bars and the
26
- * failure lines use it to choose between escape codes and plain ASCII, so a
27
- * capture redirected into a file carries no control characters at all.
25
+ * The meter bars and the failure lines use it to choose between escape
26
+ * codes and plain ASCII, so a capture redirected into a file carries no
27
+ * control characters at all.
28
28
  */
29
29
  colorOutput: boolean;
30
30
  homeDirectory: string;
@@ -44,12 +44,92 @@ export interface CliDependencies {
44
44
  */
45
45
  hostedTrustWindowsSecurity?: HostedTrustLoadOptions["windowsSecurity"];
46
46
  /**
47
- * Called once the serve command is listening.
47
+ * How acquisition requests leave this machine.
48
48
  *
49
- * The serve command never returns on its own, so this is the seam a test or
50
- * a parent process uses to reach the handle and close it again.
49
+ * Injected everywhere, so a test proves the whole path against recorded
50
+ * responses and never opens a socket. The library default is the runtime's
51
+ * own fetch behind the closed endpoint table in the core package.
51
52
  */
52
- onListening?: (handle: QuotaServerHandle) => void;
53
+ acquisitionTransport: AcquisitionTransport;
54
+ /**
55
+ * How a refresh is started behind a render.
56
+ *
57
+ * The child outlives this process on purpose: a status line has to return in
58
+ * milliseconds and a round of provider requests does not fit in that.
59
+ */
60
+ spawnDetached: DetachedSpawn;
61
+ /**
62
+ * How the Windows Credential Manager is asked for one entry.
63
+ *
64
+ * Only Antigravity needs it, and only on Windows. Absent means the file
65
+ * fallback is the only path, which is what every other platform uses.
66
+ */
67
+ windowsCredentialRunner?: CredentialCommandRunner;
68
+ /**
69
+ * Probe running Antigravity instances on loopback ports.
70
+ *
71
+ * Reaches nothing by default in tests. The real executable injects the real
72
+ * loopback probe.
73
+ */
74
+ probeAntigravity?: (options?: AntigravityProbeOptions) => Promise<AntigravityProbeResult>;
75
+ /**
76
+ * Turn a pid the Antigravity probe found listening into the executable path
77
+ * it checks against the trusted install roots.
78
+ *
79
+ * Reaches nothing by default in tests, exactly like `probeAntigravity`
80
+ * above: an unresolved pid is a pid the probe skips, never one it trusts on
81
+ * a bare process name. The real executable injects `resolveAgyExecutablePath`.
82
+ */
83
+ resolveExecutablePath?: (pid: string) => Promise<string | null>;
84
+ /**
85
+ * Interactive prompt choice helper.
86
+ */
87
+ promptChoice?: (question: string) => Promise<string>;
88
+ /**
89
+ * How a hub request leaves this machine.
90
+ *
91
+ * Injected everywhere, exactly like `acquisitionTransport`, so a test proves
92
+ * the whole sign in and sync path against recorded responses and never opens
93
+ * a socket. The library default throws, and the real executable injects the
94
+ * runtime's own fetch behind the closed endpoint table in `hub.ts`.
95
+ */
96
+ hubTransport: HubTransport;
97
+ /**
98
+ * Open a URL in the person's browser. Used only when `--open` is passed to
99
+ * `login`, since the code and address are always printed either way.
100
+ */
101
+ openBrowser: (url: string) => void;
102
+ /** An injectable delay, so a poll loop never makes a test wait in real time. */
103
+ sleep: (milliseconds: number) => Promise<void>;
104
+ /**
105
+ * Progress a long running command wants seen before it returns.
106
+ *
107
+ * `login`, `sync` and `setup` can run for minutes at a time, and a person
108
+ * watching a blank terminal for three minutes while a device code sits
109
+ * unprinted is the whole flow failing in a way no exit code explains. This
110
+ * is separate from the command's own `CliResult`, which still carries a
111
+ * final one line summary once the command actually finishes.
112
+ */
113
+ emit: (line: string) => void;
114
+ /** Set when Ctrl C should end a poll loop rather than the whole process. */
115
+ interruptSignal?: AbortSignal;
116
+ /**
117
+ * How an owner only ACL is applied to the session file on Windows.
118
+ *
119
+ * Best effort and independent of `windowsCredentialRunner`: this one writes
120
+ * an ACL rather than reading a credential, but the shape of "run this helper
121
+ * with these arguments" is the same, so the two share a type.
122
+ */
123
+ windowsAclRunner?: CredentialCommandRunner;
124
+ /**
125
+ * How the Codex device sign in child process is started, keyed by the
126
+ * executable this machine detected.
127
+ *
128
+ * The library default never spawns anything: it answers every login attempt
129
+ * with a closed `spawn` failure, so a test or another tool that calls
130
+ * `runCli` in process starts no child unless it asked for one.
131
+ */
132
+ codexDeviceLoginRunnerFactory: (executable: string) => DeviceLoginRunner;
53
133
  }
54
134
  export interface CliResult {
55
135
  exitCode: number;
@@ -61,10 +141,29 @@ export declare const EXIT_OK = 0;
61
141
  export declare const EXIT_FAILURE = 1;
62
142
  export declare const EXIT_USAGE = 2;
63
143
  export declare const EXIT_NO_DATA = 3;
144
+ export declare function runtimeDependencies(): Pick<CliDependencies, "acquisitionTransport" | "spawnDetached" | "windowsCredentialRunner" | "probeAntigravity" | "resolveExecutablePath" | "hubTransport" | "openBrowser" | "emit" | "windowsAclRunner" | "codexDeviceLoginRunnerFactory">;
64
145
  export interface RefreshResult {
65
146
  snapshots: Snapshot[];
66
147
  /** Only genuine failures. A connector offered nothing is not one. */
67
148
  failures: readonly ProviderFailure[];
68
149
  }
150
+ /**
151
+ * How a terminal with no desktop app gets fresh bars.
152
+ *
153
+ * Everything below is wiring, and only wiring. Credential discovery, the closed
154
+ * endpoint table, the cadence, the backoff and the lock all live in the core
155
+ * package, and the parsers all live in the connector package; this is the one
156
+ * place that knows both exist. That separation is why a test can prove a whole
157
+ * round without a socket and without a real login.
158
+ */
159
+ /**
160
+ * The specifications this machine will run, wired to the real parsers.
161
+ *
162
+ * Claude is here whatever the switch says, because a row that is off still owes
163
+ * a person the sentence explaining why its bar is older than the rest. Every
164
+ * other provider is unconditional: a provider with no local login simply
165
+ * reports that it has none.
166
+ */
167
+ export declare function acquisitionSpecs(providers: ProvidersConfig): AcquisitionSpec[];
69
168
  export declare function runCli(argumentsList: readonly string[], overrides?: Partial<CliDependencies>): Promise<CliResult>;
70
169
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAcL,KAAK,eAAe,EAEpB,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAC;AAoB3B,OAAO,EAWL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAG5B,MAAM,uBAAuB,CAAC;AA0B/B,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAYpB,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5C;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACpE;;;;;;;;OAQG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,0BAA0B,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACzF,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,uBAAuB,CAAC,EAAE,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;IACrE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,0BAA0B,CAAC,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IACvE;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qEAAqE;AACrE,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,YAAY,IAAI,CAAC;AA2E9B,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,qEAAqE;IACrE,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;CACtC;AAoxBD,wBAAsB,MAAM,CAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GACvC,OAAO,CAAC,SAAS,CAAC,CAiDpB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}