@wolfstar/cli 2.1.0 → 2.3.0-next-20261004131917

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 (79) hide show
  1. package/README.md +203 -42
  2. package/dist/{_shared-B-hRZDRS.js → _shared-BIQK0Bhm.js} +12 -5
  3. package/dist/_shared-BIQK0Bhm.js.map +1 -0
  4. package/dist/bridge-BvkmlAOZ.js +410 -0
  5. package/dist/bridge-BvkmlAOZ.js.map +1 -0
  6. package/dist/{build-CPnSLYME.js → build-DJcc95Yq.js} +5 -5
  7. package/dist/{build-CPnSLYME.js.map → build-DJcc95Yq.js.map} +1 -1
  8. package/dist/cli.js +1 -1
  9. package/dist/{codegen-BqpLGLLs.js → codegen-aJSyPz-J.js} +4 -4
  10. package/dist/{codegen-BqpLGLLs.js.map → codegen-aJSyPz-J.js.map} +1 -1
  11. package/dist/command-diff-BK912Hjc.js +78 -0
  12. package/dist/command-diff-BK912Hjc.js.map +1 -0
  13. package/dist/commands-CIPWQtF0.js +3 -0
  14. package/dist/commands-Clpbqq3K.js +15 -0
  15. package/dist/commands-Clpbqq3K.js.map +1 -0
  16. package/dist/{commands-ExM8HILu.js → commands-DVC7ky6f.js} +259 -9
  17. package/dist/commands-DVC7ky6f.js.map +1 -0
  18. package/dist/completions-D2KYtrrv.js +161 -0
  19. package/dist/completions-D2KYtrrv.js.map +1 -0
  20. package/dist/{dev-4wpEQC7l.js → dev-oPPVR7d_.js} +432 -45
  21. package/dist/dev-oPPVR7d_.js.map +1 -0
  22. package/dist/{diagnostics-CZBVxlpj.js → diagnostics-BysbNnPD.js} +38 -1
  23. package/dist/diagnostics-BysbNnPD.js.map +1 -0
  24. package/dist/doctor-DkVUwgDd.js +334 -0
  25. package/dist/doctor-DkVUwgDd.js.map +1 -0
  26. package/dist/{errors-Crt4hu0b.js → errors-COFWKKKw.js} +5 -2
  27. package/dist/errors-COFWKKKw.js.map +1 -0
  28. package/dist/hooks-Cy6F2bhH.js +332 -0
  29. package/dist/hooks-Cy6F2bhH.js.map +1 -0
  30. package/dist/index.d.ts +75 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +4 -4
  33. package/dist/{info-CdiQajgn.js → info-CKJVMWIT.js} +16 -5
  34. package/dist/info-CKJVMWIT.js.map +1 -0
  35. package/dist/{locales-C7X8VNmK.js → locales-BJAP4HYf.js} +5 -5
  36. package/dist/{locales-C7X8VNmK.js.map → locales-BJAP4HYf.js.map} +1 -1
  37. package/dist/log-view-B7uJEnMR.js +342 -0
  38. package/dist/log-view-B7uJEnMR.js.map +1 -0
  39. package/dist/{nitro-sP2F3SQu.js → nitro-B8u1iVgf.js} +2 -2
  40. package/dist/{nitro-sP2F3SQu.js.map → nitro-B8u1iVgf.js.map} +1 -1
  41. package/dist/{plain-B6z85uQP.js → plain-DG7cy0Kk.js} +7 -2
  42. package/dist/plain-DG7cy0Kk.js.map +1 -0
  43. package/dist/{prepare-B4ysyG6H.js → prepare-BM93i3Rm.js} +9 -5
  44. package/dist/prepare-BM93i3Rm.js.map +1 -0
  45. package/dist/{project-MD4dIo2X.js → project-zlQStwsf.js} +2 -2
  46. package/dist/{project-MD4dIo2X.js.map → project-zlQStwsf.js.map} +1 -1
  47. package/dist/{run-Ddwrxe1O.js → run-DMM2YlP3.js} +3 -13
  48. package/dist/run-DMM2YlP3.js.map +1 -0
  49. package/dist/{theme-3Fc_LI-2.js → theme-yS2h5dd_.js} +25 -1
  50. package/dist/theme-yS2h5dd_.js.map +1 -0
  51. package/dist/tsc-C5l5TQGC.js +3 -0
  52. package/dist/{tsc-DO7D_uCl.js → tsc-puVAcwmo.js} +24 -5
  53. package/dist/tsc-puVAcwmo.js.map +1 -0
  54. package/dist/{tsdown-CD68G8_U.js → tsdown-Dwt3JhPw.js} +2 -2
  55. package/dist/{tsdown-CD68G8_U.js.map → tsdown-Dwt3JhPw.js.map} +1 -1
  56. package/dist/{tui-BRddrLQP.js → tui-nldGSD4c.js} +913 -141
  57. package/dist/tui-nldGSD4c.js.map +1 -0
  58. package/dist/{vite-CLyB6wl7.js → vite-YZUtv2Hk.js} +2 -2
  59. package/dist/{vite-CLyB6wl7.js.map → vite-YZUtv2Hk.js.map} +1 -1
  60. package/package.json +5 -4
  61. package/dist/_shared-B-hRZDRS.js.map +0 -1
  62. package/dist/commands-ExM8HILu.js.map +0 -1
  63. package/dist/dev-4wpEQC7l.js.map +0 -1
  64. package/dist/diagnostics-CZBVxlpj.js.map +0 -1
  65. package/dist/errors-Crt4hu0b.js.map +0 -1
  66. package/dist/hooks-H9kjLCMk.js +0 -148
  67. package/dist/hooks-H9kjLCMk.js.map +0 -1
  68. package/dist/info-CdiQajgn.js.map +0 -1
  69. package/dist/log-buffer-CY82aqnb.js +0 -72
  70. package/dist/log-buffer-CY82aqnb.js.map +0 -1
  71. package/dist/plain-B6z85uQP.js.map +0 -1
  72. package/dist/prepare-B4ysyG6H.js.map +0 -1
  73. package/dist/run-Ddwrxe1O.js.map +0 -1
  74. package/dist/theme-3Fc_LI-2.js.map +0 -1
  75. package/dist/tsc-DO7D_uCl.js.map +0 -1
  76. package/dist/tsc-YnAWKn3n.js +0 -3
  77. package/dist/tui-BRddrLQP.js.map +0 -1
  78. package/dist/tunnel-DT1FH6oA.js +0 -175
  79. package/dist/tunnel-DT1FH6oA.js.map +0 -1
@@ -1,175 +0,0 @@
1
- import { i as readProjectEnv } from "./hooks-H9kjLCMk.js";
2
- import { EventEmitter } from "node:events";
3
- import { startTunnel } from "untun";
4
-
5
- //#region src/dev/tunnel.ts
6
- /**
7
- * Exposes the bot's interactions endpoint publicly while `stars dev` runs.
8
- *
9
- * `dev.tunnel: true` opens a `cloudflared` quick tunnel via `untun` (it changes on every run); a configured https
10
- * URL is only probed, since the user already serves it. Writing the URL to the Discord application is opt-in
11
- * through `dev.tunnel.updateEndpoint`, because it edits a live application.
12
- */
13
- var Tunnel = class extends EventEmitter {
14
- config;
15
- #startTunnel;
16
- #tunnel = null;
17
- #state = "off";
18
- #url = null;
19
- #wanted = false;
20
- constructor(config, options = {}) {
21
- super();
22
- this.config = config;
23
- this.#startTunnel = options.startTunnel ?? startTunnel;
24
- }
25
- get state() {
26
- return this.#state;
27
- }
28
- /** The public URL of the interactions endpoint, `null` until the tunnel is up. */
29
- get url() {
30
- return this.#url;
31
- }
32
- async start(forceQuick = false) {
33
- if (this.#state === "starting" || this.#state === "up") return;
34
- const configured = this.config.dev.tunnel;
35
- const tunnel = forceQuick && configured.mode === "off" ? {
36
- mode: "quick",
37
- path: "/",
38
- updateEndpoint: false
39
- } : configured;
40
- if (tunnel.mode === "off") return;
41
- this.#wanted = true;
42
- this.#setState("starting", null);
43
- const url = tunnel.mode === "url" ? await this.#useConfiguredUrl(tunnel) : await this.#openQuickTunnel();
44
- if (!url || !this.#wanted) return;
45
- this.#setState("up", endpointUrl(url, tunnel.path));
46
- this.emit("log", "success", `Tunnel ready at ${this.#url}`);
47
- if (tunnel.updateEndpoint) await this.#updateInteractionsEndpoint(this.#url);
48
- }
49
- /** Toggles the configured tunnel, opening a quick tunnel when the project did not configure one. */
50
- toggle() {
51
- return this.#state === "starting" || this.#state === "up" ? this.close() : this.start(true);
52
- }
53
- async close() {
54
- this.#wanted = false;
55
- const tunnel = this.#tunnel;
56
- this.#tunnel = null;
57
- this.#setState("off", null);
58
- if (tunnel) await tunnel.close();
59
- }
60
- async #useConfiguredUrl(tunnel) {
61
- if (!await probe(endpointUrl(tunnel.url, tunnel.path))) this.emit("log", "warn", `${tunnel.url} did not answer; make sure it forwards to ${this.config.dev.url ?? "the bot"}`);
62
- return tunnel.url;
63
- }
64
- async #openQuickTunnel() {
65
- const target = this.config.dev.url;
66
- if (!target) {
67
- this.emit("log", "error", "A quick tunnel needs `dev.url` to know what to forward to");
68
- this.#setState("failed", null);
69
- return null;
70
- }
71
- this.emit("log", "info", "Opening a cloudflared quick tunnel…");
72
- try {
73
- const tunnel = await this.#startTunnel({
74
- url: target,
75
- acceptCloudflareNotice: true
76
- });
77
- if (!this.#wanted) {
78
- await tunnel?.close();
79
- return null;
80
- }
81
- if (!tunnel) {
82
- this.emit("log", "error", "cloudflared setup was cancelled");
83
- this.#setState("failed", null);
84
- return null;
85
- }
86
- this.#tunnel = tunnel;
87
- return await tunnel.getURL();
88
- } catch (error) {
89
- this.emit("log", "error", `cloudflared failed: ${error instanceof Error ? error.message : String(error)}`);
90
- this.#setState("failed", null);
91
- return null;
92
- }
93
- }
94
- /**
95
- * Points the Discord application's interactions endpoint at the tunnel. Discord validates the endpoint with a
96
- * signed ping before accepting it, so the bot has to be up already — this runs after the first successful build.
97
- */
98
- async #updateInteractionsEndpoint(url) {
99
- const credentials = readDiscordCredentials(this.config);
100
- if (!credentials) {
101
- this.emit("log", "warn", "Skipped the interactions endpoint update: DISCORD_TOKEN is not set");
102
- return;
103
- }
104
- try {
105
- const response = await fetch("https://discord.com/api/v10/applications/@me", {
106
- method: "PATCH",
107
- headers: {
108
- authorization: `Bot ${credentials.token}`,
109
- "content-type": "application/json"
110
- },
111
- body: JSON.stringify({ interactions_endpoint_url: url }),
112
- signal: AbortSignal.timeout(1e4)
113
- });
114
- if (response.ok) this.emit("log", "success", `Interactions endpoint set to ${url}`);
115
- else this.emit("log", "error", `Discord rejected the interactions endpoint (${response.status}): ${(await response.text()).slice(0, 300)}`);
116
- } catch (error) {
117
- this.emit("log", "error", `Failed to update the interactions endpoint: ${error instanceof Error ? error.message : String(error)}`);
118
- }
119
- }
120
- #setState(state, url) {
121
- this.#state = state;
122
- this.#url = url;
123
- this.emit("state", state, url);
124
- }
125
- };
126
- /**
127
- * Joins the tunnel's origin with the path the interactions endpoint is served on.
128
- */
129
- function endpointUrl(origin, path) {
130
- return path === "/" ? origin : new URL(path, origin.endsWith("/") ? origin : `${origin}/`).href;
131
- }
132
- async function probe(url) {
133
- try {
134
- return (await fetch(url, {
135
- method: "HEAD",
136
- signal: AbortSignal.timeout(5e3)
137
- })).status < 500;
138
- } catch {
139
- return false;
140
- }
141
- }
142
- /**
143
- * Reads the Discord credentials the CLI needs from the environment, falling back to the project's `.env` files the
144
- * way the bot itself does once it starts.
145
- */
146
- function readDiscordCredentials(config, env = process.env) {
147
- const fromFiles = readProjectEnvFilesCached(config);
148
- const read = (...keys) => {
149
- for (const key of keys) {
150
- const value = config.dev.env[key] ?? env[key] ?? fromFiles[key];
151
- if (value) return value;
152
- }
153
- return null;
154
- };
155
- const token = read("DISCORD_TOKEN", "TOKEN");
156
- if (!token) return null;
157
- return {
158
- token,
159
- applicationId: read("DISCORD_APPLICATION_ID", "APPLICATION_ID", "DISCORD_CLIENT_ID", "CLIENT_ID")
160
- };
161
- }
162
- let envFileCache = null;
163
- /** The variables the bot loads (see {@link readProjectEnv}), once per project and `env` options. */
164
- function readProjectEnvFilesCached(config) {
165
- const key = JSON.stringify([config.root, config.env.options]);
166
- if (envFileCache?.key !== key) envFileCache = {
167
- key,
168
- values: readProjectEnv(config)
169
- };
170
- return envFileCache.values;
171
- }
172
-
173
- //#endregion
174
- export { readDiscordCredentials as n, Tunnel as t };
175
- //# sourceMappingURL=tunnel-DT1FH6oA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tunnel-DT1FH6oA.js","names":[],"sources":["../src/dev/tunnel.ts"],"sourcesContent":["import type { ResolvedStarsConfig, ResolvedTunnelConfig } from '@wolfstar/schema';\nimport { readProjectEnv } from '../utils/project-env.js';\nimport { EventEmitter } from 'node:events';\nimport { startTunnel, type Tunnel as UntunTunnel } from 'untun';\nimport type { LogLevel } from '../utils/log-buffer.js';\n\nexport type TunnelState = 'off' | 'starting' | 'up' | 'failed';\n\nexport interface TunnelEvents {\n\tlog: [level: LogLevel, text: string];\n\tstate: [state: TunnelState, url: string | null];\n}\n\nexport interface TunnelOptions {\n\t/** Override for tests. */\n\tstartTunnel?: typeof startTunnel;\n}\n\n/**\n * Exposes the bot's interactions endpoint publicly while `stars dev` runs.\n *\n * `dev.tunnel: true` opens a `cloudflared` quick tunnel via `untun` (it changes on every run); a configured https\n * URL is only probed, since the user already serves it. Writing the URL to the Discord application is opt-in\n * through `dev.tunnel.updateEndpoint`, because it edits a live application.\n */\nexport class Tunnel extends EventEmitter<TunnelEvents> {\n\t#startTunnel: typeof startTunnel;\n\t#tunnel: UntunTunnel | null = null;\n\t#state: TunnelState = 'off';\n\t#url: string | null = null;\n\t#wanted = false;\n\n\tpublic constructor(\n\t\tprivate readonly config: ResolvedStarsConfig,\n\t\toptions: TunnelOptions = {}\n\t) {\n\t\tsuper();\n\t\tthis.#startTunnel = options.startTunnel ?? startTunnel;\n\t}\n\n\tpublic get state(): TunnelState {\n\t\treturn this.#state;\n\t}\n\n\t/** The public URL of the interactions endpoint, `null` until the tunnel is up. */\n\tpublic get url(): string | null {\n\t\treturn this.#url;\n\t}\n\n\tpublic async start(forceQuick = false): Promise<void> {\n\t\tif (this.#state === 'starting' || this.#state === 'up') return;\n\t\tconst configured = this.config.dev.tunnel;\n\t\tconst tunnel: ResolvedTunnelConfig =\n\t\t\tforceQuick && configured.mode === 'off' ? { mode: 'quick', path: '/', updateEndpoint: false } : configured;\n\t\tif (tunnel.mode === 'off') return;\n\n\t\tthis.#wanted = true;\n\t\tthis.#setState('starting', null);\n\t\tconst url = tunnel.mode === 'url' ? await this.#useConfiguredUrl(tunnel) : await this.#openQuickTunnel();\n\t\tif (!url || !this.#wanted) return;\n\n\t\tthis.#setState('up', endpointUrl(url, tunnel.path));\n\t\tthis.emit('log', 'success', `Tunnel ready at ${this.#url}`);\n\t\tif (tunnel.updateEndpoint) await this.#updateInteractionsEndpoint(this.#url!);\n\t}\n\n\t/** Toggles the configured tunnel, opening a quick tunnel when the project did not configure one. */\n\tpublic toggle(): Promise<void> {\n\t\treturn this.#state === 'starting' || this.#state === 'up' ? this.close() : this.start(true);\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tthis.#wanted = false;\n\t\tconst tunnel = this.#tunnel;\n\t\tthis.#tunnel = null;\n\t\tthis.#setState('off', null);\n\t\tif (tunnel) await tunnel.close();\n\t}\n\n\tasync #useConfiguredUrl(tunnel: Extract<ResolvedTunnelConfig, { mode: 'url' }>): Promise<string | null> {\n\t\tconst reachable = await probe(endpointUrl(tunnel.url, tunnel.path));\n\t\tif (!reachable) {\n\t\t\tthis.emit('log', 'warn', `${tunnel.url} did not answer; make sure it forwards to ${this.config.dev.url ?? 'the bot'}`);\n\t\t}\n\n\t\treturn tunnel.url;\n\t}\n\n\tasync #openQuickTunnel(): Promise<string | null> {\n\t\tconst target = this.config.dev.url;\n\t\tif (!target) {\n\t\t\tthis.emit('log', 'error', 'A quick tunnel needs `dev.url` to know what to forward to');\n\t\t\tthis.#setState('failed', null);\n\t\t\treturn null;\n\t\t}\n\n\t\tthis.emit('log', 'info', 'Opening a cloudflared quick tunnel…');\n\n\t\ttry {\n\t\t\tconst tunnel = await this.#startTunnel({ url: target, acceptCloudflareNotice: true });\n\t\t\tif (!this.#wanted) {\n\t\t\t\tawait tunnel?.close();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!tunnel) {\n\t\t\t\tthis.emit('log', 'error', 'cloudflared setup was cancelled');\n\t\t\t\tthis.#setState('failed', null);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tthis.#tunnel = tunnel;\n\t\t\treturn await tunnel.getURL();\n\t\t} catch (error) {\n\t\t\tthis.emit('log', 'error', `cloudflared failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\tthis.#setState('failed', null);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Points the Discord application's interactions endpoint at the tunnel. Discord validates the endpoint with a\n\t * signed ping before accepting it, so the bot has to be up already — this runs after the first successful build.\n\t */\n\tasync #updateInteractionsEndpoint(url: string): Promise<void> {\n\t\tconst credentials = readDiscordCredentials(this.config);\n\t\tif (!credentials) {\n\t\t\tthis.emit('log', 'warn', 'Skipped the interactions endpoint update: DISCORD_TOKEN is not set');\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch('https://discord.com/api/v10/applications/@me', {\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\theaders: { authorization: `Bot ${credentials.token}`, 'content-type': 'application/json' },\n\t\t\t\tbody: JSON.stringify({ interactions_endpoint_url: url }),\n\t\t\t\tsignal: AbortSignal.timeout(10_000)\n\t\t\t});\n\n\t\t\tif (response.ok) this.emit('log', 'success', `Interactions endpoint set to ${url}`);\n\t\t\telse\n\t\t\t\tthis.emit(\n\t\t\t\t\t'log',\n\t\t\t\t\t'error',\n\t\t\t\t\t`Discord rejected the interactions endpoint (${response.status}): ${(await response.text()).slice(0, 300)}`\n\t\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.emit('log', 'error', `Failed to update the interactions endpoint: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\n\t#setState(state: TunnelState, url: string | null): void {\n\t\tthis.#state = state;\n\t\tthis.#url = url;\n\t\tthis.emit('state', state, url);\n\t}\n}\n\n/**\n * Joins the tunnel's origin with the path the interactions endpoint is served on.\n */\nexport function endpointUrl(origin: string, path: string): string {\n\treturn path === '/' ? origin : new URL(path, origin.endsWith('/') ? origin : `${origin}/`).href;\n}\n\nasync function probe(url: string): Promise<boolean> {\n\ttry {\n\t\tconst response = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(5000) });\n\t\treturn response.status < 500;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport interface DiscordCredentials {\n\ttoken: string;\n\tapplicationId: string | null;\n}\n\n/**\n * Reads the Discord credentials the CLI needs from the environment, falling back to the project's `.env` files the\n * way the bot itself does once it starts.\n */\nexport function readDiscordCredentials(config: ResolvedStarsConfig, env: NodeJS.ProcessEnv = process.env): DiscordCredentials | null {\n\tconst fromFiles = readProjectEnvFilesCached(config);\n\tconst read = (...keys: string[]): string | null => {\n\t\tfor (const key of keys) {\n\t\t\tconst value = config.dev.env[key] ?? env[key] ?? fromFiles[key];\n\t\t\tif (value) return value;\n\t\t}\n\t\treturn null;\n\t};\n\n\tconst token = read('DISCORD_TOKEN', 'TOKEN');\n\tif (!token) return null;\n\n\treturn { token, applicationId: read('DISCORD_APPLICATION_ID', 'APPLICATION_ID', 'DISCORD_CLIENT_ID', 'CLIENT_ID') };\n}\n\nlet envFileCache: { key: string; values: Record<string, string> } | null = null;\n\n/** The variables the bot loads (see {@link readProjectEnv}), once per project and `env` options. */\nfunction readProjectEnvFilesCached(config: ResolvedStarsConfig): Record<string, string> {\n\tconst key = JSON.stringify([config.root, config.env.options]);\n\tif (envFileCache?.key !== key) envFileCache = { key, values: readProjectEnv(config) };\n\treturn envFileCache.values;\n}\n"],"mappings":"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"}