hızlı proje kurulumu ve kullanımı için gea-cli eklendi.#12
hızlı proje kurulumu ve kullanımı için gea-cli eklendi.#12hacimertgokhan wants to merge 2 commits intodashersw:mainfrom
Conversation
📝 WalkthroughWalkthroughAdds a new CLI package ( Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant CLI as gea (packages/gea-cli)
participant Prompts as `@clack/prompts`
participant Shell as npm/execa
participant FS as Filesystem
User->>CLI: run `npx gea init [name]` or `npm run gea init`
CLI->>Prompts: show intro / ask project name & template
Prompts-->>CLI: project name, template
CLI->>Shell: run `npm create gea@latest <name>` (execa)
Shell-->>CLI: process output / exit
CLI->>FS: create/copy files if needed (scaffold)
CLI-->>User: show outro / next steps
sequenceDiagram
participant User as User
participant CLI as gea (packages/gea-cli)
participant FS as Filesystem
participant Spinner as Spinner/Output
User->>CLI: run `gea add component|store <name>`
CLI->>FS: ensure `src/` exists
CLI->>FS: write `src/<name>.tsx` or `src/<name>.ts`
CLI->>Spinner: show success message
CLI-->>User: completion notice
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
normal bir cli olduğunun farkında olarak bu cli'ı geliştirdim. mobil vb. platformlar ın proje üretiminide aynı noktadan oluşturabilmek için tekilleştirme gereği duydum. |
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (2)
packages/gea-cli/package.json (1)
18-18: Remove unusedpicocolorsdependency.The
picocolorspackage is declared as a dependency but never imported or used in the codebase. The CLI useskoloristfor terminal colors instead. Removing this unused dependency reduces package bloat.♻️ Proposed fix
"dependencies": { "commander": "^13.1.0", "@clack/prompts": "^1.1.0", "kolorist": "^1.8.0", - "picocolors": "^1.1.1", "execa": "^9.0.2", "fs-extra": "^11.3.0" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/gea-cli/package.json` at line 18, The package.json lists an unused dependency "picocolors" while the CLI uses "kolorist"; remove the "picocolors" entry from package.json dependencies, update the lockfile by running the package manager's install (npm/yarn/pnpm) to regenerate locks, and verify no import references to "picocolors" remain by searching the codebase (look for "picocolors" string) and ensuring all color usage comes from "kolorist" (verify files that import kolorist).packages/create-gea/bin/create-gea.js (1)
97-100: Prefer failing fast over silently falling back todefault.Line 99 turns a missing template folder into a successful Standard scaffold. That hides packaging mistakes and gives users the wrong project shape.
♻️ Proposed change
const selectedTemplateDir = resolve(templatesDir, template) - const templateToUse = existsSync(selectedTemplateDir) ? template : 'default' - cpSync(resolve(templatesDir, templateToUse), projectRoot, { recursive: true }) + if (!existsSync(selectedTemplateDir)) { + throw new Error(`Template "${template}" is not available in this build`) + } + + cpSync(selectedTemplateDir, projectRoot, { recursive: true })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/create-gea/bin/create-gea.js` around lines 97 - 100, The current logic silently falls back to the 'default' template when the requested template folder is missing (selectedTemplateDir / templateToUse), which masks packaging errors; change it to fail fast by checking existsSync(selectedTemplateDir) and, if false, log or throw a clear error (including the requested template name and templatesDir) and exit non‑zero instead of assigning 'default' and calling cpSync; keep cpSync(resolve(templatesDir, template), projectRoot, { recursive: true }) only for the success path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/create-gea/bin/create-gea.js`:
- Around line 61-70: The validator for targetDir (inside the text(...) call) is
only applied when the interactive prompt returns a truthy value, so positional
args like create-gea existing-dir bypass the non-empty check; update the flow so
after collecting input (the text(...) result and the positional arg fallback
assigned to targetDir) you run the same validation logic using
existsSync(resolve(process.cwd(), targetDir)) and
isEmptyDir(resolve(process.cwd(), targetDir)), rejecting non-empty directories
and blank strings; ensure you reuse the same error message ("Target directory is
not empty") and apply the identical check in the later code block referenced
around lines 78-95 where targetDir may be set from argv so both interactive and
positional paths are validated consistently.
- Around line 123-125: The printed "cd" in the outro message isn't shell-safe
for directories with spaces; update the template passed to outro so the cd
command quotes (or otherwise shell-escapes) targetDir. Specifically, change the
interpolation that builds the cd line (currently using targetDir) to produce cd
"targetDir" (or an escaped equivalent) so the variable targetDir is quoted in
the string passed to outro alongside installCommand and devCommand.
In `@packages/create-gea/package.json`:
- Around line 26-30: The package create-gea lists an unused dependency
"picocolors" in its package.json dependencies; remove the "picocolors" entry
from the "dependencies" object in package.json, then reinstall/update lockfiles
(run npm/yarn/pnpm install) to reflect the change and ensure no code references
remain to "picocolors" (search for "picocolors" in the package to confirm).
In `@packages/create-gea/templates/dashboard/src/styles.css`:
- Line 8: The CSS rule uses quoted font-family name 'Inter' which violates the
font-family-name-quotes lint rule; update the declaration in styles.css (the
font-family property) to remove the single quotes around Inter so it reads the
unquoted font name (keep system-ui and sans-serif unchanged) to satisfy the
linter.
In `@packages/create-gea/templates/mobile/src/styles.css`:
- Line 63: The font-family declaration using 'SFMono-Regular' violates
stylelint's font-family-name-quotes rule; update the CSS rule that contains
font-family: 'SFMono-Regular', ui-monospace, monospace; (search for that exact
string) and remove the single quotes around SFMono-Regular so it reads
SFMono-Regular, ui-monospace, monospace to satisfy the linter.
In `@packages/gea-cli/bin/gea.js`:
- Around line 59-61: The failure paths currently call cancel(...) but do not set
a non-zero exit status; update the init catch block (the catch handling errors
from init) and the "unknown type" error branch to set a non-zero exit code
(e.g., process.exitCode = 1 or call process.exit(1)) after calling cancel so the
process returns failure to CI/scripts; locate the catch around init and the
branch that reports "unknown type" and append a non-zero exit handling
statement.
- Around line 92-100: The code constructs filePath from untrusted name (used in
the component branch where type === 'component') which permits path traversal;
sanitize and validate name before forming filePath: reject names containing path
separators or parent segments (e.g. '/' or '..') or normalize the resolved path
and ensure it is inside srcDir (use path.resolve(srcDir, fileName) then verify
the resulting path starts with srcDir or that path.relative(srcDir,
resolvedPath) does not start with '..'); apply the same validation for the other
creation branch that also builds a path from name (the block creating filePath
around fileName at the later lines) and fail early with a clear error if
validation fails.
- Around line 16-24: The loop in getProjectRoot (variable current) uses while
(current !== '/') which hangs on Windows drive roots; change the logic to break
when the parent directory equals the current directory (compute parent =
dirname(current) each iteration and stop if parent === current), or use while
(parent !== current) / a bounded loop instead; keep the existing package.json
check and return current when `@geajs/core` is found, otherwise set current =
parent and continue.
- Around line 101-124: The generated scaffolds import and use the wrong API and
JSX attribute: replace the import of createStore with the correct export from
`@geajs/core` (use Store for store types) and keep Component for components;
update the store template to export a Store (e.g., export const ${name}: Store =
{ ... }) and update the component template to use the JSX attribute class (not
className) in the returned markup; locate the templates around the variables
content, filePath and fileName in the component and store branches and change
the import lines and template strings accordingly so they match `@geajs/core`
exports (Component and Store) and use class in the component JSX.
In `@packages/gea-cli/package.json`:
- Around line 2-3: This PR adds a new package "gea-cli" but lacks a changeset;
run npx changeset in the repo root, create an initial changeset that includes
the "gea-cli" package with the appropriate release type (patch/initial) and a
short summary, then commit the generated .changeset YAML file so the package is
included in the release workflow.
---
Nitpick comments:
In `@packages/create-gea/bin/create-gea.js`:
- Around line 97-100: The current logic silently falls back to the 'default'
template when the requested template folder is missing (selectedTemplateDir /
templateToUse), which masks packaging errors; change it to fail fast by checking
existsSync(selectedTemplateDir) and, if false, log or throw a clear error
(including the requested template name and templatesDir) and exit non‑zero
instead of assigning 'default' and calling cpSync; keep
cpSync(resolve(templatesDir, template), projectRoot, { recursive: true }) only
for the success path.
In `@packages/gea-cli/package.json`:
- Line 18: The package.json lists an unused dependency "picocolors" while the
CLI uses "kolorist"; remove the "picocolors" entry from package.json
dependencies, update the lockfile by running the package manager's install
(npm/yarn/pnpm) to regenerate locks, and verify no import references to
"picocolors" remain by searching the codebase (look for "picocolors" string) and
ensuring all color usage comes from "kolorist" (verify files that import
kolorist).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d6a22f02-0477-4aca-970f-2fdc3225d453
⛔ Files ignored due to path filters (6)
packages/create-gea/templates/dashboard/public/favicon.icois excluded by!**/*.icopackages/create-gea/templates/dashboard/public/logo.pngis excluded by!**/*.pngpackages/create-gea/templates/default/public/favicon.icois excluded by!**/*.icopackages/create-gea/templates/default/public/logo.pngis excluded by!**/*.pngpackages/create-gea/templates/mobile/public/favicon.icois excluded by!**/*.icopackages/create-gea/templates/mobile/public/logo.pngis excluded by!**/*.png
📒 Files selected for processing (38)
package.jsonpackages/create-gea/bin/create-gea.jspackages/create-gea/package.jsonpackages/create-gea/templates/dashboard/_gitignorepackages/create-gea/templates/dashboard/index.htmlpackages/create-gea/templates/dashboard/package.jsonpackages/create-gea/templates/dashboard/src/app.tsxpackages/create-gea/templates/dashboard/src/counter-note.tsxpackages/create-gea/templates/dashboard/src/counter-panel.tsxpackages/create-gea/templates/dashboard/src/counter-store.tspackages/create-gea/templates/dashboard/src/main.tspackages/create-gea/templates/dashboard/src/styles.csspackages/create-gea/templates/dashboard/tsconfig.jsonpackages/create-gea/templates/dashboard/vite.config.tspackages/create-gea/templates/default/_gitignorepackages/create-gea/templates/default/index.htmlpackages/create-gea/templates/default/package.jsonpackages/create-gea/templates/default/src/app.tsxpackages/create-gea/templates/default/src/counter-note.tsxpackages/create-gea/templates/default/src/counter-panel.tsxpackages/create-gea/templates/default/src/counter-store.tspackages/create-gea/templates/default/src/main.tspackages/create-gea/templates/default/src/styles.csspackages/create-gea/templates/default/tsconfig.jsonpackages/create-gea/templates/default/vite.config.tspackages/create-gea/templates/mobile/_gitignorepackages/create-gea/templates/mobile/index.htmlpackages/create-gea/templates/mobile/package.jsonpackages/create-gea/templates/mobile/src/app.tsxpackages/create-gea/templates/mobile/src/counter-note.tsxpackages/create-gea/templates/mobile/src/counter-panel.tsxpackages/create-gea/templates/mobile/src/counter-store.tspackages/create-gea/templates/mobile/src/main.tspackages/create-gea/templates/mobile/src/styles.csspackages/create-gea/templates/mobile/tsconfig.jsonpackages/create-gea/templates/mobile/vite.config.tspackages/gea-cli/bin/gea.jspackages/gea-cli/package.json
| "name": "gea-cli", | ||
| "version": "1.0.0", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check if a changeset file exists for this PR
# Look for changeset files that might reference gea-cli
fd -e md . .changeset/ --exec cat {} \; 2>/dev/null | head -50Repository: dashersw/gea
Length of output: 567
🏁 Script executed:
#!/bin/bash
# List all files in .changeset/ to see what exists
ls -la .changeset/ | grep -v "^total"Repository: dashersw/gea
Length of output: 278
🏁 Script executed:
#!/bin/bash
# Check .changeset/config.json for any ignore rules or special configuration
cat .changeset/config.jsonRepository: dashersw/gea
Length of output: 406
🏁 Script executed:
#!/bin/bash
# Check if there are any .md files in .changeset/ besides README.md
find .changeset -name "*.md" -not -name "README.md" | head -20Repository: dashersw/gea
Length of output: 38
Create a changeset for this new package.
Per the project's changeset workflow, every PR that changes published package output must include a changeset file. Since this is a new package, run npx changeset to declare the initial release.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/gea-cli/package.json` around lines 2 - 3, This PR adds a new package
"gea-cli" but lacks a changeset; run npx changeset in the repo root, create an
initial changeset that includes the "gea-cli" package with the appropriate
release type (patch/initial) and a short summary, then commit the generated
.changeset YAML file so the package is included in the release workflow.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/create-gea/bin/create-gea.js`:
- Around line 1-8: The published CLI entry file create-gea.js lacks a Node
shebang so POSIX systems execute it as a shell script; fix by inserting a single
line shebang "#!/usr/bin/env node" as the very first line of
packages/create-gea/bin/create-gea.js (before the first import), keep the rest
of the file unchanged, and ensure the file has executable permissions in the
package (so the bin symlink will run with Node).
In `@packages/gea-cli/bin/gea.js`:
- Around line 106-121: The code currently writes the generated component/store
unconditionally via fs.writeFile (using fileName/filePath/content), which will
overwrite existing files; update the logic to check for an existing file at
filePath before writing (e.g., use fs.existsSync, fs.stat, or fs.pathExists) and
if the file exists, abort or prompt the user rather than calling fs.writeFile;
ensure this same guard is applied to both places that call fs.writeFile (the
component and store branches) so existing user code is not silently replaced.
- Around line 54-60: Remove the wrapper UX: do not start or stop the local
spinner or print a success/outro unconditionally around the child CLI; instead
invoke execa('npm', ['create', 'gea@latest', name], { stdio: 'inherit' }) and
only print a success message if the child process truly exited successfully
(check the resolved exit code or allow execa to throw on non-zero), or better
yet let the child CLI (create-gea) own all interactive prompts and its own outro
by deleting the spinner creation/start (spinner(), s.start(...) and s.stop(...))
and the outro(...) call so the child output is the only UX the user sees.
- Line 141: The CLI uses Commander’s synchronous parse() so async command
handlers (the dev action that calls execa and the add action that uses fs-extra)
can produce unhandled rejections; change the invocation to use
program.parseAsync() so Commander will await and surface rejections, and ensure
the async action handlers (dev and add) return/await their promises so errors
propagate through Commander’s promise chain.
- Around line 92-95: The CLI currently uses the raw `name` value as a
source-code identifier which allows inputs that produce invalid JS symbols;
update the validation and/or symbol derivation: reject `name` values that do not
match a legal JavaScript identifier (use a regex like
/^[A-Za-z_$][A-Za-z0-9_$]*$/) and check against JS reserved words, or derive a
safe identifier (e.g., convert `name` to a camelCase/PascalCase symbol, strip or
replace invalid characters, ensure it doesn't start with a digit, and fall back
to a prefix like `_` if needed). Apply this fix to the initial guard around
`name` and the other places flagged (the uses around lines 109-119 and 127-131)
so source templates never embed the raw CLI `name` as an identifier.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d36942b8-e4f5-473b-b442-fadf24e7deea
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (5)
packages/create-gea/bin/create-gea.jspackages/create-gea/package.jsonpackages/create-gea/templates/dashboard/src/styles.csspackages/create-gea/templates/mobile/src/styles.csspackages/gea-cli/bin/gea.js
✅ Files skipped from review due to trivial changes (2)
- packages/create-gea/templates/dashboard/src/styles.css
- packages/create-gea/templates/mobile/src/styles.css
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/create-gea/package.json
| import { cpSync, existsSync, readdirSync, readFileSync, renameSync, writeFileSync, mkdirSync } from 'node:fs' | ||
| import { basename, dirname, resolve } from 'node:path' | ||
| import { fileURLToPath } from 'node:url' | ||
| import { stdin as input, stdout as output } from 'node:process' | ||
| import { createInterface } from 'node:readline/promises' | ||
| import { intro, outro, text, select, confirm, isCancel, cancel, spinner } from '@clack/prompts' | ||
| import { cyan, gray, green, reset } from 'kolorist' | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)) | ||
| const templateDir = resolve(__dirname, '../template') | ||
|
|
||
| function printHelp() { | ||
| console.log(`create-gea | ||
| const templatesDir = resolve(__dirname, '../templates') |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if packages/create-gea directory exists
fd "package.json" packages/create-gea
# Then examine the package.json for bin entry
cat -n packages/create-gea/package.jsonRepository: dashersw/gea
Length of output: 1082
🏁 Script executed:
# Check the current state of create-gea.js
head -20 packages/create-gea/bin/create-gea.jsRepository: dashersw/gea
Length of output: 958
🌐 Web query:
npm bin entry shebang requirement ES modules
💡 Result:
Yes, npm bin entry scripts require a shebang line (e.g., #!/usr/bin/env node) as the first line. This is a strong convention and practically required for correct execution, especially on Unix-like systems and via npx. On Unix, npm creates symlinks in node_modules/.bin to the script. Without a shebang, the OS treats it as a shell script, leading to syntax errors on JS/ESM content (e.g., "use strict: command not found"). On Windows, npm uses cmd-shim to create batch files that parse the shebang to invoke the correct interpreter (node) with arguments. Without it, the shim defaults to plain node script.js, which works for CJS but fails for ESM without "type": "module" or .mjs (syntax error on import/export). For ES modules (package.json "type": "module" or .mjs), the shebang #!/usr/bin/env node still works in modern Node.js (post-v12), as Node detects ESM via package type or extension when running the entry script. No special flags needed since v14+. Official npm docs imply executables need shebangs via examples and manpages. Community sources (SO, GitHub issues) confirm: missing shebang breaks execution, especially for ESM CLIs. Example bin script for ESM: #!/usr/bin/env node import { someFunc } from './utils.js'; someFunc; With "bin": {"mycli": "cli.js"} and "type": "module". Make executable: chmod +x cli.js. Sources confirm this across Node/npm versions up to 2026.
Citations:
- 1: [BUG] npx . launches bin script in shell npm/cli#7201
- 2: https://stackoverflow.com/questions/48179714/how-can-an-es6-module-be-run-as-a-script-in-node
- 3: https://nodejs.org/api/esm.html
- 4: shebangs and cmd shimmer documentation npm/feedback#148
- 5: https://stackoverflow.com/questions/10396305/npm-package-bin-script-for-windows
- 6: https://docs.npmjs.com/cli/v9/configuring-npm/package-json/?v=true
- 7: https://manpages.ubuntu.com/manpages/jammy/man5/package-json.5.html
- 8: https://2ality.com/2022/07/nodejs-esm-shell-scripts.html
- 9: [BUG] Experimental modules within "bin" script npm/cli#1649
- 10: https://github.com/npm/cmd-shim/blob/f59af911f1373239a7537072641d55ff882c3701/index.js
- 11: https://dev.to/orkhanhuseyn/making-your-npm-package-executable-1j0b
- 12: https://stackoverflow.com/questions/34353512/node-npm-package-throw-use-strict-command-not-found-after-publish-and-install-g
- 13: https://stackoverflow.com/questions/68111434/how-to-run-node-js-cli-with-experimental-specifier-resolution-node/68154775
- 14: https://nodejs.org/api/packages.html
Add Node shebang to the published bin entry.
packages/create-gea/package.json exposes bin/create-gea.js as an executable, but it currently starts with an import statement. Without a shebang, the symlink created on POSIX systems (Linux, macOS) will fail with "import: command not found" because the OS treats the file as a shell script instead of passing it to Node.
💡 Minimal fix
+#!/usr/bin/env node
import { cpSync, existsSync, readdirSync, readFileSync, renameSync, writeFileSync, mkdirSync } from 'node:fs'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/create-gea/bin/create-gea.js` around lines 1 - 8, The published CLI
entry file create-gea.js lacks a Node shebang so POSIX systems execute it as a
shell script; fix by inserting a single line shebang "#!/usr/bin/env node" as
the very first line of packages/create-gea/bin/create-gea.js (before the first
import), keep the rest of the file unchanged, and ensure the file has executable
permissions in the package (so the bin symlink will run with Node).
| const s = spinner() | ||
| s.start('Initalizing project...') | ||
|
|
||
| await execa('npm', ['create', 'gea@latest', name], { stdio: 'inherit' }) | ||
|
|
||
| s.stop(green('Project initialized!')) | ||
| outro(`Happy coding with ${cyan('Gea')}!`) |
There was a problem hiding this comment.
Let create-gea own the interactive UX here.
This wrapper starts a spinner and always prints success after npm create gea@latest, but the child CLI already renders its own prompts/outro. Since packages/create-gea/bin/create-gea.js exits with code 0 on cancel, a canceled template selection still reaches Project initialized! here.
💡 Minimal fix
- const s = spinner()
- s.start('Initalizing project...')
-
await execa('npm', ['create', 'gea@latest', name], { stdio: 'inherit' })
-
- s.stop(green('Project initialized!'))
- outro(`Happy coding with ${cyan('Gea')}!`)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/gea-cli/bin/gea.js` around lines 54 - 60, Remove the wrapper UX: do
not start or stop the local spinner or print a success/outro unconditionally
around the child CLI; instead invoke execa('npm', ['create', 'gea@latest',
name], { stdio: 'inherit' }) and only print a success message if the child
process truly exited successfully (check the resolved exit code or allow execa
to throw on non-zero), or better yet let the child CLI (create-gea) own all
interactive prompts and its own outro by deleting the spinner creation/start
(spinner(), s.start(...) and s.stop(...)) and the outro(...) call so the child
output is the only UX the user sees.
| if (name.includes('/') || name.includes('\\') || name.includes('..')) { | ||
| console.error(yellow('Invalid name: path segments are not allowed')) | ||
| process.exit(1) | ||
| } |
There was a problem hiding this comment.
Stop reusing the raw CLI name as a source-code identifier.
The current guard only blocks path segments. Inputs like Header.tsx, my-component, or user profile still pass, but they generate invalid declarations such as class Header.tsx or const my-component. Either derive a separate safe symbol name or reject anything that is not a legal, non-conflicting JS identifier.
Also applies to: 109-119, 127-131
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/gea-cli/bin/gea.js` around lines 92 - 95, The CLI currently uses the
raw `name` value as a source-code identifier which allows inputs that produce
invalid JS symbols; update the validation and/or symbol derivation: reject
`name` values that do not match a legal JavaScript identifier (use a regex like
/^[A-Za-z_$][A-Za-z0-9_$]*$/) and check against JS reserved words, or derive a
safe identifier (e.g., convert `name` to a camelCase/PascalCase symbol, strip or
replace invalid characters, ensure it doesn't start with a digit, and fall back
to a prefix like `_` if needed). Apply this fix to the initial guard around
`name` and the other places flagged (the uses around lines 109-119 and 127-131)
so source templates never embed the raw CLI `name` as an identifier.
| const fileName = name.endsWith('.tsx') ? name : `${name}.tsx` | ||
| const filePath = resolve(srcDir, fileName) | ||
|
|
||
| const content = `import { Component } from '@geajs/core'; | ||
|
|
||
| export default class ${name} extends Component { | ||
| template() { | ||
| return ( | ||
| <div class="${name.toLowerCase()}"> | ||
| <h2>Hello from ${name}</h2> | ||
| </div> | ||
| ); | ||
| } | ||
| } | ||
| ` | ||
| await fs.writeFile(filePath, content) |
There was a problem hiding this comment.
Guard against overwriting existing files in src/.
Both branches call fs.writeFile() unconditionally. Re-running gea add component App or gea add store counter will silently replace user code.
💡 Minimal fix
const fileName = name.endsWith('.tsx') ? name : `${name}.tsx`
const filePath = resolve(srcDir, fileName)
+ if (await fs.pathExists(filePath)) {
+ s.stop(yellow(`File already exists: ${gray(filePath)}`))
+ process.exit(1)
+ }
@@
const fileName = name.endsWith('.ts') ? name : `${name}.ts`
const filePath = resolve(srcDir, fileName)
+ if (await fs.pathExists(filePath)) {
+ s.stop(yellow(`File already exists: ${gray(filePath)}`))
+ process.exit(1)
+ }Also applies to: 124-133
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/gea-cli/bin/gea.js` around lines 106 - 121, The code currently
writes the generated component/store unconditionally via fs.writeFile (using
fileName/filePath/content), which will overwrite existing files; update the
logic to check for an existing file at filePath before writing (e.g., use
fs.existsSync, fs.stat, or fs.pathExists) and if the file exists, abort or
prompt the user rather than calling fs.writeFile; ensure this same guard is
applied to both places that call fs.writeFile (the component and store branches)
so existing user code is not silently replaced.
| } | ||
| }) | ||
|
|
||
| program.parse() |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -path "*/packages/gea-cli/bin/gea.js" -type fRepository: dashersw/gea
Length of output: 85
🏁 Script executed:
cat -n packages/gea-cli/bin/gea.jsRepository: dashersw/gea
Length of output: 4834
🏁 Script executed:
# Also check the directory structure of the gea-cli package
find ./packages/gea-cli -type f -name "*.js" | head -20Repository: dashersw/gea
Length of output: 85
Switch Commander to parseAsync() to handle async action rejections.
The dev and add commands are async but use program.parse(), which doesn't await them. Rejections from execa() at line 77 (dev) or fs-extra at lines 102, 121, and 133 (add) will become unhandled promise rejections instead of going through the normal CLI failure path.
💡 Minimal fix
-program.parse()
+program.parseAsync().catch((error) => {
+ cancel(error instanceof Error ? error.message : String(error))
+ process.exit(1)
+})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| program.parse() | |
| program.parseAsync().catch((error) => { | |
| cancel(error instanceof Error ? error.message : String(error)) | |
| process.exit(1) | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/gea-cli/bin/gea.js` at line 141, The CLI uses Commander’s
synchronous parse() so async command handlers (the dev action that calls execa
and the add action that uses fs-extra) can produce unhandled rejections; change
the invocation to use program.parseAsync() so Commander will await and surface
rejections, and ensure the async action handlers (dev and add) return/await
their promises so errors propagate through Commander’s promise chain.
gea-cli: Proje yönetimi, yeni bileşen ve store ekleme gibi geliştirici deneyimini hızlandıran komutlar eklendi.
create-gea: clack/prompts kütüphanesi kullanılarak interaktif proje kurulum arayüzüne geçildi.
şablonlar: Kurulum sırasında Standard, Mobile ve Dashboard seçeneklerinin sunulması sağlandı.
Summary by CodeRabbit
New Features
Chores