hatchkit 0.1.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/dist/config.d.ts +131 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +629 -0
- package/dist/config.js.map +1 -0
- package/dist/deploy/coolify.d.ts +4 -0
- package/dist/deploy/coolify.d.ts.map +1 -0
- package/dist/deploy/coolify.js +20 -0
- package/dist/deploy/coolify.js.map +1 -0
- package/dist/deploy/github.d.ts +4 -0
- package/dist/deploy/github.d.ts.map +1 -0
- package/dist/deploy/github.js +39 -0
- package/dist/deploy/github.js.map +1 -0
- package/dist/deploy/gpu.d.ts +4 -0
- package/dist/deploy/gpu.d.ts.map +1 -0
- package/dist/deploy/gpu.js +97 -0
- package/dist/deploy/gpu.js.map +1 -0
- package/dist/deploy/keys.d.ts +9 -0
- package/dist/deploy/keys.d.ts.map +1 -0
- package/dist/deploy/keys.js +73 -0
- package/dist/deploy/keys.js.map +1 -0
- package/dist/deploy/terraform.d.ts +4 -0
- package/dist/deploy/terraform.d.ts.map +1 -0
- package/dist/deploy/terraform.js +55 -0
- package/dist/deploy/terraform.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +599 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +52 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +313 -0
- package/dist/prompts.js.map +1 -0
- package/dist/provision/glitchtip.d.ts +6 -0
- package/dist/provision/glitchtip.d.ts.map +1 -0
- package/dist/provision/glitchtip.js +46 -0
- package/dist/provision/glitchtip.js.map +1 -0
- package/dist/provision/index.d.ts +9 -0
- package/dist/provision/index.d.ts.map +1 -0
- package/dist/provision/index.js +108 -0
- package/dist/provision/index.js.map +1 -0
- package/dist/provision/openpanel.d.ts +8 -0
- package/dist/provision/openpanel.d.ts.map +1 -0
- package/dist/provision/openpanel.js +66 -0
- package/dist/provision/openpanel.js.map +1 -0
- package/dist/provision/resend.d.ts +16 -0
- package/dist/provision/resend.d.ts.map +1 -0
- package/dist/provision/resend.js +43 -0
- package/dist/provision/resend.js.map +1 -0
- package/dist/scaffold/app.d.ts +13 -0
- package/dist/scaffold/app.d.ts.map +1 -0
- package/dist/scaffold/app.js +340 -0
- package/dist/scaffold/app.js.map +1 -0
- package/dist/scaffold/dotenvx.d.ts +30 -0
- package/dist/scaffold/dotenvx.d.ts.map +1 -0
- package/dist/scaffold/dotenvx.js +142 -0
- package/dist/scaffold/dotenvx.js.map +1 -0
- package/dist/scaffold/infra.d.ts +17 -0
- package/dist/scaffold/infra.d.ts.map +1 -0
- package/dist/scaffold/infra.js +200 -0
- package/dist/scaffold/infra.js.map +1 -0
- package/dist/scaffold/manifest.d.ts +50 -0
- package/dist/scaffold/manifest.d.ts.map +1 -0
- package/dist/scaffold/manifest.js +83 -0
- package/dist/scaffold/manifest.js.map +1 -0
- package/dist/scaffold/ml-client.d.ts +20 -0
- package/dist/scaffold/ml-client.d.ts.map +1 -0
- package/dist/scaffold/ml-client.js +38 -0
- package/dist/scaffold/ml-client.js.map +1 -0
- package/dist/scaffold/pkg-json.d.ts +20 -0
- package/dist/scaffold/pkg-json.d.ts.map +1 -0
- package/dist/scaffold/pkg-json.js +113 -0
- package/dist/scaffold/pkg-json.js.map +1 -0
- package/dist/scaffold/starter-files.d.ts +40 -0
- package/dist/scaffold/starter-files.d.ts.map +1 -0
- package/dist/scaffold/starter-files.js +197 -0
- package/dist/scaffold/starter-files.js.map +1 -0
- package/dist/scaffold/update.d.ts +8 -0
- package/dist/scaffold/update.d.ts.map +1 -0
- package/dist/scaffold/update.js +255 -0
- package/dist/scaffold/update.js.map +1 -0
- package/dist/templates/addons/analytics/middleware.ts.hbs +13 -0
- package/dist/templates/addons/analytics/sentry.ts.hbs +16 -0
- package/dist/templates/addons/storage/s3.ts.hbs +40 -0
- package/dist/templates/addons/storage/upload.ts.hbs +23 -0
- package/dist/templates/addons/stripe/checkout.ts.hbs +27 -0
- package/dist/templates/addons/stripe/client.ts.hbs +6 -0
- package/dist/templates/addons/stripe/webhook.ts.hbs +39 -0
- package/dist/templates/addons/websocket/redis.ts.hbs +25 -0
- package/dist/templates/addons/websocket/ws.ts.hbs +32 -0
- package/dist/templates/base/.dockerignore.hbs +7 -0
- package/dist/templates/base/Dockerfile.hbs +18 -0
- package/dist/templates/base/env.example.hbs +60 -0
- package/dist/templates/base/github-actions.yml.hbs +35 -0
- package/dist/templates/base/gitignore.hbs +5 -0
- package/dist/templates/base/package.json.hbs +36 -0
- package/dist/templates/base/src/auth/auth.ts.hbs +13 -0
- package/dist/templates/base/src/auth/routes.ts.hbs +19 -0
- package/dist/templates/base/src/config.ts.hbs +36 -0
- package/dist/templates/base/src/db.ts.hbs +12 -0
- package/dist/templates/base/src/index.ts.hbs +80 -0
- package/dist/templates/base/src/routes/health.ts.hbs +12 -0
- package/dist/templates/base/tsconfig.json.hbs +18 -0
- package/dist/templates/ml-clients/3d-extraction.ts.hbs +20 -0
- package/dist/templates/ml-clients/background-removal.ts.hbs +17 -0
- package/dist/templates/ml-clients/custom-hf.ts.hbs +20 -0
- package/dist/templates/ml-clients/image-recognition.ts.hbs +22 -0
- package/dist/templates/ml-clients/subtitles.ts.hbs +26 -0
- package/dist/utils/coolify-api.d.ts +45 -0
- package/dist/utils/coolify-api.d.ts.map +1 -0
- package/dist/utils/coolify-api.js +72 -0
- package/dist/utils/coolify-api.js.map +1 -0
- package/dist/utils/errors.d.ts +2 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +31 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/exec.d.ts +23 -0
- package/dist/utils/exec.d.ts.map +1 -0
- package/dist/utils/exec.js +47 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/flags.d.ts +17 -0
- package/dist/utils/flags.d.ts.map +1 -0
- package/dist/utils/flags.js +116 -0
- package/dist/utils/flags.js.map +1 -0
- package/dist/utils/hf-api.d.ts +13 -0
- package/dist/utils/hf-api.d.ts.map +1 -0
- package/dist/utils/hf-api.js +30 -0
- package/dist/utils/hf-api.js.map +1 -0
- package/dist/utils/ports.d.ts +29 -0
- package/dist/utils/ports.d.ts.map +1 -0
- package/dist/utils/ports.js +86 -0
- package/dist/utils/ports.js.map +1 -0
- package/dist/utils/secrets.d.ts +25 -0
- package/dist/utils/secrets.d.ts.map +1 -0
- package/dist/utils/secrets.js +51 -0
- package/dist/utils/secrets.js.map +1 -0
- package/dist/utils/template.d.ts +7 -0
- package/dist/utils/template.d.ts.map +1 -0
- package/dist/utils/template.js +35 -0
- package/dist/utils/template.js.map +1 -0
- package/dist/utils/validate.d.ts +16 -0
- package/dist/utils/validate.d.ts.map +1 -0
- package/dist/utils/validate.js +60 -0
- package/dist/utils/validate.js.map +1 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +21 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +48 -0
- package/scripts/copy-templates.mjs +20 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
import { confirm, input, password, select } from "@inquirer/prompts";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import Conf from "conf";
|
|
4
|
+
import ora from "ora";
|
|
5
|
+
import { verifyCoolify } from "./utils/coolify-api.js";
|
|
6
|
+
import { execOk } from "./utils/exec.js";
|
|
7
|
+
import { SECRET_KEYS, clearAllSecrets, getSecret, setSecret } from "./utils/secrets.js";
|
|
8
|
+
import { validateRequired, validateUrl } from "./utils/validate.js";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Config store
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Tests set HATCHKIT_CONF_DIR to a temp path so they don't pollute
|
|
13
|
+
// the real user config. In normal CLI runs this is unset and Conf
|
|
14
|
+
// falls back to its default OS-specific location.
|
|
15
|
+
//
|
|
16
|
+
// If the JSON store is corrupt on disk (malformed, truncated, bogus
|
|
17
|
+
// schema), Conf throws from the constructor. Catch that here and
|
|
18
|
+
// reset rather than bricking the CLI for every subsequent command —
|
|
19
|
+
// a fresh config is recoverable (re-run `init`), a crash at import
|
|
20
|
+
// time is not.
|
|
21
|
+
const STORE_DEFAULTS = {
|
|
22
|
+
version: 1,
|
|
23
|
+
providers: {
|
|
24
|
+
github: { status: "unconfigured" },
|
|
25
|
+
s3: {},
|
|
26
|
+
gpu: {},
|
|
27
|
+
},
|
|
28
|
+
mlServices: {},
|
|
29
|
+
usedPorts: [],
|
|
30
|
+
};
|
|
31
|
+
function createStore() {
|
|
32
|
+
try {
|
|
33
|
+
return new Conf({
|
|
34
|
+
projectName: "hatchkit",
|
|
35
|
+
cwd: process.env.HATCHKIT_CONF_DIR,
|
|
36
|
+
clearInvalidConfig: true,
|
|
37
|
+
defaults: STORE_DEFAULTS,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
42
|
+
console.warn(chalk.yellow(` [config] existing CLI config was unreadable (${msg}). Falling back to defaults; re-run \`hatchkit init\` to restore providers.`));
|
|
43
|
+
// Last resort: an in-memory-only store so commands that don't
|
|
44
|
+
// touch persistent state still work in this session.
|
|
45
|
+
return new Conf({
|
|
46
|
+
projectName: "hatchkit",
|
|
47
|
+
cwd: process.env.HATCHKIT_CONF_DIR,
|
|
48
|
+
defaults: STORE_DEFAULTS,
|
|
49
|
+
// `fileExtension: "json"` + a throwaway fallback file name so
|
|
50
|
+
// Conf writes next to (not over) the broken original.
|
|
51
|
+
fileExtension: "json",
|
|
52
|
+
configName: `config.recovered-${Date.now()}`,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const store = createStore();
|
|
57
|
+
export function getConfig() {
|
|
58
|
+
return store.store;
|
|
59
|
+
}
|
|
60
|
+
export function getConfigPath() {
|
|
61
|
+
return store.path;
|
|
62
|
+
}
|
|
63
|
+
/** Reset all CLI config. Clears providers and ML registry, plus every
|
|
64
|
+
* secret this CLI has stored in the OS keychain. */
|
|
65
|
+
export async function resetConfig() {
|
|
66
|
+
await clearAllSecrets();
|
|
67
|
+
store.clear();
|
|
68
|
+
}
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Migration — move legacy plaintext secrets from Conf JSON to keytar the
|
|
71
|
+
// first time they're seen. Runs lazily inside the relevant ensure/get
|
|
72
|
+
// call so we don't spin up keytar for every CLI invocation.
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
async function migrateSecret(keyInStore, keytarKey) {
|
|
75
|
+
// Conf's typed API restricts keys to `keyof CliConfig`. Migration
|
|
76
|
+
// reaches into arbitrary nested paths ("providers.coolify.token",
|
|
77
|
+
// etc.) that Conf supports at runtime but not in the type. Cast
|
|
78
|
+
// once to a permissive shape for just these two operations so the
|
|
79
|
+
// rest of the file keeps the typed API.
|
|
80
|
+
const rawStore = store;
|
|
81
|
+
const raw = rawStore.get(keyInStore);
|
|
82
|
+
if (!raw)
|
|
83
|
+
return;
|
|
84
|
+
await setSecret(keytarKey, raw);
|
|
85
|
+
rawStore.delete(keyInStore);
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Provider: GitHub
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
export async function ensureGitHub() {
|
|
91
|
+
const isAuthed = await execOk("gh", ["auth", "status"]);
|
|
92
|
+
if (isAuthed) {
|
|
93
|
+
store.set("providers.github", {
|
|
94
|
+
status: "configured",
|
|
95
|
+
lastVerified: new Date().toISOString(),
|
|
96
|
+
});
|
|
97
|
+
console.log(chalk.green(" ✓ GitHub: Authenticated via gh CLI"));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(chalk.yellow(" GitHub: Not authenticated. Running gh auth login..."));
|
|
101
|
+
const { execStream } = await import("./utils/exec.js");
|
|
102
|
+
const exitCode = await execStream("gh", ["auth", "login"]);
|
|
103
|
+
if (exitCode !== 0) {
|
|
104
|
+
throw new Error("GitHub authentication failed. Install gh CLI and try again.");
|
|
105
|
+
}
|
|
106
|
+
store.set("providers.github", {
|
|
107
|
+
status: "configured",
|
|
108
|
+
lastVerified: new Date().toISOString(),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Provider: Coolify
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
export async function ensureCoolify() {
|
|
115
|
+
await migrateSecret("providers.coolify.token", SECRET_KEYS.coolifyToken);
|
|
116
|
+
const existing = store.get("providers.coolify");
|
|
117
|
+
const existingToken = await getSecret(SECRET_KEYS.coolifyToken);
|
|
118
|
+
if (existing?.status === "configured" && existingToken) {
|
|
119
|
+
// Skip verification if checked within last 24 hours
|
|
120
|
+
const lastVerified = existing.lastVerified ? new Date(existing.lastVerified).getTime() : 0;
|
|
121
|
+
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
|
|
122
|
+
if (lastVerified > oneDayAgo) {
|
|
123
|
+
return { ...existing, token: existingToken };
|
|
124
|
+
}
|
|
125
|
+
// Verify connection is still valid
|
|
126
|
+
try {
|
|
127
|
+
await verifyCoolify(existing.url, existingToken);
|
|
128
|
+
store.set("providers.coolify.lastVerified", new Date().toISOString());
|
|
129
|
+
return { ...existing, token: existingToken };
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
console.log(chalk.yellow(" Coolify token expired or invalid. Let's reconfigure."));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const url = await input({
|
|
136
|
+
message: "Coolify dashboard URL:",
|
|
137
|
+
default: existing?.url,
|
|
138
|
+
validate: (v) => validateUrl(v),
|
|
139
|
+
});
|
|
140
|
+
const token = await password({
|
|
141
|
+
message: "Coolify API token (from Settings → API Tokens):",
|
|
142
|
+
});
|
|
143
|
+
const spinner = ora("Testing Coolify connection...").start();
|
|
144
|
+
try {
|
|
145
|
+
const version = await verifyCoolify(url, token);
|
|
146
|
+
spinner.succeed(`Connected to Coolify v${version}`);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
spinner.fail("Could not connect to Coolify");
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
// Cache server list
|
|
153
|
+
const { CoolifyApi } = await import("./utils/coolify-api.js");
|
|
154
|
+
const api = new CoolifyApi({ url, token });
|
|
155
|
+
const servers = await api.listServers();
|
|
156
|
+
const meta = {
|
|
157
|
+
status: "configured",
|
|
158
|
+
url,
|
|
159
|
+
serversCache: servers,
|
|
160
|
+
lastVerified: new Date().toISOString(),
|
|
161
|
+
};
|
|
162
|
+
store.set("providers.coolify", meta);
|
|
163
|
+
await setSecret(SECRET_KEYS.coolifyToken, token);
|
|
164
|
+
console.log(chalk.green(` ✓ Coolify: ${servers.length} server(s) found`));
|
|
165
|
+
return { ...meta, token };
|
|
166
|
+
}
|
|
167
|
+
/** Read Coolify config (meta + token) from storage. Returns null if not
|
|
168
|
+
* configured or if the secret has been removed out-of-band. */
|
|
169
|
+
export async function getCoolifyConfig() {
|
|
170
|
+
await migrateSecret("providers.coolify.token", SECRET_KEYS.coolifyToken);
|
|
171
|
+
const meta = store.get("providers.coolify");
|
|
172
|
+
if (!meta || meta.status !== "configured")
|
|
173
|
+
return null;
|
|
174
|
+
const token = await getSecret(SECRET_KEYS.coolifyToken);
|
|
175
|
+
if (!token)
|
|
176
|
+
return null;
|
|
177
|
+
return { ...meta, token };
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Provider: Hetzner
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
export async function ensureHetzner() {
|
|
183
|
+
await migrateSecret("providers.hetzner.token", SECRET_KEYS.hetznerToken);
|
|
184
|
+
const existing = store.get("providers.hetzner");
|
|
185
|
+
const existingToken = await getSecret(SECRET_KEYS.hetznerToken);
|
|
186
|
+
if (existing?.status === "configured" && existingToken) {
|
|
187
|
+
return { ...existing, token: existingToken };
|
|
188
|
+
}
|
|
189
|
+
const token = await password({
|
|
190
|
+
message: "Hetzner Cloud API token:",
|
|
191
|
+
});
|
|
192
|
+
const spinner = ora("Testing Hetzner connection...").start();
|
|
193
|
+
try {
|
|
194
|
+
const res = await fetch("https://api.hetzner.cloud/v1/servers", {
|
|
195
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
196
|
+
});
|
|
197
|
+
if (!res.ok)
|
|
198
|
+
throw new Error(`HTTP ${res.status}`);
|
|
199
|
+
spinner.succeed("Hetzner Cloud connected");
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
spinner.fail("Could not connect to Hetzner Cloud");
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
const meta = {
|
|
206
|
+
status: "configured",
|
|
207
|
+
lastVerified: new Date().toISOString(),
|
|
208
|
+
};
|
|
209
|
+
store.set("providers.hetzner", meta);
|
|
210
|
+
await setSecret(SECRET_KEYS.hetznerToken, token);
|
|
211
|
+
return { ...meta, token };
|
|
212
|
+
}
|
|
213
|
+
export async function getHetznerToken() {
|
|
214
|
+
await migrateSecret("providers.hetzner.token", SECRET_KEYS.hetznerToken);
|
|
215
|
+
return getSecret(SECRET_KEYS.hetznerToken);
|
|
216
|
+
}
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
// Provider: DNS
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
export async function ensureDns() {
|
|
221
|
+
await migrateSecret("providers.dns.password", SECRET_KEYS.dnsInwxPassword);
|
|
222
|
+
await migrateSecret("providers.dns.apiToken", SECRET_KEYS.dnsCloudflareToken);
|
|
223
|
+
const existing = store.get("providers.dns");
|
|
224
|
+
if (existing?.status === "configured") {
|
|
225
|
+
const password = await getSecret(SECRET_KEYS.dnsInwxPassword);
|
|
226
|
+
const apiToken = await getSecret(SECRET_KEYS.dnsCloudflareToken);
|
|
227
|
+
return {
|
|
228
|
+
...existing,
|
|
229
|
+
password: password ?? undefined,
|
|
230
|
+
apiToken: apiToken ?? undefined,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
const provider = await select({
|
|
234
|
+
message: "DNS provider:",
|
|
235
|
+
choices: [
|
|
236
|
+
{ name: "INWX (auto-configure DNS)", value: "inwx" },
|
|
237
|
+
{ name: "Cloudflare DNS", value: "cloudflare" },
|
|
238
|
+
{ name: "Manual (I'll set DNS records myself)", value: "manual" },
|
|
239
|
+
],
|
|
240
|
+
});
|
|
241
|
+
if (provider === "manual") {
|
|
242
|
+
const meta = { status: "configured", provider: "manual" };
|
|
243
|
+
store.set("providers.dns", meta);
|
|
244
|
+
return { ...meta };
|
|
245
|
+
}
|
|
246
|
+
if (provider === "inwx") {
|
|
247
|
+
const username = await input({ message: "INWX username:", validate: validateRequired });
|
|
248
|
+
const pwd = await password({ message: "INWX password:" });
|
|
249
|
+
const meta = {
|
|
250
|
+
status: "configured",
|
|
251
|
+
provider: "inwx",
|
|
252
|
+
username,
|
|
253
|
+
};
|
|
254
|
+
store.set("providers.dns", meta);
|
|
255
|
+
await setSecret(SECRET_KEYS.dnsInwxPassword, pwd);
|
|
256
|
+
console.log(chalk.green(" ✓ INWX DNS configured"));
|
|
257
|
+
return { ...meta, password: pwd };
|
|
258
|
+
}
|
|
259
|
+
// Cloudflare
|
|
260
|
+
const apiToken = await password({ message: "Cloudflare API token:" });
|
|
261
|
+
const meta = {
|
|
262
|
+
status: "configured",
|
|
263
|
+
provider: "cloudflare",
|
|
264
|
+
};
|
|
265
|
+
store.set("providers.dns", meta);
|
|
266
|
+
await setSecret(SECRET_KEYS.dnsCloudflareToken, apiToken);
|
|
267
|
+
console.log(chalk.green(" ✓ Cloudflare DNS configured"));
|
|
268
|
+
return { ...meta, apiToken };
|
|
269
|
+
}
|
|
270
|
+
export async function getDnsConfig() {
|
|
271
|
+
await migrateSecret("providers.dns.password", SECRET_KEYS.dnsInwxPassword);
|
|
272
|
+
await migrateSecret("providers.dns.apiToken", SECRET_KEYS.dnsCloudflareToken);
|
|
273
|
+
const meta = store.get("providers.dns");
|
|
274
|
+
if (!meta || meta.status !== "configured")
|
|
275
|
+
return null;
|
|
276
|
+
const password = await getSecret(SECRET_KEYS.dnsInwxPassword);
|
|
277
|
+
const apiToken = await getSecret(SECRET_KEYS.dnsCloudflareToken);
|
|
278
|
+
return {
|
|
279
|
+
...meta,
|
|
280
|
+
password: password ?? undefined,
|
|
281
|
+
apiToken: apiToken ?? undefined,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
// Provider: S3
|
|
286
|
+
// ---------------------------------------------------------------------------
|
|
287
|
+
export async function ensureS3(provider) {
|
|
288
|
+
await migrateSecret(`providers.s3.${provider}.accessKey`, SECRET_KEYS.s3AccessKey(provider));
|
|
289
|
+
await migrateSecret(`providers.s3.${provider}.secretKey`, SECRET_KEYS.s3SecretKey(provider));
|
|
290
|
+
const existing = store.get(`providers.s3.${provider}`);
|
|
291
|
+
const accessKey = await getSecret(SECRET_KEYS.s3AccessKey(provider));
|
|
292
|
+
const secretKey = await getSecret(SECRET_KEYS.s3SecretKey(provider));
|
|
293
|
+
if (existing?.status === "configured" && accessKey && secretKey) {
|
|
294
|
+
return { ...existing, accessKey, secretKey };
|
|
295
|
+
}
|
|
296
|
+
console.log(chalk.yellow(`\n ${provider.toUpperCase()} S3 is not configured yet. Let's set it up.`));
|
|
297
|
+
const promptedAccessKey = await password({ message: `${provider} S3 access key:` });
|
|
298
|
+
const promptedSecretKey = await password({ message: `${provider} S3 secret key:` });
|
|
299
|
+
let endpoint;
|
|
300
|
+
let region;
|
|
301
|
+
let location;
|
|
302
|
+
if (provider === "hetzner") {
|
|
303
|
+
location = await select({
|
|
304
|
+
message: "Hetzner Object Storage location:",
|
|
305
|
+
choices: [
|
|
306
|
+
{ name: "Nuremberg (nbg1)", value: "nbg1" },
|
|
307
|
+
{ name: "Falkenstein (fsn1)", value: "fsn1" },
|
|
308
|
+
{ name: "Helsinki (hel1)", value: "hel1" },
|
|
309
|
+
],
|
|
310
|
+
});
|
|
311
|
+
endpoint = `https://${location}.your-objectstorage.com`;
|
|
312
|
+
region = location;
|
|
313
|
+
}
|
|
314
|
+
else if (provider === "r2") {
|
|
315
|
+
const accountId = await input({
|
|
316
|
+
message: "Cloudflare account ID:",
|
|
317
|
+
validate: validateRequired,
|
|
318
|
+
});
|
|
319
|
+
endpoint = `https://${accountId}.r2.cloudflarestorage.com`;
|
|
320
|
+
region = "auto";
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
region = await input({ message: "AWS region:", default: "us-east-1" });
|
|
324
|
+
endpoint = `https://s3.${region}.amazonaws.com`;
|
|
325
|
+
}
|
|
326
|
+
const meta = {
|
|
327
|
+
status: "configured",
|
|
328
|
+
endpoint,
|
|
329
|
+
region,
|
|
330
|
+
location,
|
|
331
|
+
lastVerified: new Date().toISOString(),
|
|
332
|
+
};
|
|
333
|
+
store.set(`providers.s3.${provider}`, meta);
|
|
334
|
+
await setSecret(SECRET_KEYS.s3AccessKey(provider), promptedAccessKey);
|
|
335
|
+
await setSecret(SECRET_KEYS.s3SecretKey(provider), promptedSecretKey);
|
|
336
|
+
console.log(chalk.green(` ✓ ${provider} S3 configured`));
|
|
337
|
+
return { ...meta, accessKey: promptedAccessKey, secretKey: promptedSecretKey };
|
|
338
|
+
}
|
|
339
|
+
export async function getS3Config(provider) {
|
|
340
|
+
await migrateSecret(`providers.s3.${provider}.accessKey`, SECRET_KEYS.s3AccessKey(provider));
|
|
341
|
+
await migrateSecret(`providers.s3.${provider}.secretKey`, SECRET_KEYS.s3SecretKey(provider));
|
|
342
|
+
const meta = store.get(`providers.s3.${provider}`);
|
|
343
|
+
if (!meta || meta.status !== "configured")
|
|
344
|
+
return null;
|
|
345
|
+
const accessKey = await getSecret(SECRET_KEYS.s3AccessKey(provider));
|
|
346
|
+
const secretKey = await getSecret(SECRET_KEYS.s3SecretKey(provider));
|
|
347
|
+
if (!accessKey || !secretKey)
|
|
348
|
+
return null;
|
|
349
|
+
return { ...meta, accessKey, secretKey };
|
|
350
|
+
}
|
|
351
|
+
// ---------------------------------------------------------------------------
|
|
352
|
+
// Provider: GPU (Modal, RunPod, etc.)
|
|
353
|
+
// ---------------------------------------------------------------------------
|
|
354
|
+
export async function ensureGpuProvider(platform) {
|
|
355
|
+
await migrateSecret(`providers.gpu.${platform}.apiKey`, SECRET_KEYS.gpuApiKey(platform));
|
|
356
|
+
const existing = store.get(`providers.gpu.${platform}`);
|
|
357
|
+
const existingKey = await getSecret(SECRET_KEYS.gpuApiKey(platform));
|
|
358
|
+
if (existing?.status === "configured" && (platform === "modal" || existingKey)) {
|
|
359
|
+
return { ...existing, apiKey: existingKey ?? undefined };
|
|
360
|
+
}
|
|
361
|
+
console.log(chalk.yellow(`\n ${platform} is not configured yet. Let's set it up.`));
|
|
362
|
+
let apiKey;
|
|
363
|
+
switch (platform) {
|
|
364
|
+
case "modal": {
|
|
365
|
+
// Modal uses its own CLI auth — no API key to store here.
|
|
366
|
+
const hasModal = await execOk("modal", ["token", "peek"]);
|
|
367
|
+
if (!hasModal) {
|
|
368
|
+
console.log(" Running modal setup...");
|
|
369
|
+
const { execStream } = await import("./utils/exec.js");
|
|
370
|
+
await execStream("modal", ["setup"]);
|
|
371
|
+
}
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
case "runpod":
|
|
375
|
+
apiKey = await password({ message: "RunPod API key:" });
|
|
376
|
+
break;
|
|
377
|
+
case "hf":
|
|
378
|
+
apiKey = await password({ message: "HuggingFace token (from hf.co/settings/tokens):" });
|
|
379
|
+
break;
|
|
380
|
+
case "replicate":
|
|
381
|
+
apiKey = await password({ message: "Replicate API token:" });
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
const meta = {
|
|
385
|
+
status: "configured",
|
|
386
|
+
lastVerified: new Date().toISOString(),
|
|
387
|
+
};
|
|
388
|
+
store.set(`providers.gpu.${platform}`, meta);
|
|
389
|
+
if (apiKey)
|
|
390
|
+
await setSecret(SECRET_KEYS.gpuApiKey(platform), apiKey);
|
|
391
|
+
console.log(chalk.green(` ✓ ${platform} configured`));
|
|
392
|
+
return { ...meta, apiKey };
|
|
393
|
+
}
|
|
394
|
+
export async function getGpuConfig(platform) {
|
|
395
|
+
await migrateSecret(`providers.gpu.${platform}.apiKey`, SECRET_KEYS.gpuApiKey(platform));
|
|
396
|
+
const meta = store.get(`providers.gpu.${platform}`);
|
|
397
|
+
if (!meta || meta.status !== "configured")
|
|
398
|
+
return null;
|
|
399
|
+
const apiKey = await getSecret(SECRET_KEYS.gpuApiKey(platform));
|
|
400
|
+
return { ...meta, apiKey: apiKey ?? undefined };
|
|
401
|
+
}
|
|
402
|
+
// ---------------------------------------------------------------------------
|
|
403
|
+
// Port registry (shared across all scaffolded projects)
|
|
404
|
+
// ---------------------------------------------------------------------------
|
|
405
|
+
export function getUsedPorts() {
|
|
406
|
+
return store.get("usedPorts") ?? [];
|
|
407
|
+
}
|
|
408
|
+
export function addUsedPorts(ports) {
|
|
409
|
+
const existing = new Set(getUsedPorts());
|
|
410
|
+
for (const p of ports)
|
|
411
|
+
existing.add(p);
|
|
412
|
+
store.set("usedPorts", [...existing].sort((a, b) => a - b));
|
|
413
|
+
}
|
|
414
|
+
/** Remove ports from the used-ports registry. Used for rollback when a
|
|
415
|
+
* scaffold that already claimed ports subsequently fails. */
|
|
416
|
+
export function removeUsedPorts(ports) {
|
|
417
|
+
const remove = new Set(ports);
|
|
418
|
+
const remaining = getUsedPorts().filter((p) => !remove.has(p));
|
|
419
|
+
store.set("usedPorts", remaining);
|
|
420
|
+
}
|
|
421
|
+
// ---------------------------------------------------------------------------
|
|
422
|
+
// ML Service Registry
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
export function getMlServices() {
|
|
425
|
+
return store.get("mlServices") || {};
|
|
426
|
+
}
|
|
427
|
+
export function registerMlService(name, entry) {
|
|
428
|
+
store.set(`mlServices.${name}`, entry);
|
|
429
|
+
}
|
|
430
|
+
// ---------------------------------------------------------------------------
|
|
431
|
+
// Provider: GlitchTip (self-hosted error tracking, Sentry-compatible API)
|
|
432
|
+
// ---------------------------------------------------------------------------
|
|
433
|
+
export async function ensureGlitchtip() {
|
|
434
|
+
const existing = store.get("providers.glitchtip");
|
|
435
|
+
const existingToken = await getSecret(SECRET_KEYS.glitchtipToken);
|
|
436
|
+
if (existing?.status === "configured" && existingToken) {
|
|
437
|
+
return { ...existing, token: existingToken };
|
|
438
|
+
}
|
|
439
|
+
console.log(chalk.yellow("\n GlitchTip is not configured yet. Let's set it up."));
|
|
440
|
+
const url = await input({
|
|
441
|
+
message: "GlitchTip base URL:",
|
|
442
|
+
default: existing?.url ?? "https://glitchtip.trebeljahr.com",
|
|
443
|
+
validate: (v) => validateUrl(v),
|
|
444
|
+
});
|
|
445
|
+
const token = await password({
|
|
446
|
+
message: "GlitchTip auth token (Profile → Auth Tokens, needs project:admin):",
|
|
447
|
+
});
|
|
448
|
+
const organizationSlug = await input({
|
|
449
|
+
message: "GlitchTip organization slug:",
|
|
450
|
+
default: existing?.organizationSlug,
|
|
451
|
+
validate: validateRequired,
|
|
452
|
+
});
|
|
453
|
+
const teamSlug = await input({
|
|
454
|
+
message: "GlitchTip team slug (must exist under that org):",
|
|
455
|
+
default: existing?.teamSlug,
|
|
456
|
+
validate: validateRequired,
|
|
457
|
+
});
|
|
458
|
+
const meta = {
|
|
459
|
+
status: "configured",
|
|
460
|
+
url: url.replace(/\/$/, ""),
|
|
461
|
+
organizationSlug,
|
|
462
|
+
teamSlug,
|
|
463
|
+
lastVerified: new Date().toISOString(),
|
|
464
|
+
};
|
|
465
|
+
store.set("providers.glitchtip", meta);
|
|
466
|
+
await setSecret(SECRET_KEYS.glitchtipToken, token);
|
|
467
|
+
console.log(chalk.green(" ✓ GlitchTip configured"));
|
|
468
|
+
return { ...meta, token };
|
|
469
|
+
}
|
|
470
|
+
export async function getGlitchtipConfig() {
|
|
471
|
+
const meta = store.get("providers.glitchtip");
|
|
472
|
+
if (!meta || meta.status !== "configured")
|
|
473
|
+
return null;
|
|
474
|
+
const token = await getSecret(SECRET_KEYS.glitchtipToken);
|
|
475
|
+
if (!token)
|
|
476
|
+
return null;
|
|
477
|
+
return { ...meta, token };
|
|
478
|
+
}
|
|
479
|
+
// ---------------------------------------------------------------------------
|
|
480
|
+
// Provider: OpenPanel (self-hosted product analytics)
|
|
481
|
+
// ---------------------------------------------------------------------------
|
|
482
|
+
export async function ensureOpenpanel() {
|
|
483
|
+
const existing = store.get("providers.openpanel");
|
|
484
|
+
const existingToken = await getSecret(SECRET_KEYS.openpanelToken);
|
|
485
|
+
if (existing?.status === "configured" && existingToken) {
|
|
486
|
+
return { ...existing, token: existingToken };
|
|
487
|
+
}
|
|
488
|
+
console.log(chalk.yellow("\n OpenPanel is not configured yet. Let's set it up."));
|
|
489
|
+
const url = await input({
|
|
490
|
+
message: "OpenPanel base URL:",
|
|
491
|
+
default: existing?.url ?? "https://analytics.trebeljahr.com",
|
|
492
|
+
validate: (v) => validateUrl(v),
|
|
493
|
+
});
|
|
494
|
+
const token = await password({
|
|
495
|
+
message: "OpenPanel personal access token (Settings → Access Tokens):",
|
|
496
|
+
});
|
|
497
|
+
const organizationSlug = await input({
|
|
498
|
+
message: "OpenPanel organization slug:",
|
|
499
|
+
default: existing?.organizationSlug,
|
|
500
|
+
validate: validateRequired,
|
|
501
|
+
});
|
|
502
|
+
const meta = {
|
|
503
|
+
status: "configured",
|
|
504
|
+
url: url.replace(/\/$/, ""),
|
|
505
|
+
organizationSlug,
|
|
506
|
+
lastVerified: new Date().toISOString(),
|
|
507
|
+
};
|
|
508
|
+
store.set("providers.openpanel", meta);
|
|
509
|
+
await setSecret(SECRET_KEYS.openpanelToken, token);
|
|
510
|
+
console.log(chalk.green(" ✓ OpenPanel configured"));
|
|
511
|
+
return { ...meta, token };
|
|
512
|
+
}
|
|
513
|
+
export async function getOpenpanelConfig() {
|
|
514
|
+
const meta = store.get("providers.openpanel");
|
|
515
|
+
if (!meta || meta.status !== "configured")
|
|
516
|
+
return null;
|
|
517
|
+
const token = await getSecret(SECRET_KEYS.openpanelToken);
|
|
518
|
+
if (!token)
|
|
519
|
+
return null;
|
|
520
|
+
return { ...meta, token };
|
|
521
|
+
}
|
|
522
|
+
// ---------------------------------------------------------------------------
|
|
523
|
+
// Provider: Resend (transactional email SaaS)
|
|
524
|
+
// ---------------------------------------------------------------------------
|
|
525
|
+
export async function ensureResend() {
|
|
526
|
+
const existing = store.get("providers.resend");
|
|
527
|
+
const existingKey = await getSecret(SECRET_KEYS.resendApiKey);
|
|
528
|
+
if (existing?.status === "configured" && existingKey) {
|
|
529
|
+
return { ...existing, apiKey: existingKey };
|
|
530
|
+
}
|
|
531
|
+
console.log(chalk.yellow("\n Resend is not configured yet. Let's set it up."));
|
|
532
|
+
const apiKey = await password({
|
|
533
|
+
message: "Resend API key (resend.com/api-keys, needs 'full access'):",
|
|
534
|
+
});
|
|
535
|
+
const spinner = ora("Verifying Resend API key...").start();
|
|
536
|
+
try {
|
|
537
|
+
const res = await fetch("https://api.resend.com/domains", {
|
|
538
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
539
|
+
});
|
|
540
|
+
if (!res.ok)
|
|
541
|
+
throw new Error(`HTTP ${res.status}`);
|
|
542
|
+
spinner.succeed("Resend API key verified");
|
|
543
|
+
}
|
|
544
|
+
catch (error) {
|
|
545
|
+
spinner.fail("Could not verify Resend API key");
|
|
546
|
+
throw error;
|
|
547
|
+
}
|
|
548
|
+
const meta = {
|
|
549
|
+
status: "configured",
|
|
550
|
+
lastVerified: new Date().toISOString(),
|
|
551
|
+
};
|
|
552
|
+
store.set("providers.resend", meta);
|
|
553
|
+
await setSecret(SECRET_KEYS.resendApiKey, apiKey);
|
|
554
|
+
console.log(chalk.green(" ✓ Resend configured"));
|
|
555
|
+
return { ...meta, apiKey };
|
|
556
|
+
}
|
|
557
|
+
export async function getResendConfig() {
|
|
558
|
+
const meta = store.get("providers.resend");
|
|
559
|
+
if (!meta || meta.status !== "configured")
|
|
560
|
+
return null;
|
|
561
|
+
const apiKey = await getSecret(SECRET_KEYS.resendApiKey);
|
|
562
|
+
if (!apiKey)
|
|
563
|
+
return null;
|
|
564
|
+
return { ...meta, apiKey };
|
|
565
|
+
}
|
|
566
|
+
// ---------------------------------------------------------------------------
|
|
567
|
+
// First-time setup / onboarding
|
|
568
|
+
// ---------------------------------------------------------------------------
|
|
569
|
+
export async function isFirstRun() {
|
|
570
|
+
const config = getConfig();
|
|
571
|
+
return config.providers.github.status === "unconfigured" && !config.providers.coolify;
|
|
572
|
+
}
|
|
573
|
+
export async function runOnboarding() {
|
|
574
|
+
console.log(chalk.bold("\n Welcome! Let's set up your development infrastructure."));
|
|
575
|
+
console.log(chalk.dim(" This is a one-time setup — metadata is stored locally in"));
|
|
576
|
+
console.log(chalk.dim(` ${getConfigPath()}`));
|
|
577
|
+
console.log(chalk.dim(` Secrets (tokens, passwords) go to your OS keychain.\n`));
|
|
578
|
+
// Core providers
|
|
579
|
+
console.log(chalk.bold(" ── Core Providers (required) ──────────────────────────────\n"));
|
|
580
|
+
await ensureGitHub();
|
|
581
|
+
await ensureCoolify();
|
|
582
|
+
// Infrastructure providers
|
|
583
|
+
console.log(chalk.bold("\n ── Infrastructure Providers ───────────────────────────────\n"));
|
|
584
|
+
const configHetzner = await confirm({
|
|
585
|
+
message: "Configure Hetzner Cloud? (needed for new servers)",
|
|
586
|
+
default: true,
|
|
587
|
+
});
|
|
588
|
+
if (configHetzner) {
|
|
589
|
+
await ensureHetzner();
|
|
590
|
+
}
|
|
591
|
+
await ensureDns();
|
|
592
|
+
// Storage — all skippable
|
|
593
|
+
console.log(chalk.bold("\n ── Storage Providers (configure as needed) ────────────────\n"));
|
|
594
|
+
const configStorage = await confirm({
|
|
595
|
+
message: "Configure any S3 storage provider now?",
|
|
596
|
+
default: false,
|
|
597
|
+
});
|
|
598
|
+
if (configStorage) {
|
|
599
|
+
const s3Provider = await select({
|
|
600
|
+
message: "Which S3 provider?",
|
|
601
|
+
choices: [
|
|
602
|
+
{ name: "Hetzner Object Storage", value: "hetzner" },
|
|
603
|
+
{ name: "AWS S3", value: "aws" },
|
|
604
|
+
{ name: "Cloudflare R2", value: "r2" },
|
|
605
|
+
],
|
|
606
|
+
});
|
|
607
|
+
await ensureS3(s3Provider);
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
console.log(chalk.dim(" Skipped — will prompt when you first need S3 storage."));
|
|
611
|
+
}
|
|
612
|
+
// GPU — all skippable
|
|
613
|
+
console.log(chalk.bold("\n ── GPU / ML Providers (configure when needed) ─────────────\n"));
|
|
614
|
+
console.log(chalk.dim(" Skipped — will prompt when you first add an ML service.\n"));
|
|
615
|
+
// Done
|
|
616
|
+
console.log(chalk.bold(" ── Done! ──────────────────────────────────────────────────\n"));
|
|
617
|
+
const configuredProviders = ["GitHub"];
|
|
618
|
+
if (store.get("providers.coolify"))
|
|
619
|
+
configuredProviders.push("Coolify");
|
|
620
|
+
if (store.get("providers.hetzner"))
|
|
621
|
+
configuredProviders.push("Hetzner Cloud");
|
|
622
|
+
const dnsMeta = store.get("providers.dns");
|
|
623
|
+
if (dnsMeta?.provider && dnsMeta.provider !== "manual") {
|
|
624
|
+
configuredProviders.push(dnsMeta.provider.toUpperCase());
|
|
625
|
+
}
|
|
626
|
+
console.log(chalk.green(` ✓ Providers configured: ${configuredProviders.join(", ")}`));
|
|
627
|
+
console.log(chalk.dim(" ✓ Skipped providers will be prompted when first needed.\n"));
|
|
628
|
+
}
|
|
629
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|