@fentaris/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/app/main.d.ts +3 -0
  2. package/dist/app/main.d.ts.map +1 -0
  3. package/dist/app/main.js +64 -0
  4. package/dist/app/main.js.map +1 -0
  5. package/dist/commands/auth.d.ts +3 -0
  6. package/dist/commands/auth.d.ts.map +1 -0
  7. package/dist/commands/auth.js +49 -0
  8. package/dist/commands/auth.js.map +1 -0
  9. package/dist/commands/build.d.ts +3 -0
  10. package/dist/commands/build.d.ts.map +1 -0
  11. package/dist/commands/build.js +27 -0
  12. package/dist/commands/build.js.map +1 -0
  13. package/dist/commands/check.d.ts +3 -0
  14. package/dist/commands/check.d.ts.map +1 -0
  15. package/dist/commands/check.js +13 -0
  16. package/dist/commands/check.js.map +1 -0
  17. package/dist/commands/dev.d.ts +3 -0
  18. package/dist/commands/dev.d.ts.map +1 -0
  19. package/dist/commands/dev.js +9 -0
  20. package/dist/commands/dev.js.map +1 -0
  21. package/dist/commands/doctor.d.ts +3 -0
  22. package/dist/commands/doctor.d.ts.map +1 -0
  23. package/dist/commands/doctor.js +11 -0
  24. package/dist/commands/doctor.js.map +1 -0
  25. package/dist/commands/init.d.ts +3 -0
  26. package/dist/commands/init.d.ts.map +1 -0
  27. package/dist/commands/init.js +46 -0
  28. package/dist/commands/init.js.map +1 -0
  29. package/dist/commands/secrets.d.ts +3 -0
  30. package/dist/commands/secrets.d.ts.map +1 -0
  31. package/dist/commands/secrets.js +21 -0
  32. package/dist/commands/secrets.js.map +1 -0
  33. package/dist/domain/auth/local-store.d.ts +11 -0
  34. package/dist/domain/auth/local-store.d.ts.map +1 -0
  35. package/dist/domain/auth/local-store.js +75 -0
  36. package/dist/domain/auth/local-store.js.map +1 -0
  37. package/dist/domain/health/checks.d.ts +6 -0
  38. package/dist/domain/health/checks.d.ts.map +1 -0
  39. package/dist/domain/health/checks.js +124 -0
  40. package/dist/domain/health/checks.js.map +1 -0
  41. package/dist/domain/project/project.d.ts +8 -0
  42. package/dist/domain/project/project.d.ts.map +1 -0
  43. package/dist/domain/project/project.js +92 -0
  44. package/dist/domain/project/project.js.map +1 -0
  45. package/dist/domain/template/template.d.ts +11 -0
  46. package/dist/domain/template/template.d.ts.map +1 -0
  47. package/dist/domain/template/template.js +215 -0
  48. package/dist/domain/template/template.js.map +1 -0
  49. package/dist/index.d.ts +6 -71
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +11 -864
  52. package/dist/index.js.map +1 -1
  53. package/dist/platform/runtime.d.ts +3 -0
  54. package/dist/platform/runtime.d.ts.map +1 -0
  55. package/dist/platform/runtime.js +43 -0
  56. package/dist/platform/runtime.js.map +1 -0
  57. package/dist/shared/constants.d.ts +7 -0
  58. package/dist/shared/constants.d.ts.map +1 -0
  59. package/dist/shared/constants.js +6 -0
  60. package/dist/shared/constants.js.map +1 -0
  61. package/dist/shared/parse.d.ts +3 -0
  62. package/dist/shared/parse.d.ts.map +1 -0
  63. package/dist/shared/parse.js +22 -0
  64. package/dist/shared/parse.js.map +1 -0
  65. package/dist/shared/types.d.ts +61 -0
  66. package/dist/shared/types.d.ts.map +1 -0
  67. package/dist/shared/types.js +2 -0
  68. package/dist/shared/types.js.map +1 -0
  69. package/dist/shared/utils.d.ts +11 -0
  70. package/dist/shared/utils.d.ts.map +1 -0
  71. package/dist/shared/utils.js +54 -0
  72. package/dist/shared/utils.js.map +1 -0
  73. package/dist/ui/format.d.ts +17 -0
  74. package/dist/ui/format.d.ts.map +1 -0
  75. package/dist/ui/format.js +79 -0
  76. package/dist/ui/format.js.map +1 -0
  77. package/package.json +7 -7
  78. package/dist/index.test.d.ts +0 -2
  79. package/dist/index.test.d.ts.map +0 -1
  80. package/dist/index.test.js +0 -150
  81. package/dist/index.test.js.map +0 -1
@@ -0,0 +1,8 @@
1
+ import type { ExecProbe, PackageManager, ProcessRunner, ProjectDiscovery, Prompt } from "../../shared/types.js";
2
+ export declare function resolveProjectName(provided: string | undefined, prompt: Prompt): Promise<string>;
3
+ export declare function ensureEmptyTargetDirectory(targetDir: string): Promise<void>;
4
+ export declare function selectPackageManager(probe: ExecProbe, prompt: Prompt): Promise<PackageManager>;
5
+ export declare function discoverProject(fromDir: string): Promise<ProjectDiscovery>;
6
+ export declare function runPackageInstall(packageManager: PackageManager, cwd: string, runner: ProcessRunner): Promise<void>;
7
+ export declare function runPackageScript(packageManager: PackageManager, cwd: string, script: string, runner: ProcessRunner): Promise<void>;
8
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/domain/project/project.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAiB,gBAAgB,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/H,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWtG;AAED,wBAAsB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAajF;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAWpG;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqBhF;AAED,wBAAsB,iBAAiB,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzH;AAED,wBAAsB,gBAAgB,CAAC,cAAc,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxI"}
@@ -0,0 +1,92 @@
1
+ import { readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { supportedPackageManagers } from "../../shared/constants.js";
4
+ import { exists, isNodeError, readJson } from "../../shared/utils.js";
5
+ export async function resolveProjectName(provided, prompt) {
6
+ const value = provided?.trim() || (await prompt.text("Project name"));
7
+ if (!value.trim()) {
8
+ throw new Error("Project name is required.");
9
+ }
10
+ if (!/^[a-zA-Z0-9._-]+$/.test(value)) {
11
+ throw new Error("Project name may only contain letters, numbers, dots, underscores, and hyphens.");
12
+ }
13
+ return value;
14
+ }
15
+ export async function ensureEmptyTargetDirectory(targetDir) {
16
+ try {
17
+ const current = await readdir(targetDir);
18
+ if (current.length > 0) {
19
+ throw new Error(`Fentaris can only initialize into a new or empty directory: ${targetDir}`);
20
+ }
21
+ }
22
+ catch (error) {
23
+ if (isNodeError(error, "ENOENT")) {
24
+ return;
25
+ }
26
+ throw error;
27
+ }
28
+ }
29
+ export async function selectPackageManager(probe, prompt) {
30
+ const available = supportedPackageManagers.filter((manager) => probe(manager, ["--version"]));
31
+ if (available.length === 0) {
32
+ throw new Error("No supported package manager found. Install pnpm, npm, or bun.");
33
+ }
34
+ if (available.length === 1) {
35
+ return available[0];
36
+ }
37
+ return prompt.select("Package manager", available);
38
+ }
39
+ export async function discoverProject(fromDir) {
40
+ let current = path.resolve(fromDir);
41
+ while (true) {
42
+ const configPath = path.join(current, "fentaris.json");
43
+ if (await exists(configPath)) {
44
+ const config = validateProjectConfig(await readJson(configPath), configPath);
45
+ return { root: current, configPath, config };
46
+ }
47
+ const legacyConfigPath = path.join(current, "fentaris.config.json");
48
+ if (await exists(legacyConfigPath)) {
49
+ const config = validateProjectConfig(await readJson(legacyConfigPath), legacyConfigPath);
50
+ return { root: current, configPath: legacyConfigPath, config };
51
+ }
52
+ const parent = path.dirname(current);
53
+ if (parent === current) {
54
+ throw new Error("No Fentaris project found. Run this command inside a generated Fentaris project.");
55
+ }
56
+ current = parent;
57
+ }
58
+ }
59
+ export async function runPackageInstall(packageManager, cwd, runner) {
60
+ const result = await runner(packageManager, ["install"], { cwd, stdio: "inherit" });
61
+ if (result.code !== 0) {
62
+ throw new Error(`${packageManager} install failed.`);
63
+ }
64
+ }
65
+ export async function runPackageScript(packageManager, cwd, script, runner) {
66
+ const args = packageManager === "npm" ? ["run", script] : script === "dev" ? ["dev"] : ["run", script];
67
+ const result = await runner(packageManager, args, { cwd, stdio: "inherit" });
68
+ if (result.code !== 0) {
69
+ throw new Error(`${packageManager} ${script} failed.`);
70
+ }
71
+ }
72
+ function validateProjectConfig(value, configPath) {
73
+ if (!value || typeof value !== "object") {
74
+ throw new Error(`Invalid Fentaris config at ${configPath}`);
75
+ }
76
+ const config = value;
77
+ if (!config.name || !config.packageManager || !config.entrypoint || !config.port || !config.path || !config.authDir) {
78
+ throw new Error(`Invalid Fentaris config at ${configPath}`);
79
+ }
80
+ if (!supportedPackageManagers.includes(config.packageManager)) {
81
+ throw new Error(`Unsupported package manager in ${configPath}`);
82
+ }
83
+ return {
84
+ name: config.name,
85
+ packageManager: config.packageManager,
86
+ entrypoint: config.entrypoint,
87
+ port: config.port,
88
+ path: config.path,
89
+ authDir: config.authDir,
90
+ };
91
+ }
92
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/domain/project/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { TemplateInput } from "../../shared/types.js";
2
+ export declare function renderTemplate(input: TemplateInput): {
3
+ files: Record<string, string>;
4
+ authKey: string;
5
+ guestApiKey: string;
6
+ adminApiKey: string;
7
+ };
8
+ export declare function renderEntrypoint(input: TemplateInput): string;
9
+ export declare function writeTemplate(targetDir: string, files: Record<string, string>): Promise<void>;
10
+ export declare function initTemplateAuth(dir: string, key: string, guestApiKey: string, adminApiKey: string): Promise<void>;
11
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/domain/template/template.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAkFjJ;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAkF7D;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAMnG;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxH"}
@@ -0,0 +1,215 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { FentarisAuth } from "@fentaris/core";
4
+ import { authDir, remoteMcpUrl } from "../../shared/constants.js";
5
+ import { writeCredentials } from "../auth/local-store.js";
6
+ export function renderTemplate(input) {
7
+ return {
8
+ authKey: input.authKey,
9
+ guestApiKey: input.guestApiKey,
10
+ adminApiKey: input.adminApiKey,
11
+ files: {
12
+ "README.md": renderReadme(input),
13
+ "package.json": JSON.stringify({
14
+ name: input.projectName,
15
+ version: "0.1.0",
16
+ private: true,
17
+ type: "module",
18
+ scripts: {
19
+ dev: "tsx src/index.ts",
20
+ build: "tsc -p tsconfig.json",
21
+ start: "node dist/index.js",
22
+ },
23
+ dependencies: {
24
+ "@modelcontextprotocol/server-filesystem": "latest",
25
+ "@fentaris/core": "latest",
26
+ tsx: "latest",
27
+ },
28
+ devDependencies: {
29
+ typescript: "latest",
30
+ },
31
+ }, null, 2),
32
+ "tsconfig.json": JSON.stringify({
33
+ compilerOptions: {
34
+ target: "ES2022",
35
+ module: "NodeNext",
36
+ moduleResolution: "NodeNext",
37
+ strict: true,
38
+ esModuleInterop: true,
39
+ skipLibCheck: true,
40
+ outDir: "dist",
41
+ rootDir: "src",
42
+ },
43
+ include: ["src"],
44
+ }, null, 2),
45
+ "fentaris.json": JSON.stringify({
46
+ name: input.projectName,
47
+ packageManager: input.packageManager,
48
+ entrypoint: "src/index.ts",
49
+ port: input.port,
50
+ path: input.proxyPath,
51
+ authDir,
52
+ }, null, 2),
53
+ ".env.example": [
54
+ `FENTARIS_AUTH_KEY=${input.authKey}`,
55
+ `FENTARIS_GUEST_API_KEY=${input.guestApiKey}`,
56
+ `FENTARIS_ADMIN_API_KEY=${input.adminApiKey}`,
57
+ `FENTARIS_PORT=${input.port}`,
58
+ `FENTARIS_PATH=${input.proxyPath}`,
59
+ "",
60
+ ].join("\n"),
61
+ ".gitignore": [
62
+ "node_modules/",
63
+ "dist/",
64
+ ".env",
65
+ ".env.*",
66
+ "!.env.example",
67
+ ".fentaris/",
68
+ ".fentaris/build/",
69
+ "*.log",
70
+ "",
71
+ ].join("\n"),
72
+ "src/index.ts": renderEntrypoint(input),
73
+ "demo-files/README.md": "# Fentaris demo files\n\nThis directory is intentionally scoped for the demo filesystem MCP server.\n",
74
+ },
75
+ };
76
+ }
77
+ export function renderEntrypoint(input) {
78
+ return `import {
79
+ MemoryRateLimitStore,
80
+ SlidingWindowRateLimiter,
81
+ credentialJson,
82
+ fentaris,
83
+ group,
84
+ mcp,
85
+ policy,
86
+ rateLimitMiddleware,
87
+ stdio,
88
+ streamableHttp,
89
+ user,
90
+ } from "@fentaris/core";
91
+
92
+ const port = Number(process.env.FENTARIS_PORT ?? ${input.port});
93
+ const proxyPath = process.env.FENTARIS_PATH ?? "${input.proxyPath}";
94
+
95
+ const guest = user("guest", {
96
+ displayName: "Guest Demo User",
97
+ apiKeys: [credentialJson("users.guest.apiKeys.0")],
98
+ });
99
+ const admin = user("admin", {
100
+ displayName: "Admin Demo User",
101
+ apiKeys: [credentialJson("users.admin.apiKeys.0")],
102
+ });
103
+
104
+ const limitedPolicy = policy("limited-demo")
105
+ .server("demo-files")
106
+ .allow("list_allowed_directories")
107
+ .server("demo-files")
108
+ .allow("list_directory")
109
+ .server("specification")
110
+ .allow("*");
111
+
112
+ const adminPolicy = policy("admin-full-access").server("*").allow("*");
113
+
114
+ const limiter = new SlidingWindowRateLimiter({
115
+ store: new MemoryRateLimitStore(),
116
+ maxPerWindow: 30,
117
+ windowMs: 60_000,
118
+ });
119
+
120
+ const app = fentaris({
121
+ port,
122
+ path: proxyPath,
123
+ groups: [
124
+ group({ id: "limited", users: [guest], policy: limitedPolicy }),
125
+ group({ id: "admins", users: [admin], policy: adminPolicy }),
126
+ ],
127
+ servers: [
128
+ mcp("demo-files", {
129
+ transport: stdio({
130
+ command: "npx",
131
+ args: ["-y", "@modelcontextprotocol/server-filesystem", "./demo-files"],
132
+ }),
133
+ }),
134
+ mcp("specification", {
135
+ transport: streamableHttp({
136
+ url: "${remoteMcpUrl}",
137
+ }),
138
+ }),
139
+ ],
140
+ });
141
+
142
+ // Global middleware runs before requests are forwarded to upstream MCP servers.
143
+ app.use(rateLimitMiddleware({ limiter }));
144
+
145
+ app.server("demo-files").use((ctx, next) => {
146
+ console.log(\`demo-files -> \${ctx.operation}\`);
147
+ return next();
148
+ });
149
+
150
+ app.server("specification").on("tool:success", ({ ctx }) => {
151
+ console.log(\`specification -> \${ctx.tool?.name ?? ctx.operation}\`);
152
+ });
153
+
154
+ await app.start(() => {
155
+ console.log(\`Fentaris proxy listening at http://localhost:\${port}\${proxyPath}\`);
156
+ console.log("Use x-fentaris-api-key with the generated guest or admin key.");
157
+ });
158
+ `;
159
+ }
160
+ export async function writeTemplate(targetDir, files) {
161
+ for (const [relativePath, contents] of Object.entries(files)) {
162
+ const filePath = path.join(targetDir, relativePath);
163
+ await mkdir(path.dirname(filePath), { recursive: true });
164
+ await writeFile(filePath, contents);
165
+ }
166
+ }
167
+ export async function initTemplateAuth(dir, key, guestApiKey, adminApiKey) {
168
+ await mkdir(dir, { recursive: true });
169
+ await writeCredentials(dir, key, {
170
+ users: {
171
+ guest: { apiKeys: [FentarisAuth.hashApiKey(guestApiKey)], credentials: {} },
172
+ admin: { apiKeys: [FentarisAuth.hashApiKey(adminApiKey)], credentials: {} },
173
+ },
174
+ groups: { limited: {} },
175
+ defaults: {},
176
+ });
177
+ }
178
+ function renderReadme(input) {
179
+ return `# ${input.projectName}
180
+
181
+ This project was generated by the Fentaris CLI. It starts a local MCP proxy with:
182
+
183
+ - API-key authentication backed by encrypted credentials in \`.fentaris/credentials.enc.json\`
184
+ - A limited \`guest\` user and an unrestricted \`admin\` user
185
+ - A local filesystem demo server mounted as \`demo-files\`
186
+ - A remote HTTP MCP server mounted as \`specification\`
187
+ - A sliding-window rate limiter installed as global middleware
188
+
189
+ ## Quick start
190
+
191
+ \`\`\`sh
192
+ ${input.packageManager} install
193
+ cp .env.example .env
194
+ ${input.packageManager} dev
195
+ \`\`\`
196
+
197
+ The proxy listens on \`http://localhost:${input.port}${input.proxyPath}\` by default. Send requests with the \`x-fentaris-api-key\` header using one of the keys printed by \`fentaris init\`.
198
+
199
+ ## Project files
200
+
201
+ - \`src/index.ts\` configures the proxy, users, policies, middleware, and upstream MCP servers.
202
+ - \`fentaris.json\` is used by \`fentaris check\`, \`fentaris dev\`, and \`fentaris build\`.
203
+ - \`.fentaris/credentials.enc.json\` stores encrypted local credentials and is intentionally ignored by git.
204
+ - \`demo-files\` is the sandboxed directory exposed by the demo filesystem server.
205
+
206
+ ## Useful commands
207
+
208
+ \`\`\`sh
209
+ fentaris check --offline
210
+ fentaris secrets set github.token --user admin
211
+ fentaris build
212
+ \`\`\`
213
+ `;
214
+ }
215
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/domain/template/template.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,74 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { type SpawnOptions } from "node:child_process";
3
- type CliOptions = Record<string, string | boolean>;
4
- type CliCommand = {
5
- name: string;
6
- args: string[];
7
- options: CliOptions;
8
- };
9
- type PackageManager = "pnpm" | "npm" | "bun";
10
- type CommandResult = {
11
- code: number;
12
- };
13
- type ProcessRunner = (command: string, args: string[], options?: SpawnOptions) => Promise<CommandResult>;
14
- type ExecProbe = (command: string, args?: string[]) => boolean;
15
- export type Prompt = {
16
- text(question: string, options?: {
17
- secret?: boolean;
18
- defaultValue?: string;
19
- }): Promise<string>;
20
- select<T extends string>(question: string, choices: T[]): Promise<T>;
21
- confirm(question: string): Promise<boolean>;
22
- close(): void;
23
- };
24
- export type Runtime = {
25
- cwd: string;
26
- env: NodeJS.ProcessEnv;
27
- out: Pick<typeof console, "log" | "error">;
28
- runner: ProcessRunner;
29
- probe: ExecProbe;
30
- prompt: Prompt;
31
- };
32
- type TemplateInput = {
33
- projectName: string;
34
- packageManager: PackageManager;
35
- port: number;
36
- proxyPath: string;
37
- authKey: string;
38
- guestApiKey: string;
39
- adminApiKey: string;
40
- };
41
- type ProjectConfig = {
42
- name: string;
43
- packageManager: PackageManager;
44
- entrypoint: string;
45
- port: number;
46
- path: string;
47
- authDir: string;
48
- upstreams?: Array<{
49
- name: string;
50
- type: "stdio" | "http";
51
- url?: string;
52
- command?: string;
53
- args?: string[];
54
- }>;
55
- };
56
- type ProjectDiscovery = {
57
- root: string;
58
- configPath: string;
59
- config: ProjectConfig;
60
- };
2
+ import { discoverProject, ensureEmptyTargetDirectory, resolveProjectName, selectPackageManager } from "./domain/project/project.js";
3
+ import { renderEntrypoint, renderTemplate } from "./domain/template/template.js";
4
+ import { parseCommand } from "./shared/parse.js";
5
+ import type { Runtime } from "./shared/types.js";
6
+ export { discoverProject, ensureEmptyTargetDirectory, parseCommand, renderEntrypoint, renderTemplate, resolveProjectName, selectPackageManager };
7
+ export type { Prompt, Runtime } from "./shared/types.js";
61
8
  export declare function main(argv: string[], runtime?: Runtime): Promise<number>;
62
- export declare function parseCommand(argv: string[]): CliCommand;
63
- export declare function resolveProjectName(provided: string | undefined, prompt: Prompt): Promise<string>;
64
- export declare function ensureEmptyTargetDirectory(targetDir: string): Promise<void>;
65
- export declare function selectPackageManager(probe: ExecProbe, prompt: Prompt): Promise<PackageManager>;
66
- export declare function renderTemplate(input: TemplateInput): {
67
- files: Record<string, string>;
68
- authKey: string;
69
- guestApiKey: string;
70
- adminApiKey: string;
71
- };
72
- export declare function discoverProject(fromDir: string): Promise<ProjectDiscovery>;
73
- export {};
74
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACpI,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;AACjJ,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEzD,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,OAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAEzF"}