@chat-js/cli 0.3.0 → 0.6.0
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 +1173 -964
- package/package.json +1 -1
- package/templates/chat-app/app/(auth)/device-login/page.tsx +37 -0
- package/templates/chat-app/app/(auth)/login/page.tsx +26 -2
- package/templates/chat-app/app/(auth)/register/page.tsx +0 -12
- package/templates/chat-app/app/(chat)/api/chat/filter-reasoning-parts.ts +1 -1
- package/templates/chat-app/app/(chat)/api/chat/prepare/route.ts +94 -0
- package/templates/chat-app/app/(chat)/api/chat/route.ts +107 -16
- package/templates/chat-app/app/(chat)/layout.tsx +4 -1
- package/templates/chat-app/app/api/trpc/[trpc]/route.ts +1 -0
- package/templates/chat-app/app/globals.css +9 -9
- package/templates/chat-app/app/layout.tsx +4 -2
- package/templates/chat-app/biome.jsonc +3 -3
- package/templates/chat-app/chat.config.ts +32 -12
- package/templates/chat-app/components/ai-elements/prompt-input.tsx +1 -1
- package/templates/chat-app/components/anonymous-session-init.tsx +10 -6
- package/templates/chat-app/components/artifact-actions.tsx +81 -18
- package/templates/chat-app/components/artifact-panel.tsx +142 -41
- package/templates/chat-app/components/attachment-list.tsx +1 -1
- package/templates/chat-app/components/{social-auth-providers.tsx → auth-providers.tsx} +49 -4
- package/templates/chat-app/components/chat/chat-welcome.tsx +3 -3
- package/templates/chat-app/components/chat-menu-items.tsx +1 -1
- package/templates/chat-app/components/chat-sync.tsx +9 -11
- package/templates/chat-app/components/console.tsx +9 -9
- package/templates/chat-app/components/context-usage.tsx +2 -2
- package/templates/chat-app/components/create-artifact.tsx +15 -5
- package/templates/chat-app/components/data-stream-handler.tsx +57 -16
- package/templates/chat-app/components/device-login-page.tsx +191 -0
- package/templates/chat-app/components/diffview.tsx +8 -2
- package/templates/chat-app/components/electron-auth-handler.tsx +184 -0
- package/templates/chat-app/components/electron-auth-ui.tsx +121 -0
- package/templates/chat-app/components/favicon-group.tsx +1 -1
- package/templates/chat-app/components/feedback-actions.tsx +7 -3
- package/templates/chat-app/components/greeting.tsx +1 -1
- package/templates/chat-app/components/interactive-chart-impl.tsx +3 -4
- package/templates/chat-app/components/interactive-charts.tsx +1 -1
- package/templates/chat-app/components/login-form.tsx +52 -10
- package/templates/chat-app/components/message-editor.tsx +7 -3
- package/templates/chat-app/components/message-siblings.tsx +14 -1
- package/templates/chat-app/components/model-selector.tsx +295 -27
- package/templates/chat-app/components/multimodal-input.tsx +259 -22
- package/templates/chat-app/components/parallel-response-cards.tsx +175 -0
- package/templates/chat-app/components/part/code-execution.tsx +8 -2
- package/templates/chat-app/components/part/document-common.tsx +1 -1
- package/templates/chat-app/components/part/document-preview.tsx +5 -5
- package/templates/chat-app/components/part/retrieve-url.tsx +12 -12
- package/templates/chat-app/components/part/text-message-part.tsx +9 -1
- package/templates/chat-app/components/project-chat-item.tsx +1 -1
- package/templates/chat-app/components/project-menu-items.tsx +1 -1
- package/templates/chat-app/components/research-task.tsx +1 -1
- package/templates/chat-app/components/research-tasks.tsx +1 -1
- package/templates/chat-app/components/retry-button.tsx +25 -8
- package/templates/chat-app/components/sandbox.tsx +1 -1
- package/templates/chat-app/components/sheet-editor.tsx +7 -7
- package/templates/chat-app/components/sidebar-chats-list.tsx +1 -1
- package/templates/chat-app/components/sidebar-toggle.tsx +15 -2
- package/templates/chat-app/components/sidebar-top-row.tsx +27 -12
- package/templates/chat-app/components/sidebar-user-nav.tsx +10 -1
- package/templates/chat-app/components/signup-form.tsx +49 -10
- package/templates/chat-app/components/sources.tsx +4 -4
- package/templates/chat-app/components/text-editor.tsx +5 -2
- package/templates/chat-app/components/toolbar.tsx +3 -3
- package/templates/chat-app/components/ui/sidebar.tsx +0 -1
- package/templates/chat-app/components/upgrade-cta/limit-display.tsx +1 -1
- package/templates/chat-app/components/user-message.tsx +14 -2
- package/templates/chat-app/electron.d.ts +41 -0
- package/templates/chat-app/evals/my-eval.eval.ts +3 -1
- package/templates/chat-app/hooks/chat-sync-hooks.ts +11 -0
- package/templates/chat-app/hooks/use-artifact.tsx +13 -13
- package/templates/chat-app/hooks/use-navigate-to-message.ts +39 -0
- package/templates/chat-app/lib/ai/gateways/provider-types.ts +19 -10
- package/templates/chat-app/lib/ai/stream-errors.test.ts +72 -0
- package/templates/chat-app/lib/ai/stream-errors.ts +94 -0
- package/templates/chat-app/lib/ai/tools/code-execution.javascript.ts +171 -0
- package/templates/chat-app/lib/ai/tools/code-execution.python.ts +336 -0
- package/templates/chat-app/lib/ai/tools/code-execution.shared.test.ts +71 -0
- package/templates/chat-app/lib/ai/tools/code-execution.shared.ts +59 -0
- package/templates/chat-app/lib/ai/tools/code-execution.ts +62 -391
- package/templates/chat-app/lib/ai/tools/code-execution.types.ts +24 -0
- package/templates/chat-app/lib/ai/tools/steps/multi-query-web-search.ts +3 -2
- package/templates/chat-app/lib/ai/types.ts +74 -3
- package/templates/chat-app/lib/anonymous-session-client.ts +0 -3
- package/templates/chat-app/lib/artifacts/code/client.tsx +35 -5
- package/templates/chat-app/lib/artifacts/sheet/client.tsx +11 -3
- package/templates/chat-app/lib/auth-client.ts +23 -1
- package/templates/chat-app/lib/auth.ts +18 -1
- package/templates/chat-app/lib/blob.ts +1 -1
- package/templates/chat-app/lib/clone-messages.ts +1 -1
- package/templates/chat-app/lib/config-schema.ts +18 -1
- package/templates/chat-app/lib/constants.ts +3 -4
- package/templates/chat-app/lib/db/migrations/0044_gray_red_shift.sql +5 -0
- package/templates/chat-app/lib/db/migrations/meta/0044_snapshot.json +1480 -0
- package/templates/chat-app/lib/db/migrations/meta/_journal.json +7 -0
- package/templates/chat-app/lib/db/queries.ts +84 -4
- package/templates/chat-app/lib/db/schema.ts +4 -1
- package/templates/chat-app/lib/editor/config.ts +4 -4
- package/templates/chat-app/lib/electron-auth.ts +96 -0
- package/templates/chat-app/lib/env-schema.ts +33 -4
- package/templates/chat-app/lib/message-conversion.ts +14 -2
- package/templates/chat-app/lib/playwright-test-environment.ts +18 -0
- package/templates/chat-app/lib/social-auth.ts +5 -0
- package/templates/chat-app/lib/stores/hooks-threads.ts +38 -1
- package/templates/chat-app/lib/stores/with-threads.test.ts +137 -0
- package/templates/chat-app/lib/stores/with-threads.ts +159 -7
- package/templates/chat-app/lib/stores/with-tracing.ts +1 -1
- package/templates/chat-app/lib/thread-utils.ts +22 -3
- package/templates/chat-app/lib/utils/download-assets.ts +6 -7
- package/templates/chat-app/lib/utils/rate-limit.ts +9 -3
- package/templates/chat-app/package.json +20 -18
- package/templates/chat-app/playwright.config.ts +0 -19
- package/templates/chat-app/providers/chat-input-provider.tsx +40 -2
- package/templates/chat-app/proxy.ts +28 -3
- package/templates/chat-app/scripts/check-env.ts +10 -0
- package/templates/chat-app/scripts/db-branch-delete.sh +7 -1
- package/templates/chat-app/scripts/db-branch-use.sh +7 -1
- package/templates/chat-app/scripts/with-db.sh +7 -1
- package/templates/chat-app/trpc/server.tsx +7 -2
- package/templates/chat-app/tsconfig.json +2 -1
- package/templates/chat-app/vercel.json +0 -10
- package/templates/chat-app/vitest.config.ts +2 -0
- package/templates/electron/CHANGELOG.md +7 -0
- package/templates/electron/README.md +54 -0
- package/templates/electron/entitlements.mac.plist +10 -0
- package/templates/electron/forge.config.ts +157 -0
- package/templates/electron/icon.png +0 -0
- package/templates/electron/package.json +53 -0
- package/templates/electron/scripts/generate-icons.test.js +37 -0
- package/templates/electron/scripts/generate-icons.ts +29 -0
- package/templates/electron/scripts/run-forge.cjs +28 -0
- package/templates/electron/scripts/write-branding.ts +18 -0
- package/templates/electron/src/config.ts +16 -0
- package/templates/electron/src/lib/auth-client.ts +64 -0
- package/templates/electron/src/main.ts +670 -0
- package/templates/electron/src/preload.d.ts +27 -0
- package/templates/electron/src/preload.ts +25 -0
- package/templates/electron/tsconfig.json +18 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type ConsoleOutput,
|
|
7
7
|
type ConsoleOutputContent,
|
|
8
8
|
} from "@/components/console";
|
|
9
|
-
import { Artifact } from "@/components/create-artifact";
|
|
9
|
+
import { Artifact, type ArtifactMetadata } from "@/components/create-artifact";
|
|
10
10
|
import { config } from "@/lib/config";
|
|
11
11
|
import { generateUUID, getLanguageFromFileName } from "@/lib/utils";
|
|
12
12
|
|
|
@@ -56,12 +56,36 @@ function detectRequiredHandlers(code: string): string[] {
|
|
|
56
56
|
return handlers;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
interface
|
|
59
|
+
export interface CodeArtifactMetadata {
|
|
60
60
|
language: string;
|
|
61
61
|
outputs: ConsoleOutput[];
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export
|
|
64
|
+
export function isCodeArtifactMetadata(
|
|
65
|
+
metadata: ArtifactMetadata
|
|
66
|
+
): metadata is CodeArtifactMetadata {
|
|
67
|
+
return (
|
|
68
|
+
metadata !== null &&
|
|
69
|
+
typeof metadata === "object" &&
|
|
70
|
+
"language" in metadata &&
|
|
71
|
+
typeof metadata.language === "string" &&
|
|
72
|
+
"outputs" in metadata &&
|
|
73
|
+
Array.isArray(metadata.outputs)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getCodeArtifactMetadata(
|
|
78
|
+
metadata: ArtifactMetadata
|
|
79
|
+
): CodeArtifactMetadata {
|
|
80
|
+
return isCodeArtifactMetadata(metadata)
|
|
81
|
+
? metadata
|
|
82
|
+
: {
|
|
83
|
+
language: "python",
|
|
84
|
+
outputs: [],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const codeArtifact = new Artifact<"code", CodeArtifactMetadata>({
|
|
65
89
|
kind: "code",
|
|
66
90
|
description:
|
|
67
91
|
"Useful for code generation; Code execution is only available for Python code.",
|
|
@@ -184,14 +208,20 @@ export const codeArtifact = new Artifact<"code", Metadata>({
|
|
|
184
208
|
},
|
|
185
209
|
],
|
|
186
210
|
}));
|
|
187
|
-
} catch (error:
|
|
211
|
+
} catch (error: unknown) {
|
|
188
212
|
setMetadata((metadata) => ({
|
|
189
213
|
...metadata,
|
|
190
214
|
outputs: [
|
|
191
215
|
...metadata.outputs.filter((output) => output.id !== runId),
|
|
192
216
|
{
|
|
193
217
|
id: runId,
|
|
194
|
-
contents: [
|
|
218
|
+
contents: [
|
|
219
|
+
{
|
|
220
|
+
type: "text",
|
|
221
|
+
value:
|
|
222
|
+
error instanceof Error ? error.message : String(error),
|
|
223
|
+
},
|
|
224
|
+
],
|
|
195
225
|
status: "failed",
|
|
196
226
|
},
|
|
197
227
|
],
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { Copy, LineChart, Redo2, Sparkles, Undo2 } from "lucide-react";
|
|
2
2
|
import { parse, unparse } from "papaparse";
|
|
3
3
|
import { toast } from "sonner";
|
|
4
|
-
import { Artifact } from "@/components/create-artifact";
|
|
4
|
+
import { Artifact, type ArtifactMetadata } from "@/components/create-artifact";
|
|
5
5
|
import { SpreadsheetEditor } from "@/components/sheet-editor";
|
|
6
6
|
import { config } from "@/lib/config";
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
export type SheetArtifactMetadata = Record<string, unknown>;
|
|
9
9
|
|
|
10
|
-
export
|
|
10
|
+
export function getSheetArtifactMetadata(
|
|
11
|
+
metadata: ArtifactMetadata
|
|
12
|
+
): SheetArtifactMetadata {
|
|
13
|
+
return metadata && typeof metadata === "object"
|
|
14
|
+
? Object.fromEntries(Object.entries(metadata))
|
|
15
|
+
: {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const sheetArtifact = new Artifact<"sheet", SheetArtifactMetadata>({
|
|
11
19
|
kind: "sheet",
|
|
12
20
|
description: "Useful for working with spreadsheets",
|
|
13
21
|
initialize: async () => {
|
|
@@ -1,10 +1,32 @@
|
|
|
1
|
+
import { electronProxyClient } from "@better-auth/electron/proxy";
|
|
1
2
|
import { nextCookies } from "better-auth/next-js";
|
|
2
3
|
import { createAuthClient } from "better-auth/react";
|
|
4
|
+
import { config } from "@/lib/config";
|
|
5
|
+
import {
|
|
6
|
+
ELECTRON_APP_SCHEME,
|
|
7
|
+
ELECTRON_AUTH_CALLBACK_PATH,
|
|
8
|
+
ELECTRON_AUTH_CLIENT_ID,
|
|
9
|
+
ELECTRON_AUTH_COOKIE_PREFIX,
|
|
10
|
+
} from "@/lib/electron-auth";
|
|
3
11
|
|
|
4
12
|
// Better Auth auto-detects the base URL from window.location.origin on client
|
|
5
13
|
// and uses relative URLs for SSR, so we don't need to specify baseURL
|
|
6
14
|
const authClient = createAuthClient({
|
|
7
|
-
plugins: [
|
|
15
|
+
plugins: [
|
|
16
|
+
nextCookies(),
|
|
17
|
+
...(config.desktopApp.enabled
|
|
18
|
+
? [
|
|
19
|
+
electronProxyClient({
|
|
20
|
+
callbackPath: ELECTRON_AUTH_CALLBACK_PATH,
|
|
21
|
+
clientID: ELECTRON_AUTH_CLIENT_ID,
|
|
22
|
+
cookiePrefix: ELECTRON_AUTH_COOKIE_PREFIX,
|
|
23
|
+
protocol: {
|
|
24
|
+
scheme: ELECTRON_APP_SCHEME,
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
]
|
|
28
|
+
: []),
|
|
29
|
+
],
|
|
8
30
|
});
|
|
9
31
|
|
|
10
32
|
export default authClient;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { electron } from "@better-auth/electron";
|
|
1
2
|
import { betterAuth } from "better-auth";
|
|
2
3
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
3
4
|
import { nextCookies } from "better-auth/next-js";
|
|
@@ -5,6 +6,11 @@ import { env } from "@/lib/env";
|
|
|
5
6
|
import { config } from "./config";
|
|
6
7
|
import { db } from "./db/client";
|
|
7
8
|
import { schema } from "./db/schema";
|
|
9
|
+
import {
|
|
10
|
+
ELECTRON_AUTH_CLIENT_ID,
|
|
11
|
+
ELECTRON_AUTH_COOKIE_PREFIX,
|
|
12
|
+
ELECTRON_TRUSTED_ORIGINS,
|
|
13
|
+
} from "./electron-auth";
|
|
8
14
|
|
|
9
15
|
export const auth = betterAuth({
|
|
10
16
|
database: drizzleAdapter(db, {
|
|
@@ -16,6 +22,7 @@ export const auth = betterAuth({
|
|
|
16
22
|
// Vercel URL for preview branches
|
|
17
23
|
...(env.VERCEL_URL ? [`https://${env.VERCEL_URL}`] : []),
|
|
18
24
|
config.appUrl,
|
|
25
|
+
...(config.desktopApp.enabled ? ELECTRON_TRUSTED_ORIGINS : []),
|
|
19
26
|
],
|
|
20
27
|
secret: env.AUTH_SECRET,
|
|
21
28
|
|
|
@@ -60,7 +67,17 @@ export const auth = betterAuth({
|
|
|
60
67
|
|
|
61
68
|
return { google, github, vercel } as const;
|
|
62
69
|
})(),
|
|
63
|
-
plugins: [
|
|
70
|
+
plugins: [
|
|
71
|
+
nextCookies(),
|
|
72
|
+
...(config.desktopApp.enabled
|
|
73
|
+
? [
|
|
74
|
+
electron({
|
|
75
|
+
clientID: ELECTRON_AUTH_CLIENT_ID,
|
|
76
|
+
cookiePrefix: ELECTRON_AUTH_COOKIE_PREFIX,
|
|
77
|
+
}),
|
|
78
|
+
]
|
|
79
|
+
: []),
|
|
80
|
+
],
|
|
64
81
|
});
|
|
65
82
|
|
|
66
83
|
// Infer session type from the auth instance for type safety
|
|
@@ -67,7 +67,7 @@ export function extractFilenameFromUrl(url: string): string | null {
|
|
|
67
67
|
|
|
68
68
|
// Remove the prefix if it exists in the URL
|
|
69
69
|
if (filename.startsWith(BLOB_FILE_PREFIX)) {
|
|
70
|
-
return filename.
|
|
70
|
+
return filename.slice(BLOB_FILE_PREFIX.length);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
return filename;
|
|
@@ -224,9 +224,14 @@ export const featuresConfigSchema = z
|
|
|
224
224
|
attachments: z
|
|
225
225
|
.boolean()
|
|
226
226
|
.describe("File attachments (requires BLOB_READ_WRITE_TOKEN)"),
|
|
227
|
+
parallelResponses: z
|
|
228
|
+
.boolean()
|
|
229
|
+
.default(true)
|
|
230
|
+
.describe("Send one message to multiple models simultaneously"),
|
|
227
231
|
})
|
|
228
232
|
.default({
|
|
229
233
|
attachments: false,
|
|
234
|
+
parallelResponses: true,
|
|
230
235
|
});
|
|
231
236
|
|
|
232
237
|
export const authenticationConfigSchema = z
|
|
@@ -249,6 +254,16 @@ export const authenticationConfigSchema = z
|
|
|
249
254
|
vercel: false,
|
|
250
255
|
});
|
|
251
256
|
|
|
257
|
+
export const desktopAppConfigSchema = z
|
|
258
|
+
.object({
|
|
259
|
+
enabled: z
|
|
260
|
+
.boolean()
|
|
261
|
+
.describe("Enable Electron desktop auth/runtime integration"),
|
|
262
|
+
})
|
|
263
|
+
.default({
|
|
264
|
+
enabled: false,
|
|
265
|
+
});
|
|
266
|
+
|
|
252
267
|
export const configSchema = z.object({
|
|
253
268
|
appPrefix: z.string().default("chatjs"),
|
|
254
269
|
appName: z.string().default("My AI Chat"),
|
|
@@ -321,6 +336,8 @@ export const configSchema = z.object({
|
|
|
321
336
|
|
|
322
337
|
authentication: authenticationConfigSchema,
|
|
323
338
|
|
|
339
|
+
desktopApp: desktopAppConfigSchema,
|
|
340
|
+
|
|
324
341
|
ai: aiConfigSchema,
|
|
325
342
|
|
|
326
343
|
anonymous: anonymousConfigSchema,
|
|
@@ -336,6 +353,7 @@ export type AnonymousConfig = z.infer<typeof anonymousConfigSchema>;
|
|
|
336
353
|
export type AttachmentsConfig = z.infer<typeof attachmentsConfigSchema>;
|
|
337
354
|
export type FeaturesConfig = z.infer<typeof featuresConfigSchema>;
|
|
338
355
|
export type AuthenticationConfig = z.infer<typeof authenticationConfigSchema>;
|
|
356
|
+
export type DesktopAppConfig = z.infer<typeof desktopAppConfigSchema>;
|
|
339
357
|
|
|
340
358
|
// Gateway-aware input types: model IDs narrowed per gateway for autocomplete
|
|
341
359
|
type ZodConfigInput = z.input<typeof configSchema>;
|
|
@@ -384,7 +402,6 @@ interface AiToolsInputFor<G extends GatewayType> {
|
|
|
384
402
|
}
|
|
385
403
|
|
|
386
404
|
// Only gateway is required; everything else is an override on top of GATEWAY_MODEL_DEFAULTS
|
|
387
|
-
// biome-ignore lint/style/useConsistentTypeDefinitions: type is used intentionally here
|
|
388
405
|
type AiInputFor<G extends GatewayType> = {
|
|
389
406
|
gateway: G;
|
|
390
407
|
providerOrder?: AiShape["providerOrder"];
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { config } from "@/lib/config";
|
|
2
|
+
import { isPlaywrightTestEnvironment as getIsPlaywrightTestEnvironment } from "@/lib/playwright-test-environment";
|
|
2
3
|
|
|
3
4
|
const _isProductionEnvironment = process.env.NODE_ENV === "production";
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
process.env
|
|
7
|
-
process.env.PLAYWRIGHT ||
|
|
8
|
-
process.env.CI_PLAYWRIGHT
|
|
6
|
+
export const isPlaywrightTestEnvironment = getIsPlaywrightTestEnvironment(
|
|
7
|
+
process.env
|
|
9
8
|
);
|
|
10
9
|
|
|
11
10
|
export const BLOB_FILE_PREFIX = `${config.appPrefix}/files/`;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
ALTER TABLE "Message" ALTER COLUMN "selectedModel" DROP DEFAULT;--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "Message" ALTER COLUMN "selectedModel" SET DATA TYPE json USING to_json("selectedModel");--> statement-breakpoint
|
|
3
|
+
ALTER TABLE "Message" ADD COLUMN "parallelGroupId" uuid;--> statement-breakpoint
|
|
4
|
+
ALTER TABLE "Message" ADD COLUMN "parallelIndex" integer;--> statement-breakpoint
|
|
5
|
+
ALTER TABLE "Message" ADD COLUMN "isPrimaryParallel" boolean;--> statement-breakpoint
|