From 2b55f897787dfc58423265e8519255c8a1426934 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 30 Jun 2026 20:16:34 +0200 Subject: [PATCH 01/18] bump expo template --- packages/typegpu-cli/src/create.ts | 2 +- .../template-expo-bare/_package.json | 36 +++++++++++-------- .../templates/template-expo-bare/app.json | 28 ++++++++++----- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/packages/typegpu-cli/src/create.ts b/packages/typegpu-cli/src/create.ts index 4418337438..0f554ccd19 100644 --- a/packages/typegpu-cli/src/create.ts +++ b/packages/typegpu-cli/src/create.ts @@ -113,7 +113,7 @@ export async function createProject(cwd: string, options?: CreateProjectOptions) const cdPath = path.relative(cwd, root); const installCmd = resolveCommand(pm, 'install', []); const prebuildCmd = projectTemplate.includes('expo') - ? { command: 'npx', args: ['expo', 'prebuild'] } + ? resolveCommand(pm, 'execute', ['expo', 'prebuild']) : undefined; const runCmd = projectTemplate.includes('expo') ? resolveCommand(pm, 'run', ['ios # or android']) diff --git a/packages/typegpu-cli/templates/template-expo-bare/_package.json b/packages/typegpu-cli/templates/template-expo-bare/_package.json index 51416be643..fa8c48cbcb 100644 --- a/packages/typegpu-cli/templates/template-expo-bare/_package.json +++ b/packages/typegpu-cli/templates/template-expo-bare/_package.json @@ -13,37 +13,45 @@ "types": "tsc --noEmit -p tsconfig.json" }, "dependencies": { - "@typegpu/react": "^0.11.0", - "expo": "~54.0.21", - "react": "19.1.0", - "react-dom": "19.1.0", - "react-native": "0.81.5", - "react-native-safe-area-context": "~5.6.0", + "@typegpu/react": "^0.11.2", + "expo": "~56.0.12", + "expo-build-properties": "~56.0.19", + "expo-splash-screen": "~56.0.10", + "react": "19.2.3", + "react-dom": "19.2.3", + "react-native": "0.85.3", + "react-native-safe-area-context": "~5.7.0", "react-native-web": "^0.21.0", "react-native-webgpu": "^0.5.11", - "typegpu": "^0.11.6", - "unplugin-typegpu": "^0.11.4" + "react-native-worklets": "0.10.0", + "typegpu": "^0.11.9", + "unplugin-typegpu": "^0.11.6" }, "devDependencies": { "@babel/core": "^7.28.5", - "@types/react": "~19.1.10", + "@types/react": "~19.2.17", "@webgpu/types": "^0.1.69", - "babel-preset-expo": "^54.0.0", + "babel-preset-expo": "~56.0.15", "eslint": "^9.38.0", "eslint-plugin-typegpu": "^0.11.1", "oxfmt": "^0.49.0", "oxlint": "^1.64.0", - "typescript": "npm:tsover@5.9.2" + "typescript": "npm:tsover@6.0.2" }, "resolutions": { - "typescript": "npm:tsover@5.9.2" + "typescript": "npm:tsover@6.0.2" }, "overrides": { - "typescript": "npm:tsover@5.9.2" + "typescript": "npm:tsover@6.0.2" }, "pnpm": { "overrides": { - "typescript": "npm:tsover@5.9.2" + "typescript": "npm:tsover@6.0.2" + } + }, + "expo": { + "install": { + "exclude": ["typescript", "react-native-worklets"] } } } diff --git a/packages/typegpu-cli/templates/template-expo-bare/app.json b/packages/typegpu-cli/templates/template-expo-bare/app.json index 0917eb6fe0..34e5826e5c 100644 --- a/packages/typegpu-cli/templates/template-expo-bare/app.json +++ b/packages/typegpu-cli/templates/template-expo-bare/app.json @@ -5,13 +5,6 @@ "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", - "userInterfaceStyle": "automatic", - "newArchEnabled": true, - "splash": { - "image": "./assets/splash-icon.png", - "resizeMode": "contain", - "backgroundColor": "#ffffff" - }, "ios": { "supportsTablet": true, "bundleIdentifier": "com.anonymous.typegpubareexpo" @@ -25,6 +18,25 @@ }, "web": { "favicon": "./assets/favicon.png" - } + }, + "plugins": [ + [ + "expo-splash-screen", + { + "backgroundColor": "#ffffff", + "image": "./assets/splash-icon.png", + "imageWidth": 200, + "resizeMode": "contain" + } + ], + [ + "expo-build-properties", + { + "android": { + "minSdkVersion": 26 + } + } + ] + ] } } From c72f92601bb657a1c8ae3a9cf552841db8951afb Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 30 Jun 2026 20:21:42 +0200 Subject: [PATCH 02/18] better order of pm inference --- packages/typegpu-cli/src/create.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/typegpu-cli/src/create.ts b/packages/typegpu-cli/src/create.ts index 0f554ccd19..572e79d84b 100644 --- a/packages/typegpu-cli/src/create.ts +++ b/packages/typegpu-cli/src/create.ts @@ -86,11 +86,10 @@ export async function createProject(cwd: string, options?: CreateProjectOptions) p.log.success(`Scaffolded project at ${projectName}.`); - const detected = await detect({ cwd: root }); - let pm: Agent | undefined = options?.packageManager ?? detected?.agent; - if (!pm && process.env.npm_config_user_agent) { - pm = pmFromUserAgent(process.env.npm_config_user_agent); - } + const userAgentPm = process.env.npm_config_user_agent + ? pmFromUserAgent(process.env.npm_config_user_agent) + : undefined; + const pm = options?.packageManager ?? userAgentPm ?? (await detect({ cwd: root }))?.agent; if (!pm) { failAndExit('Could not detect package manager. Pass --package-manager .'); } From 41d0b7415551405ee1a46b954f7522380c89c4bb Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 30 Jun 2026 20:25:21 +0200 Subject: [PATCH 03/18] zed and vscode oxc configs --- packages/typegpu-cli/src/create.ts | 8 +++- .../_vscode/extensions.json | 3 ++ .../template-expo-bare/_vscode/settings.json | 15 ++++++- .../template-expo-bare/_zed/settings.json | 43 +++++++++++++++++++ .../_vscode/extensions.json | 3 ++ .../template-vite-bare/_vscode/settings.json | 15 ++++++- .../template-vite-bare/_zed/settings.json | 43 +++++++++++++++++++ .../_vscode/extensions.json | 3 ++ .../_vscode/settings.json | 15 ++++++- .../template-vite-complex/_zed/settings.json | 43 +++++++++++++++++++ .../_vscode/extensions.json | 3 ++ .../template-vite-react/_vscode/settings.json | 15 ++++++- .../template-vite-react/_zed/settings.json | 43 +++++++++++++++++++ 13 files changed, 246 insertions(+), 6 deletions(-) create mode 100644 packages/typegpu-cli/templates/template-expo-bare/_vscode/extensions.json create mode 100644 packages/typegpu-cli/templates/template-vite-bare/_vscode/extensions.json create mode 100644 packages/typegpu-cli/templates/template-vite-complex/_vscode/extensions.json create mode 100644 packages/typegpu-cli/templates/template-vite-react/_vscode/extensions.json diff --git a/packages/typegpu-cli/src/create.ts b/packages/typegpu-cli/src/create.ts index 572e79d84b..d1386d4e98 100644 --- a/packages/typegpu-cli/src/create.ts +++ b/packages/typegpu-cli/src/create.ts @@ -139,9 +139,13 @@ export async function createProject(cwd: string, options?: CreateProjectOptions) msg += steps.join('\n'); msg += `\n\n`; msg += `\ + Note: To enable Oxlint highlighting, install the OXC extension for your editor, + or refer to the documentation: + https://oxc.rs/docs/guide/usage/linter/editors.html + Note: If you are using VS Code or Cursor, you may need to run - “TypeScript: Select TypeScript Version” and choose - “Use Workspace Version” to enable tsover.`; + "TypeScript: Select TypeScript Version" and choose + "Use Workspace Version" to enable tsover.`; } p.outro(msg); diff --git a/packages/typegpu-cli/templates/template-expo-bare/_vscode/extensions.json b/packages/typegpu-cli/templates/template-expo-bare/_vscode/extensions.json new file mode 100644 index 0000000000..99e2f7ddf7 --- /dev/null +++ b/packages/typegpu-cli/templates/template-expo-bare/_vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/packages/typegpu-cli/templates/template-expo-bare/_vscode/settings.json b/packages/typegpu-cli/templates/template-expo-bare/_vscode/settings.json index 0dfacd95d2..1056eac024 100644 --- a/packages/typegpu-cli/templates/template-expo-bare/_vscode/settings.json +++ b/packages/typegpu-cli/templates/template-expo-bare/_vscode/settings.json @@ -1,5 +1,18 @@ { "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": ".oxfmtrc.json", + "oxc.lint.run": "onType", + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + + "editor.codeActionsOnSave": { + "source.organizeImports": "never", + "source.format.oxc": "always", + "source.fixAll.oxc": "always" + } } diff --git a/packages/typegpu-cli/templates/template-expo-bare/_zed/settings.json b/packages/typegpu-cli/templates/template-expo-bare/_zed/settings.json index 9d7badfbd2..ee27702340 100644 --- a/packages/typegpu-cli/templates/template-expo-bare/_zed/settings.json +++ b/packages/typegpu-cli/templates/template-expo-bare/_zed/settings.json @@ -10,6 +10,49 @@ "tsdk": "node_modules/typescript/lib" } } + }, + "oxlint": { + "initialization_options": { + "settings": { + "configPath": "./oxlint.config.ts", + "run": "onType", + "fixKind": "safe_fix" + } + } + }, + "oxfmt": { + "initialization_options": { + "settings": { + "fmt.configPath": ".oxfmtrc.json" + } + } + } + }, + "languages": { + "TypeScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "TSX": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JavaScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSON": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSONC": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] } } } diff --git a/packages/typegpu-cli/templates/template-vite-bare/_vscode/extensions.json b/packages/typegpu-cli/templates/template-vite-bare/_vscode/extensions.json new file mode 100644 index 0000000000..99e2f7ddf7 --- /dev/null +++ b/packages/typegpu-cli/templates/template-vite-bare/_vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/packages/typegpu-cli/templates/template-vite-bare/_vscode/settings.json b/packages/typegpu-cli/templates/template-vite-bare/_vscode/settings.json index 0dfacd95d2..1056eac024 100644 --- a/packages/typegpu-cli/templates/template-vite-bare/_vscode/settings.json +++ b/packages/typegpu-cli/templates/template-vite-bare/_vscode/settings.json @@ -1,5 +1,18 @@ { "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": ".oxfmtrc.json", + "oxc.lint.run": "onType", + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + + "editor.codeActionsOnSave": { + "source.organizeImports": "never", + "source.format.oxc": "always", + "source.fixAll.oxc": "always" + } } diff --git a/packages/typegpu-cli/templates/template-vite-bare/_zed/settings.json b/packages/typegpu-cli/templates/template-vite-bare/_zed/settings.json index 9d7badfbd2..ee27702340 100644 --- a/packages/typegpu-cli/templates/template-vite-bare/_zed/settings.json +++ b/packages/typegpu-cli/templates/template-vite-bare/_zed/settings.json @@ -10,6 +10,49 @@ "tsdk": "node_modules/typescript/lib" } } + }, + "oxlint": { + "initialization_options": { + "settings": { + "configPath": "./oxlint.config.ts", + "run": "onType", + "fixKind": "safe_fix" + } + } + }, + "oxfmt": { + "initialization_options": { + "settings": { + "fmt.configPath": ".oxfmtrc.json" + } + } + } + }, + "languages": { + "TypeScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "TSX": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JavaScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSON": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSONC": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] } } } diff --git a/packages/typegpu-cli/templates/template-vite-complex/_vscode/extensions.json b/packages/typegpu-cli/templates/template-vite-complex/_vscode/extensions.json new file mode 100644 index 0000000000..99e2f7ddf7 --- /dev/null +++ b/packages/typegpu-cli/templates/template-vite-complex/_vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/packages/typegpu-cli/templates/template-vite-complex/_vscode/settings.json b/packages/typegpu-cli/templates/template-vite-complex/_vscode/settings.json index 0dfacd95d2..1056eac024 100644 --- a/packages/typegpu-cli/templates/template-vite-complex/_vscode/settings.json +++ b/packages/typegpu-cli/templates/template-vite-complex/_vscode/settings.json @@ -1,5 +1,18 @@ { "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": ".oxfmtrc.json", + "oxc.lint.run": "onType", + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + + "editor.codeActionsOnSave": { + "source.organizeImports": "never", + "source.format.oxc": "always", + "source.fixAll.oxc": "always" + } } diff --git a/packages/typegpu-cli/templates/template-vite-complex/_zed/settings.json b/packages/typegpu-cli/templates/template-vite-complex/_zed/settings.json index 9d7badfbd2..ee27702340 100644 --- a/packages/typegpu-cli/templates/template-vite-complex/_zed/settings.json +++ b/packages/typegpu-cli/templates/template-vite-complex/_zed/settings.json @@ -10,6 +10,49 @@ "tsdk": "node_modules/typescript/lib" } } + }, + "oxlint": { + "initialization_options": { + "settings": { + "configPath": "./oxlint.config.ts", + "run": "onType", + "fixKind": "safe_fix" + } + } + }, + "oxfmt": { + "initialization_options": { + "settings": { + "fmt.configPath": ".oxfmtrc.json" + } + } + } + }, + "languages": { + "TypeScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "TSX": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JavaScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSON": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSONC": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] } } } diff --git a/packages/typegpu-cli/templates/template-vite-react/_vscode/extensions.json b/packages/typegpu-cli/templates/template-vite-react/_vscode/extensions.json new file mode 100644 index 0000000000..99e2f7ddf7 --- /dev/null +++ b/packages/typegpu-cli/templates/template-vite-react/_vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/packages/typegpu-cli/templates/template-vite-react/_vscode/settings.json b/packages/typegpu-cli/templates/template-vite-react/_vscode/settings.json index 0dfacd95d2..1056eac024 100644 --- a/packages/typegpu-cli/templates/template-vite-react/_vscode/settings.json +++ b/packages/typegpu-cli/templates/template-vite-react/_vscode/settings.json @@ -1,5 +1,18 @@ { "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": ".oxfmtrc.json", + "oxc.lint.run": "onType", + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + + "editor.codeActionsOnSave": { + "source.organizeImports": "never", + "source.format.oxc": "always", + "source.fixAll.oxc": "always" + } } diff --git a/packages/typegpu-cli/templates/template-vite-react/_zed/settings.json b/packages/typegpu-cli/templates/template-vite-react/_zed/settings.json index 9d7badfbd2..ee27702340 100644 --- a/packages/typegpu-cli/templates/template-vite-react/_zed/settings.json +++ b/packages/typegpu-cli/templates/template-vite-react/_zed/settings.json @@ -10,6 +10,49 @@ "tsdk": "node_modules/typescript/lib" } } + }, + "oxlint": { + "initialization_options": { + "settings": { + "configPath": "./oxlint.config.ts", + "run": "onType", + "fixKind": "safe_fix" + } + } + }, + "oxfmt": { + "initialization_options": { + "settings": { + "fmt.configPath": ".oxfmtrc.json" + } + } + } + }, + "languages": { + "TypeScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "TSX": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JavaScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSON": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSONC": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] } } } From c40c4a1f75dd0199425d9ce5c2c651c23f724881 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 30 Jun 2026 20:39:15 +0200 Subject: [PATCH 04/18] unused import --- packages/typegpu-cli/src/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typegpu-cli/src/create.ts b/packages/typegpu-cli/src/create.ts index d1386d4e98..fdcc02124e 100644 --- a/packages/typegpu-cli/src/create.ts +++ b/packages/typegpu-cli/src/create.ts @@ -5,7 +5,7 @@ import { pmFromUserAgent, pmInstall } from './utils/pm.ts'; import { cancelExit, confirmStep, failAndExit, rgbText } from './utils/prompts.ts'; import { scaffoldProject, prepareDirectory } from './utils/files.ts'; import { getProjectName, isValidPackageName, getPackageName } from './utils/inputs.ts'; -import { detect, resolveCommand, type Agent } from 'package-manager-detector'; +import { detect, resolveCommand } from 'package-manager-detector'; import { addAgentSkills, askForAgentSkills } from './steps/skills.ts'; import { DEFAULT_PROJECT_TEMPLATE, From a9791fc445e2922ac4828db3b81734b725b8ad51 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 30 Jun 2026 20:38:46 +0200 Subject: [PATCH 05/18] ascii logo --- packages/typegpu-cli/src/index.ts | 3 +++ packages/typegpu-cli/src/utils/logo.ts | 1 + 2 files changed, 4 insertions(+) create mode 100644 packages/typegpu-cli/src/utils/logo.ts diff --git a/packages/typegpu-cli/src/index.ts b/packages/typegpu-cli/src/index.ts index b254217332..d55ff6f094 100644 --- a/packages/typegpu-cli/src/index.ts +++ b/packages/typegpu-cli/src/index.ts @@ -14,6 +14,7 @@ import { } from './options.ts'; import { failAndExit } from './utils/prompts.ts'; import { typegpuPkgs } from './utils/pkg.ts'; +import { typegpuAsciiLogo } from './utils/logo.ts'; function formatHelpEntries(entries: readonly { value: string; label?: string; hint?: string }[]) { const maxLength = Math.max(...entries.map((entry) => entry.value.length)); @@ -74,6 +75,8 @@ const commonOptions = { ...(packageManager ? { packageManager } : {}), }; +console.log(typegpuAsciiLogo); + if (argv.enhance) { const targetDir = positionals[0] ? path.resolve(cwd, positionals[0]) : cwd; if (!fs.existsSync(targetDir) || !fs.statSync(targetDir).isDirectory()) { diff --git a/packages/typegpu-cli/src/utils/logo.ts b/packages/typegpu-cli/src/utils/logo.ts new file mode 100644 index 0000000000..a92496485e --- /dev/null +++ b/packages/typegpu-cli/src/utils/logo.ts @@ -0,0 +1 @@ +export const typegpuAsciiLogo = ` \u001b[38;2;209;137;255ma\u001b[0m \n \u001b[38;2;211;140;254m)\u001b[0m\u001b[38;2;209;138;255mL\u001b[0m \n \u001b[38;2;211;140;255m\\\u001b[0m\u001b[38;2;216;144;255m[\u001b[0m\u001b[38;2;211;140;255m1\u001b[0m \n \u001b[38;2;210;138;255mY\u001b[0m\u001b[38;2;211;140;255m{\u001b[0m\u001b[38;2;226;150;255m?\u001b[0m\u001b[38;2;210;139;255mc\u001b[0m \n \u001b[38;2;209;136;255m#\u001b[0m\u001b[38;2;210;139;255mJ\u001b[0m\u001b[38;2;210;139;255m(\u001b[0m\u001b[38;2;207;139;255ma\u001b[0m \n \u001b[38;2;207;137;254mp\u001b[0m\u001b[38;2;207;137;254mp\u001b[0m\u001b[38;2;210;140;255mZ\u001b[0m\u001b[38;2;212;140;255mZ\u001b[0m\u001b[38;2;213;142;255mp\u001b[0m\u001b[38;2;215;143;255mk\u001b[0m\u001b[38;2;211;139;255ma\u001b[0m\u001b[38;2;209;136;254mo\u001b[0m\u001b[38;2;201;132;255m#\u001b[0m\u001b[38;2;191;133;248mM\u001b[0m \n \u001b[38;2;209;138;255mp\u001b[0m\u001b[38;2;209;138;255mv\u001b[0m\u001b[38;2;206;137;253m{\u001b[0m\u001b[38;2;217;147;255m]\u001b[0m\u001b[38;2;203;138;255m{\u001b[0m\u001b[38;2;194;134;252m)\u001b[0m\u001b[38;2;188;132;251m(\u001b[0m\u001b[38;2;184;130;251m|\u001b[0m\u001b[38;2;180;128;250m\\\u001b[0m\u001b[38;2;174;126;250m/\u001b[0m\u001b[38;2;170;124;248mt\u001b[0m\u001b[38;2;165;122;248mr\u001b[0m\u001b[38;2;161;120;246mx\u001b[0m\u001b[38;2;155;118;246mc\u001b[0m\u001b[38;2;148;114;244mw\u001b[0m \n \u001b[38;2;162;125;255mk\u001b[0m\u001b[38;2;160;126;255mX\u001b[0m\u001b[38;2;157;125;255mq\u001b[0m \u001b[38;2;185;129;251mQ\u001b[0m\u001b[38;2;179;127;249mt\u001b[0m\u001b[38;2;185;134;255m)\u001b[0m\u001b[38;2;173;126;251m|\u001b[0m\u001b[38;2;167;123;249m\\\u001b[0m\u001b[38;2;164;123;251m\\\u001b[0m\u001b[38;2;160;121;251m/\u001b[0m\u001b[38;2;157;120;252mt\u001b[0m\u001b[38;2;153;119;252mt\u001b[0m\u001b[38;2;149;117;253mf\u001b[0m\u001b[38;2;147;117;255mf\u001b[0m\u001b[38;2;144;117;255mf\u001b[0m\u001b[38;2;128;106;241md\u001b[0m \n \u001b[38;2;156;125;254mJ\u001b[0m\u001b[38;2;162;129;255m\\\u001b[0m\u001b[38;2;164;132;255m|\u001b[0m\u001b[38;2;162;132;255m|\u001b[0m\u001b[38;2;151;123;255mr\u001b[0m\u001b[38;2;148;122;255mQ\u001b[0m\u001b[38;2;149;123;255m*\u001b[0m \u001b[38;2;160;119;246m0\u001b[0m\u001b[38;2;153;116;246mf\u001b[0m\u001b[38;2;154;120;254mt\u001b[0m\u001b[38;2;145;114;245mj\u001b[0m\u001b[38;2;140;112;244mr\u001b[0m\u001b[38;2;136;111;245mr\u001b[0m\u001b[38;2;132;108;243mx\u001b[0m\u001b[38;2;128;107;243mn\u001b[0m\u001b[38;2;122;105;242mn\u001b[0m\u001b[38;2;118;104;242mu\u001b[0m\u001b[38;2;115;102;242mu\u001b[0m\u001b[38;2;102;93;238mM\u001b[0m \n \u001b[38;2;155;123;255md\u001b[0m\u001b[38;2;154;124;255mr\u001b[0m\u001b[38;2;162;131;255m|\u001b[0m\u001b[38;2;151;124;255m/\u001b[0m\u001b[38;2;149;124;254mt\u001b[0m\u001b[38;2;148;123;254mt\u001b[0m\u001b[38;2;149;125;255m/\u001b[0m\u001b[38;2;154;130;255m\\\u001b[0m\u001b[38;2;142;121;255mf\u001b[0m\u001b[38;2;140;120;255mY\u001b[0m\u001b[38;2;137;117;255mk\u001b[0m \u001b[38;2;137;109;242m#\u001b[0m\u001b[38;2;132;108;244mX\u001b[0m\u001b[38;2;133;112;254mr\u001b[0m\u001b[38;2;124;105;243mn\u001b[0m\u001b[38;2;120;104;243mn\u001b[0m\u001b[38;2;116;102;242mu\u001b[0m\u001b[38;2;111;101;241mv\u001b[0m\u001b[38;2;107;99;242mv\u001b[0m\u001b[38;2;102;97;240mc\u001b[0m\u001b[38;2;97;95;240mz\u001b[0m\u001b[38;2;92;92;238mJ\u001b[0m \n \u001b[38;2;151;121;255m0\u001b[0m\u001b[38;2;156;128;255m\\\u001b[0m\u001b[38;2;152;126;255m/\u001b[0m\u001b[38;2;147;123;254mt\u001b[0m\u001b[38;2;146;122;255mt\u001b[0m\u001b[38;2;145;123;255mt\u001b[0m\u001b[38;2;142;121;255mf\u001b[0m\u001b[38;2;140;121;255mf\u001b[0m\u001b[38;2;139;120;255mj\u001b[0m\u001b[38;2;138;121;255mf\u001b[0m\u001b[38;2;142;126;255mt\u001b[0m\u001b[38;2;138;123;255mf\u001b[0m\u001b[38;2;131;118;255mz\u001b[0m\u001b[38;2;127;115;255mh\u001b[0m \u001b[38;2;111;99;240m0\u001b[0m\u001b[38;2;110;102;250mu\u001b[0m\u001b[38;2;103;97;240mc\u001b[0m\u001b[38;2;98;95;241mz\u001b[0m\u001b[38;2;94;93;240mz\u001b[0m\u001b[38;2;89;92;239mX\u001b[0m\u001b[38;2;85;90;239mY\u001b[0m\u001b[38;2;82;89;236mY\u001b[0m\u001b[38;2;82;89;240mY\u001b[0m\u001b[38;2;76;84;232mZ\u001b[0m \n \u001b[38;2;144;120;255mb\u001b[0m\u001b[38;2;147;124;255mt\u001b[0m\u001b[38;2;143;122;254mf\u001b[0m\u001b[38;2;142;122;255mt\u001b[0m\u001b[38;2;141;121;255mf\u001b[0m\u001b[38;2;139;121;255mf\u001b[0m\u001b[38;2;137;120;255mf\u001b[0m\u001b[38;2;135;120;255mf\u001b[0m\u001b[38;2;133;120;255mf\u001b[0m\u001b[38;2;131;119;255mj\u001b[0m\u001b[38;2;129;118;254mr\u001b[0m\u001b[38;2;129;117;255mr\u001b[0m\u001b[38;2;131;122;255mf\u001b[0m\u001b[38;2;128;120;255mj\u001b[0m\u001b[38;2;122;114;255mQ\u001b[0m \u001b[38;2;89;91;238mm\u001b[0m\u001b[38;2;88;92;244mX\u001b[0m\u001b[38;2;83;89;237mY\u001b[0m\u001b[38;2;80;88;237mU\u001b[0m\u001b[38;2;79;86;235mU\u001b[0m\u001b[38;2;77;85;234mU\u001b[0m\u001b[38;2;76;84;232mJ\u001b[0m\u001b[38;2;74;82;229mJ\u001b[0m\u001b[38;2;76;85;235mU\u001b[0m\u001b[38;2;69;78;224mk\u001b[0m \n \u001b[38;2;138;118;255mO\u001b[0m\u001b[38;2;142;124;255mt\u001b[0m\u001b[38;2;136;120;255mf\u001b[0m\u001b[38;2;135;120;255mf\u001b[0m\u001b[38;2;133;119;255mj\u001b[0m\u001b[38;2;132;119;255mj\u001b[0m\u001b[38;2;130;118;255mj\u001b[0m\u001b[38;2;128;118;255mj\u001b[0m\u001b[38;2;126;118;255mj\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;122;116;255mr\u001b[0m\u001b[38;2;120;115;255mx\u001b[0m\u001b[38;2;119;115;255mx\u001b[0m\u001b[38;2;124;121;255mj\u001b[0m\u001b[38;2;115;113;255mc\u001b[0m\u001b[38;2;105;109;250mM\u001b[0m \u001b[38;2;76;85;233m0\u001b[0m\u001b[38;2;76;85;232mU\u001b[0m\u001b[38;2;75;83;230mJ\u001b[0m\u001b[38;2;74;82;228mJ\u001b[0m\u001b[38;2;72;81;227mC\u001b[0m\u001b[38;2;71;80;225mC\u001b[0m\u001b[38;2;69;79;224mC\u001b[0m\u001b[38;2;67;77;222mL\u001b[0m\u001b[38;2;69;79;230mC\u001b[0m\u001b[38;2;58;70;215m&\u001b[0m \n \u001b[38;2;132;118;255mU\u001b[0m\u001b[38;2;134;121;255mf\u001b[0m\u001b[38;2;129;118;255mj\u001b[0m\u001b[38;2;128;118;255mj\u001b[0m\u001b[38;2;126;117;255mj\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;123;116;255mr\u001b[0m\u001b[38;2;120;116;255mr\u001b[0m\u001b[38;2;119;115;255mr\u001b[0m\u001b[38;2;118;114;255mx\u001b[0m\u001b[38;2;116;115;255mx\u001b[0m\u001b[38;2;112;113;254mx\u001b[0m\u001b[38;2;108;113;252mn\u001b[0m\u001b[38;2;106;114;255mn\u001b[0m\u001b[38;2;97;109;250mc\u001b[0m\u001b[38;2;91;104;245m*\u001b[0m \u001b[38;2;65;80;225m&\u001b[0m\u001b[38;2;71;80;226mC\u001b[0m\u001b[38;2;70;79;224mC\u001b[0m\u001b[38;2;68;78;223mL\u001b[0m\u001b[38;2;67;77;222mL\u001b[0m\u001b[38;2;65;75;219mL\u001b[0m\u001b[38;2;63;73;218mQ\u001b[0m\u001b[38;2;65;76;226mL\u001b[0m\u001b[38;2;60;70;216mm\u001b[0m\u001b[38;2;56;68;209m%\u001b[0m \n \u001b[38;2;125;116;255mv\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;122;116;255mr\u001b[0m\u001b[38;2;121;116;255mr\u001b[0m\u001b[38;2;119;115;255mr\u001b[0m\u001b[38;2;117;115;255mx\u001b[0m\u001b[38;2;115;114;255mx\u001b[0m\u001b[38;2;112;114;254mx\u001b[0m\u001b[38;2;108;113;253mn\u001b[0m\u001b[38;2;103;112;252mn\u001b[0m\u001b[38;2;98;111;251mu\u001b[0m\u001b[38;2;93;109;249mv\u001b[0m\u001b[38;2;88;108;247mc\u001b[0m\u001b[38;2;84;109;249mv\u001b[0m\u001b[38;2;78;105;243mz\u001b[0m\u001b[38;2;67;102;237m#\u001b[0m \u001b[38;2;64;74;219mq\u001b[0m\u001b[38;2;64;74;218mQ\u001b[0m\u001b[38;2;63;73;218mQ\u001b[0m\u001b[38;2;61;72;215mQ\u001b[0m\u001b[38;2;59;71;214m0\u001b[0m\u001b[38;2;61;73;222mQ\u001b[0m\u001b[38;2;56;67;209md\u001b[0m \n \u001b[38;2;115;110;255mM\u001b[0m\u001b[38;2;117;114;255mx\u001b[0m\u001b[38;2;117;115;255mx\u001b[0m\u001b[38;2;114;114;255mn\u001b[0m\u001b[38;2;111;113;255mn\u001b[0m\u001b[38;2;107;112;252mn\u001b[0m\u001b[38;2;103;112;252mu\u001b[0m\u001b[38;2;97;109;249mv\u001b[0m\u001b[38;2;92;108;248mv\u001b[0m\u001b[38;2;87;108;247mc\u001b[0m\u001b[38;2;83;107;245mc\u001b[0m\u001b[38;2;78;106;244mz\u001b[0m\u001b[38;2;73;105;243mz\u001b[0m\u001b[38;2;68;104;241mX\u001b[0m\u001b[38;2;64;103;241mX\u001b[0m\u001b[38;2;59;101;239mU\u001b[0m\u001b[38;2;50;95;232m&\u001b[0m\u001b[38;2;57;63;210mW\u001b[0m\u001b[38;2;59;70;214m0\u001b[0m\u001b[38;2;57;69;211m0\u001b[0m\u001b[38;2;56;69;212m0\u001b[0m\u001b[38;2;55;68;212mO\u001b[0m\u001b[38;2;52;65;206ma\u001b[0m \n \u001b[38;2;110;110;255mk\u001b[0m\u001b[38;2;106;112;254mn\u001b[0m\u001b[38;2;107;119;255mx\u001b[0m\u001b[38;2;101;117;255mn\u001b[0m\u001b[38;2;95;115;255mn\u001b[0m\u001b[38;2;90;113;255mu\u001b[0m\u001b[38;2;84;111;255mv\u001b[0m\u001b[38;2;79;109;252mc\u001b[0m\u001b[38;2;74;107;248mz\u001b[0m\u001b[38;2;69;105;245mz\u001b[0m\u001b[38;2;64;104;243mX\u001b[0m\u001b[38;2;59;103;241mY\u001b[0m\u001b[38;2;54;101;238mU\u001b[0m\u001b[38;2;49;99;236mU\u001b[0m\u001b[38;2;44;99;235mJ\u001b[0m\u001b[38;2;39;97;232mQ\u001b[0m \u001b[38;2;53;64;205mZ\u001b[0m\u001b[38;2;53;67;212mO\u001b[0m\u001b[38;2;49;62;202mm\u001b[0m\u001b[38;2;48;63;200mM\u001b[0m \n \u001b[38;2;91;106;251m#\u001b[0m\u001b[38;2;86;106;245mq\u001b[0m\u001b[38;2;82;107;245mZ\u001b[0m\u001b[38;2;77;106;244mO\u001b[0m\u001b[38;2;73;104;243m0\u001b[0m\u001b[38;2;66;103;241mQ\u001b[0m\u001b[38;2;62;102;240mC\u001b[0m\u001b[38;2;57;100;237mC\u001b[0m\u001b[38;2;53;100;237mJ\u001b[0m\u001b[38;2;47;99;236mJ\u001b[0m\u001b[38;2;42;98;234mC\u001b[0m\u001b[38;2;38;97;234mC\u001b[0m\u001b[38;2;34;98;236mC\u001b[0m\u001b[38;2;29;98;238mC\u001b[0m\u001b[38;2;25;101;246mC\u001b[0m\u001b[38;2;15;91;227mm\u001b[0m\u001b[38;2;43;61;201mb\u001b[0m\u001b[38;2;45;59;199md\u001b[0m\u001b[38;2;43;54;195m%\u001b[0m \n \u001b[38;2;28;92;231m8\u001b[0m\u001b[38;2;25;95;229m&\u001b[0m\u001b[38;2;20;93;227mW\u001b[0m\u001b[38;2;17;93;226m#\u001b[0m\u001b[38;2;9;91;227m*\u001b[0m\u001b[38;2;7;90;225ma\u001b[0m\u001b[38;2;24;67;205mW\u001b[0m \n `; From cbc2460bd51af11ce60d7bf723e6c487949324b0 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 30 Jun 2026 20:38:56 +0200 Subject: [PATCH 06/18] matching gradient --- packages/typegpu-cli/src/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typegpu-cli/src/create.ts b/packages/typegpu-cli/src/create.ts index fdcc02124e..f30d8fd29c 100644 --- a/packages/typegpu-cli/src/create.ts +++ b/packages/typegpu-cli/src/create.ts @@ -16,7 +16,7 @@ import { } from './options.ts'; const GRADIENT_START = [0.831, 0.553, 1.0] as const; -const GRADIENT_END = [0.32, 0.4, 0.95] as const; +const GRADIENT_END = [0.0, 0.349, 0.874] as const; const coloredLabelsTemplates = PROJECT_TEMPLATES.map((template, i) => { const t = i / (PROJECT_TEMPLATES.length - 1); From f5304efaa4590d004c68d6d1728fec8800df4bec Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Wed, 1 Jul 2026 16:53:19 +0200 Subject: [PATCH 07/18] smaller logo + no color mode --- packages/typegpu-cli/src/index.ts | 8 ++++++-- packages/typegpu-cli/src/utils/logo.ts | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/typegpu-cli/src/index.ts b/packages/typegpu-cli/src/index.ts index d55ff6f094..7e88cdf5fd 100644 --- a/packages/typegpu-cli/src/index.ts +++ b/packages/typegpu-cli/src/index.ts @@ -14,7 +14,7 @@ import { } from './options.ts'; import { failAndExit } from './utils/prompts.ts'; import { typegpuPkgs } from './utils/pkg.ts'; -import { typegpuAsciiLogo } from './utils/logo.ts'; +import { typegpuAsciiLogoColor, typegpuAsciiLogoNoColor } from './utils/logo.ts'; function formatHelpEntries(entries: readonly { value: string; label?: string; hint?: string }[]) { const maxLength = Math.max(...entries.map((entry) => entry.value.length)); @@ -75,7 +75,11 @@ const commonOptions = { ...(packageManager ? { packageManager } : {}), }; -console.log(typegpuAsciiLogo); +if (!process.env.NO_COLOR) { + console.log(typegpuAsciiLogoColor); +} else { + console.log(typegpuAsciiLogoNoColor); +} if (argv.enhance) { const targetDir = positionals[0] ? path.resolve(cwd, positionals[0]) : cwd; diff --git a/packages/typegpu-cli/src/utils/logo.ts b/packages/typegpu-cli/src/utils/logo.ts index a92496485e..b43e64e8ba 100644 --- a/packages/typegpu-cli/src/utils/logo.ts +++ b/packages/typegpu-cli/src/utils/logo.ts @@ -1 +1,3 @@ -export const typegpuAsciiLogo = ` \u001b[38;2;209;137;255ma\u001b[0m \n \u001b[38;2;211;140;254m)\u001b[0m\u001b[38;2;209;138;255mL\u001b[0m \n \u001b[38;2;211;140;255m\\\u001b[0m\u001b[38;2;216;144;255m[\u001b[0m\u001b[38;2;211;140;255m1\u001b[0m \n \u001b[38;2;210;138;255mY\u001b[0m\u001b[38;2;211;140;255m{\u001b[0m\u001b[38;2;226;150;255m?\u001b[0m\u001b[38;2;210;139;255mc\u001b[0m \n \u001b[38;2;209;136;255m#\u001b[0m\u001b[38;2;210;139;255mJ\u001b[0m\u001b[38;2;210;139;255m(\u001b[0m\u001b[38;2;207;139;255ma\u001b[0m \n \u001b[38;2;207;137;254mp\u001b[0m\u001b[38;2;207;137;254mp\u001b[0m\u001b[38;2;210;140;255mZ\u001b[0m\u001b[38;2;212;140;255mZ\u001b[0m\u001b[38;2;213;142;255mp\u001b[0m\u001b[38;2;215;143;255mk\u001b[0m\u001b[38;2;211;139;255ma\u001b[0m\u001b[38;2;209;136;254mo\u001b[0m\u001b[38;2;201;132;255m#\u001b[0m\u001b[38;2;191;133;248mM\u001b[0m \n \u001b[38;2;209;138;255mp\u001b[0m\u001b[38;2;209;138;255mv\u001b[0m\u001b[38;2;206;137;253m{\u001b[0m\u001b[38;2;217;147;255m]\u001b[0m\u001b[38;2;203;138;255m{\u001b[0m\u001b[38;2;194;134;252m)\u001b[0m\u001b[38;2;188;132;251m(\u001b[0m\u001b[38;2;184;130;251m|\u001b[0m\u001b[38;2;180;128;250m\\\u001b[0m\u001b[38;2;174;126;250m/\u001b[0m\u001b[38;2;170;124;248mt\u001b[0m\u001b[38;2;165;122;248mr\u001b[0m\u001b[38;2;161;120;246mx\u001b[0m\u001b[38;2;155;118;246mc\u001b[0m\u001b[38;2;148;114;244mw\u001b[0m \n \u001b[38;2;162;125;255mk\u001b[0m\u001b[38;2;160;126;255mX\u001b[0m\u001b[38;2;157;125;255mq\u001b[0m \u001b[38;2;185;129;251mQ\u001b[0m\u001b[38;2;179;127;249mt\u001b[0m\u001b[38;2;185;134;255m)\u001b[0m\u001b[38;2;173;126;251m|\u001b[0m\u001b[38;2;167;123;249m\\\u001b[0m\u001b[38;2;164;123;251m\\\u001b[0m\u001b[38;2;160;121;251m/\u001b[0m\u001b[38;2;157;120;252mt\u001b[0m\u001b[38;2;153;119;252mt\u001b[0m\u001b[38;2;149;117;253mf\u001b[0m\u001b[38;2;147;117;255mf\u001b[0m\u001b[38;2;144;117;255mf\u001b[0m\u001b[38;2;128;106;241md\u001b[0m \n \u001b[38;2;156;125;254mJ\u001b[0m\u001b[38;2;162;129;255m\\\u001b[0m\u001b[38;2;164;132;255m|\u001b[0m\u001b[38;2;162;132;255m|\u001b[0m\u001b[38;2;151;123;255mr\u001b[0m\u001b[38;2;148;122;255mQ\u001b[0m\u001b[38;2;149;123;255m*\u001b[0m \u001b[38;2;160;119;246m0\u001b[0m\u001b[38;2;153;116;246mf\u001b[0m\u001b[38;2;154;120;254mt\u001b[0m\u001b[38;2;145;114;245mj\u001b[0m\u001b[38;2;140;112;244mr\u001b[0m\u001b[38;2;136;111;245mr\u001b[0m\u001b[38;2;132;108;243mx\u001b[0m\u001b[38;2;128;107;243mn\u001b[0m\u001b[38;2;122;105;242mn\u001b[0m\u001b[38;2;118;104;242mu\u001b[0m\u001b[38;2;115;102;242mu\u001b[0m\u001b[38;2;102;93;238mM\u001b[0m \n \u001b[38;2;155;123;255md\u001b[0m\u001b[38;2;154;124;255mr\u001b[0m\u001b[38;2;162;131;255m|\u001b[0m\u001b[38;2;151;124;255m/\u001b[0m\u001b[38;2;149;124;254mt\u001b[0m\u001b[38;2;148;123;254mt\u001b[0m\u001b[38;2;149;125;255m/\u001b[0m\u001b[38;2;154;130;255m\\\u001b[0m\u001b[38;2;142;121;255mf\u001b[0m\u001b[38;2;140;120;255mY\u001b[0m\u001b[38;2;137;117;255mk\u001b[0m \u001b[38;2;137;109;242m#\u001b[0m\u001b[38;2;132;108;244mX\u001b[0m\u001b[38;2;133;112;254mr\u001b[0m\u001b[38;2;124;105;243mn\u001b[0m\u001b[38;2;120;104;243mn\u001b[0m\u001b[38;2;116;102;242mu\u001b[0m\u001b[38;2;111;101;241mv\u001b[0m\u001b[38;2;107;99;242mv\u001b[0m\u001b[38;2;102;97;240mc\u001b[0m\u001b[38;2;97;95;240mz\u001b[0m\u001b[38;2;92;92;238mJ\u001b[0m \n \u001b[38;2;151;121;255m0\u001b[0m\u001b[38;2;156;128;255m\\\u001b[0m\u001b[38;2;152;126;255m/\u001b[0m\u001b[38;2;147;123;254mt\u001b[0m\u001b[38;2;146;122;255mt\u001b[0m\u001b[38;2;145;123;255mt\u001b[0m\u001b[38;2;142;121;255mf\u001b[0m\u001b[38;2;140;121;255mf\u001b[0m\u001b[38;2;139;120;255mj\u001b[0m\u001b[38;2;138;121;255mf\u001b[0m\u001b[38;2;142;126;255mt\u001b[0m\u001b[38;2;138;123;255mf\u001b[0m\u001b[38;2;131;118;255mz\u001b[0m\u001b[38;2;127;115;255mh\u001b[0m \u001b[38;2;111;99;240m0\u001b[0m\u001b[38;2;110;102;250mu\u001b[0m\u001b[38;2;103;97;240mc\u001b[0m\u001b[38;2;98;95;241mz\u001b[0m\u001b[38;2;94;93;240mz\u001b[0m\u001b[38;2;89;92;239mX\u001b[0m\u001b[38;2;85;90;239mY\u001b[0m\u001b[38;2;82;89;236mY\u001b[0m\u001b[38;2;82;89;240mY\u001b[0m\u001b[38;2;76;84;232mZ\u001b[0m \n \u001b[38;2;144;120;255mb\u001b[0m\u001b[38;2;147;124;255mt\u001b[0m\u001b[38;2;143;122;254mf\u001b[0m\u001b[38;2;142;122;255mt\u001b[0m\u001b[38;2;141;121;255mf\u001b[0m\u001b[38;2;139;121;255mf\u001b[0m\u001b[38;2;137;120;255mf\u001b[0m\u001b[38;2;135;120;255mf\u001b[0m\u001b[38;2;133;120;255mf\u001b[0m\u001b[38;2;131;119;255mj\u001b[0m\u001b[38;2;129;118;254mr\u001b[0m\u001b[38;2;129;117;255mr\u001b[0m\u001b[38;2;131;122;255mf\u001b[0m\u001b[38;2;128;120;255mj\u001b[0m\u001b[38;2;122;114;255mQ\u001b[0m \u001b[38;2;89;91;238mm\u001b[0m\u001b[38;2;88;92;244mX\u001b[0m\u001b[38;2;83;89;237mY\u001b[0m\u001b[38;2;80;88;237mU\u001b[0m\u001b[38;2;79;86;235mU\u001b[0m\u001b[38;2;77;85;234mU\u001b[0m\u001b[38;2;76;84;232mJ\u001b[0m\u001b[38;2;74;82;229mJ\u001b[0m\u001b[38;2;76;85;235mU\u001b[0m\u001b[38;2;69;78;224mk\u001b[0m \n \u001b[38;2;138;118;255mO\u001b[0m\u001b[38;2;142;124;255mt\u001b[0m\u001b[38;2;136;120;255mf\u001b[0m\u001b[38;2;135;120;255mf\u001b[0m\u001b[38;2;133;119;255mj\u001b[0m\u001b[38;2;132;119;255mj\u001b[0m\u001b[38;2;130;118;255mj\u001b[0m\u001b[38;2;128;118;255mj\u001b[0m\u001b[38;2;126;118;255mj\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;122;116;255mr\u001b[0m\u001b[38;2;120;115;255mx\u001b[0m\u001b[38;2;119;115;255mx\u001b[0m\u001b[38;2;124;121;255mj\u001b[0m\u001b[38;2;115;113;255mc\u001b[0m\u001b[38;2;105;109;250mM\u001b[0m \u001b[38;2;76;85;233m0\u001b[0m\u001b[38;2;76;85;232mU\u001b[0m\u001b[38;2;75;83;230mJ\u001b[0m\u001b[38;2;74;82;228mJ\u001b[0m\u001b[38;2;72;81;227mC\u001b[0m\u001b[38;2;71;80;225mC\u001b[0m\u001b[38;2;69;79;224mC\u001b[0m\u001b[38;2;67;77;222mL\u001b[0m\u001b[38;2;69;79;230mC\u001b[0m\u001b[38;2;58;70;215m&\u001b[0m \n \u001b[38;2;132;118;255mU\u001b[0m\u001b[38;2;134;121;255mf\u001b[0m\u001b[38;2;129;118;255mj\u001b[0m\u001b[38;2;128;118;255mj\u001b[0m\u001b[38;2;126;117;255mj\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;123;116;255mr\u001b[0m\u001b[38;2;120;116;255mr\u001b[0m\u001b[38;2;119;115;255mr\u001b[0m\u001b[38;2;118;114;255mx\u001b[0m\u001b[38;2;116;115;255mx\u001b[0m\u001b[38;2;112;113;254mx\u001b[0m\u001b[38;2;108;113;252mn\u001b[0m\u001b[38;2;106;114;255mn\u001b[0m\u001b[38;2;97;109;250mc\u001b[0m\u001b[38;2;91;104;245m*\u001b[0m \u001b[38;2;65;80;225m&\u001b[0m\u001b[38;2;71;80;226mC\u001b[0m\u001b[38;2;70;79;224mC\u001b[0m\u001b[38;2;68;78;223mL\u001b[0m\u001b[38;2;67;77;222mL\u001b[0m\u001b[38;2;65;75;219mL\u001b[0m\u001b[38;2;63;73;218mQ\u001b[0m\u001b[38;2;65;76;226mL\u001b[0m\u001b[38;2;60;70;216mm\u001b[0m\u001b[38;2;56;68;209m%\u001b[0m \n \u001b[38;2;125;116;255mv\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;122;116;255mr\u001b[0m\u001b[38;2;121;116;255mr\u001b[0m\u001b[38;2;119;115;255mr\u001b[0m\u001b[38;2;117;115;255mx\u001b[0m\u001b[38;2;115;114;255mx\u001b[0m\u001b[38;2;112;114;254mx\u001b[0m\u001b[38;2;108;113;253mn\u001b[0m\u001b[38;2;103;112;252mn\u001b[0m\u001b[38;2;98;111;251mu\u001b[0m\u001b[38;2;93;109;249mv\u001b[0m\u001b[38;2;88;108;247mc\u001b[0m\u001b[38;2;84;109;249mv\u001b[0m\u001b[38;2;78;105;243mz\u001b[0m\u001b[38;2;67;102;237m#\u001b[0m \u001b[38;2;64;74;219mq\u001b[0m\u001b[38;2;64;74;218mQ\u001b[0m\u001b[38;2;63;73;218mQ\u001b[0m\u001b[38;2;61;72;215mQ\u001b[0m\u001b[38;2;59;71;214m0\u001b[0m\u001b[38;2;61;73;222mQ\u001b[0m\u001b[38;2;56;67;209md\u001b[0m \n \u001b[38;2;115;110;255mM\u001b[0m\u001b[38;2;117;114;255mx\u001b[0m\u001b[38;2;117;115;255mx\u001b[0m\u001b[38;2;114;114;255mn\u001b[0m\u001b[38;2;111;113;255mn\u001b[0m\u001b[38;2;107;112;252mn\u001b[0m\u001b[38;2;103;112;252mu\u001b[0m\u001b[38;2;97;109;249mv\u001b[0m\u001b[38;2;92;108;248mv\u001b[0m\u001b[38;2;87;108;247mc\u001b[0m\u001b[38;2;83;107;245mc\u001b[0m\u001b[38;2;78;106;244mz\u001b[0m\u001b[38;2;73;105;243mz\u001b[0m\u001b[38;2;68;104;241mX\u001b[0m\u001b[38;2;64;103;241mX\u001b[0m\u001b[38;2;59;101;239mU\u001b[0m\u001b[38;2;50;95;232m&\u001b[0m\u001b[38;2;57;63;210mW\u001b[0m\u001b[38;2;59;70;214m0\u001b[0m\u001b[38;2;57;69;211m0\u001b[0m\u001b[38;2;56;69;212m0\u001b[0m\u001b[38;2;55;68;212mO\u001b[0m\u001b[38;2;52;65;206ma\u001b[0m \n \u001b[38;2;110;110;255mk\u001b[0m\u001b[38;2;106;112;254mn\u001b[0m\u001b[38;2;107;119;255mx\u001b[0m\u001b[38;2;101;117;255mn\u001b[0m\u001b[38;2;95;115;255mn\u001b[0m\u001b[38;2;90;113;255mu\u001b[0m\u001b[38;2;84;111;255mv\u001b[0m\u001b[38;2;79;109;252mc\u001b[0m\u001b[38;2;74;107;248mz\u001b[0m\u001b[38;2;69;105;245mz\u001b[0m\u001b[38;2;64;104;243mX\u001b[0m\u001b[38;2;59;103;241mY\u001b[0m\u001b[38;2;54;101;238mU\u001b[0m\u001b[38;2;49;99;236mU\u001b[0m\u001b[38;2;44;99;235mJ\u001b[0m\u001b[38;2;39;97;232mQ\u001b[0m \u001b[38;2;53;64;205mZ\u001b[0m\u001b[38;2;53;67;212mO\u001b[0m\u001b[38;2;49;62;202mm\u001b[0m\u001b[38;2;48;63;200mM\u001b[0m \n \u001b[38;2;91;106;251m#\u001b[0m\u001b[38;2;86;106;245mq\u001b[0m\u001b[38;2;82;107;245mZ\u001b[0m\u001b[38;2;77;106;244mO\u001b[0m\u001b[38;2;73;104;243m0\u001b[0m\u001b[38;2;66;103;241mQ\u001b[0m\u001b[38;2;62;102;240mC\u001b[0m\u001b[38;2;57;100;237mC\u001b[0m\u001b[38;2;53;100;237mJ\u001b[0m\u001b[38;2;47;99;236mJ\u001b[0m\u001b[38;2;42;98;234mC\u001b[0m\u001b[38;2;38;97;234mC\u001b[0m\u001b[38;2;34;98;236mC\u001b[0m\u001b[38;2;29;98;238mC\u001b[0m\u001b[38;2;25;101;246mC\u001b[0m\u001b[38;2;15;91;227mm\u001b[0m\u001b[38;2;43;61;201mb\u001b[0m\u001b[38;2;45;59;199md\u001b[0m\u001b[38;2;43;54;195m%\u001b[0m \n \u001b[38;2;28;92;231m8\u001b[0m\u001b[38;2;25;95;229m&\u001b[0m\u001b[38;2;20;93;227mW\u001b[0m\u001b[38;2;17;93;226m#\u001b[0m\u001b[38;2;9;91;227m*\u001b[0m\u001b[38;2;7;90;225ma\u001b[0m\u001b[38;2;24;67;205mW\u001b[0m \n `; +export const typegpuAsciiLogoColor = ` \u001b[38;2;211;137;255mp\u001b[0m \n \u001b[38;2;211;138;255mJ\u001b[0m\u001b[38;2;211;139;254m{\u001b[0m \n \u001b[38;2;210;140;254m|\u001b[0m\u001b[38;2;223;148;255m?\u001b[0m\u001b[38;2;210;139;255mc\u001b[0m \n \u001b[38;2;209;138;254m0\u001b[0m\u001b[38;2;209;139;255m/\u001b[0m\u001b[38;2;204;136;254mo\u001b[0m \n \u001b[38;2;207;139;255mk\u001b[0m\u001b[38;2;208;139;255mp\u001b[0m\u001b[38;2;210;139;254mQ\u001b[0m\u001b[38;2;210;139;254mQ\u001b[0m\u001b[38;2;210;139;255mm\u001b[0m\u001b[38;2;203;137;255mp\u001b[0m\u001b[38;2;197;133;251mb\u001b[0m\u001b[38;2;188;132;248mk\u001b[0m\u001b[38;2;184;129;247ma\u001b[0m\u001b[38;2;179;129;250mo\u001b[0m\u001b[38;2;174;122;250m#\u001b[0m\u001b[38;2;170;124;249mM\u001b[0m \n \u001b[38;2;165;127;255mW\u001b[0m \u001b[38;2;207;137;255mb\u001b[0m\u001b[38;2;202;136;253mu\u001b[0m\u001b[38;2;202;139;255m{\u001b[0m\u001b[38;2;213;148;255m]\u001b[0m\u001b[38;2;196;138;255m{\u001b[0m\u001b[38;2;185;132;255m)\u001b[0m\u001b[38;2;176;128;255m|\u001b[0m\u001b[38;2;168;123;250m\\\u001b[0m\u001b[38;2;161;120;247mt\u001b[0m\u001b[38;2;154;118;246mj\u001b[0m\u001b[38;2;146;114;245mv\u001b[0m\u001b[38;2;138;111;241m#\u001b[0m \n \u001b[38;2;158;125;255mq\u001b[0m\u001b[38;2;156;124;254mf\u001b[0m\u001b[38;2;156;125;255mj\u001b[0m\u001b[38;2;152;124;255mL\u001b[0m\u001b[38;2;140;119;255mM\u001b[0m \u001b[38;2;170;117;248mW\u001b[0m\u001b[38;2;167;122;247mC\u001b[0m\u001b[38;2;160;119;247mt\u001b[0m\u001b[38;2;157;120;251mt\u001b[0m\u001b[38;2;149;116;246mf\u001b[0m\u001b[38;2;145;114;246mj\u001b[0m\u001b[38;2;139;112;246mj\u001b[0m\u001b[38;2;134;111;247mr\u001b[0m\u001b[38;2;132;111;252mr\u001b[0m\u001b[38;2;121;104;241mz\u001b[0m \n \u001b[38;2;155;124;255mX\u001b[0m\u001b[38;2;160;130;255m\\\u001b[0m\u001b[38;2;154;126;255m/\u001b[0m\u001b[38;2;153;127;255m/\u001b[0m\u001b[38;2;156;130;255m\\\u001b[0m\u001b[38;2;144;121;254mf\u001b[0m\u001b[38;2;141;121;255mY\u001b[0m\u001b[38;2;139;119;255ma\u001b[0m \u001b[38;2;142;112;241ma\u001b[0m\u001b[38;2;134;109;243mc\u001b[0m\u001b[38;2;132;111;251mr\u001b[0m\u001b[38;2;123;105;242mn\u001b[0m\u001b[38;2;117;103;242mu\u001b[0m\u001b[38;2;111;101;241mv\u001b[0m\u001b[38;2;105;98;240mc\u001b[0m\u001b[38;2;102;98;244mc\u001b[0m\u001b[38;2;92;92;238mZ\u001b[0m \n \u001b[38;2;150;123;255mf\u001b[0m\u001b[38;2;155;129;255m\\\u001b[0m\u001b[38;2;146;123;254mt\u001b[0m\u001b[38;2;143;121;255mf\u001b[0m\u001b[38;2;142;121;255mf\u001b[0m\u001b[38;2;139;120;254mf\u001b[0m\u001b[38;2;138;122;255mf\u001b[0m\u001b[38;2;142;126;255mt\u001b[0m\u001b[38;2;137;122;255mf\u001b[0m\u001b[38;2;129;117;254mU\u001b[0m\u001b[38;2;127;115;255m*\u001b[0m \u001b[38;2;108;98;239mC\u001b[0m\u001b[38;2;104;99;246mv\u001b[0m\u001b[38;2;96;95;240mz\u001b[0m\u001b[38;2;90;92;239mX\u001b[0m\u001b[38;2;86;90;238mY\u001b[0m\u001b[38;2;81;88;235mU\u001b[0m\u001b[38;2;82;90;241mY\u001b[0m\u001b[38;2;75;82;231mh\u001b[0m \n \u001b[38;2;143;121;255mL\u001b[0m\u001b[38;2;144;124;255mt\u001b[0m\u001b[38;2;139;120;255mf\u001b[0m\u001b[38;2;137;120;255mf\u001b[0m\u001b[38;2;135;120;255mf\u001b[0m\u001b[38;2;133;119;255mj\u001b[0m\u001b[38;2;130;119;255mj\u001b[0m\u001b[38;2;128;118;254mr\u001b[0m\u001b[38;2;125;116;255mr\u001b[0m\u001b[38;2;130;123;255mf\u001b[0m\u001b[38;2;121;115;254mx\u001b[0m\u001b[38;2;118;112;255mw\u001b[0m \u001b[38;2;81;88;236mQ\u001b[0m\u001b[38;2;80;87;236mU\u001b[0m\u001b[38;2;78;86;234mU\u001b[0m\u001b[38;2;76;84;232mJ\u001b[0m\u001b[38;2;74;83;230mJ\u001b[0m\u001b[38;2;72;80;226mC\u001b[0m\u001b[38;2;70;79;225mC\u001b[0m\u001b[38;2;65;73;220mW\u001b[0m \n \u001b[38;2;133;118;255mz\u001b[0m\u001b[38;2;134;120;255mf\u001b[0m\u001b[38;2;131;118;255mj\u001b[0m\u001b[38;2;128;118;255mj\u001b[0m\u001b[38;2;126;117;255mj\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;122;116;255mr\u001b[0m\u001b[38;2;119;115;255mx\u001b[0m\u001b[38;2;117;115;254mx\u001b[0m\u001b[38;2;115;114;255mx\u001b[0m\u001b[38;2;116;119;255mr\u001b[0m\u001b[38;2;100;109;250mO\u001b[0m \u001b[38;2;72;78;228m8\u001b[0m\u001b[38;2;72;81;228mC\u001b[0m\u001b[38;2;71;81;226mC\u001b[0m\u001b[38;2;69;79;224mC\u001b[0m\u001b[38;2;67;77;222mL\u001b[0m\u001b[38;2;66;75;220mL\u001b[0m\u001b[38;2;66;77;228mL\u001b[0m\u001b[38;2;59;72;216mh\u001b[0m \n \u001b[38;2;124;116;255mn\u001b[0m\u001b[38;2;123;116;255mr\u001b[0m\u001b[38;2;121;116;255mr\u001b[0m\u001b[38;2;119;115;255mx\u001b[0m\u001b[38;2;117;115;255mx\u001b[0m\u001b[38;2;114;114;255mx\u001b[0m\u001b[38;2;109;113;253mn\u001b[0m\u001b[38;2;104;111;252mn\u001b[0m\u001b[38;2;97;110;250mu\u001b[0m\u001b[38;2;91;109;248mv\u001b[0m\u001b[38;2;90;112;255mu\u001b[0m\u001b[38;2;76;104;243mZ\u001b[0m \u001b[38;2;64;74;218mp\u001b[0m\u001b[38;2;64;74;218mQ\u001b[0m\u001b[38;2;62;73;216mQ\u001b[0m\u001b[38;2;61;72;216mQ\u001b[0m\u001b[38;2;60;72;217mQ\u001b[0m\u001b[38;2;55;68;208mh\u001b[0m \n \u001b[38;2;116;113;255ma\u001b[0m\u001b[38;2;119;117;255mr\u001b[0m\u001b[38;2;116;117;255mr\u001b[0m\u001b[38;2;110;114;255mx\u001b[0m\u001b[38;2;104;112;253mn\u001b[0m\u001b[38;2;97;110;249mu\u001b[0m\u001b[38;2;91;108;247mv\u001b[0m\u001b[38;2;85;107;246mc\u001b[0m\u001b[38;2;79;107;245mz\u001b[0m\u001b[38;2;73;104;242mX\u001b[0m\u001b[38;2;66;103;241mY\u001b[0m\u001b[38;2;63;105;245mX\u001b[0m\u001b[38;2;51;98;235md\u001b[0m\u001b[38;2;62;66;207m&\u001b[0m\u001b[38;2;58;69;212m0\u001b[0m\u001b[38;2;57;69;214m0\u001b[0m\u001b[38;2;52;64;207mZ\u001b[0m\u001b[38;2;51;63;204m#\u001b[0m \n \u001b[38;2;104;110;252md\u001b[0m\u001b[38;2;95;110;249mz\u001b[0m\u001b[38;2;89;107;246mc\u001b[0m\u001b[38;2;83;107;246mc\u001b[0m\u001b[38;2;78;107;249mc\u001b[0m\u001b[38;2;74;108;252mc\u001b[0m\u001b[38;2;68;110;255mc\u001b[0m\u001b[38;2;63;110;255mz\u001b[0m\u001b[38;2;56;108;255mX\u001b[0m\u001b[38;2;49;106;251mY\u001b[0m\u001b[38;2;42;102;246mU\u001b[0m\u001b[38;2;38;104;251mU\u001b[0m\u001b[38;2;24;90;224mo\u001b[0m\u001b[38;2;50;62;203mm\u001b[0m\u001b[38;2;47;61;201mq\u001b[0m\u001b[38;2;43;57;197m8\u001b[0m \n \u001b[38;2;73;102;243m&\u001b[0m\u001b[38;2;69;103;242mW\u001b[0m\u001b[38;2;62;99;237m#\u001b[0m\u001b[38;2;57;98;237m*\u001b[0m\u001b[38;2;50;100;237mo\u001b[0m\u001b[38;2;43;96;235ma\u001b[0m\u001b[38;2;38;97;231mk\u001b[0m\u001b[38;2;31;94;232mb\u001b[0m\u001b[38;2;23;92;229md\u001b[0m\u001b[38;2;17;93;228mp\u001b[0m\u001b[38;2;10;91;226mp\u001b[0m\u001b[38;2;37;60;200m*\u001b[0m \n `; + +export const typegpuAsciiLogoNoColor = ` p \n J{ \n |?c \n 0/o \n kpQQmpbkao#M \n W bu{]{)|\\tjv# \n qfjLM WCttfjjrrz \n X\\//\\fYa acrnuvccZ \n f\\tfffftfU* CvzXYUYh \n Ltfffjjrrfxw QUUJJCCW \n zfjjjrrxxxrO 8CCCLLLh \n nrrxxxnnuvuZ pQQQQh \n arrxnuvczXYXd&00Z# \n dzccccczXYUUomq8 \n &W#*oakbdpp* \n `; From 0874ce5c1936eee37b620f1330c85d9fa41b730e Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 7 Jul 2026 16:15:56 +0200 Subject: [PATCH 08/18] robust NO_COLOR handling --- packages/typegpu-cli/src/create.ts | 8 ++++---- packages/typegpu-cli/src/index.ts | 8 ++------ packages/typegpu-cli/src/utils/logo.ts | 6 ++++-- packages/typegpu-cli/src/utils/prompts.ts | 4 ++++ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/typegpu-cli/src/create.ts b/packages/typegpu-cli/src/create.ts index f30d8fd29c..171d455590 100644 --- a/packages/typegpu-cli/src/create.ts +++ b/packages/typegpu-cli/src/create.ts @@ -15,8 +15,8 @@ import { type ProjectTemplate, } from './options.ts'; -const GRADIENT_START = [0.831, 0.553, 1.0] as const; -const GRADIENT_END = [0.0, 0.349, 0.874] as const; +const GRADIENT_START = [0.867, 0.663, 1.0] as const; +const GRADIENT_END = [0.384, 0.439, 0.964] as const; const coloredLabelsTemplates = PROJECT_TEMPLATES.map((template, i) => { const t = i / (PROJECT_TEMPLATES.length - 1); @@ -54,8 +54,6 @@ export async function createProject(cwd: string, options?: CreateProjectOptions) options?.projectDir ?? (nonInteractive ? DEFAULT_PROJECT_DIR : await getProjectName(DEFAULT_PROJECT_DIR)); - const root = await prepareDirectory(cwd, projectName, { interactive: !nonInteractive }); - const packageName = getDefaultPackageName(cwd, projectName) ?? (nonInteractive ? undefined : await getPackageName()); @@ -72,6 +70,8 @@ export async function createProject(cwd: string, options?: CreateProjectOptions) p.log.step(`Scaffolding project in ${projectName}...`); + const root = await prepareDirectory(cwd, projectName, { interactive: !nonInteractive }); + const templateDir = path.resolve( import.meta.dirname, '../templates', diff --git a/packages/typegpu-cli/src/index.ts b/packages/typegpu-cli/src/index.ts index 7e88cdf5fd..0a70b86bf7 100644 --- a/packages/typegpu-cli/src/index.ts +++ b/packages/typegpu-cli/src/index.ts @@ -12,7 +12,7 @@ import { parsePackageManager, parseTemplate, } from './options.ts'; -import { failAndExit } from './utils/prompts.ts'; +import { colorsEnabled, failAndExit } from './utils/prompts.ts'; import { typegpuPkgs } from './utils/pkg.ts'; import { typegpuAsciiLogoColor, typegpuAsciiLogoNoColor } from './utils/logo.ts'; @@ -75,11 +75,7 @@ const commonOptions = { ...(packageManager ? { packageManager } : {}), }; -if (!process.env.NO_COLOR) { - console.log(typegpuAsciiLogoColor); -} else { - console.log(typegpuAsciiLogoNoColor); -} +console.log(colorsEnabled ? typegpuAsciiLogoColor : typegpuAsciiLogoNoColor); if (argv.enhance) { const targetDir = positionals[0] ? path.resolve(cwd, positionals[0]) : cwd; diff --git a/packages/typegpu-cli/src/utils/logo.ts b/packages/typegpu-cli/src/utils/logo.ts index b43e64e8ba..10932e482a 100644 --- a/packages/typegpu-cli/src/utils/logo.ts +++ b/packages/typegpu-cli/src/utils/logo.ts @@ -1,3 +1,5 @@ -export const typegpuAsciiLogoColor = ` \u001b[38;2;211;137;255mp\u001b[0m \n \u001b[38;2;211;138;255mJ\u001b[0m\u001b[38;2;211;139;254m{\u001b[0m \n \u001b[38;2;210;140;254m|\u001b[0m\u001b[38;2;223;148;255m?\u001b[0m\u001b[38;2;210;139;255mc\u001b[0m \n \u001b[38;2;209;138;254m0\u001b[0m\u001b[38;2;209;139;255m/\u001b[0m\u001b[38;2;204;136;254mo\u001b[0m \n \u001b[38;2;207;139;255mk\u001b[0m\u001b[38;2;208;139;255mp\u001b[0m\u001b[38;2;210;139;254mQ\u001b[0m\u001b[38;2;210;139;254mQ\u001b[0m\u001b[38;2;210;139;255mm\u001b[0m\u001b[38;2;203;137;255mp\u001b[0m\u001b[38;2;197;133;251mb\u001b[0m\u001b[38;2;188;132;248mk\u001b[0m\u001b[38;2;184;129;247ma\u001b[0m\u001b[38;2;179;129;250mo\u001b[0m\u001b[38;2;174;122;250m#\u001b[0m\u001b[38;2;170;124;249mM\u001b[0m \n \u001b[38;2;165;127;255mW\u001b[0m \u001b[38;2;207;137;255mb\u001b[0m\u001b[38;2;202;136;253mu\u001b[0m\u001b[38;2;202;139;255m{\u001b[0m\u001b[38;2;213;148;255m]\u001b[0m\u001b[38;2;196;138;255m{\u001b[0m\u001b[38;2;185;132;255m)\u001b[0m\u001b[38;2;176;128;255m|\u001b[0m\u001b[38;2;168;123;250m\\\u001b[0m\u001b[38;2;161;120;247mt\u001b[0m\u001b[38;2;154;118;246mj\u001b[0m\u001b[38;2;146;114;245mv\u001b[0m\u001b[38;2;138;111;241m#\u001b[0m \n \u001b[38;2;158;125;255mq\u001b[0m\u001b[38;2;156;124;254mf\u001b[0m\u001b[38;2;156;125;255mj\u001b[0m\u001b[38;2;152;124;255mL\u001b[0m\u001b[38;2;140;119;255mM\u001b[0m \u001b[38;2;170;117;248mW\u001b[0m\u001b[38;2;167;122;247mC\u001b[0m\u001b[38;2;160;119;247mt\u001b[0m\u001b[38;2;157;120;251mt\u001b[0m\u001b[38;2;149;116;246mf\u001b[0m\u001b[38;2;145;114;246mj\u001b[0m\u001b[38;2;139;112;246mj\u001b[0m\u001b[38;2;134;111;247mr\u001b[0m\u001b[38;2;132;111;252mr\u001b[0m\u001b[38;2;121;104;241mz\u001b[0m \n \u001b[38;2;155;124;255mX\u001b[0m\u001b[38;2;160;130;255m\\\u001b[0m\u001b[38;2;154;126;255m/\u001b[0m\u001b[38;2;153;127;255m/\u001b[0m\u001b[38;2;156;130;255m\\\u001b[0m\u001b[38;2;144;121;254mf\u001b[0m\u001b[38;2;141;121;255mY\u001b[0m\u001b[38;2;139;119;255ma\u001b[0m \u001b[38;2;142;112;241ma\u001b[0m\u001b[38;2;134;109;243mc\u001b[0m\u001b[38;2;132;111;251mr\u001b[0m\u001b[38;2;123;105;242mn\u001b[0m\u001b[38;2;117;103;242mu\u001b[0m\u001b[38;2;111;101;241mv\u001b[0m\u001b[38;2;105;98;240mc\u001b[0m\u001b[38;2;102;98;244mc\u001b[0m\u001b[38;2;92;92;238mZ\u001b[0m \n \u001b[38;2;150;123;255mf\u001b[0m\u001b[38;2;155;129;255m\\\u001b[0m\u001b[38;2;146;123;254mt\u001b[0m\u001b[38;2;143;121;255mf\u001b[0m\u001b[38;2;142;121;255mf\u001b[0m\u001b[38;2;139;120;254mf\u001b[0m\u001b[38;2;138;122;255mf\u001b[0m\u001b[38;2;142;126;255mt\u001b[0m\u001b[38;2;137;122;255mf\u001b[0m\u001b[38;2;129;117;254mU\u001b[0m\u001b[38;2;127;115;255m*\u001b[0m \u001b[38;2;108;98;239mC\u001b[0m\u001b[38;2;104;99;246mv\u001b[0m\u001b[38;2;96;95;240mz\u001b[0m\u001b[38;2;90;92;239mX\u001b[0m\u001b[38;2;86;90;238mY\u001b[0m\u001b[38;2;81;88;235mU\u001b[0m\u001b[38;2;82;90;241mY\u001b[0m\u001b[38;2;75;82;231mh\u001b[0m \n \u001b[38;2;143;121;255mL\u001b[0m\u001b[38;2;144;124;255mt\u001b[0m\u001b[38;2;139;120;255mf\u001b[0m\u001b[38;2;137;120;255mf\u001b[0m\u001b[38;2;135;120;255mf\u001b[0m\u001b[38;2;133;119;255mj\u001b[0m\u001b[38;2;130;119;255mj\u001b[0m\u001b[38;2;128;118;254mr\u001b[0m\u001b[38;2;125;116;255mr\u001b[0m\u001b[38;2;130;123;255mf\u001b[0m\u001b[38;2;121;115;254mx\u001b[0m\u001b[38;2;118;112;255mw\u001b[0m \u001b[38;2;81;88;236mQ\u001b[0m\u001b[38;2;80;87;236mU\u001b[0m\u001b[38;2;78;86;234mU\u001b[0m\u001b[38;2;76;84;232mJ\u001b[0m\u001b[38;2;74;83;230mJ\u001b[0m\u001b[38;2;72;80;226mC\u001b[0m\u001b[38;2;70;79;225mC\u001b[0m\u001b[38;2;65;73;220mW\u001b[0m \n \u001b[38;2;133;118;255mz\u001b[0m\u001b[38;2;134;120;255mf\u001b[0m\u001b[38;2;131;118;255mj\u001b[0m\u001b[38;2;128;118;255mj\u001b[0m\u001b[38;2;126;117;255mj\u001b[0m\u001b[38;2;124;117;255mr\u001b[0m\u001b[38;2;122;116;255mr\u001b[0m\u001b[38;2;119;115;255mx\u001b[0m\u001b[38;2;117;115;254mx\u001b[0m\u001b[38;2;115;114;255mx\u001b[0m\u001b[38;2;116;119;255mr\u001b[0m\u001b[38;2;100;109;250mO\u001b[0m \u001b[38;2;72;78;228m8\u001b[0m\u001b[38;2;72;81;228mC\u001b[0m\u001b[38;2;71;81;226mC\u001b[0m\u001b[38;2;69;79;224mC\u001b[0m\u001b[38;2;67;77;222mL\u001b[0m\u001b[38;2;66;75;220mL\u001b[0m\u001b[38;2;66;77;228mL\u001b[0m\u001b[38;2;59;72;216mh\u001b[0m \n \u001b[38;2;124;116;255mn\u001b[0m\u001b[38;2;123;116;255mr\u001b[0m\u001b[38;2;121;116;255mr\u001b[0m\u001b[38;2;119;115;255mx\u001b[0m\u001b[38;2;117;115;255mx\u001b[0m\u001b[38;2;114;114;255mx\u001b[0m\u001b[38;2;109;113;253mn\u001b[0m\u001b[38;2;104;111;252mn\u001b[0m\u001b[38;2;97;110;250mu\u001b[0m\u001b[38;2;91;109;248mv\u001b[0m\u001b[38;2;90;112;255mu\u001b[0m\u001b[38;2;76;104;243mZ\u001b[0m \u001b[38;2;64;74;218mp\u001b[0m\u001b[38;2;64;74;218mQ\u001b[0m\u001b[38;2;62;73;216mQ\u001b[0m\u001b[38;2;61;72;216mQ\u001b[0m\u001b[38;2;60;72;217mQ\u001b[0m\u001b[38;2;55;68;208mh\u001b[0m \n \u001b[38;2;116;113;255ma\u001b[0m\u001b[38;2;119;117;255mr\u001b[0m\u001b[38;2;116;117;255mr\u001b[0m\u001b[38;2;110;114;255mx\u001b[0m\u001b[38;2;104;112;253mn\u001b[0m\u001b[38;2;97;110;249mu\u001b[0m\u001b[38;2;91;108;247mv\u001b[0m\u001b[38;2;85;107;246mc\u001b[0m\u001b[38;2;79;107;245mz\u001b[0m\u001b[38;2;73;104;242mX\u001b[0m\u001b[38;2;66;103;241mY\u001b[0m\u001b[38;2;63;105;245mX\u001b[0m\u001b[38;2;51;98;235md\u001b[0m\u001b[38;2;62;66;207m&\u001b[0m\u001b[38;2;58;69;212m0\u001b[0m\u001b[38;2;57;69;214m0\u001b[0m\u001b[38;2;52;64;207mZ\u001b[0m\u001b[38;2;51;63;204m#\u001b[0m \n \u001b[38;2;104;110;252md\u001b[0m\u001b[38;2;95;110;249mz\u001b[0m\u001b[38;2;89;107;246mc\u001b[0m\u001b[38;2;83;107;246mc\u001b[0m\u001b[38;2;78;107;249mc\u001b[0m\u001b[38;2;74;108;252mc\u001b[0m\u001b[38;2;68;110;255mc\u001b[0m\u001b[38;2;63;110;255mz\u001b[0m\u001b[38;2;56;108;255mX\u001b[0m\u001b[38;2;49;106;251mY\u001b[0m\u001b[38;2;42;102;246mU\u001b[0m\u001b[38;2;38;104;251mU\u001b[0m\u001b[38;2;24;90;224mo\u001b[0m\u001b[38;2;50;62;203mm\u001b[0m\u001b[38;2;47;61;201mq\u001b[0m\u001b[38;2;43;57;197m8\u001b[0m \n \u001b[38;2;73;102;243m&\u001b[0m\u001b[38;2;69;103;242mW\u001b[0m\u001b[38;2;62;99;237m#\u001b[0m\u001b[38;2;57;98;237m*\u001b[0m\u001b[38;2;50;100;237mo\u001b[0m\u001b[38;2;43;96;235ma\u001b[0m\u001b[38;2;38;97;231mk\u001b[0m\u001b[38;2;31;94;232mb\u001b[0m\u001b[38;2;23;92;229md\u001b[0m\u001b[38;2;17;93;228mp\u001b[0m\u001b[38;2;10;91;226mp\u001b[0m\u001b[38;2;37;60;200m*\u001b[0m \n `; +export const typegpuAsciiLogoColor = + '\n \x1b[38;2;221;169;255m /|\x1b[0m\n \x1b[38;2;207;159;255m \\|____\x1b[0m\n \x1b[38;2;176;145;255m , `\\ \\\x1b[0m\n \x1b[38;2;147;136;255m/ `\\ \\ \\\x1b[0m\n \x1b[38;2;113;124;255m\\ `\\| /\x1b[0m\n \x1b[38;2;95;112;255m \\_____/\x1b[0m\n'; -export const typegpuAsciiLogoNoColor = ` p \n J{ \n |?c \n 0/o \n kpQQmpbkao#M \n W bu{]{)|\\tjv# \n qfjLM WCttfjjrrz \n X\\//\\fYa acrnuvccZ \n f\\tfffftfU* CvzXYUYh \n Ltfffjjrrfxw QUUJJCCW \n zfjjjrrxxxrO 8CCCLLLh \n nrrxxxnnuvuZ pQQQQh \n arrxnuvczXYXd&00Z# \n dzccccczXYUUomq8 \n &W#*oakbdpp* \n `; +export const typegpuAsciiLogoNoColor = + '\n /|\n \\|____\n , `\\ \\\n / `\\ \\ \\\n \\ `\\| /\n \\_____/\n'; diff --git a/packages/typegpu-cli/src/utils/prompts.ts b/packages/typegpu-cli/src/utils/prompts.ts index 3344be6bf2..5557d3dee2 100644 --- a/packages/typegpu-cli/src/utils/prompts.ts +++ b/packages/typegpu-cli/src/utils/prompts.ts @@ -1,5 +1,8 @@ +import { styleText } from 'node:util'; import * as p from '@clack/prompts'; +export const colorsEnabled = styleText('red', '_', { stream: process.stdout }) !== '_'; + export function cancelExit(): never { p.cancel('Operation cancelled.'); process.exit(0); @@ -22,5 +25,6 @@ export async function confirmStep(message: string, initialValue?: boolean) { // 0-255 range export function rgbText(text: string, r: number, g: number, b: number) { + if (!colorsEnabled) return text; return `\x1b[38;2;${r};${g};${b}m${text}\x1b[39m`; } From c101579a263bdf74032a1531542fd10ec3caaf19 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 7 Jul 2026 17:25:32 +0200 Subject: [PATCH 09/18] color align in enhance --- packages/typegpu-cli/src/enhance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typegpu-cli/src/enhance.ts b/packages/typegpu-cli/src/enhance.ts index 4ed7f0bb72..a00d007140 100644 --- a/packages/typegpu-cli/src/enhance.ts +++ b/packages/typegpu-cli/src/enhance.ts @@ -13,7 +13,7 @@ import { askForVite, setupVite } from './steps/vite.ts'; import { addAgentSkills, askForAgentSkills } from './steps/skills.ts'; import type { EnhanceProjectOptions } from './options.ts'; -const PROJECT_KINDS = [{ value: 'vite', label: rgbText('Vite', 175, 105, 245) }]; +const PROJECT_KINDS = [{ value: 'vite', label: rgbText('Vite', 221, 169, 255) }]; async function runViteFlow( cwd: string, From 88de6f5a5bb9634a5ef5c59a8393856c0263f3ec Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 7 Jul 2026 18:51:10 +0200 Subject: [PATCH 10/18] smaller indents --- packages/typegpu-cli/src/utils/logo.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typegpu-cli/src/utils/logo.ts b/packages/typegpu-cli/src/utils/logo.ts index 10932e482a..7e336c7468 100644 --- a/packages/typegpu-cli/src/utils/logo.ts +++ b/packages/typegpu-cli/src/utils/logo.ts @@ -1,5 +1,5 @@ export const typegpuAsciiLogoColor = - '\n \x1b[38;2;221;169;255m /|\x1b[0m\n \x1b[38;2;207;159;255m \\|____\x1b[0m\n \x1b[38;2;176;145;255m , `\\ \\\x1b[0m\n \x1b[38;2;147;136;255m/ `\\ \\ \\\x1b[0m\n \x1b[38;2;113;124;255m\\ `\\| /\x1b[0m\n \x1b[38;2;95;112;255m \\_____/\x1b[0m\n'; + '\n \x1b[38;2;221;169;255m /|\x1b[0m\n \x1b[38;2;207;159;255m \\|____\x1b[0m\n \x1b[38;2;176;145;255m , `\\ \\\x1b[0m\n \x1b[38;2;147;136;255m/ `\\ \\ \\\x1b[0m\n \x1b[38;2;113;124;255m\\ `\\| /\x1b[0m\n \x1b[38;2;95;112;255m \\_____/\x1b[0m\n'; export const typegpuAsciiLogoNoColor = - '\n /|\n \\|____\n , `\\ \\\n / `\\ \\ \\\n \\ `\\| /\n \\_____/\n'; + '\n /|\n \\|____\n , `\\ \\\n / `\\ \\ \\\n \\ `\\| /\n \\_____/\n'; From 05f0ca2292a04248b873ae7b766cea58b67955bf Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Wed, 10 Jun 2026 14:34:52 +0200 Subject: [PATCH 11/18] nextjs template --- .../templates/template-nextjs-bare/AGENTS.md | 5 + .../templates/template-nextjs-bare/CLAUDE.md | 1 + .../templates/template-nextjs-bare/_gitignore | 42 ++++++ .../templates/template-nextjs-bare/_nvmrc | 1 + .../template-nextjs-bare/_oxfmtrc.json | 4 + .../template-nextjs-bare/_package.json | 41 ++++++ .../_vscode/settings.json | 5 + .../template-nextjs-bare/_zed/settings.json | 15 ++ .../template-nextjs-bare/app/Canvas.tsx | 10 ++ .../template-nextjs-bare/app/CanvasInner.tsx | 29 ++++ .../template-nextjs-bare/app/favicon.ico | Bin 0 -> 12007 bytes .../template-nextjs-bare/app/globals.css | 64 +++++++++ .../template-nextjs-bare/app/layout.tsx | 22 +++ .../template-nextjs-bare/app/page.tsx | 133 ++++++++++++++++++ .../template-nextjs-bare/babel.config.js | 7 + .../template-nextjs-bare/next.config.ts | 8 ++ .../template-nextjs-bare/oxlint.config.ts | 21 +++ .../template-nextjs-bare/pnpm-workspace.yaml | 3 + .../template-nextjs-bare/postcss.config.mjs | 7 + .../template-nextjs-bare/public/icons.svg | 19 +++ .../template-nextjs-bare/public/next.svg | 1 + .../public/typegpu-logo-dark.svg | 59 ++++++++ .../public/typegpu-logo-light.svg | 58 ++++++++ .../template-nextjs-bare/tsconfig.json | 38 +++++ 24 files changed, 593 insertions(+) create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/AGENTS.md create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/CLAUDE.md create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_gitignore create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_nvmrc create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_oxfmtrc.json create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_package.json create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/favicon.ico create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/globals.css create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/babel.config.js create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/next.config.ts create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/oxlint.config.ts create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/pnpm-workspace.yaml create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/postcss.config.mjs create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/public/icons.svg create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/public/next.svg create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-dark.svg create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-light.svg create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/AGENTS.md b/packages/typegpu-cli/templates/template-nextjs-bare/AGENTS.md new file mode 100644 index 0000000000..8bd0e39085 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/AGENTS.md @@ -0,0 +1,5 @@ + +# This is NOT the Next.js you know + +This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices. + diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/CLAUDE.md b/packages/typegpu-cli/templates/template-nextjs-bare/CLAUDE.md new file mode 100644 index 0000000000..43c994c2d3 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore b/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore new file mode 100644 index 0000000000..c5e8b4ffbb --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore @@ -0,0 +1,42 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build +/dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_nvmrc b/packages/typegpu-cli/templates/template-nextjs-bare/_nvmrc new file mode 100644 index 0000000000..a45fd52cc5 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_nvmrc @@ -0,0 +1 @@ +24 diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_oxfmtrc.json b/packages/typegpu-cli/templates/template-nextjs-bare/_oxfmtrc.json new file mode 100644 index 0000000000..acf53a0834 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_oxfmtrc.json @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "ignorePatterns": [".agents/**", "AGENTS.md", "CLAUDE.md"] +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json new file mode 100644 index 0000000000..1e5fb0e451 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json @@ -0,0 +1,41 @@ +{ + "name": "typegpu-nextjs-simple-project", + "version": "0.0.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "check": "oxlint && oxfmt --check", + "fix": "oxlint --fix && oxfmt", + "types": "tsc --p ./tsconfig.json --noEmit" + }, + "dependencies": { + "@typegpu/react": "^0.11.1", + "next": "16.2.7", + "react": "19.2.4", + "react-dom": "19.2.4", + "typegpu": "^0.11.8" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "@webgpu/types": "^0.1.70", + "eslint-plugin-typegpu": "^0.11.1", + "oxfmt": "^0.49.0", + "oxlint": "^1.64.0", + "tailwindcss": "^4", + "typescript": "npm:tsover@6.0.1", + "unplugin-typegpu": "^0.11.4" + }, + "overrides": { + "typescript": "npm:tsover@6.0.1" + }, + "pnpm": { + "overrides": { + "typescript": "npm:tsover@6.0.1" + } + } +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json b/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json new file mode 100644 index 0000000000..0dfacd95d2 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json @@ -0,0 +1,5 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.preferences.importModuleSpecifier": "relative", + "typescript.enablePromptUseWorkspaceTsdk": true +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json b/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json new file mode 100644 index 0000000000..9d7badfbd2 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json @@ -0,0 +1,15 @@ +// Folder-specific settings +// +// For a full list of overridable settings, and general information on folder-specific settings, +// see the documentation: https://zed.dev/docs/configuring-zed#settings-files +{ + "lsp": { + "vtsls": { + "settings": { + "typescript": { + "tsdk": "node_modules/typescript/lib" + } + } + } + } +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx new file mode 100644 index 0000000000..b1ff0fac19 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx @@ -0,0 +1,10 @@ +'use client'; + +import React from 'react'; +import dynamic from 'next/dynamic'; + +const CanvasInner = dynamic(() => import('./CanvasInner'), { ssr: false }); + +export default function Canvas({ className }: { className?: string }) { + return ; +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx new file mode 100644 index 0000000000..80483dbc04 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx @@ -0,0 +1,29 @@ +'use client'; + +import React, { useMemo } from 'react'; +import { useConfigureContext, useFrame, useRoot } from '@typegpu/react'; +import { common, d } from 'typegpu'; + +export default function CanvasInner({ className }: { className?: string }) { + const { ref, ctxRef } = useConfigureContext({ autoResize: true, alphaMode: 'premultiplied' }); + + const root = useRoot(); + const renderPipeline = useMemo( + () => + root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: ({ uv }) => { + 'use gpu'; + return d.vec4f(0.55, uv, 1); + }, + }), + [root], + ); + + useFrame(() => { + if (!ctxRef.current) return; + renderPipeline.withColorAttachment({ view: ctxRef.current }).draw(3); + }); + + return ; +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/favicon.ico b/packages/typegpu-cli/templates/template-nextjs-bare/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2901de79c80cfa3680096859b29ddc4a4cfbd68d GIT binary patch literal 12007 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 M37}Xe{~_rA0Anx%tN;K2 literal 0 HcmV?d00001 diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/globals.css b/packages/typegpu-cli/templates/template-nextjs-bare/app/globals.css new file mode 100644 index 0000000000..f232fefb0e --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/globals.css @@ -0,0 +1,64 @@ +@import 'tailwindcss'; + +:root { + --text: #6b6375; + --text-h: #08060d; + --bg: #fff; + --border: #e5e4e7; + --social-bg: rgba(244, 243, 236, 0.5); + --shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; +} + +@theme inline { + --color-bg: var(--bg); + --color-text: var(--text); + --color-text-h: var(--text-h); + --color-border: var(--border); + --color-social: var(--social-bg); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} + +@media (prefers-color-scheme: dark) { + :root { + --text: #9ca3af; + --text-h: #f3f4f6; + --bg: #16171d; + --border: #2e303a; + --social-bg: rgba(47, 48, 58, 0.5); + --shadow: rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px; + } + + .button-icon { + filter: invert(1) brightness(2); + } +} + +body { + margin: 0; + background: var(--bg); + color: var(--text); +} + +.ticks { + position: relative; + width: 100%; +} + +.ticks::before, +.ticks::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; +} + +.ticks::before { + left: 0; + border-left-color: var(--border); +} + +.ticks::after { + right: 0; + border-right-color: var(--border); +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx new file mode 100644 index 0000000000..51983e0490 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import type { Metadata } from 'next'; + +// oxlint-disable-next-line import/no-unassigned-import +import './globals.css'; + +export const metadata: Metadata = { + title: 'typegpu-nextjs-simple-project', + description: 'TypeGPU + Next.js', +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + {children} + + ); +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx new file mode 100644 index 0000000000..8630eced1b --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx @@ -0,0 +1,133 @@ +import React from 'react'; + +import Canvas from './Canvas.tsx'; +import typegpuLogoDark from '../public/typegpu-logo-dark.svg'; +import typegpuLogoLight from '../public/typegpu-logo-light.svg'; +import nextLogo from '../public/next.svg'; + +export function generateStaticParams() { + return [{ slug: [''] }]; +} + +export default function Page() { + return ( +
+
+ +
+ +
+ +
+ {/* TypeGPU */} +
+ + + TypeGPU + + +

Type-safe WebGPU

+ + +
+ + {/* Next.js */} +
+

+ + + +

+ +

The React framework

+ + +
+
+ +
+ +
+
+ ); +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/babel.config.js b/packages/typegpu-cli/templates/template-nextjs-bare/babel.config.js new file mode 100644 index 0000000000..ef07c2dc32 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/babel.config.js @@ -0,0 +1,7 @@ +module.exports = (api) => { + api.cache(true); + return { + presets: ['next/babel'], + plugins: ['unplugin-typegpu/babel'], + }; +}; diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/next.config.ts b/packages/typegpu-cli/templates/template-nextjs-bare/next.config.ts new file mode 100644 index 0000000000..9c1882429e --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/next.config.ts @@ -0,0 +1,8 @@ +import type { NextConfig } from 'next'; + +const nextConfig: NextConfig = { + output: 'export', + distDir: './dist', +}; + +export default nextConfig; diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/oxlint.config.ts b/packages/typegpu-cli/templates/template-nextjs-bare/oxlint.config.ts new file mode 100644 index 0000000000..b18160f3d2 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/oxlint.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'oxlint'; +import typegpu from 'eslint-plugin-typegpu'; + +export default defineConfig({ + plugins: ['typescript', 'import', 'unicorn', 'oxc', 'react', 'nextjs'], + jsPlugins: ['eslint-plugin-typegpu'], + categories: { + correctness: 'warn', + suspicious: 'warn', + }, + rules: { + ...typegpu.configs.recommended.rules, + 'typescript/no-non-null-assertion': 'error', + 'typescript/no-explicit-any': 'error', + 'typescript/no-unsafe-type-assertion': 'off', + 'import/no-named-as-default': 'off', + }, + env: { + builtin: true, + }, +}); diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/pnpm-workspace.yaml b/packages/typegpu-cli/templates/template-nextjs-bare/pnpm-workspace.yaml new file mode 100644 index 0000000000..581a9d5b59 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +ignoredBuiltDependencies: + - sharp + - unrs-resolver diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/postcss.config.mjs b/packages/typegpu-cli/templates/template-nextjs-bare/postcss.config.mjs new file mode 100644 index 0000000000..297374d80b --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/postcss.config.mjs @@ -0,0 +1,7 @@ +const config = { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; + +export default config; diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/public/icons.svg b/packages/typegpu-cli/templates/template-nextjs-bare/public/icons.svg new file mode 100644 index 0000000000..36acdb9f18 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/public/icons.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/public/next.svg b/packages/typegpu-cli/templates/template-nextjs-bare/public/next.svg new file mode 100644 index 0000000000..5174b28c56 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-dark.svg b/packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-dark.svg new file mode 100644 index 0000000000..65c9a02c31 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-dark.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-light.svg b/packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-light.svg new file mode 100644 index 0000000000..a1b63335fc --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/public/typegpu-logo-light.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json b/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json new file mode 100644 index 0000000000..aec10d7402 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "ESNext", + "esModuleInterop": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true, + "noFallthroughCasesInSwitch": true, + "allowJs": true, + "forceConsistentCasingInFileNames": true, + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "types": ["@webgpu/types"] + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts", + "**/*.mts", + "dist/types/**/*.ts", + "dist/dev/types/**/*.ts" + ], + "exclude": ["node_modules"] +} From 986a7cf5f5e904ce690f0f1e4b047e292d551eec Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Thu, 11 Jun 2026 16:33:00 +0200 Subject: [PATCH 12/18] canvas -> shader rename --- .../template-nextjs-bare/app/{Canvas.tsx => Shader.tsx} | 4 ++-- .../app/{CanvasInner.tsx => ShaderInner.tsx} | 2 +- .../typegpu-cli/templates/template-nextjs-bare/app/page.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename packages/typegpu-cli/templates/template-nextjs-bare/app/{Canvas.tsx => Shader.tsx} (54%) rename packages/typegpu-cli/templates/template-nextjs-bare/app/{CanvasInner.tsx => ShaderInner.tsx} (92%) diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx similarity index 54% rename from packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx rename to packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx index b1ff0fac19..b030fc93df 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/Canvas.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx @@ -3,8 +3,8 @@ import React from 'react'; import dynamic from 'next/dynamic'; -const CanvasInner = dynamic(() => import('./CanvasInner'), { ssr: false }); +const ShaderInner = dynamic(() => import('./ShaderInner.tsx'), { ssr: false }); export default function Canvas({ className }: { className?: string }) { - return ; + return ; } diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx similarity index 92% rename from packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx rename to packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx index 80483dbc04..8b64066c2c 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/CanvasInner.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx @@ -4,7 +4,7 @@ import React, { useMemo } from 'react'; import { useConfigureContext, useFrame, useRoot } from '@typegpu/react'; import { common, d } from 'typegpu'; -export default function CanvasInner({ className }: { className?: string }) { +export default function ShaderInner({ className }: { className?: string }) { const { ref, ctxRef } = useConfigureContext({ autoResize: true, alphaMode: 'premultiplied' }); const root = useRoot(); diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx index 8630eced1b..8a3c537619 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import Canvas from './Canvas.tsx'; +import Shader from './Shader.tsx'; import typegpuLogoDark from '../public/typegpu-logo-dark.svg'; import typegpuLogoLight from '../public/typegpu-logo-light.svg'; import nextLogo from '../public/next.svg'; @@ -13,7 +13,7 @@ export default function Page() { return (
- +
From bd1f54a9cfe75d29d91da3760754d0172c2d10a6 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Thu, 11 Jun 2026 16:40:27 +0200 Subject: [PATCH 13/18] simple -> bare --- .../typegpu-cli/templates/template-nextjs-bare/_package.json | 2 +- .../typegpu-cli/templates/template-nextjs-bare/app/layout.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json index 1e5fb0e451..41348b8cb6 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json @@ -1,5 +1,5 @@ { - "name": "typegpu-nextjs-simple-project", + "name": "typegpu-nextjs-bare-project", "version": "0.0.0", "private": true, "scripts": { diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx index 51983e0490..ad42aadbce 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/layout.tsx @@ -5,7 +5,7 @@ import type { Metadata } from 'next'; import './globals.css'; export const metadata: Metadata = { - title: 'typegpu-nextjs-simple-project', + title: 'typegpu-nextjs-bare-project', description: 'TypeGPU + Next.js', }; From 214553c5ba87b71614d0cf9b1f9dca5efcf807e0 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Thu, 11 Jun 2026 18:21:11 +0200 Subject: [PATCH 14/18] agents gitignore --- packages/typegpu-cli/templates/template-nextjs-bare/_gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore b/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore index c5e8b4ffbb..166e81b14a 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_gitignore @@ -24,6 +24,7 @@ # misc .DS_Store *.pem +.agents # debug npm-debug.log* From 8b37577c744dc89423bf6a10c43082edcd3a4f2f Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Fri, 12 Jun 2026 16:22:25 +0200 Subject: [PATCH 15/18] bump es version so extarnals dont fail --- .../typegpu-cli/templates/template-nextjs-bare/tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json b/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json index aec10d7402..698cbb13de 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ESNext", "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ES2020"], + "lib": ["DOM", "DOM.Iterable", "ESNext"], "module": "ESNext", "esModuleInterop": true, "skipLibCheck": true, From 1dc63717392f1d0201e0abb9eea3dc9bc0e56e6a Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 7 Jul 2026 19:14:20 +0200 Subject: [PATCH 16/18] bump --- packages/typegpu-cli/src/options.ts | 1 + .../template-nextjs-bare/_package.json | 6 +-- .../_vscode/extensions.json | 3 ++ .../_vscode/settings.json | 15 ++++++- .../template-nextjs-bare/_zed/settings.json | 43 +++++++++++++++++++ .../template-nextjs-bare/app/Shader.tsx | 29 ++++++++++--- .../template-nextjs-bare/app/ShaderInner.tsx | 29 ------------- .../template-nextjs-bare/app/page.tsx | 9 +++- .../template-nextjs-bare/tsconfig.json | 5 +-- 9 files changed, 98 insertions(+), 42 deletions(-) create mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/_vscode/extensions.json delete mode 100644 packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx diff --git a/packages/typegpu-cli/src/options.ts b/packages/typegpu-cli/src/options.ts index f6250de5f4..ef2584dd72 100644 --- a/packages/typegpu-cli/src/options.ts +++ b/packages/typegpu-cli/src/options.ts @@ -10,6 +10,7 @@ export const PROJECT_TEMPLATES = [ { value: 'vite-bare', label: 'Vite (Bare)' }, { value: 'vite-complex', label: 'Vite (Complex - Domain Warping)' }, { value: 'vite-react', label: 'Vite + React (Bare)' }, + { value: 'nextjs-bare', label: 'Next.js (Bare)' }, { value: 'expo-bare', label: 'Expo RN (Bare)' }, ] as const; diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json index 41348b8cb6..d2681ac679 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json @@ -11,11 +11,11 @@ "types": "tsc --p ./tsconfig.json --noEmit" }, "dependencies": { - "@typegpu/react": "^0.11.1", + "@typegpu/react": "^0.11.2", "next": "16.2.7", "react": "19.2.4", "react-dom": "19.2.4", - "typegpu": "^0.11.8" + "typegpu": "^0.11.9" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -28,7 +28,7 @@ "oxlint": "^1.64.0", "tailwindcss": "^4", "typescript": "npm:tsover@6.0.1", - "unplugin-typegpu": "^0.11.4" + "unplugin-typegpu": "^0.11.6" }, "overrides": { "typescript": "npm:tsover@6.0.1" diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/extensions.json b/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/extensions.json new file mode 100644 index 0000000000..99e2f7ddf7 --- /dev/null +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json b/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json index 0dfacd95d2..1056eac024 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_vscode/settings.json @@ -1,5 +1,18 @@ { "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + + "oxc.configPath": "oxlint.config.ts", + "oxc.fmt.configPath": ".oxfmtrc.json", + "oxc.lint.run": "onType", + "editor.defaultFormatter": "oxc.oxc-vscode", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + + "editor.codeActionsOnSave": { + "source.organizeImports": "never", + "source.format.oxc": "always", + "source.fixAll.oxc": "always" + } } diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json b/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json index 9d7badfbd2..ee27702340 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_zed/settings.json @@ -10,6 +10,49 @@ "tsdk": "node_modules/typescript/lib" } } + }, + "oxlint": { + "initialization_options": { + "settings": { + "configPath": "./oxlint.config.ts", + "run": "onType", + "fixKind": "safe_fix" + } + } + }, + "oxfmt": { + "initialization_options": { + "settings": { + "fmt.configPath": ".oxfmtrc.json" + } + } + } + }, + "languages": { + "TypeScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "TSX": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JavaScript": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSON": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] + }, + "JSONC": { + "format_on_save": "on", + "prettier": { "allowed": false }, + "formatter": [{ "language_server": { "name": "oxfmt" } }] } } } diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx index b030fc93df..d256615280 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/Shader.tsx @@ -1,10 +1,29 @@ 'use client'; -import React from 'react'; -import dynamic from 'next/dynamic'; +import React, { useMemo } from 'react'; +import { useConfigureContext, useFrame, useRoot } from '@typegpu/react'; +import { common, d } from 'typegpu'; -const ShaderInner = dynamic(() => import('./ShaderInner.tsx'), { ssr: false }); +export default function Shader({ className }: { className?: string }) { + const { ref, ctxRef } = useConfigureContext({ autoResize: true, alphaMode: 'premultiplied' }); -export default function Canvas({ className }: { className?: string }) { - return ; + const root = useRoot(); + const renderPipeline = useMemo( + () => + root.createRenderPipeline({ + vertex: common.fullScreenTriangle, + fragment: ({ uv }) => { + 'use gpu'; + return d.vec4f(0.55, uv, 1); + }, + }), + [root], + ); + + useFrame(() => { + if (!ctxRef.current) return; + renderPipeline.withColorAttachment({ view: ctxRef.current }).draw(3); + }); + + return ; } diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx deleted file mode 100644 index 8b64066c2c..0000000000 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/ShaderInner.tsx +++ /dev/null @@ -1,29 +0,0 @@ -'use client'; - -import React, { useMemo } from 'react'; -import { useConfigureContext, useFrame, useRoot } from '@typegpu/react'; -import { common, d } from 'typegpu'; - -export default function ShaderInner({ className }: { className?: string }) { - const { ref, ctxRef } = useConfigureContext({ autoResize: true, alphaMode: 'premultiplied' }); - - const root = useRoot(); - const renderPipeline = useMemo( - () => - root.createRenderPipeline({ - vertex: common.fullScreenTriangle, - fragment: ({ uv }) => { - 'use gpu'; - return d.vec4f(0.55, uv, 1); - }, - }), - [root], - ); - - useFrame(() => { - if (!ctxRef.current) return; - renderPipeline.withColorAttachment({ view: ctxRef.current }).draw(3); - }); - - return ; -} diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx index 8a3c537619..262282707b 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { ClientOnly } from '@typegpu/react'; import Shader from './Shader.tsx'; import typegpuLogoDark from '../public/typegpu-logo-dark.svg'; @@ -13,7 +14,13 @@ export default function Page() { return (
- + Loading...

+ } + > + +
diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json b/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json index 698cbb13de..5a416dd8af 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/tsconfig.json @@ -7,22 +7,21 @@ "esModuleInterop": true, "skipLibCheck": true, "moduleResolution": "bundler", + "moduleDetection": "force", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": true, - "noFallthroughCasesInSwitch": true, "allowJs": true, - "forceConsistentCasingInFileNames": true, "incremental": true, "plugins": [ { "name": "next" } ], - "types": ["@webgpu/types"] + "types": ["@webgpu/types", "@types/react", "@types/react-dom", "@types/node"] }, "include": [ "next-env.d.ts", From f815cab993323d55031ad78a28b80a3bf4b1862c Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 7 Jul 2026 20:03:38 +0200 Subject: [PATCH 17/18] review changes --- .../typegpu-cli/templates/template-nextjs-bare/app/page.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx index 262282707b..2a72f31174 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx +++ b/packages/typegpu-cli/templates/template-nextjs-bare/app/page.tsx @@ -6,10 +6,6 @@ import typegpuLogoDark from '../public/typegpu-logo-dark.svg'; import typegpuLogoLight from '../public/typegpu-logo-light.svg'; import nextLogo from '../public/next.svg'; -export function generateStaticParams() { - return [{ slug: [''] }]; -} - export default function Page() { return (
From e50975bda9cd9801ffbaacb57888e819d0981236 Mon Sep 17 00:00:00 2001 From: Szymon Szulc Date: Tue, 18 Aug 2026 15:13:15 +0200 Subject: [PATCH 18/18] bump --- .../template-nextjs-bare/_package.json | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json index d2681ac679..e07b653b17 100644 --- a/packages/typegpu-cli/templates/template-nextjs-bare/_package.json +++ b/packages/typegpu-cli/templates/template-nextjs-bare/_package.json @@ -11,31 +11,31 @@ "types": "tsc --p ./tsconfig.json --noEmit" }, "dependencies": { - "@typegpu/react": "^0.11.2", - "next": "16.2.7", - "react": "19.2.4", - "react-dom": "19.2.4", - "typegpu": "^0.11.9" + "@typegpu/react": "^0.12.0", + "next": "16.3.1", + "react": "19.2.8", + "react-dom": "19.2.8", + "typegpu": "^0.12.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "@webgpu/types": "^0.1.70", - "eslint-plugin-typegpu": "^0.11.1", - "oxfmt": "^0.49.0", - "oxlint": "^1.64.0", + "@webgpu/types": "^0.1.71", + "eslint-plugin-typegpu": "^0.12.0", + "oxfmt": "^0.63.0", + "oxlint": "^1.78.0", "tailwindcss": "^4", - "typescript": "npm:tsover@6.0.1", - "unplugin-typegpu": "^0.11.6" + "typescript": "npm:tsover@6.0.2", + "unplugin-typegpu": "^0.12.1" }, "overrides": { - "typescript": "npm:tsover@6.0.1" + "typescript": "npm:tsover@6.0.2" }, "pnpm": { "overrides": { - "typescript": "npm:tsover@6.0.1" + "typescript": "npm:tsover@6.0.2" } } }