Flatten the repo: move everything out of app/ to the root
Now that the CLI and the Next.js app are one package, nesting it inside app/ served no purpose - the repo root itself becomes the published npm package. Merges app/.gitignore and app/README.md into the root versions, drops the now-duplicate app/LICENSE, and updates path references (README, docs/ARCHITECTURE.md, docs/CONFIG_REFERENCE.md, package.json's repository.directory) that assumed the app/ nesting. Also fixes a real bug this surfaced: the in-app docs viewer resolved docs/ relative to process.cwd(), which only worked by accident when the CLI happened to be invoked from app/'s parent directory. A first attempt at fixing it with import.meta.dirname broke instead, for the same cross-module-graph reason config-path resolution already documented - Next compiles Route Handlers through a separate module graph that doesn't preserve source-relative import.meta paths. Fixed by exposing the app root via TRIGGERSHELL_APP_ROOT (set once in server.ts, where import.meta *does* resolve correctly), the same pattern already used for TRIGGERSHELL_CONFIG_PATH. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { resolveAppRoot } from "../lib/paths";
|
||||
|
||||
const DEFAULT_CONFIG_NAME = "triggershell.yml";
|
||||
|
||||
export interface InitOptions {
|
||||
port: number;
|
||||
auth: boolean;
|
||||
force: boolean;
|
||||
}
|
||||
|
||||
export async function initCommand(targetPath: string | undefined, opts: InitOptions): Promise<void> {
|
||||
const targetDir = path.resolve(process.cwd(), targetPath ?? ".");
|
||||
fs.mkdirSync(targetDir, { recursive: true });
|
||||
const configPath = path.join(targetDir, DEFAULT_CONFIG_NAME);
|
||||
|
||||
if (fs.existsSync(configPath) && !opts.force) {
|
||||
console.error(`${configPath} already exists. Use --force to overwrite.`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
const templatePath = path.join(resolveAppRoot(), "templates", DEFAULT_CONFIG_NAME);
|
||||
const template = fs.readFileSync(templatePath, "utf-8");
|
||||
const rendered = template
|
||||
.replace("__PORT__", String(opts.port))
|
||||
.replace("__AUTH_ENABLED__", opts.auth ? "true" : "false");
|
||||
fs.writeFileSync(configPath, rendered);
|
||||
console.log(`Created ${configPath}`);
|
||||
|
||||
const envPath = path.join(targetDir, ".env");
|
||||
if (opts.auth) {
|
||||
if (fs.existsSync(envPath)) {
|
||||
console.log(
|
||||
`${envPath} already exists - make sure it sets TRIGGERSHELL_SESSION_SECRET (>= 32 chars).`,
|
||||
);
|
||||
} else {
|
||||
const sessionSecret = crypto.randomBytes(32).toString("hex");
|
||||
fs.writeFileSync(envPath, `TRIGGERSHELL_SESSION_SECRET=${sessionSecret}\n`);
|
||||
console.log(`Created ${envPath} (keep this out of version control)`);
|
||||
}
|
||||
console.log("\nAuth is enabled but no users are configured yet. Add one with:");
|
||||
console.log(` triggershell users add <username> --config ${configPath}`);
|
||||
}
|
||||
|
||||
console.log("\nStart the app with:");
|
||||
console.log(` triggershell start --config ${configPath}`);
|
||||
}
|
||||
Reference in New Issue
Block a user