chore: prepare release v0.2.0#27
Conversation
Add packages/backend as a new workspace package powered by Convex, and wire both apps/web and apps/widget to the live deployment at https://terrific-llama-923.convex.cloud. - packages/backend: new workspace package (@workspace/backend) - convex/schema.ts: defines `users` table (name: string) - convex/users.ts: getMany query + add mutation - convex/_generated: committed generated API types for TypeScript safety - package.json: name @workspace/backend, convex ^1.42.0 dep - tsconfig.json: TypeScript config for Convex functions - .gitignore: excludes .env.local (contains deployment secrets) - apps/web + apps/widget: Convex client integration - package.json: added @workspace/backend workspace dep + convex ^1.42.0 - tsconfig.json: added @workspace/backend/* path alias pointing to packages/backend/convex/* for generated API type imports - components/theme-provider.tsx: wrapped children in ConvexProvider initialised with NEXT_PUBLIC_CONVEX_URL env var - app/page.tsx: replaced static math demo with live Convex hooks — useQuery(api.users.getMany) + useMutation(api.users.add) - pnpm-lock.yaml: updated to reflect new convex dependency resolution
… build Apply Prettier auto-formatting across 14 new/modified files to satisfy the format-check CI job. No logic changes — whitespace and quote style only. Add NEXT_PUBLIC_CONVEX_URL env var to the build steps in ci.yml and release.yml so ConvexReactClient initialises with a valid URL during next build, preventing the empty-string URL error on prerender. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add packages/backend/convex/_generated/ and convex/README.md to .prettierignore — these files are auto-generated by convex dev and should not be subject to Prettier formatting rules.
CodeQL workflow runs pnpm build without NEXT_PUBLIC_CONVEX_URL set, causing ConvexReactClient to receive an empty URL and fail. Add the dev deployment URL to the build env, matching ci.yml and release.yml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat(web): integrate Convex real-time backend
Update CHANGELOG.md and README.md for the v0.2.0 release. CHANGELOG: - Add [0.2.0] section detailing the Convex backend integration: packages/backend scaffolding, server functions, CI env var additions, and .prettierignore updates. Document technical decisions. - Update compare links to point v0.2.0 as the latest release. README: - Add Convex badge to header - Add Real-Time Backend to Features list - Add packages/backend to Architecture diagram - Add Convex row to Tech Stack table - Update Environment Variables section with NEXT_PUBLIC_CONVEX_URL - Update dev commands to include --filter backend dev - Update Project Structure tree with backend/convex layout - Add @workspace/backend to Packages section with usage example Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds a new ChangesConvex Backend Integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed: private package registry requires authentication. Disable ESLint in CodeRabbit settings or use public packages. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
packages/backend/convex/README.md (1)
1-90: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReplace the stock Convex README with package-specific docs.
This still documents generic
myFunctions.tsexamples, so it does not help someone working on the actualusersschema and endpoints added in this PR. A short README forconvex/users.ts, codegen, and deploy/dev commands would be more maintainable.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/backend/convex/README.md` around lines 1 - 90, The Convex README still contains the default template and generic myFunctions examples, so replace it with package-specific documentation for the actual Convex setup. Update the README to describe the real schema/endpoints in convex/users.ts, and include the relevant codegen and deploy/dev commands so contributors can work with this package instead of the stock Convex starter content.README.md (1)
86-86: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winClarify what
@workspace/backendactually provides.The description states the package "provides a shared Convex client," but the package contains the database schema and generated API types. The
ConvexReactClientis instantiated in the app-level providers (fromconvex/react), not exported by@workspace/backend. Update to avoid confusing new contributors.-The `@workspace/backend` package provides a shared Convex client that both apps import for real-time data access. +The `@workspace/backend` package provides the Convex schema and generated API types that both apps import for real-time data access.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@README.md` at line 86, The README description of `@workspace/backend` is inaccurate because it implies the package exports a shared Convex client, when it actually contains the database schema and generated API types. Update the wording near the workspace dependency graph section to describe `@workspace/backend` as the source of Convex schema/types, and note that ConvexReactClient is created in app-level providers from convex/react rather than exported from the package.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/app/page.tsx`:
- Around line 7-18: The Page component renders the Convex useQuery result
directly, so it shows nothing while the query is loading or has failed. Update
the Page function to check users before JSON.stringify: show a loading message
when users is undefined, an error message when users is null, and only render
the user data once it is available. Use the existing Page and useQuery symbols
to locate the logic and keep the Button/addUser behavior unchanged.
In `@apps/web/components/theme-provider.tsx`:
- Around line 9-13: The ThemeProvider wrapper currently returns only
ConvexProvider, so it drops the NextThemesProvider context and ThemeHotkey
behavior. Update ThemeProvider to compose ConvexProvider inside
NextThemesProvider while still forwarding the next-themes props, and keep
ThemeHotkey mounted so children retain class/system-theme handling and the d
hotkey. Use the existing ThemeProvider, NextThemesProvider, ConvexProvider, and
ThemeHotkey symbols to place the providers in the correct nesting.
In `@apps/widget/app/page.tsx`:
- Line 14: The Add button handler in page.tsx ignores the promise returned by
addUser(), so failures are not handled locally and the user gets no feedback.
Update the onClick path around addUser() to explicitly handle the mutation
promise, using the existing addUser function and Button handler to await or
catch the result and surface an error state or message if the write fails.
In `@packages/backend/convex/users.ts`:
- Around line 3-20: The getMany and add handlers in users are publicly callable
without any identity or authorization check, exposing the users table and
allowing anonymous inserts. Add an auth guard at the start of both
query/mutation handlers by checking the current user identity from ctx and
rejecting unauthenticated callers before ctx.db.query("users").collect() or
ctx.db.insert("users", ...) runs; use the getMany and add symbols to update the
correct handlers.
In `@packages/backend/package.json`:
- Around line 8-10: The package exports in the backend package only expose the
exact convex entry, so the generated API files under convex are still not
resolvable through `@workspace/backend`. Update the exports map in package.json to
either add explicit subpath exports for the generated convex files (especially
_generated/api and related generated modules) or broaden the pattern to
./convex/* so consumers can import those generated paths through the package
surface.
---
Nitpick comments:
In `@packages/backend/convex/README.md`:
- Around line 1-90: The Convex README still contains the default template and
generic myFunctions examples, so replace it with package-specific documentation
for the actual Convex setup. Update the README to describe the real
schema/endpoints in convex/users.ts, and include the relevant codegen and
deploy/dev commands so contributors can work with this package instead of the
stock Convex starter content.
In `@README.md`:
- Line 86: The README description of `@workspace/backend` is inaccurate because it
implies the package exports a shared Convex client, when it actually contains
the database schema and generated API types. Update the wording near the
workspace dependency graph section to describe `@workspace/backend` as the source
of Convex schema/types, and note that ConvexReactClient is created in app-level
providers from convex/react rather than exported from the package.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d9c295c0-8b0b-4796-a4b3-ff06b8eb71a4
⛔ Files ignored due to path filters (6)
packages/backend/convex/_generated/api.d.tsis excluded by!**/_generated/**packages/backend/convex/_generated/api.jsis excluded by!**/_generated/**packages/backend/convex/_generated/dataModel.d.tsis excluded by!**/_generated/**packages/backend/convex/_generated/server.d.tsis excluded by!**/_generated/**packages/backend/convex/_generated/server.jsis excluded by!**/_generated/**pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (21)
.github/workflows/ci.yml.github/workflows/codeql.yml.github/workflows/release.yml.prettierignoreCHANGELOG.mdREADME.mdapps/web/app/page.tsxapps/web/components/theme-provider.tsxapps/web/package.jsonapps/web/tsconfig.jsonapps/widget/app/page.tsxapps/widget/components/theme-provider.tsxapps/widget/package.jsonapps/widget/tsconfig.jsonpackages/backend/.gitignorepackages/backend/convex/README.mdpackages/backend/convex/schema.tspackages/backend/convex/tsconfig.jsonpackages/backend/convex/users.tspackages/backend/package.jsonpackages/backend/tsconfig.json
| export default function Page() { | ||
| const users = useQuery(api.users.getMany) | ||
| const addUser = useMutation(api.users.add) | ||
| return ( | ||
| <div className="flex min-h-svh items-center justify-center"> | ||
| <div className="flex flex-col items-center justify-center gap-4"> | ||
| <h1 className="text-2xl font-bold">Hello apps/web</h1> | ||
| <Button className="sm">Button</Button> | ||
| <p>{add(2, 6)}</p> | ||
| <div className="flex min-h-svh flex-col items-center justify-center"> | ||
| <p> apps/web</p> | ||
| <Button onClick={() => addUser()}>Add</Button> | ||
| <div className="mx-auto w-full max-w-sm"> | ||
| {JSON.stringify(users, null, 2)} | ||
| </div> | ||
| </div> | ||
| ) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Add loading and error states for the Convex query.
useQuery returns undefined while loading and null on error. Currently, JSON.stringify(undefined, null, 2) renders as empty whitespace with no user feedback. Add explicit loading and error handling before rendering results.
export default function Page() {
const users = useQuery(api.users.getMany)
const addUser = useMutation(api.users.add)
+
+ if (users === undefined) {
+ return <div className="flex min-h-svh items-center justify-center">Loading...</div>
+ }
+
+ if (users === null) {
+ return <div className="flex min-h-svh items-center justify-center text-red-500">Error loading users</div>
+ }
+
return (
<div className="flex min-h-svh flex-col items-center justify-center">
<p> apps/web</p>
<Button onClick={() => addUser()}>Add</Button>
<div className="mx-auto w-full max-w-sm">
- {JSON.stringify(users, null, 2)}
+ <pre className="rounded bg-muted p-4 overflow-auto">
+ {JSON.stringify(users, null, 2)}
+ </pre>
</div>
</div>
)
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/app/page.tsx` around lines 7 - 18, The Page component renders the
Convex useQuery result directly, so it shows nothing while the query is loading
or has failed. Update the Page function to check users before JSON.stringify:
show a loading message when users is undefined, an error message when users is
null, and only render the user data once it is available. Use the existing Page
and useQuery symbols to locate the logic and keep the Button/addUser behavior
unchanged.
| function ThemeProvider({ | ||
| children, | ||
| ...props | ||
| }: React.ComponentProps<typeof NextThemesProvider>) { | ||
| return ( | ||
| <NextThemesProvider | ||
| attribute="class" | ||
| defaultTheme="system" | ||
| enableSystem | ||
| disableTransitionOnChange | ||
| {...props} | ||
| > | ||
| <ThemeHotkey /> | ||
| {children} | ||
| </NextThemesProvider> | ||
| ) | ||
| return <ConvexProvider client={convex}>{children}</ConvexProvider> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
git diff -- apps/web/components/theme-provider.tsx -- apps/web/components/theme-provider.tsx || true
printf '\n--- file ---\n'
cat -n apps/web/components/theme-provider.tsx | sed -n '1,220p'
printf '\n--- theme hotkey refs ---\n'
rg -n "ThemeHotkey|useTheme|NextThemesProvider|ConvexProvider" apps/web/components/theme-provider.tsx apps/web -g '!**/node_modules/**'Repository: RISHII7/echo
Length of output: 3236
Compose ConvexProvider inside NextThemesProvider. This wrapper still takes next-themes props, but it no longer provides theme context or mounts ThemeHotkey, so children lose the class/system-theme behavior and the d hotkey.
🧰 Tools
🪛 GitHub Check: Lint
[warning] 11-11:
'props' is defined but never used
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/components/theme-provider.tsx` around lines 9 - 13, The
ThemeProvider wrapper currently returns only ConvexProvider, so it drops the
NextThemesProvider context and ThemeHotkey behavior. Update ThemeProvider to
compose ConvexProvider inside NextThemesProvider while still forwarding the
next-themes props, and keep ThemeHotkey mounted so children retain
class/system-theme handling and the d hotkey. Use the existing ThemeProvider,
NextThemesProvider, ConvexProvider, and ThemeHotkey symbols to place the
providers in the correct nesting.
| <Input /> | ||
| <div className="flex min-h-svh flex-col items-center justify-center"> | ||
| <p> apps/widget</p> | ||
| <Button onClick={() => addUser()}>Add</Button> |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== page.tsx ==\n'
sed -n '1,120p' apps/widget/app/page.tsx
printf '\n== users mutation ==\n'
sed -n '1,220p' packages/backend/convex/users.ts
printf '\n== useMutation usages ==\n'
rg -n "useMutation\\(|addUser\\(" apps/widget packages/backend -S
printf '\n== convex/react docs in repo (if any) ==\n'
rg -n "useMutation" . -g '!node_modules' -g '!dist' -g '!build' -SRepository: RISHII7/echo
Length of output: 2119
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the relevant files precisely and inspect surrounding context.
git ls-files 'apps/widget/app/page.tsx' 'packages/backend/convex/users.ts' || true
printf '\n== page.tsx with line numbers ==\n'
cat -n apps/widget/app/page.tsx | sed -n '1,120p'
printf '\n== users.ts with line numbers ==\n'
cat -n packages/backend/convex/users.ts | sed -n '1,220p'
printf '\n== search for any local error handling around addUser ==\n'
rg -n "addUser\\(|console\\.error|catch \\(" apps/widget -SRepository: RISHII7/echo
Length of output: 1674
Handle the mutation promise here. addUser() is ignored, so a failed write has no local error path and the user gets no feedback.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/widget/app/page.tsx` at line 14, The Add button handler in page.tsx
ignores the promise returned by addUser(), so failures are not handled locally
and the user gets no feedback. Update the onClick path around addUser() to
explicitly handle the mutation promise, using the existing addUser function and
Button handler to await or catch the result and surface an error state or
message if the write fails.
| export const getMany = query({ | ||
| args: {}, | ||
| handler: async (ctx) => { | ||
| const users = await ctx.db.query("users").collect() | ||
|
|
||
| return users | ||
| }, | ||
| }) | ||
|
|
||
| export const add = mutation({ | ||
| args: {}, | ||
| handler: async (ctx) => { | ||
| const userId = await ctx.db.insert("users", { | ||
| name: "RISHII", | ||
| }) | ||
|
|
||
| return userId | ||
| }, |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Add auth before exposing the users table.
These handlers are callable from a public client component, but neither checks identity or authorization. Once the deployed NEXT_PUBLIC_CONVEX_URL is public, any anonymous visitor can read the full users table and spam inserts into it.
Minimal guard
export const getMany = query({
args: {},
handler: async (ctx) => {
+ const identity = await ctx.auth.getUserIdentity()
+ if (!identity) {
+ throw new Error("Unauthorized")
+ }
const users = await ctx.db.query("users").collect()
return users
},
})
@@
export const add = mutation({
args: {},
handler: async (ctx) => {
+ const identity = await ctx.auth.getUserIdentity()
+ if (!identity) {
+ throw new Error("Unauthorized")
+ }
const userId = await ctx.db.insert("users", {
name: "RISHII",
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const getMany = query({ | |
| args: {}, | |
| handler: async (ctx) => { | |
| const users = await ctx.db.query("users").collect() | |
| return users | |
| }, | |
| }) | |
| export const add = mutation({ | |
| args: {}, | |
| handler: async (ctx) => { | |
| const userId = await ctx.db.insert("users", { | |
| name: "RISHII", | |
| }) | |
| return userId | |
| }, | |
| export const getMany = query({ | |
| args: {}, | |
| handler: async (ctx) => { | |
| const identity = await ctx.auth.getUserIdentity() | |
| if (!identity) { | |
| throw new Error("Unauthorized") | |
| } | |
| const users = await ctx.db.query("users").collect() | |
| return users | |
| }, | |
| }) | |
| export const add = mutation({ | |
| args: {}, | |
| handler: async (ctx) => { | |
| const identity = await ctx.auth.getUserIdentity() | |
| if (!identity) { | |
| throw new Error("Unauthorized") | |
| } | |
| const userId = await ctx.db.insert("users", { | |
| name: "RISHII", | |
| }) | |
| return userId | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/backend/convex/users.ts` around lines 3 - 20, The getMany and add
handlers in users are publicly callable without any identity or authorization
check, exposing the users table and allowing anonymous inserts. Add an auth
guard at the start of both query/mutation handlers by checking the current user
identity from ctx and rejecting unauthenticated callers before
ctx.db.query("users").collect() or ctx.db.insert("users", ...) runs; use the
getMany and add symbols to update the correct handlers.
| "exports": { | ||
| "./convex": "./convex/*.ts" | ||
| }, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
echo "Declared exports:"
jq '.exports' packages/backend/package.json
echo
echo "Backend package imports in the repo:"
rg -n '"`@workspace/backend`[^"]*"' apps packagesRepository: RISHII7/echo
Length of output: 865
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "backend package manifest:"
cat -n packages/backend/package.json
echo
echo "backend tsconfig:"
cat -n packages/backend/tsconfig.json
echo
echo "backend file tree:"
find packages/backend -maxdepth 3 -type f | sort
echo
echo "generated API file locations:"
find packages/backend -path '*/_generated/*' -type f | sortRepository: RISHII7/echo
Length of output: 1705
🏁 Script executed:
node - <<'JS'
import fs from 'fs';
import os from 'os';
import path from 'path';
import { pathToFileURL } from 'url';
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'exports-test-'));
fs.mkdirSync(path.join(dir, 'pkg', 'convex', '_generated'), { recursive: true });
fs.writeFileSync(path.join(dir, 'pkg', 'package.json'), JSON.stringify({
name: 'pkg',
type: 'module',
exports: { './convex': './convex/*.ts' }
}, null, 2));
fs.writeFileSync(path.join(dir, 'pkg', 'convex', 'foo.ts'), 'export const x = 1;\n');
fs.writeFileSync(path.join(dir, 'pkg', 'convex', '_generated', 'api.ts'), 'export const api = 1;\n');
const pkgUrl = pathToFileURL(path.join(dir, 'pkg', 'package.json')).href;
console.log('package.json:', pkgUrl);
for (const spec of ['pkg/convex', 'pkg/convex/foo', 'pkg/convex/_generated/api']) {
try {
const resolved = await import.meta.resolve(spec, pkgUrl);
console.log(spec, '=>', resolved);
} catch (e) {
console.log(spec, '=> ERROR:', e.code || e.message);
}
}
JSRepository: RISHII7/echo
Length of output: 358
🏁 Script executed:
node - <<'JS'
import fs from 'fs';
import os from 'os';
import path from 'path';
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'pkg-exports-'));
const nodeModules = path.join(root, 'node_modules');
const pkgDir = path.join(nodeModules, 'pkg');
fs.mkdirSync(path.join(pkgDir, 'convex', '_generated'), { recursive: true });
fs.writeFileSync(path.join(pkgDir, 'package.json'), JSON.stringify({
name: 'pkg',
type: 'module',
exports: {
'./convex': './convex/*.ts'
}
}, null, 2));
fs.writeFileSync(path.join(pkgDir, 'convex', 'foo.ts'), 'export const x = 1;\n');
fs.writeFileSync(path.join(pkgDir, 'convex', '_generated', 'api.ts'), 'export const api = 1;\n');
const app = path.join(root, 'app.mjs');
fs.writeFileSync(app, `
for (const spec of ['pkg/convex', 'pkg/convex/foo', 'pkg/convex/_generated/api']) {
try {
console.log(spec + ' => ' + await import.meta.resolve(spec));
} catch (e) {
console.log(spec + ' => ERROR: ' + e.code);
}
}
`);
const { spawnSync } = await import('child_process');
const r = spawnSync(process.execPath, [app], { cwd: root, encoding: 'utf8' });
process.stdout.write(r.stdout);
process.stderr.write(r.stderr);
process.exit(r.status ?? 0);
JSRepository: RISHII7/echo
Length of output: 345
Export the generated API subpaths from @workspace/backend.
"./convex": "./convex/*.ts" only exposes the exact @workspace/backend/convex entry; it does not make @workspace/backend/_generated/api or the other generated files under convex/ resolvable through the package surface. Add explicit subpath exports for the generated files or switch to ./convex/*.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/backend/package.json` around lines 8 - 10, The package exports in
the backend package only expose the exact convex entry, so the generated API
files under convex are still not resolvable through `@workspace/backend`. Update
the exports map in package.json to either add explicit subpath exports for the
generated convex files (especially _generated/api and related generated modules)
or broaden the pattern to ./convex/* so consumers can import those generated
paths through the package surface.
Release v0.2.0 — Convex Real-Time Backend
This PR merges
release/0.2.0intomainto ship the Convex backend integration.What's in this release
New:
@workspace/backendpackageusersschema,getManyquery, andaddmutation.gitignoreexcludes.env.local(deployment secrets)Apps: Convex client integration
apps/webandapps/widgetwired withConvexProviderNEXT_PUBLIC_CONVEX_URLenv var drives the client in all environmentsuseQuery/useMutationhooks replacing static math demo@workspace/backend/*CI improvements
NEXT_PUBLIC_CONVEX_URLadded to build steps inci.yml,release.yml,codeql.ymlconvex/_generated/andconvex/README.mdexcluded from Prettier formattingDocs
Deployment notes
Convex backend is live at
https://terrific-llama-923.convex.cloud(project:rishii:echo).After cloning, set
NEXT_PUBLIC_CONVEX_URLinapps/web/.env.localandapps/widget/.env.local.Checklist
release/0.2.0v0.2.0tag to be created after merge🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores