Kanshō

Docs / Sandbox and code /

CodeEditorPane

Read-only code pane with syntax highlighting, line numbers, and optional line range focus.

Preview

src/lib/auth.tstypescript
1import { SignJWT, jwtVerify } from 'jose'
2import { db } from './db'
3
4const SECRET = new TextEncoder().encode(process.env.JWT_SECRET!)
5
6export class AuthError extends Error {}
7
8export async function signToken(userId: string): Promise<string> {
9 return new SignJWT({ sub: userId })
Agent added sub claim for user identity
10 .setProtectedHeader({ alg: 'HS256' })
11 .setExpirationTime('7d')
12 .sign(SECRET)
13}
14
15export async function verifyJWT(token: string) {
16 const { payload } = await jwtVerify(token, SECRET)
17 if (!payload.sub) throw new AuthError('Invalid token')
Consider checking token expiry explicitly
18 return payload
19}
Ln 9, Col 22No errors

Variants

TypeScript

src/lib/auth.tstypescript
1import { SignJWT, jwtVerify } from 'jose'
2import { db } from './db'
3
4const SECRET = new TextEncoder().encode(process.env.JWT_SECRET!)
5
6export class AuthError extends Error {}
7
8export async function signToken(userId: string): Promise<string> {
9 return new SignJWT({ sub: userId })
Agent added sub claim for user identity
10 .setProtectedHeader({ alg: 'HS256' })
11 .setExpirationTime('7d')
12 .sign(SECRET)
13}
14
15export async function verifyJWT(token: string) {
16 const { payload } = await jwtVerify(token, SECRET)
17 if (!payload.sub) throw new AuthError('Invalid token')
Consider checking token expiry explicitly
18 return payload
19}
Ln 9, Col 22No errors

JSON

tsconfig.jsonjson
1{
2 "compilerOptions": {
3 "target": "ES2022",
4 "lib": ["dom", "dom.iterable", "esnext"],
5 "allowJs": true,
6 "skipLibCheck": true,
7 "strict": true,
8 "noEmit": true,
9 "esModuleInterop": true,
10 "module": "esnext",
11 "moduleResolution": "bundler",
12 "resolveJsonModule": true,
13 "isolatedModules": true,
14 "jsx": "preserve",
15 "incremental": true,
16 "paths": {
17 "@/*": ["./src/*"]
18 }
19 },
20 "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
21 "exclude": ["node_modules"]
22}
Ln 1, Col 1Valid JSON

Props

PropTypeDescription
tabs*SandboxTab[]Open file tabs. Each tab carries an id, label, optional path, dirty flag, and badge.
activeTab*stringThe id of the currently active tab.
onSelectTab*(id: string) => voidCalled when a tab is clicked.
onCloseTab(id: string) => voidWhen provided, shows a close button on each tab.
onNewTab() => voidWhen provided, shows a + button to open a new tab.
lines*EditorLine[]Source lines for the active file. Supports agentEdit, failing, matched highlights, and inline annotations.
languagestringLanguage label shown in the breadcrumb. Defaults to 'typescript'.
pathstringFile path shown in the breadcrumb bar.
cursor{ line: number; col: number }Cursor position shown in the status bar.
status{ ok: boolean; message: string }Diagnostic status shown in the status bar.
classNamestringAdditional class names for the root element.

* required.

Usage

import { CodeEditorPane } from "@/components/sandbox/code-editor-pane";

<CodeEditorPane
  tabs={[{ id: "auth", label: "auth.ts", path: "src/lib/auth.ts", dirty: true }]}
  activeTab="auth"
  onSelectTab={setActiveTab}
  lines={[
    { text: "export async function signToken(userId: string) {" },
    { text: "  // ...", agentEdit: true },
    { text: "}" },
  ]}
  path="src/lib/auth.ts"
  language="typescript"
  cursor={{ line: 2, col: 8 }}
  status={{ ok: true, message: "No errors" }}
/>