@chat-js/cli 0.1.1 → 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.
- package/README.md +7 -3
- package/dist/index.js +110 -60
- package/package.json +4 -4
- package/templates/chat-app/.devtools/generations.json +132 -0
- package/templates/chat-app/app/opengraph-image.png +0 -0
- package/templates/chat-app/chat.config.ts +0 -1
- package/templates/chat-app/components/header-actions.tsx +0 -12
- package/templates/chat-app/lib/config-schema.ts +0 -1
- package/templates/chat-app/lib/env-schema.ts +140 -0
- package/templates/chat-app/lib/env.ts +2 -49
- package/templates/chat-app/next-env.d.ts +1 -1
- package/templates/chat-app/package.json +7 -3
- package/templates/chat-app/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -5,11 +5,15 @@ CLI to scaffold and extend ChatJS apps.
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx @chat-js/cli@latest
|
|
8
|
+
npx @chat-js/cli@latest
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Or with the command alias:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
chat-js create
|
|
14
|
+
npx @chat-js/cli@latest create
|
|
15
15
|
```
|
|
16
|
+
|
|
17
|
+
After install, the binary is:
|
|
18
|
+
|
|
19
|
+
- `chat-js`
|
package/dist/index.js
CHANGED
|
@@ -3914,17 +3914,17 @@ var {
|
|
|
3914
3914
|
// package.json
|
|
3915
3915
|
var package_default = {
|
|
3916
3916
|
name: "@chat-js/cli",
|
|
3917
|
-
version: "0.1.
|
|
3917
|
+
version: "0.1.2",
|
|
3918
3918
|
description: "CLI for creating and extending ChatJS apps",
|
|
3919
3919
|
license: "Apache-2.0",
|
|
3920
3920
|
repository: {
|
|
3921
3921
|
type: "git",
|
|
3922
|
-
url: "https://github.com/
|
|
3922
|
+
url: "https://github.com/franciscomoretti/chat.js.git",
|
|
3923
3923
|
directory: "packages/cli"
|
|
3924
3924
|
},
|
|
3925
|
-
homepage: "https://github.com/
|
|
3925
|
+
homepage: "https://github.com/franciscomoretti/chat.js/tree/main/packages/cli",
|
|
3926
3926
|
bugs: {
|
|
3927
|
-
url: "https://github.com/
|
|
3927
|
+
url: "https://github.com/franciscomoretti/chat.js/issues"
|
|
3928
3928
|
},
|
|
3929
3929
|
keywords: [
|
|
3930
3930
|
"chatjs",
|
|
@@ -18727,6 +18727,37 @@ var authEnvRequirements = {
|
|
|
18727
18727
|
}
|
|
18728
18728
|
};
|
|
18729
18729
|
|
|
18730
|
+
// ../../apps/chat/lib/env-schema.ts
|
|
18731
|
+
var serverEnvSchema = {
|
|
18732
|
+
DATABASE_URL: exports_external.string().min(1).describe("Postgres connection string"),
|
|
18733
|
+
AUTH_SECRET: exports_external.string().min(1).describe("NextAuth.js secret for signing session tokens"),
|
|
18734
|
+
BLOB_READ_WRITE_TOKEN: exports_external.string().optional().describe("Vercel Blob storage token for file uploads"),
|
|
18735
|
+
AUTH_GOOGLE_ID: exports_external.string().optional().describe("Google OAuth client ID"),
|
|
18736
|
+
AUTH_GOOGLE_SECRET: exports_external.string().optional().describe("Google OAuth client secret"),
|
|
18737
|
+
AUTH_GITHUB_ID: exports_external.string().optional().describe("GitHub OAuth app client ID"),
|
|
18738
|
+
AUTH_GITHUB_SECRET: exports_external.string().optional().describe("GitHub OAuth app client secret"),
|
|
18739
|
+
VERCEL_APP_CLIENT_ID: exports_external.string().optional().describe("Vercel OAuth integration client ID"),
|
|
18740
|
+
VERCEL_APP_CLIENT_SECRET: exports_external.string().optional().describe("Vercel OAuth integration client secret"),
|
|
18741
|
+
AI_GATEWAY_API_KEY: exports_external.string().optional().describe("Vercel AI Gateway API key"),
|
|
18742
|
+
VERCEL_OIDC_TOKEN: exports_external.string().optional().describe("Vercel OIDC token (auto-set on Vercel deployments)"),
|
|
18743
|
+
OPENROUTER_API_KEY: exports_external.string().optional().describe("OpenRouter API key"),
|
|
18744
|
+
OPENAI_COMPATIBLE_BASE_URL: exports_external.string().url().optional().describe("Base URL for OpenAI-compatible provider"),
|
|
18745
|
+
OPENAI_COMPATIBLE_API_KEY: exports_external.string().optional().describe("API key for OpenAI-compatible provider"),
|
|
18746
|
+
OPENAI_API_KEY: exports_external.string().optional().describe("OpenAI API key"),
|
|
18747
|
+
CRON_SECRET: exports_external.string().optional().describe("Secret for cleanup cron job endpoint"),
|
|
18748
|
+
REDIS_URL: exports_external.string().optional().describe("Redis URL for resumable streams"),
|
|
18749
|
+
TAVILY_API_KEY: exports_external.string().optional().describe("Tavily API key for web search"),
|
|
18750
|
+
EXA_API_KEY: exports_external.string().optional().describe("Exa API key for web search"),
|
|
18751
|
+
FIRECRAWL_API_KEY: exports_external.string().optional().describe("Firecrawl API key for web search and URL retrieval"),
|
|
18752
|
+
MCP_ENCRYPTION_KEY: exports_external.union([exports_external.string().length(44), exports_external.literal("")]).optional().describe("Encryption key for MCP server credentials (base64, 44 chars)"),
|
|
18753
|
+
VERCEL_TEAM_ID: exports_external.string().optional().describe("Vercel team ID for sandbox (non-Vercel deployments)"),
|
|
18754
|
+
VERCEL_PROJECT_ID: exports_external.string().optional().describe("Vercel project ID for sandbox (non-Vercel deployments)"),
|
|
18755
|
+
VERCEL_TOKEN: exports_external.string().optional().describe("Vercel API token for sandbox (non-Vercel deployments)"),
|
|
18756
|
+
VERCEL_SANDBOX_RUNTIME: exports_external.string().optional().describe("Vercel sandbox runtime identifier"),
|
|
18757
|
+
APP_URL: exports_external.url().optional().describe("App URL for non-Vercel deployments (full URL including https://)"),
|
|
18758
|
+
VERCEL_URL: exports_external.string().optional().describe("Auto-set by Vercel platform")
|
|
18759
|
+
};
|
|
18760
|
+
|
|
18730
18761
|
// src/types.ts
|
|
18731
18762
|
var FEATURE_KEYS = [
|
|
18732
18763
|
"sandbox",
|
|
@@ -18740,23 +18771,66 @@ var FEATURE_KEYS = [
|
|
|
18740
18771
|
];
|
|
18741
18772
|
|
|
18742
18773
|
// src/helpers/env-checklist.ts
|
|
18774
|
+
function extractEnvDescriptions() {
|
|
18775
|
+
const result = new Map;
|
|
18776
|
+
for (const [key, schema] of Object.entries(serverEnvSchema)) {
|
|
18777
|
+
const desc = schema.description;
|
|
18778
|
+
if (desc) {
|
|
18779
|
+
result.set(key, desc);
|
|
18780
|
+
}
|
|
18781
|
+
}
|
|
18782
|
+
return result;
|
|
18783
|
+
}
|
|
18784
|
+
var envDescriptions = extractEnvDescriptions();
|
|
18785
|
+
function requirementToEntries(requirement) {
|
|
18786
|
+
const oneOfGroup = requirement.options.length > 1 ? requirement.options.map((group) => group.map(String).join("+")).join("|") : undefined;
|
|
18787
|
+
return requirement.options.map((group) => {
|
|
18788
|
+
const description = group.map((v) => {
|
|
18789
|
+
const varName = String(v);
|
|
18790
|
+
return envDescriptions.get(varName) ?? varName;
|
|
18791
|
+
}).join(", ");
|
|
18792
|
+
return {
|
|
18793
|
+
vars: group.map(String).join(" + "),
|
|
18794
|
+
description: description || requirement.description,
|
|
18795
|
+
oneOfGroup
|
|
18796
|
+
};
|
|
18797
|
+
});
|
|
18798
|
+
}
|
|
18743
18799
|
function collectEnvChecklist(input) {
|
|
18744
|
-
const
|
|
18745
|
-
|
|
18800
|
+
const entries = [];
|
|
18801
|
+
entries.push({
|
|
18802
|
+
vars: "AUTH_SECRET",
|
|
18803
|
+
description: envDescriptions.get("AUTH_SECRET") ?? "AUTH_SECRET"
|
|
18804
|
+
});
|
|
18805
|
+
entries.push({
|
|
18806
|
+
vars: "DATABASE_URL",
|
|
18807
|
+
description: envDescriptions.get("DATABASE_URL") ?? "DATABASE_URL"
|
|
18808
|
+
});
|
|
18809
|
+
const gwReq = gatewayEnvRequirements[input.gateway];
|
|
18810
|
+
const gwEntries = requirementToEntries(gwReq);
|
|
18811
|
+
entries.push(...gwEntries);
|
|
18812
|
+
const featureItems = [];
|
|
18813
|
+
const seen = new Set;
|
|
18746
18814
|
for (const feature of FEATURE_KEYS) {
|
|
18747
18815
|
if (!input.features[feature])
|
|
18748
18816
|
continue;
|
|
18749
18817
|
const requirement = featureEnvRequirements[feature];
|
|
18750
|
-
if (requirement)
|
|
18751
|
-
|
|
18752
|
-
|
|
18818
|
+
if (!requirement)
|
|
18819
|
+
continue;
|
|
18820
|
+
if (seen.has(requirement.description))
|
|
18821
|
+
continue;
|
|
18822
|
+
seen.add(requirement.description);
|
|
18823
|
+
featureItems.push(...requirementToEntries(requirement));
|
|
18753
18824
|
}
|
|
18825
|
+
entries.push(...featureItems);
|
|
18826
|
+
const authItems = [];
|
|
18754
18827
|
for (const provider of Object.keys(authEnvRequirements)) {
|
|
18755
18828
|
if (!input.auth[provider])
|
|
18756
18829
|
continue;
|
|
18757
|
-
|
|
18830
|
+
authItems.push(...requirementToEntries(authEnvRequirements[provider]));
|
|
18758
18831
|
}
|
|
18759
|
-
|
|
18832
|
+
entries.push(...authItems);
|
|
18833
|
+
return entries;
|
|
18760
18834
|
}
|
|
18761
18835
|
|
|
18762
18836
|
// ../../apps/chat/lib/ai/gateway-model-defaults.ts
|
|
@@ -18994,7 +19068,6 @@ var authenticationConfigSchema = exports_external.object({
|
|
|
18994
19068
|
vercel: false
|
|
18995
19069
|
});
|
|
18996
19070
|
var configSchema = exports_external.object({
|
|
18997
|
-
githubUrl: exports_external.url().default("https://github.com/your-username/your-repo"),
|
|
18998
19071
|
appPrefix: exports_external.string().default("chatjs"),
|
|
18999
19072
|
appName: exports_external.string().default("My AI Chat"),
|
|
19000
19073
|
appTitle: exports_external.string().optional().describe("Browser tab title (defaults to appName)"),
|
|
@@ -19124,7 +19197,6 @@ ${spaces}},`;
|
|
|
19124
19197
|
function buildConfigTs(input) {
|
|
19125
19198
|
const modelDefaults = GATEWAY_MODEL_DEFAULTS[input.gateway];
|
|
19126
19199
|
const fullConfig = {
|
|
19127
|
-
githubUrl: input.githubUrl,
|
|
19128
19200
|
appPrefix: input.appPrefix,
|
|
19129
19201
|
appName: input.appName,
|
|
19130
19202
|
appDescription: "AI chat powered by ChatJS",
|
|
@@ -19266,42 +19338,6 @@ async function promptProjectName(targetArg, skipPrompt) {
|
|
|
19266
19338
|
handleCancel(name);
|
|
19267
19339
|
return toKebabCase(name) || "my-chat-app";
|
|
19268
19340
|
}
|
|
19269
|
-
async function promptAppDetails(skipPrompt) {
|
|
19270
|
-
if (skipPrompt) {
|
|
19271
|
-
return {
|
|
19272
|
-
appName: "My Chat App",
|
|
19273
|
-
appPrefix: "chat",
|
|
19274
|
-
appUrl: "http://localhost:3000",
|
|
19275
|
-
githubUrl: "https://github.com/your-org/your-repo"
|
|
19276
|
-
};
|
|
19277
|
-
}
|
|
19278
|
-
const appName = await Ze({
|
|
19279
|
-
message: `What is the ${highlighter.info("display name")} of your app?`,
|
|
19280
|
-
initialValue: "My Chat App"
|
|
19281
|
-
});
|
|
19282
|
-
handleCancel(appName);
|
|
19283
|
-
const appPrefix = await Ze({
|
|
19284
|
-
message: `What ${highlighter.info("prefix")} should be used?`,
|
|
19285
|
-
initialValue: toKebabCase(appName) || "chat"
|
|
19286
|
-
});
|
|
19287
|
-
handleCancel(appPrefix);
|
|
19288
|
-
const appUrl = await Ze({
|
|
19289
|
-
message: `What is your ${highlighter.info("app URL")}?`,
|
|
19290
|
-
initialValue: "http://localhost:3000"
|
|
19291
|
-
});
|
|
19292
|
-
handleCancel(appUrl);
|
|
19293
|
-
const githubUrl = await Ze({
|
|
19294
|
-
message: `What is your ${highlighter.info("GitHub repository URL")}?`,
|
|
19295
|
-
initialValue: "https://github.com/your-org/your-repo"
|
|
19296
|
-
});
|
|
19297
|
-
handleCancel(githubUrl);
|
|
19298
|
-
return {
|
|
19299
|
-
appName: appName || "My Chat App",
|
|
19300
|
-
appPrefix: appPrefix || "chat",
|
|
19301
|
-
appUrl: appUrl || "http://localhost:3000",
|
|
19302
|
-
githubUrl: githubUrl || "https://github.com/your-org/your-repo"
|
|
19303
|
-
};
|
|
19304
|
-
}
|
|
19305
19341
|
async function promptGateway(skipPrompt) {
|
|
19306
19342
|
if (skipPrompt)
|
|
19307
19343
|
return "vercel";
|
|
@@ -20751,6 +20787,24 @@ function spinner(text, options) {
|
|
|
20751
20787
|
}
|
|
20752
20788
|
|
|
20753
20789
|
// src/commands/create.ts
|
|
20790
|
+
function printEnvChecklist(entries) {
|
|
20791
|
+
logger.info("Required for your configuration:");
|
|
20792
|
+
logger.break();
|
|
20793
|
+
for (let i = 0;i < entries.length; i += 1) {
|
|
20794
|
+
const entry = entries[i];
|
|
20795
|
+
if (!entry.oneOfGroup) {
|
|
20796
|
+
logger.log(` ${highlighter.warn("*")} ${highlighter.warn(entry.vars)} ${highlighter.dim(`- ${entry.description}`)}`);
|
|
20797
|
+
continue;
|
|
20798
|
+
}
|
|
20799
|
+
logger.log(` ${highlighter.warn("*")} ${highlighter.dim("One of:")}`);
|
|
20800
|
+
while (i < entries.length && entries[i].oneOfGroup === entry.oneOfGroup) {
|
|
20801
|
+
const option = entries[i];
|
|
20802
|
+
logger.log(` ${highlighter.warn("*")} ${highlighter.warn(option.vars)} ${highlighter.dim(`- ${option.description}`)}`);
|
|
20803
|
+
i += 1;
|
|
20804
|
+
}
|
|
20805
|
+
i -= 1;
|
|
20806
|
+
}
|
|
20807
|
+
}
|
|
20754
20808
|
var createOptionsSchema = exports_external.object({
|
|
20755
20809
|
target: exports_external.string().optional(),
|
|
20756
20810
|
yes: exports_external.boolean(),
|
|
@@ -20769,11 +20823,13 @@ var create = new Command().name("create").description("scaffold a new ChatJS cha
|
|
|
20769
20823
|
}
|
|
20770
20824
|
const projectName = await promptProjectName(options.target, options.yes);
|
|
20771
20825
|
const targetDir = resolve2(process.cwd(), projectName);
|
|
20772
|
-
|
|
20826
|
+
await ensureTargetEmpty(targetDir);
|
|
20827
|
+
const appName = projectName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
20828
|
+
const appPrefix = projectName;
|
|
20829
|
+
const appUrl = "http://localhost:3000";
|
|
20773
20830
|
const gateway = await promptGateway(options.yes);
|
|
20774
20831
|
const features = await promptFeatures(options.yes);
|
|
20775
20832
|
const auth = await promptAuth(options.yes);
|
|
20776
|
-
await ensureTargetEmpty(targetDir);
|
|
20777
20833
|
logger.break();
|
|
20778
20834
|
const scaffoldSpinner = spinner("Scaffolding project...").start();
|
|
20779
20835
|
try {
|
|
@@ -20798,7 +20854,6 @@ var create = new Command().name("create").description("scaffold a new ChatJS cha
|
|
|
20798
20854
|
appName,
|
|
20799
20855
|
appPrefix,
|
|
20800
20856
|
appUrl,
|
|
20801
|
-
githubUrl,
|
|
20802
20857
|
gateway,
|
|
20803
20858
|
features,
|
|
20804
20859
|
auth
|
|
@@ -20820,19 +20875,14 @@ var create = new Command().name("create").description("scaffold a new ChatJS cha
|
|
|
20820
20875
|
throw error48;
|
|
20821
20876
|
}
|
|
20822
20877
|
}
|
|
20823
|
-
const
|
|
20878
|
+
const envEntries = collectEnvChecklist({ gateway, features, auth });
|
|
20824
20879
|
Le("Your ChatJS app is ready!");
|
|
20825
20880
|
logger.info("Next steps:");
|
|
20826
20881
|
logger.log(` cd ${highlighter.info(projectName)}`);
|
|
20882
|
+
logger.log(` Copy ${highlighter.info(".env.example")} to ${highlighter.info(".env.local")} and fill in the values below`);
|
|
20827
20883
|
logger.log(` ${highlighter.info(`${packageManager} run dev`)}`);
|
|
20828
20884
|
logger.break();
|
|
20829
|
-
|
|
20830
|
-
logger.info("Required environment variables:");
|
|
20831
|
-
for (const item of envChecklist) {
|
|
20832
|
-
logger.log(` ${highlighter.warn("*")} ${item}`);
|
|
20833
|
-
}
|
|
20834
|
-
logger.break();
|
|
20835
|
-
}
|
|
20885
|
+
printEnvChecklist(envEntries);
|
|
20836
20886
|
} catch (error48) {
|
|
20837
20887
|
handleError(error48);
|
|
20838
20888
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chat-js/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI for creating and extending ChatJS apps",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/
|
|
8
|
+
"url": "https://github.com/franciscomoretti/chat.js.git",
|
|
9
9
|
"directory": "packages/cli"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://github.com/
|
|
11
|
+
"homepage": "https://github.com/franciscomoretti/chat.js/tree/main/packages/cli",
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/
|
|
13
|
+
"url": "https://github.com/franciscomoretti/chat.js/issues"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"chatjs",
|