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/index.js
ADDED
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { confirm } from "@inquirer/prompts";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { ensureCoolify, ensureDns, ensureGitHub, ensureGlitchtip, ensureGpuProvider, ensureHetzner, ensureOpenpanel, ensureResend, ensureS3, getConfig, getConfigPath, getMlServices, isFirstRun, resetConfig, runOnboarding, } from "./config.js";
|
|
6
|
+
import { runCoolifySetup } from "./deploy/coolify.js";
|
|
7
|
+
import { setupGitHub } from "./deploy/github.js";
|
|
8
|
+
import { deployMlServices } from "./deploy/gpu.js";
|
|
9
|
+
import { pushProjectKeyToCoolify, showProjectKey } from "./deploy/keys.js";
|
|
10
|
+
import { runTerraform } from "./deploy/terraform.js";
|
|
11
|
+
import { collectProjectConfig } from "./prompts.js";
|
|
12
|
+
import { runProvision } from "./provision/index.js";
|
|
13
|
+
import { scaffoldApp } from "./scaffold/app.js";
|
|
14
|
+
import { scaffoldInfra } from "./scaffold/infra.js";
|
|
15
|
+
import { mlEnvVarName, printMlSummary, resolveMlServices } from "./scaffold/ml-client.js";
|
|
16
|
+
import { runUpdate } from "./scaffold/update.js";
|
|
17
|
+
import { exec, execOk } from "./utils/exec.js";
|
|
18
|
+
import { parseCreateFlags } from "./utils/flags.js";
|
|
19
|
+
import { getCliVersion } from "./utils/version.js";
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// CLI
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const args = process.argv.slice(2);
|
|
24
|
+
const command = args[0];
|
|
25
|
+
// Resolve the monorepo root. From both `cli/src/index.ts` (tsx) and
|
|
26
|
+
// `cli/dist/index.js` (compiled), two parent hops land at the worktree.
|
|
27
|
+
// STARTER_ROOT is resolved inside scaffold/app.ts (not here) — it's
|
|
28
|
+
// only needed from that module.
|
|
29
|
+
const MONOREPO_ROOT = resolve(join(import.meta.dirname, "..", ".."));
|
|
30
|
+
const INFRA_ROOT = join(MONOREPO_ROOT, "infra");
|
|
31
|
+
const SERVICES_ROOT = join(MONOREPO_ROOT, "services");
|
|
32
|
+
async function main() {
|
|
33
|
+
// --version / -v short-circuit before the banner and any config work.
|
|
34
|
+
if (command === "--version" || command === "-v") {
|
|
35
|
+
console.log(getCliVersion());
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
console.log(chalk.bold(`\n hatchkit v${getCliVersion()}\n`));
|
|
39
|
+
// Global --help without a subcommand prints the top-level help.
|
|
40
|
+
if (command === "--help" || command === "-h") {
|
|
41
|
+
printHelp();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
switch (command) {
|
|
45
|
+
case "init":
|
|
46
|
+
if (args.includes("--help"))
|
|
47
|
+
return printHelp("init");
|
|
48
|
+
await runOnboarding();
|
|
49
|
+
break;
|
|
50
|
+
case "config":
|
|
51
|
+
if (args.includes("--help") && args.length === 2)
|
|
52
|
+
return printHelp("config");
|
|
53
|
+
await handleConfig();
|
|
54
|
+
break;
|
|
55
|
+
case "create":
|
|
56
|
+
case undefined:
|
|
57
|
+
if (args.includes("--help"))
|
|
58
|
+
return printHelp("create");
|
|
59
|
+
await handleCreate();
|
|
60
|
+
break;
|
|
61
|
+
case "update":
|
|
62
|
+
if (args.includes("--help"))
|
|
63
|
+
return printHelp("update");
|
|
64
|
+
await handleUpdate();
|
|
65
|
+
break;
|
|
66
|
+
case "keys":
|
|
67
|
+
if (args.includes("--help") && args.length === 2)
|
|
68
|
+
return printHelp("keys");
|
|
69
|
+
await handleKeys();
|
|
70
|
+
break;
|
|
71
|
+
case "provision":
|
|
72
|
+
if (args.includes("--help"))
|
|
73
|
+
return printHelp("provision");
|
|
74
|
+
await handleProvision();
|
|
75
|
+
break;
|
|
76
|
+
default:
|
|
77
|
+
printHelp();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function handleKeys() {
|
|
81
|
+
const sub = args[1];
|
|
82
|
+
const projectName = args[2];
|
|
83
|
+
if (!sub || !projectName) {
|
|
84
|
+
console.log("Usage: hatchkit keys <show|push> <project-name>");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
switch (sub) {
|
|
88
|
+
case "show":
|
|
89
|
+
await showProjectKey(projectName);
|
|
90
|
+
break;
|
|
91
|
+
case "push":
|
|
92
|
+
await pushProjectKeyToCoolify(projectName);
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
console.log(`Unknown keys subcommand: ${sub}`);
|
|
96
|
+
console.log("Valid: show, push");
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function handleProvision() {
|
|
101
|
+
// Positional args are optional — anything missing is prompted for.
|
|
102
|
+
// hatchkit provision (fully interactive)
|
|
103
|
+
// hatchkit provision raptor-runner (prompts for services)
|
|
104
|
+
// hatchkit provision raptor-runner all
|
|
105
|
+
// hatchkit provision raptor-runner glitchtip,resend
|
|
106
|
+
const positional = args.slice(1).filter((a) => !a.startsWith("--"));
|
|
107
|
+
let baseName = positional[0];
|
|
108
|
+
const rawService = positional[1];
|
|
109
|
+
const allServices = ["glitchtip", "openpanel", "resend"];
|
|
110
|
+
if (!baseName) {
|
|
111
|
+
const { input } = await import("@inquirer/prompts");
|
|
112
|
+
const { validateProjectName } = await import("./utils/validate.js");
|
|
113
|
+
baseName = await input({
|
|
114
|
+
message: "Base name for the new clients (e.g. raptor-runner):",
|
|
115
|
+
validate: validateProjectName,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
let services;
|
|
119
|
+
if (!rawService) {
|
|
120
|
+
const { checkbox } = await import("@inquirer/prompts");
|
|
121
|
+
services = await checkbox({
|
|
122
|
+
message: "Which services to provision (-dev and -prod pair each)?",
|
|
123
|
+
choices: [
|
|
124
|
+
{ name: "GlitchTip (error tracking)", value: "glitchtip", checked: true },
|
|
125
|
+
{ name: "OpenPanel (product analytics)", value: "openpanel", checked: true },
|
|
126
|
+
{ name: "Resend (transactional email)", value: "resend", checked: true },
|
|
127
|
+
],
|
|
128
|
+
required: true,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else if (rawService === "all") {
|
|
132
|
+
services = allServices;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const requested = rawService.split(",").map((s) => s.trim().toLowerCase());
|
|
136
|
+
const invalid = requested.filter((s) => !allServices.includes(s));
|
|
137
|
+
if (invalid.length > 0) {
|
|
138
|
+
console.log(chalk.red(` Unknown service(s): ${invalid.join(", ")}`));
|
|
139
|
+
console.log(chalk.dim(` Valid: ${allServices.join(", ")}, or 'all'`));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
services = requested;
|
|
143
|
+
}
|
|
144
|
+
await runProvision({ baseName, services });
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Commands
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
async function handleCreate() {
|
|
150
|
+
// Parse CLI flags. `--yes` (with optional `--config <path>`) turns
|
|
151
|
+
// the flow non-interactive; otherwise we still prompt for anything
|
|
152
|
+
// not supplied via flags / config file.
|
|
153
|
+
const flags = parseCreateFlags(args);
|
|
154
|
+
const { yes: nonInteractive, dryRun, presets, forceNoGithub, forceNoDeploy } = flags;
|
|
155
|
+
// Check if first run (skip onboarding when non-interactive — the
|
|
156
|
+
// onboarding prompts would stall automation).
|
|
157
|
+
if (!nonInteractive && (await isFirstRun())) {
|
|
158
|
+
await runOnboarding();
|
|
159
|
+
}
|
|
160
|
+
// Collect project config via interactive prompts (or presets).
|
|
161
|
+
const config = await collectProjectConfig({ dryRun, presets, nonInteractive });
|
|
162
|
+
if (forceNoGithub)
|
|
163
|
+
config.createGithubRepo = false;
|
|
164
|
+
if (forceNoDeploy)
|
|
165
|
+
config.runDeployment = false;
|
|
166
|
+
// Ensure needed providers are configured (lazy prompting).
|
|
167
|
+
// Coolify + Hetzner are only needed when actually deploying —
|
|
168
|
+
// scaffold-only + --no-deploy runs skip their setup prompts.
|
|
169
|
+
if (config.deployTarget === "existing" || config.runDeployment) {
|
|
170
|
+
await ensureCoolify();
|
|
171
|
+
}
|
|
172
|
+
// GitHub is checked here so auth failures surface before scaffold
|
|
173
|
+
// (not deep inside `setupGitHub` after files are on disk).
|
|
174
|
+
if (config.createGithubRepo) {
|
|
175
|
+
await ensureGitHub();
|
|
176
|
+
}
|
|
177
|
+
if (config.deployTarget === "new" && config.runDeployment) {
|
|
178
|
+
await ensureHetzner();
|
|
179
|
+
}
|
|
180
|
+
if (config.features.includes("s3") &&
|
|
181
|
+
config.s3Provider !== "existing" &&
|
|
182
|
+
config.s3Provider !== "none") {
|
|
183
|
+
if (config.s3Provider === "hetzner" ||
|
|
184
|
+
config.s3Provider === "aws" ||
|
|
185
|
+
config.s3Provider === "r2") {
|
|
186
|
+
await ensureS3(config.s3Provider);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const appDir = resolve(config.name);
|
|
190
|
+
// Resolve ML services (reuse or deploy)
|
|
191
|
+
const { reuse, deploy } = await resolveMlServices(config);
|
|
192
|
+
if (config.mlServices.length > 0) {
|
|
193
|
+
printMlSummary(reuse, deploy);
|
|
194
|
+
}
|
|
195
|
+
// Summary before execution
|
|
196
|
+
console.log(chalk.bold("\n ── Summary ───────────────────────────────────────────────\n"));
|
|
197
|
+
console.log(` Project: ${chalk.cyan(config.name)}`);
|
|
198
|
+
console.log(` Domain: ${chalk.cyan(config.domain)}`);
|
|
199
|
+
console.log(` Deploy to: ${config.deployTarget === "existing" ? `existing server (${config.serverIp})` : `new Hetzner ${config.serverSize}`}`);
|
|
200
|
+
console.log(` Features: ${config.features.length > 0 ? config.features.join(", ") : "none"}`);
|
|
201
|
+
console.log(` ML: ${config.mlServices.length > 0 ? config.mlServices.join(", ") : "none"}`);
|
|
202
|
+
console.log(` Scaffold: ${config.scaffoldRepo ? "yes" : "no"}`);
|
|
203
|
+
console.log(` GitHub: ${config.createGithubRepo ? "yes" : "no"}`);
|
|
204
|
+
console.log(` Deploy now: ${config.runDeployment ? "yes" : "no"}`);
|
|
205
|
+
if (config.dryRun) {
|
|
206
|
+
console.log(chalk.yellow("\n [dry-run mode — no changes will be made]\n"));
|
|
207
|
+
}
|
|
208
|
+
// Step 1: Scaffold app repo
|
|
209
|
+
let scaffoldResult;
|
|
210
|
+
if (config.scaffoldRepo) {
|
|
211
|
+
scaffoldResult = await scaffoldApp(config, appDir);
|
|
212
|
+
const { ports } = scaffoldResult;
|
|
213
|
+
console.log(chalk.dim(` Ports: server=${ports.server}, client=${ports.client}` +
|
|
214
|
+
(ports.nativeHmr ? `, native HMR=${ports.nativeHmr}` : "")));
|
|
215
|
+
if (scaffoldResult.dotenvx) {
|
|
216
|
+
const { printDotenvxSummary } = await import("./scaffold/dotenvx.js");
|
|
217
|
+
printDotenvxSummary(scaffoldResult.dotenvx, config.name);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (config.dryRun) {
|
|
221
|
+
scaffoldInfra(config, INFRA_ROOT, {
|
|
222
|
+
serverPort: scaffoldResult?.ports.server,
|
|
223
|
+
clientPort: scaffoldResult?.ports.client,
|
|
224
|
+
});
|
|
225
|
+
console.log(chalk.green("\n ✓ Dry run complete. No changes were made.\n"));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Step 2: Install deps. Required for the initial commit to pick up
|
|
229
|
+
// the lockfile delta and for the user to `pnpm dev` immediately.
|
|
230
|
+
let installedDeps = false;
|
|
231
|
+
if (config.scaffoldRepo) {
|
|
232
|
+
const hasPnpm = await execOk("pnpm", ["--version"]);
|
|
233
|
+
if (!hasPnpm) {
|
|
234
|
+
console.log(chalk.yellow(" pnpm not found on PATH — skipping install step. Install deps with your preferred tool once available."));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// In non-interactive mode, auto-accept the install so `--yes`
|
|
238
|
+
// doesn't stall waiting on a y/n prompt.
|
|
239
|
+
const shouldInstall = nonInteractive
|
|
240
|
+
? true
|
|
241
|
+
: await confirm({
|
|
242
|
+
message: "Install dependencies now (pnpm install)?",
|
|
243
|
+
default: true,
|
|
244
|
+
});
|
|
245
|
+
if (shouldInstall) {
|
|
246
|
+
const res = await exec("pnpm", ["install"], {
|
|
247
|
+
cwd: appDir,
|
|
248
|
+
spinner: "Installing dependencies...",
|
|
249
|
+
});
|
|
250
|
+
if (res.exitCode === 0) {
|
|
251
|
+
installedDeps = true;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.log(chalk.yellow(" pnpm install failed — continuing anyway."));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Step 3: Git + GitHub — must run BEFORE scaffoldInfra so the repo
|
|
260
|
+
// URL can be threaded into the Coolify env (GITHUB_REPO_URL).
|
|
261
|
+
let repoUrl = null;
|
|
262
|
+
if (config.scaffoldRepo) {
|
|
263
|
+
repoUrl = await setupGitHub(config, appDir);
|
|
264
|
+
}
|
|
265
|
+
// Step 4: Generate infra configs (with repo URL + ports baked in).
|
|
266
|
+
scaffoldInfra(config, INFRA_ROOT, {
|
|
267
|
+
repoUrl: repoUrl ?? undefined,
|
|
268
|
+
serverPort: scaffoldResult?.ports.server,
|
|
269
|
+
clientPort: scaffoldResult?.ports.client,
|
|
270
|
+
});
|
|
271
|
+
// Step 5: Terraform (DNS + optionally server)
|
|
272
|
+
if (config.runDeployment) {
|
|
273
|
+
await runTerraform(config, INFRA_ROOT);
|
|
274
|
+
}
|
|
275
|
+
// Step 6: Coolify setup
|
|
276
|
+
if (config.runDeployment) {
|
|
277
|
+
await runCoolifySetup(config, INFRA_ROOT);
|
|
278
|
+
// Push the dotenvx private key to Coolify so the starter's server
|
|
279
|
+
// can decrypt .env.production at runtime. Best-effort — if the
|
|
280
|
+
// Coolify app doesn't exist yet (race with the stack script), we
|
|
281
|
+
// print the manual command instead of failing the whole flow.
|
|
282
|
+
if (scaffoldResult?.dotenvx) {
|
|
283
|
+
try {
|
|
284
|
+
await pushProjectKeyToCoolify(config.name);
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
console.log(chalk.yellow(` Couldn't auto-push dotenvx key: ${err.message}`));
|
|
288
|
+
console.log(chalk.dim(` Push manually once the Coolify app exists: hatchkit keys push ${config.name}`));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Step 7: Deploy ML services
|
|
293
|
+
if (config.runDeployment && deploy.length > 0 && config.gpuPlatform) {
|
|
294
|
+
const endpoints = await deployMlServices(deploy, config.gpuPlatform, SERVICES_ROOT, config.customHfModelId);
|
|
295
|
+
// Print env vars to set
|
|
296
|
+
if (Object.keys(endpoints).length > 0) {
|
|
297
|
+
console.log(chalk.bold("\n ML service endpoints (add to Coolify env):"));
|
|
298
|
+
for (const [service, endpoint] of Object.entries(endpoints)) {
|
|
299
|
+
// Service keys come from our own `deploy: MlService[]` so the
|
|
300
|
+
// cast is sound, but narrow via the literal-array check so a
|
|
301
|
+
// stray unknown slips don't silently format wrong.
|
|
302
|
+
const knownServices = [
|
|
303
|
+
"3d-extraction",
|
|
304
|
+
"subtitles",
|
|
305
|
+
"image-recognition",
|
|
306
|
+
"background-removal",
|
|
307
|
+
"custom-hf",
|
|
308
|
+
];
|
|
309
|
+
if (knownServices.includes(service)) {
|
|
310
|
+
console.log(chalk.dim(` ${mlEnvVarName(service)}=${endpoint}`));
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Final summary
|
|
316
|
+
console.log(chalk.bold("\n ── Done! ─────────────────────────────────────────────────\n"));
|
|
317
|
+
console.log(` App: ${chalk.cyan(`https://${config.domain}`)}`);
|
|
318
|
+
console.log(` API: ${chalk.cyan(`https://api.${config.domain}`)}`);
|
|
319
|
+
console.log(` App dir: ${chalk.dim(appDir)}`);
|
|
320
|
+
console.log(` Config: ${chalk.dim(getConfigPath())}`);
|
|
321
|
+
if (config.scaffoldRepo) {
|
|
322
|
+
if (installedDeps) {
|
|
323
|
+
console.log(chalk.yellow(`\n Next: cd ${config.name} && pnpm dev`));
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
console.log(chalk.yellow(`\n Next: cd ${config.name} && pnpm install && pnpm dev`));
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (config.features.includes("stripe")) {
|
|
330
|
+
console.log(chalk.yellow("\n Next: Set STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRET in Coolify"));
|
|
331
|
+
}
|
|
332
|
+
if (config.features.includes("mobile")) {
|
|
333
|
+
console.log(chalk.yellow("\n Next (mobile): generate native projects once:"));
|
|
334
|
+
console.log(chalk.dim(" pnpm cap:add:ios # requires Xcode"));
|
|
335
|
+
console.log(chalk.dim(" pnpm cap:add:android # requires Android Studio / SDK"));
|
|
336
|
+
}
|
|
337
|
+
if (config.features.includes("desktop")) {
|
|
338
|
+
console.log(chalk.yellow("\n Next (desktop): replace build/icon.png with a 512×512 logo, then:"));
|
|
339
|
+
console.log(chalk.dim(" pnpm icons:desktop # cross-platform (electron-icon-builder)"));
|
|
340
|
+
}
|
|
341
|
+
if (config.features.includes("desktop") || config.features.includes("mobile")) {
|
|
342
|
+
console.log(chalk.yellow("\n Server CORS: TRUSTED_ORIGINS is already set in .env.example for native clients."));
|
|
343
|
+
console.log(chalk.dim(" Make sure the same values land in your production env (Coolify / secret store)."));
|
|
344
|
+
// Note: file:// sends Origin: null — not safe with credentials. A
|
|
345
|
+
// custom Electron protocol (app://-) is what needs to be trusted.
|
|
346
|
+
}
|
|
347
|
+
console.log();
|
|
348
|
+
}
|
|
349
|
+
async function handleUpdate() {
|
|
350
|
+
const projectDir = resolve(".");
|
|
351
|
+
const result = await runUpdate(projectDir);
|
|
352
|
+
if (result.added.length > 0) {
|
|
353
|
+
console.log(chalk.green(`\n ✓ Added features: ${result.added.join(", ")}`));
|
|
354
|
+
console.log(chalk.yellow(" Run `pnpm install` to pick up the new dependencies."));
|
|
355
|
+
}
|
|
356
|
+
if (result.removed.length > 0) {
|
|
357
|
+
console.log(chalk.yellow(` ⚠ Removal requested but skipped: ${result.removed.join(", ")}`));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async function handleConfig() {
|
|
361
|
+
const subcommand = args[1];
|
|
362
|
+
switch (subcommand) {
|
|
363
|
+
case "add": {
|
|
364
|
+
const provider = args[2];
|
|
365
|
+
if (!provider) {
|
|
366
|
+
console.log("Usage: hatchkit config add <provider>");
|
|
367
|
+
console.log("Providers: coolify, hetzner, dns, s3, modal, runpod, hf, replicate, glitchtip, openpanel, resend");
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
// Handle provider setup based on name
|
|
371
|
+
const gpuPlatforms = ["modal", "runpod", "hf", "replicate"];
|
|
372
|
+
const isGpuPlatform = (p) => gpuPlatforms.includes(p);
|
|
373
|
+
switch (provider) {
|
|
374
|
+
case "coolify":
|
|
375
|
+
await ensureCoolify();
|
|
376
|
+
break;
|
|
377
|
+
case "hetzner":
|
|
378
|
+
await ensureHetzner();
|
|
379
|
+
break;
|
|
380
|
+
case "dns":
|
|
381
|
+
await ensureDns();
|
|
382
|
+
break;
|
|
383
|
+
case "glitchtip":
|
|
384
|
+
await ensureGlitchtip();
|
|
385
|
+
break;
|
|
386
|
+
case "openpanel":
|
|
387
|
+
await ensureOpenpanel();
|
|
388
|
+
break;
|
|
389
|
+
case "resend":
|
|
390
|
+
await ensureResend();
|
|
391
|
+
break;
|
|
392
|
+
case "s3": {
|
|
393
|
+
const { select } = await import("@inquirer/prompts");
|
|
394
|
+
const p = await select({
|
|
395
|
+
message: "S3 provider:",
|
|
396
|
+
choices: [
|
|
397
|
+
{ name: "Hetzner", value: "hetzner" },
|
|
398
|
+
{ name: "AWS", value: "aws" },
|
|
399
|
+
{ name: "R2", value: "r2" },
|
|
400
|
+
],
|
|
401
|
+
});
|
|
402
|
+
await ensureS3(p);
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
default:
|
|
406
|
+
if (!isGpuPlatform(provider)) {
|
|
407
|
+
console.log(chalk.red(` Unknown provider: ${provider}`));
|
|
408
|
+
console.log(chalk.dim(" Valid: coolify, hetzner, dns, s3, modal, runpod, hf, replicate, glitchtip, openpanel, resend"));
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
await ensureGpuProvider(provider);
|
|
412
|
+
}
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
case "reset": {
|
|
416
|
+
const ok = await confirm({
|
|
417
|
+
message: "Clear ALL CLI config (providers, tokens, ML registry)?",
|
|
418
|
+
default: false,
|
|
419
|
+
});
|
|
420
|
+
if (ok) {
|
|
421
|
+
await resetConfig();
|
|
422
|
+
console.log(chalk.green(" ✓ Config cleared."));
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
console.log(chalk.dim(" Cancelled."));
|
|
426
|
+
}
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
default: {
|
|
430
|
+
// Show current config status
|
|
431
|
+
const config = getConfig();
|
|
432
|
+
console.log(chalk.bold("\n Provider Status:\n"));
|
|
433
|
+
console.log(` GitHub: ${config.providers.github.status === "configured" ? chalk.green("✓") : chalk.red("✗")}`);
|
|
434
|
+
console.log(` Coolify: ${config.providers.coolify?.status === "configured" ? chalk.green("✓") : chalk.red("✗")}`);
|
|
435
|
+
console.log(` Hetzner: ${config.providers.hetzner?.status === "configured" ? chalk.green("✓") : chalk.red("✗")}`);
|
|
436
|
+
console.log(` DNS: ${config.providers.dns?.status === "configured" ? chalk.green(`✓ (${config.providers.dns.provider})`) : chalk.red("✗")}`);
|
|
437
|
+
const s3Providers = Object.keys(config.providers.s3);
|
|
438
|
+
console.log(` S3: ${s3Providers.length > 0 ? chalk.green(`✓ (${s3Providers.join(", ")})`) : chalk.dim("not configured")}`);
|
|
439
|
+
const gpuProviders = Object.keys(config.providers.gpu);
|
|
440
|
+
console.log(` GPU: ${gpuProviders.length > 0 ? chalk.green(`✓ (${gpuProviders.join(", ")})`) : chalk.dim("not configured")}`);
|
|
441
|
+
const services = getMlServices();
|
|
442
|
+
const serviceCount = Object.keys(services).length;
|
|
443
|
+
console.log(`\n ML Services: ${serviceCount > 0 ? chalk.green(`${serviceCount} registered`) : chalk.dim("none")}`);
|
|
444
|
+
for (const [name, entry] of Object.entries(services)) {
|
|
445
|
+
console.log(chalk.dim(` ${name}: ${entry.endpoint} (${entry.platform})`));
|
|
446
|
+
}
|
|
447
|
+
console.log(chalk.dim(`\n Config: ${getConfigPath()}\n`));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function printHelp(topic) {
|
|
452
|
+
if (topic === "create") {
|
|
453
|
+
console.log(`
|
|
454
|
+
${chalk.bold("hatchkit create")} — scaffold a new project
|
|
455
|
+
|
|
456
|
+
${chalk.bold("Usage:")}
|
|
457
|
+
hatchkit create [--dry-run]
|
|
458
|
+
|
|
459
|
+
${chalk.bold("What it does (interactively):")}
|
|
460
|
+
1. Prompts for project name, domain, deploy target, features, ML services
|
|
461
|
+
2. Copies the starter template and strips unselected features
|
|
462
|
+
3. Assigns unique ports per project (server, client, native HMR)
|
|
463
|
+
4. Runs \`pnpm install\` (if pnpm is present and you opt in)
|
|
464
|
+
5. Initializes git, optionally creates a GitHub repo
|
|
465
|
+
6. Generates Terraform tfvars + Coolify .env
|
|
466
|
+
7. Optionally deploys: Terraform → Coolify → ML services
|
|
467
|
+
|
|
468
|
+
${chalk.bold("Options:")}
|
|
469
|
+
--dry-run Show the plan without writing anything
|
|
470
|
+
--help Show this help
|
|
471
|
+
`);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
if (topic === "init") {
|
|
475
|
+
console.log(`
|
|
476
|
+
${chalk.bold("hatchkit init")} — one-time onboarding
|
|
477
|
+
|
|
478
|
+
Prompts for: GitHub (via gh CLI), Coolify (URL + token), optionally
|
|
479
|
+
Hetzner Cloud, DNS provider, S3, and GPU platforms. Tokens go to the
|
|
480
|
+
OS keychain; metadata to ${chalk.dim(getConfigPath())}.
|
|
481
|
+
`);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
if (topic === "keys") {
|
|
485
|
+
console.log(`
|
|
486
|
+
${chalk.bold("hatchkit keys")} — manage per-project dotenvx private keys
|
|
487
|
+
|
|
488
|
+
${chalk.bold("Subcommands:")}
|
|
489
|
+
keys show <project> Print DOTENV_PRIVATE_KEY_PRODUCTION from the
|
|
490
|
+
OS keychain. Useful for piping into pbcopy or
|
|
491
|
+
pasting into Coolify / CI secret stores.
|
|
492
|
+
keys push <project> Upsert the key onto the project's Coolify
|
|
493
|
+
app via the Coolify API. Assumes the app
|
|
494
|
+
already exists (created by \`create\` with
|
|
495
|
+
runDeployment or manually).
|
|
496
|
+
|
|
497
|
+
The key is generated at scaffold time and lives in macOS Keychain /
|
|
498
|
+
libsecret under the "hatchkit" service. Never written to git.
|
|
499
|
+
`);
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
if (topic === "update") {
|
|
503
|
+
console.log(`
|
|
504
|
+
${chalk.bold("hatchkit update")} — add features to an already-scaffolded project
|
|
505
|
+
|
|
506
|
+
${chalk.bold("Usage:")}
|
|
507
|
+
cd <project-dir> && hatchkit update
|
|
508
|
+
|
|
509
|
+
${chalk.bold("What it does:")}
|
|
510
|
+
Reads the project's .hatchkit.json manifest, lets you pick a new
|
|
511
|
+
feature set, and copies the additive pieces from the starter.
|
|
512
|
+
Currently supported additions: ${chalk.cyan("desktop")}, ${chalk.cyan("mobile")}.
|
|
513
|
+
|
|
514
|
+
${chalk.bold("Removal is not supported.")} Removing features could delete
|
|
515
|
+
user code — remove manually + edit the manifest.
|
|
516
|
+
`);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
if (topic === "provision") {
|
|
520
|
+
console.log(`
|
|
521
|
+
${chalk.bold("hatchkit provision")} — create per-service clients for an existing project
|
|
522
|
+
|
|
523
|
+
${chalk.bold("Usage:")}
|
|
524
|
+
hatchkit provision [<base-name>] [<services>]
|
|
525
|
+
|
|
526
|
+
Both args are optional — anything missing is prompted for, including a
|
|
527
|
+
multi-select of which services to run. ${chalk.dim("(<services> is 'all', a single")}
|
|
528
|
+
${chalk.dim("service, or a comma-separated list.)")}
|
|
529
|
+
|
|
530
|
+
${chalk.bold("What it does:")}
|
|
531
|
+
For every selected service, creates two clients:
|
|
532
|
+
- ${chalk.cyan("<base-name>-dev")}
|
|
533
|
+
- ${chalk.cyan("<base-name>-prod")}
|
|
534
|
+
…and prints an env block for each, plus saves it under
|
|
535
|
+
${chalk.dim("<config-dir>/provisioned/<base-name>.{dev,prod}.env")}.
|
|
536
|
+
|
|
537
|
+
${chalk.bold("Services:")}
|
|
538
|
+
glitchtip Creates a GlitchTip project, returns GLITCHTIP_DSN
|
|
539
|
+
openpanel Creates an OpenPanel client, returns OPENPANEL_CLIENT_ID/_SECRET
|
|
540
|
+
resend Creates a restricted Resend API key, returns RESEND_API_KEY
|
|
541
|
+
|
|
542
|
+
${chalk.bold("Examples:")}
|
|
543
|
+
hatchkit provision
|
|
544
|
+
hatchkit provision raptor-runner
|
|
545
|
+
hatchkit provision raptor-runner all
|
|
546
|
+
hatchkit provision raptor-runner glitchtip,resend
|
|
547
|
+
`);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (topic === "config") {
|
|
551
|
+
console.log(`
|
|
552
|
+
${chalk.bold("hatchkit config")} — manage provider credentials
|
|
553
|
+
|
|
554
|
+
${chalk.bold("Subcommands:")}
|
|
555
|
+
config Show status of every configured provider
|
|
556
|
+
config add <p> Configure a provider
|
|
557
|
+
(coolify, hetzner, dns, s3, modal, runpod, hf, replicate)
|
|
558
|
+
config reset Clear ALL CLI config (providers, tokens, ML registry, ports)
|
|
559
|
+
`);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
console.log(`
|
|
563
|
+
${chalk.bold("Usage:")} hatchkit <command> [options]
|
|
564
|
+
|
|
565
|
+
${chalk.bold("Commands:")}
|
|
566
|
+
create Scaffold a new project (default)
|
|
567
|
+
provision Create GlitchTip / OpenPanel / Resend clients for an existing project
|
|
568
|
+
update Add features to an already-scaffolded project (run in project dir)
|
|
569
|
+
keys show <p> Print the dotenvx private key for a project
|
|
570
|
+
keys push <p> Push the key onto the project's Coolify app
|
|
571
|
+
init Run first-time setup / onboarding
|
|
572
|
+
config Show provider status
|
|
573
|
+
config add <p> Configure a provider (coolify, hetzner, dns, s3, modal, etc.)
|
|
574
|
+
config reset Clear ALL CLI config (providers, tokens, ML registry, ports)
|
|
575
|
+
|
|
576
|
+
${chalk.bold("Options:")}
|
|
577
|
+
--version, -v Print the CLI version
|
|
578
|
+
--help, -h Show this help message (pass to a subcommand for detail)
|
|
579
|
+
--dry-run (with \`create\`) show what would change without writing
|
|
580
|
+
--yes, -y (with \`create\`) skip prompts, use defaults / --config values
|
|
581
|
+
--config <path> (with \`create\`) load JSON overrides for ProjectConfig fields
|
|
582
|
+
--name <name> (with \`create\`) set project name without prompting
|
|
583
|
+
--no-github (with \`create\`) skip GitHub repo creation
|
|
584
|
+
--no-deploy (with \`create\`) skip Terraform/Coolify/ML deployment
|
|
585
|
+
|
|
586
|
+
${chalk.bold("Environment:")}
|
|
587
|
+
HATCHKIT_CONF_DIR Override the config/ports-registry location
|
|
588
|
+
(advanced — useful for isolated per-workspace state
|
|
589
|
+
or automated testing).
|
|
590
|
+
`);
|
|
591
|
+
}
|
|
592
|
+
// ---------------------------------------------------------------------------
|
|
593
|
+
// Run
|
|
594
|
+
// ---------------------------------------------------------------------------
|
|
595
|
+
main().catch((error) => {
|
|
596
|
+
console.error(chalk.red(`\n Error: ${error.message}\n`));
|
|
597
|
+
process.exit(1);
|
|
598
|
+
});
|
|
599
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|