@chat-js/cli 0.1.2 → 0.1.3
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/index.js +185 -177
- package/package.json +1 -1
- package/templates/chat-app/app/api/dev-login/route.ts +11 -4
- package/templates/chat-app/biome.jsonc +26 -0
- package/templates/chat-app/components/chat-sync.tsx +2 -4
- package/templates/chat-app/components/followup-suggestions.tsx +22 -14
- package/templates/chat-app/components/image-editor.tsx +1 -1
- package/templates/chat-app/components/part/weather.tsx +1 -1
- package/templates/chat-app/components/social-auth-providers.tsx +2 -0
- package/templates/chat-app/components/toolbar.tsx +1 -1
- package/templates/chat-app/lib/env-schema.ts +11 -33
- package/templates/chat-app/package.json +3 -2
- package/templates/chat-app/scripts/check-env.ts +11 -10
- package/templates/chat-app/.devtools/generations.json +0 -288
- package/templates/chat-app/.gemini/settings.json +0 -3
- package/templates/chat-app/.qwen/settings.json +0 -3
- package/templates/chat-app/next-env.d.ts +0 -6
- package/templates/chat-app/tsconfig.tsbuildinfo +0 -1
package/dist/index.js
CHANGED
|
@@ -3914,7 +3914,7 @@ var {
|
|
|
3914
3914
|
// package.json
|
|
3915
3915
|
var package_default = {
|
|
3916
3916
|
name: "@chat-js/cli",
|
|
3917
|
-
version: "0.1.
|
|
3917
|
+
version: "0.1.3",
|
|
3918
3918
|
description: "CLI for creating and extending ChatJS apps",
|
|
3919
3919
|
license: "Apache-2.0",
|
|
3920
3920
|
repository: {
|
|
@@ -18660,179 +18660,6 @@ ${l}
|
|
|
18660
18660
|
}
|
|
18661
18661
|
} }).prompt();
|
|
18662
18662
|
|
|
18663
|
-
// ../../apps/chat/lib/config-requirements.ts
|
|
18664
|
-
var gatewayEnvRequirements = {
|
|
18665
|
-
openrouter: {
|
|
18666
|
-
options: [["OPENROUTER_API_KEY"]],
|
|
18667
|
-
description: "OPENROUTER_API_KEY"
|
|
18668
|
-
},
|
|
18669
|
-
openai: {
|
|
18670
|
-
options: [["OPENAI_API_KEY"]],
|
|
18671
|
-
description: "OPENAI_API_KEY"
|
|
18672
|
-
},
|
|
18673
|
-
vercel: {
|
|
18674
|
-
options: [["AI_GATEWAY_API_KEY"], ["VERCEL_OIDC_TOKEN"]],
|
|
18675
|
-
description: "AI_GATEWAY_API_KEY or VERCEL_OIDC_TOKEN"
|
|
18676
|
-
},
|
|
18677
|
-
"openai-compatible": {
|
|
18678
|
-
options: [["OPENAI_COMPATIBLE_BASE_URL", "OPENAI_COMPATIBLE_API_KEY"]],
|
|
18679
|
-
description: "OPENAI_COMPATIBLE_BASE_URL, OPENAI_COMPATIBLE_API_KEY"
|
|
18680
|
-
}
|
|
18681
|
-
};
|
|
18682
|
-
var featureEnvRequirements = {
|
|
18683
|
-
webSearch: {
|
|
18684
|
-
options: [["TAVILY_API_KEY"], ["FIRECRAWL_API_KEY"]],
|
|
18685
|
-
description: "TAVILY_API_KEY or FIRECRAWL_API_KEY"
|
|
18686
|
-
},
|
|
18687
|
-
deepResearch: {
|
|
18688
|
-
options: [["TAVILY_API_KEY"], ["FIRECRAWL_API_KEY"]],
|
|
18689
|
-
description: "TAVILY_API_KEY or FIRECRAWL_API_KEY"
|
|
18690
|
-
},
|
|
18691
|
-
urlRetrieval: {
|
|
18692
|
-
options: [["FIRECRAWL_API_KEY"]],
|
|
18693
|
-
description: "FIRECRAWL_API_KEY"
|
|
18694
|
-
},
|
|
18695
|
-
mcp: {
|
|
18696
|
-
options: [["MCP_ENCRYPTION_KEY"]],
|
|
18697
|
-
description: "MCP_ENCRYPTION_KEY"
|
|
18698
|
-
},
|
|
18699
|
-
sandbox: {
|
|
18700
|
-
options: [
|
|
18701
|
-
["VERCEL_OIDC_TOKEN"],
|
|
18702
|
-
["VERCEL_TEAM_ID", "VERCEL_PROJECT_ID", "VERCEL_TOKEN"]
|
|
18703
|
-
],
|
|
18704
|
-
description: "VERCEL_OIDC_TOKEN (auto on Vercel) or VERCEL_TEAM_ID + VERCEL_PROJECT_ID + VERCEL_TOKEN"
|
|
18705
|
-
},
|
|
18706
|
-
imageGeneration: {
|
|
18707
|
-
options: [["BLOB_READ_WRITE_TOKEN"]],
|
|
18708
|
-
description: "BLOB_READ_WRITE_TOKEN"
|
|
18709
|
-
},
|
|
18710
|
-
attachments: {
|
|
18711
|
-
options: [["BLOB_READ_WRITE_TOKEN"]],
|
|
18712
|
-
description: "BLOB_READ_WRITE_TOKEN"
|
|
18713
|
-
}
|
|
18714
|
-
};
|
|
18715
|
-
var authEnvRequirements = {
|
|
18716
|
-
google: {
|
|
18717
|
-
options: [["AUTH_GOOGLE_ID", "AUTH_GOOGLE_SECRET"]],
|
|
18718
|
-
description: "AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET"
|
|
18719
|
-
},
|
|
18720
|
-
github: {
|
|
18721
|
-
options: [["AUTH_GITHUB_ID", "AUTH_GITHUB_SECRET"]],
|
|
18722
|
-
description: "AUTH_GITHUB_ID, AUTH_GITHUB_SECRET"
|
|
18723
|
-
},
|
|
18724
|
-
vercel: {
|
|
18725
|
-
options: [["VERCEL_APP_CLIENT_ID", "VERCEL_APP_CLIENT_SECRET"]],
|
|
18726
|
-
description: "VERCEL_APP_CLIENT_ID, VERCEL_APP_CLIENT_SECRET"
|
|
18727
|
-
}
|
|
18728
|
-
};
|
|
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
|
-
|
|
18761
|
-
// src/types.ts
|
|
18762
|
-
var FEATURE_KEYS = [
|
|
18763
|
-
"sandbox",
|
|
18764
|
-
"webSearch",
|
|
18765
|
-
"urlRetrieval",
|
|
18766
|
-
"deepResearch",
|
|
18767
|
-
"mcp",
|
|
18768
|
-
"imageGeneration",
|
|
18769
|
-
"attachments",
|
|
18770
|
-
"followupSuggestions"
|
|
18771
|
-
];
|
|
18772
|
-
|
|
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
|
-
}
|
|
18799
|
-
function collectEnvChecklist(input) {
|
|
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;
|
|
18814
|
-
for (const feature of FEATURE_KEYS) {
|
|
18815
|
-
if (!input.features[feature])
|
|
18816
|
-
continue;
|
|
18817
|
-
const requirement = featureEnvRequirements[feature];
|
|
18818
|
-
if (!requirement)
|
|
18819
|
-
continue;
|
|
18820
|
-
if (seen.has(requirement.description))
|
|
18821
|
-
continue;
|
|
18822
|
-
seen.add(requirement.description);
|
|
18823
|
-
featureItems.push(...requirementToEntries(requirement));
|
|
18824
|
-
}
|
|
18825
|
-
entries.push(...featureItems);
|
|
18826
|
-
const authItems = [];
|
|
18827
|
-
for (const provider of Object.keys(authEnvRequirements)) {
|
|
18828
|
-
if (!input.auth[provider])
|
|
18829
|
-
continue;
|
|
18830
|
-
authItems.push(...requirementToEntries(authEnvRequirements[provider]));
|
|
18831
|
-
}
|
|
18832
|
-
entries.push(...authItems);
|
|
18833
|
-
return entries;
|
|
18834
|
-
}
|
|
18835
|
-
|
|
18836
18663
|
// ../../apps/chat/lib/ai/gateway-model-defaults.ts
|
|
18837
18664
|
var multiProviderDefaults = {
|
|
18838
18665
|
providerOrder: ["openai", "google", "anthropic"],
|
|
@@ -19283,6 +19110,179 @@ async function ensureTargetEmpty(targetDir) {
|
|
|
19283
19110
|
}
|
|
19284
19111
|
}
|
|
19285
19112
|
|
|
19113
|
+
// ../../apps/chat/lib/config-requirements.ts
|
|
19114
|
+
var gatewayEnvRequirements = {
|
|
19115
|
+
openrouter: {
|
|
19116
|
+
options: [["OPENROUTER_API_KEY"]],
|
|
19117
|
+
description: "OPENROUTER_API_KEY"
|
|
19118
|
+
},
|
|
19119
|
+
openai: {
|
|
19120
|
+
options: [["OPENAI_API_KEY"]],
|
|
19121
|
+
description: "OPENAI_API_KEY"
|
|
19122
|
+
},
|
|
19123
|
+
vercel: {
|
|
19124
|
+
options: [["AI_GATEWAY_API_KEY"], ["VERCEL_OIDC_TOKEN"]],
|
|
19125
|
+
description: "AI_GATEWAY_API_KEY or VERCEL_OIDC_TOKEN"
|
|
19126
|
+
},
|
|
19127
|
+
"openai-compatible": {
|
|
19128
|
+
options: [["OPENAI_COMPATIBLE_BASE_URL", "OPENAI_COMPATIBLE_API_KEY"]],
|
|
19129
|
+
description: "OPENAI_COMPATIBLE_BASE_URL, OPENAI_COMPATIBLE_API_KEY"
|
|
19130
|
+
}
|
|
19131
|
+
};
|
|
19132
|
+
var featureEnvRequirements = {
|
|
19133
|
+
webSearch: {
|
|
19134
|
+
options: [["TAVILY_API_KEY"], ["FIRECRAWL_API_KEY"]],
|
|
19135
|
+
description: "TAVILY_API_KEY or FIRECRAWL_API_KEY"
|
|
19136
|
+
},
|
|
19137
|
+
deepResearch: {
|
|
19138
|
+
options: [["TAVILY_API_KEY"], ["FIRECRAWL_API_KEY"]],
|
|
19139
|
+
description: "TAVILY_API_KEY or FIRECRAWL_API_KEY"
|
|
19140
|
+
},
|
|
19141
|
+
urlRetrieval: {
|
|
19142
|
+
options: [["FIRECRAWL_API_KEY"]],
|
|
19143
|
+
description: "FIRECRAWL_API_KEY"
|
|
19144
|
+
},
|
|
19145
|
+
mcp: {
|
|
19146
|
+
options: [["MCP_ENCRYPTION_KEY"]],
|
|
19147
|
+
description: "MCP_ENCRYPTION_KEY"
|
|
19148
|
+
},
|
|
19149
|
+
sandbox: {
|
|
19150
|
+
options: [
|
|
19151
|
+
["VERCEL_OIDC_TOKEN"],
|
|
19152
|
+
["VERCEL_TEAM_ID", "VERCEL_PROJECT_ID", "VERCEL_TOKEN"]
|
|
19153
|
+
],
|
|
19154
|
+
description: "VERCEL_OIDC_TOKEN (auto on Vercel) or VERCEL_TEAM_ID + VERCEL_PROJECT_ID + VERCEL_TOKEN"
|
|
19155
|
+
},
|
|
19156
|
+
imageGeneration: {
|
|
19157
|
+
options: [["BLOB_READ_WRITE_TOKEN"]],
|
|
19158
|
+
description: "BLOB_READ_WRITE_TOKEN"
|
|
19159
|
+
},
|
|
19160
|
+
attachments: {
|
|
19161
|
+
options: [["BLOB_READ_WRITE_TOKEN"]],
|
|
19162
|
+
description: "BLOB_READ_WRITE_TOKEN"
|
|
19163
|
+
}
|
|
19164
|
+
};
|
|
19165
|
+
var authEnvRequirements = {
|
|
19166
|
+
google: {
|
|
19167
|
+
options: [["AUTH_GOOGLE_ID", "AUTH_GOOGLE_SECRET"]],
|
|
19168
|
+
description: "AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET"
|
|
19169
|
+
},
|
|
19170
|
+
github: {
|
|
19171
|
+
options: [["AUTH_GITHUB_ID", "AUTH_GITHUB_SECRET"]],
|
|
19172
|
+
description: "AUTH_GITHUB_ID, AUTH_GITHUB_SECRET"
|
|
19173
|
+
},
|
|
19174
|
+
vercel: {
|
|
19175
|
+
options: [["VERCEL_APP_CLIENT_ID", "VERCEL_APP_CLIENT_SECRET"]],
|
|
19176
|
+
description: "VERCEL_APP_CLIENT_ID, VERCEL_APP_CLIENT_SECRET"
|
|
19177
|
+
}
|
|
19178
|
+
};
|
|
19179
|
+
|
|
19180
|
+
// ../../apps/chat/lib/env-schema.ts
|
|
19181
|
+
var serverEnvSchema = {
|
|
19182
|
+
DATABASE_URL: exports_external.string().min(1).describe("Postgres connection string"),
|
|
19183
|
+
AUTH_SECRET: exports_external.string().min(1).describe("NextAuth.js secret for signing session tokens"),
|
|
19184
|
+
BLOB_READ_WRITE_TOKEN: exports_external.string().optional().describe("Vercel Blob storage token for file uploads"),
|
|
19185
|
+
AUTH_GOOGLE_ID: exports_external.string().optional().describe("Google OAuth client ID"),
|
|
19186
|
+
AUTH_GOOGLE_SECRET: exports_external.string().optional().describe("Google OAuth client secret"),
|
|
19187
|
+
AUTH_GITHUB_ID: exports_external.string().optional().describe("GitHub OAuth app client ID"),
|
|
19188
|
+
AUTH_GITHUB_SECRET: exports_external.string().optional().describe("GitHub OAuth app client secret"),
|
|
19189
|
+
VERCEL_APP_CLIENT_ID: exports_external.string().optional().describe("Vercel OAuth integration client ID"),
|
|
19190
|
+
VERCEL_APP_CLIENT_SECRET: exports_external.string().optional().describe("Vercel OAuth integration client secret"),
|
|
19191
|
+
AI_GATEWAY_API_KEY: exports_external.string().optional().describe("Vercel AI Gateway API key"),
|
|
19192
|
+
VERCEL_OIDC_TOKEN: exports_external.string().optional().describe("Vercel OIDC token (auto-set on Vercel deployments)"),
|
|
19193
|
+
OPENROUTER_API_KEY: exports_external.string().optional().describe("OpenRouter API key"),
|
|
19194
|
+
OPENAI_COMPATIBLE_BASE_URL: exports_external.string().url().optional().describe("Base URL for OpenAI-compatible provider"),
|
|
19195
|
+
OPENAI_COMPATIBLE_API_KEY: exports_external.string().optional().describe("API key for OpenAI-compatible provider"),
|
|
19196
|
+
OPENAI_API_KEY: exports_external.string().optional().describe("OpenAI API key"),
|
|
19197
|
+
CRON_SECRET: exports_external.string().optional().describe("Secret for cleanup cron job endpoint"),
|
|
19198
|
+
REDIS_URL: exports_external.string().optional().describe("Redis URL for resumable streams"),
|
|
19199
|
+
TAVILY_API_KEY: exports_external.string().optional().describe("Tavily API key for web search"),
|
|
19200
|
+
EXA_API_KEY: exports_external.string().optional().describe("Exa API key for web search"),
|
|
19201
|
+
FIRECRAWL_API_KEY: exports_external.string().optional().describe("Firecrawl API key for web search and URL retrieval"),
|
|
19202
|
+
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)"),
|
|
19203
|
+
VERCEL_TEAM_ID: exports_external.string().optional().describe("Vercel team ID for sandbox (non-Vercel deployments)"),
|
|
19204
|
+
VERCEL_PROJECT_ID: exports_external.string().optional().describe("Vercel project ID for sandbox (non-Vercel deployments)"),
|
|
19205
|
+
VERCEL_TOKEN: exports_external.string().optional().describe("Vercel API token for sandbox (non-Vercel deployments)"),
|
|
19206
|
+
VERCEL_SANDBOX_RUNTIME: exports_external.string().optional().describe("Vercel sandbox runtime identifier"),
|
|
19207
|
+
APP_URL: exports_external.url().optional().describe("App URL for non-Vercel deployments (full URL including https://)"),
|
|
19208
|
+
VERCEL_URL: exports_external.string().optional().describe("Auto-set by Vercel platform")
|
|
19209
|
+
};
|
|
19210
|
+
|
|
19211
|
+
// src/types.ts
|
|
19212
|
+
var FEATURE_KEYS = [
|
|
19213
|
+
"sandbox",
|
|
19214
|
+
"webSearch",
|
|
19215
|
+
"urlRetrieval",
|
|
19216
|
+
"deepResearch",
|
|
19217
|
+
"mcp",
|
|
19218
|
+
"imageGeneration",
|
|
19219
|
+
"attachments",
|
|
19220
|
+
"followupSuggestions"
|
|
19221
|
+
];
|
|
19222
|
+
|
|
19223
|
+
// src/helpers/env-checklist.ts
|
|
19224
|
+
function extractEnvDescriptions() {
|
|
19225
|
+
const result = new Map;
|
|
19226
|
+
for (const [key, schema] of Object.entries(serverEnvSchema)) {
|
|
19227
|
+
const desc = schema.description;
|
|
19228
|
+
if (desc) {
|
|
19229
|
+
result.set(key, desc);
|
|
19230
|
+
}
|
|
19231
|
+
}
|
|
19232
|
+
return result;
|
|
19233
|
+
}
|
|
19234
|
+
var envDescriptions = extractEnvDescriptions();
|
|
19235
|
+
function requirementToEntries(requirement) {
|
|
19236
|
+
const oneOfGroup = requirement.options.length > 1 ? requirement.options.map((group) => group.map(String).join("+")).join("|") : undefined;
|
|
19237
|
+
return requirement.options.map((group) => {
|
|
19238
|
+
const description = group.map((v) => {
|
|
19239
|
+
const varName = String(v);
|
|
19240
|
+
return envDescriptions.get(varName) ?? varName;
|
|
19241
|
+
}).join(", ");
|
|
19242
|
+
return {
|
|
19243
|
+
vars: group.map(String).join(" + "),
|
|
19244
|
+
description: description || requirement.description,
|
|
19245
|
+
oneOfGroup
|
|
19246
|
+
};
|
|
19247
|
+
});
|
|
19248
|
+
}
|
|
19249
|
+
function collectEnvChecklist(input) {
|
|
19250
|
+
const entries = [];
|
|
19251
|
+
entries.push({
|
|
19252
|
+
vars: "AUTH_SECRET",
|
|
19253
|
+
description: envDescriptions.get("AUTH_SECRET") ?? "AUTH_SECRET"
|
|
19254
|
+
});
|
|
19255
|
+
entries.push({
|
|
19256
|
+
vars: "DATABASE_URL",
|
|
19257
|
+
description: envDescriptions.get("DATABASE_URL") ?? "DATABASE_URL"
|
|
19258
|
+
});
|
|
19259
|
+
const gwReq = gatewayEnvRequirements[input.gateway];
|
|
19260
|
+
const gwEntries = requirementToEntries(gwReq);
|
|
19261
|
+
entries.push(...gwEntries);
|
|
19262
|
+
const featureItems = [];
|
|
19263
|
+
const seen = new Set;
|
|
19264
|
+
for (const feature of FEATURE_KEYS) {
|
|
19265
|
+
if (!input.features[feature])
|
|
19266
|
+
continue;
|
|
19267
|
+
const requirement = featureEnvRequirements[feature];
|
|
19268
|
+
if (!requirement)
|
|
19269
|
+
continue;
|
|
19270
|
+
if (seen.has(requirement.description))
|
|
19271
|
+
continue;
|
|
19272
|
+
seen.add(requirement.description);
|
|
19273
|
+
featureItems.push(...requirementToEntries(requirement));
|
|
19274
|
+
}
|
|
19275
|
+
entries.push(...featureItems);
|
|
19276
|
+
const authItems = [];
|
|
19277
|
+
for (const provider of Object.keys(authEnvRequirements)) {
|
|
19278
|
+
if (!input.auth[provider])
|
|
19279
|
+
continue;
|
|
19280
|
+
authItems.push(...requirementToEntries(authEnvRequirements[provider]));
|
|
19281
|
+
}
|
|
19282
|
+
entries.push(...authItems);
|
|
19283
|
+
return entries;
|
|
19284
|
+
}
|
|
19285
|
+
|
|
19286
19286
|
// src/helpers/prompts.ts
|
|
19287
19287
|
var FEATURE_DEFAULTS = {
|
|
19288
19288
|
sandbox: false,
|
|
@@ -20878,9 +20878,17 @@ var create = new Command().name("create").description("scaffold a new ChatJS cha
|
|
|
20878
20878
|
const envEntries = collectEnvChecklist({ gateway, features, auth });
|
|
20879
20879
|
Le("Your ChatJS app is ready!");
|
|
20880
20880
|
logger.info("Next steps:");
|
|
20881
|
-
logger.
|
|
20882
|
-
logger.log(`
|
|
20883
|
-
logger.log(` ${highlighter.info(
|
|
20881
|
+
logger.break();
|
|
20882
|
+
logger.log(` ${highlighter.dim("1.")} cd ${highlighter.info(projectName)}`);
|
|
20883
|
+
logger.log(` ${highlighter.dim("2.")} Copy ${highlighter.info(".env.example")} to ${highlighter.info(".env.local")} and fill in the values below`);
|
|
20884
|
+
if (!installNow) {
|
|
20885
|
+
logger.log(` ${highlighter.dim("3.")} ${highlighter.info(`${packageManager} install`)}`);
|
|
20886
|
+
logger.log(` ${highlighter.dim("4.")} ${highlighter.info(`${packageManager} run db:push`)}`);
|
|
20887
|
+
logger.log(` ${highlighter.dim("5.")} ${highlighter.info(`${packageManager} run dev`)}`);
|
|
20888
|
+
} else {
|
|
20889
|
+
logger.log(` ${highlighter.dim("3.")} ${highlighter.info(`${packageManager} run db:push`)}`);
|
|
20890
|
+
logger.log(` ${highlighter.dim("4.")} ${highlighter.info(`${packageManager} run dev`)}`);
|
|
20891
|
+
}
|
|
20884
20892
|
logger.break();
|
|
20885
20893
|
printEnvChecklist(envEntries);
|
|
20886
20894
|
} catch (error48) {
|
package/package.json
CHANGED
|
@@ -30,11 +30,18 @@ async function serializeSignedCookie(
|
|
|
30
30
|
const signedValue = encodeURIComponent(`${value}.${base64Sig}`);
|
|
31
31
|
|
|
32
32
|
let cookie = `${name}=${signedValue}`;
|
|
33
|
-
if (opt.path)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (opt.
|
|
33
|
+
if (opt.path) {
|
|
34
|
+
cookie += `; Path=${opt.path}`;
|
|
35
|
+
}
|
|
36
|
+
if (opt.expires) {
|
|
37
|
+
cookie += `; Expires=${opt.expires.toUTCString()}`;
|
|
38
|
+
}
|
|
39
|
+
if (opt.httpOnly) {
|
|
40
|
+
cookie += "; HttpOnly";
|
|
41
|
+
}
|
|
42
|
+
if (opt.sameSite) {
|
|
37
43
|
cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`;
|
|
44
|
+
}
|
|
38
45
|
return cookie;
|
|
39
46
|
}
|
|
40
47
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": ["ultracite/core", "ultracite/react", "ultracite/next"],
|
|
3
|
+
"files": {
|
|
4
|
+
"includes": [
|
|
5
|
+
"**/*",
|
|
6
|
+
"!.next",
|
|
7
|
+
"!.next",
|
|
8
|
+
"!.devtools",
|
|
9
|
+
"!.devtools",
|
|
10
|
+
"!components/ui",
|
|
11
|
+
"!components/ai-elements",
|
|
12
|
+
"!components/streamdown",
|
|
13
|
+
"!components/stick-to-bottom",
|
|
14
|
+
"!lib/utils.ts",
|
|
15
|
+
"!hooks/use-mobile.ts"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"linter": {
|
|
19
|
+
"rules": {
|
|
20
|
+
"suspicious": {
|
|
21
|
+
/* Needs more work to fix */
|
|
22
|
+
"noExplicitAny": "off"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -35,9 +35,6 @@ export function ChatSync({
|
|
|
35
35
|
|
|
36
36
|
const lastMessage = threadInitialMessages.at(-1);
|
|
37
37
|
const isLastMessagePartial = !!lastMessage?.metadata?.activeStreamId;
|
|
38
|
-
const transportFetch = Object.assign(fetchWithErrorHandlers, {
|
|
39
|
-
preconnect: fetch.preconnect,
|
|
40
|
-
}) satisfies typeof fetch;
|
|
41
38
|
|
|
42
39
|
// Backstop: if we remount ChatSync (e.g. threadEpoch changes), ensure the prior
|
|
43
40
|
// in-flight stream is aborted and we don't replay old deltas.
|
|
@@ -65,7 +62,8 @@ export function ChatSync({
|
|
|
65
62
|
resume: isLastMessagePartial,
|
|
66
63
|
transport: new DefaultChatTransport({
|
|
67
64
|
api: "/api/chat",
|
|
68
|
-
fetch
|
|
65
|
+
// @ts-expect-error CI has a stricter global fetch type (includes preconnect).
|
|
66
|
+
fetch: fetchWithErrorHandlers,
|
|
69
67
|
prepareSendMessagesRequest({ messages, id: requestId, body }) {
|
|
70
68
|
setAutoResume(true);
|
|
71
69
|
|
|
@@ -63,20 +63,28 @@ function FollowUpSuggestions({
|
|
|
63
63
|
<div className={cn("mt-2 mb-2 flex flex-col gap-2", className)}>
|
|
64
64
|
<div className="font-medium text-muted-foreground text-xs">Related</div>
|
|
65
65
|
<Suggestions className="gap-1.5">
|
|
66
|
-
{
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
66
|
+
{(() => {
|
|
67
|
+
const seen = new Map<string, number>();
|
|
68
|
+
return suggestions.map((s) => {
|
|
69
|
+
const count = seen.get(s) ?? 0;
|
|
70
|
+
seen.set(s, count + 1);
|
|
71
|
+
const key = count === 0 ? s : `${s}-${count}`;
|
|
72
|
+
return (
|
|
73
|
+
<Suggestion
|
|
74
|
+
className="h-7 text-muted-foreground hover:text-foreground"
|
|
75
|
+
key={key}
|
|
76
|
+
onClick={handleClick}
|
|
77
|
+
size="sm"
|
|
78
|
+
suggestion={s}
|
|
79
|
+
type="button"
|
|
80
|
+
variant="ghost"
|
|
81
|
+
>
|
|
82
|
+
{s}
|
|
83
|
+
<PlusIcon className="size-3 opacity-70" />
|
|
84
|
+
</Suggestion>
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
})()}
|
|
80
88
|
</Suggestions>
|
|
81
89
|
</div>
|
|
82
90
|
);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { cn } from "@/lib/utils";
|
|
4
3
|
import { format, isWithinInterval } from "date-fns";
|
|
5
4
|
import { useIsMobile } from "@/hooks/use-mobile";
|
|
6
5
|
import type { WeatherAtLocation } from "@/lib/ai/tools/get-weather";
|
|
7
6
|
import type { ChatMessage } from "@/lib/ai/types";
|
|
7
|
+
import { cn } from "@/lib/utils";
|
|
8
8
|
|
|
9
9
|
const SAMPLE = {
|
|
10
10
|
latitude: 37.763_283,
|
|
@@ -8,6 +8,7 @@ import { config } from "@/lib/config";
|
|
|
8
8
|
function GoogleIcon({ className }: { className?: string }) {
|
|
9
9
|
return (
|
|
10
10
|
<svg className={className} viewBox="0 0 24 24">
|
|
11
|
+
<title>Google</title>
|
|
11
12
|
<path
|
|
12
13
|
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"
|
|
13
14
|
fill="#4285F4"
|
|
@@ -31,6 +32,7 @@ function GoogleIcon({ className }: { className?: string }) {
|
|
|
31
32
|
function VercelIcon({ className }: { className?: string }) {
|
|
32
33
|
return (
|
|
33
34
|
<svg className={className} fill="currentColor" viewBox="0 0 24 24">
|
|
35
|
+
<title>Vercel</title>
|
|
34
36
|
<path d="M12 1L24 22H0L12 1z" />
|
|
35
37
|
</svg>
|
|
36
38
|
);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import type { UseChatHelpers } from "@ai-sdk/react";
|
|
3
3
|
import { useChatActions, type useChatStoreApi } from "@ai-sdk-tools/store";
|
|
4
|
-
import { cn } from "@/lib/utils";
|
|
5
4
|
import { ArrowUp, Square } from "lucide-react";
|
|
6
5
|
import {
|
|
7
6
|
AnimatePresence,
|
|
@@ -28,6 +27,7 @@ import {
|
|
|
28
27
|
} from "@/components/ui/tooltip";
|
|
29
28
|
import type { ChatMessage } from "@/lib/ai/types";
|
|
30
29
|
import type { ArtifactKind } from "@/lib/artifacts/artifact-kind";
|
|
30
|
+
import { cn } from "@/lib/utils";
|
|
31
31
|
import { useChatInput } from "@/providers/chat-input-provider";
|
|
32
32
|
import { artifactDefinitions } from "./artifact-panel";
|
|
33
33
|
import type {
|
|
@@ -12,10 +12,7 @@ import { z } from "zod";
|
|
|
12
12
|
*/
|
|
13
13
|
export const serverEnvSchema = {
|
|
14
14
|
// Required core
|
|
15
|
-
DATABASE_URL: z
|
|
16
|
-
.string()
|
|
17
|
-
.min(1)
|
|
18
|
-
.describe("Postgres connection string"),
|
|
15
|
+
DATABASE_URL: z.string().min(1).describe("Postgres connection string"),
|
|
19
16
|
AUTH_SECRET: z
|
|
20
17
|
.string()
|
|
21
18
|
.min(1)
|
|
@@ -28,18 +25,12 @@ export const serverEnvSchema = {
|
|
|
28
25
|
.describe("Vercel Blob storage token for file uploads"),
|
|
29
26
|
|
|
30
27
|
// Authentication providers (enable in chat.config.ts)
|
|
31
|
-
AUTH_GOOGLE_ID: z
|
|
32
|
-
.string()
|
|
33
|
-
.optional()
|
|
34
|
-
.describe("Google OAuth client ID"),
|
|
28
|
+
AUTH_GOOGLE_ID: z.string().optional().describe("Google OAuth client ID"),
|
|
35
29
|
AUTH_GOOGLE_SECRET: z
|
|
36
30
|
.string()
|
|
37
31
|
.optional()
|
|
38
32
|
.describe("Google OAuth client secret"),
|
|
39
|
-
AUTH_GITHUB_ID: z
|
|
40
|
-
.string()
|
|
41
|
-
.optional()
|
|
42
|
-
.describe("GitHub OAuth app client ID"),
|
|
33
|
+
AUTH_GITHUB_ID: z.string().optional().describe("GitHub OAuth app client ID"),
|
|
43
34
|
AUTH_GITHUB_SECRET: z
|
|
44
35
|
.string()
|
|
45
36
|
.optional()
|
|
@@ -62,10 +53,7 @@ export const serverEnvSchema = {
|
|
|
62
53
|
.string()
|
|
63
54
|
.optional()
|
|
64
55
|
.describe("Vercel OIDC token (auto-set on Vercel deployments)"),
|
|
65
|
-
OPENROUTER_API_KEY: z
|
|
66
|
-
.string()
|
|
67
|
-
.optional()
|
|
68
|
-
.describe("OpenRouter API key"),
|
|
56
|
+
OPENROUTER_API_KEY: z.string().optional().describe("OpenRouter API key"),
|
|
69
57
|
OPENAI_COMPATIBLE_BASE_URL: z
|
|
70
58
|
.string()
|
|
71
59
|
.url()
|
|
@@ -75,10 +63,7 @@ export const serverEnvSchema = {
|
|
|
75
63
|
.string()
|
|
76
64
|
.optional()
|
|
77
65
|
.describe("API key for OpenAI-compatible provider"),
|
|
78
|
-
OPENAI_API_KEY: z
|
|
79
|
-
.string()
|
|
80
|
-
.optional()
|
|
81
|
-
.describe("OpenAI API key"),
|
|
66
|
+
OPENAI_API_KEY: z.string().optional().describe("OpenAI API key"),
|
|
82
67
|
|
|
83
68
|
// Optional cleanup cron job secret
|
|
84
69
|
CRON_SECRET: z
|
|
@@ -87,18 +72,12 @@ export const serverEnvSchema = {
|
|
|
87
72
|
.describe("Secret for cleanup cron job endpoint"),
|
|
88
73
|
|
|
89
74
|
// Optional features (enable in chat.config.ts)
|
|
90
|
-
REDIS_URL: z
|
|
91
|
-
.string()
|
|
92
|
-
.optional()
|
|
93
|
-
.describe("Redis URL for resumable streams"),
|
|
75
|
+
REDIS_URL: z.string().optional().describe("Redis URL for resumable streams"),
|
|
94
76
|
TAVILY_API_KEY: z
|
|
95
77
|
.string()
|
|
96
78
|
.optional()
|
|
97
79
|
.describe("Tavily API key for web search"),
|
|
98
|
-
EXA_API_KEY: z
|
|
99
|
-
.string()
|
|
100
|
-
.optional()
|
|
101
|
-
.describe("Exa API key for web search"),
|
|
80
|
+
EXA_API_KEY: z.string().optional().describe("Exa API key for web search"),
|
|
102
81
|
FIRECRAWL_API_KEY: z
|
|
103
82
|
.string()
|
|
104
83
|
.optional()
|
|
@@ -130,11 +109,10 @@ export const serverEnvSchema = {
|
|
|
130
109
|
APP_URL: z
|
|
131
110
|
.url()
|
|
132
111
|
.optional()
|
|
133
|
-
.describe(
|
|
112
|
+
.describe(
|
|
113
|
+
"App URL for non-Vercel deployments (full URL including https://)"
|
|
114
|
+
),
|
|
134
115
|
|
|
135
116
|
// Vercel platform (auto-set by Vercel)
|
|
136
|
-
VERCEL_URL: z
|
|
137
|
-
.string()
|
|
138
|
-
.optional()
|
|
139
|
-
.describe("Auto-set by Vercel platform"),
|
|
117
|
+
VERCEL_URL: z.string().optional().describe("Auto-set by Vercel platform"),
|
|
140
118
|
};
|