Es lint prettier support#62
Conversation
|
@ChubbyMmoh is attempting to deploy a commit to the flamki's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Caution Review failedFailed to post review comments 📝 WalkthroughWalkthroughAdds Prettier and ESLint configs, npm scripts, and a GitHub Actions lint workflow; documents formatting rules; reapplies consistent semicolon-free formatting across many files; updates pricing docs and refactors orchestrator x402/payment parsing, planning, and broadcast/result wiring. ChangesESLint, Prettier, and CI Linting Infrastructure
Documentation Updates and Pricing/Quick-start Docs
Orchestrator and x402 Payment Flow
Repo-wide Reformat and Peripheral Script Updates
Estimated code review effort 🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/agents/orchestrator.js (1)
198-242:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't signal a fallback here unless you actually take it.
When
settlereports failure, this branch emitsx402_retrywithfallback: true, but it still returns immediately from the x402 path. The XLM fallback below never runs, so settlement failures are treated as completed calls withpaidVia: 'none'.Suggested fix
if (response.ok) { const settle = parseSettlementHeader(response) const txHash = extractTxHash(settle) const settlementFailed = settle?.success === false || Boolean(settle?.error || settle?.errorReason) if (settlementFailed) { const reason = settle?.errorReason || settle?.error || 'x402 settlement failed' broadcastFn?.({ type: 'x402_retry', agent: agent.name, agentId: agent.id, reason, fallback: true, timestamp: new Date().toISOString(), }) console.warn(` x402 settlement reported failure: ${reason}`) - } else { + } else { const verification = txHash ? 'verified' : 'unverified' broadcastFn?.({ type: 'x402_payment', agent: agent.name, agentId: agent.id, flow: '402 -> sign -> settle -> 200', protocol: 'x402', amount: agent.price, currency: agent.currency, verification, txHash: txHash || null, explorerUrl: buildExplorerUrl(txHash), timestamp: new Date().toISOString(), }) - } - - return { - result: data.result || JSON.stringify(data), - paymentMethod: 'x402', - paymentSuccess: !settlementFailed, - paidVia: !settlementFailed ? 'x402' : 'none', - txHash: !settlementFailed ? txHash || null : null, - explorerUrl: !settlementFailed ? buildExplorerUrl(txHash) : null, - warning: - !settlementFailed && !txHash - ? 'x402 settlement completed without transaction hash header' - : undefined, - } + return { + result: data.result ?? JSON.stringify(data), + paymentMethod: 'x402', + paymentSuccess: true, + paidVia: 'x402', + txHash: txHash || null, + explorerUrl: buildExplorerUrl(txHash), + warning: !txHash + ? 'x402 settlement completed without transaction hash header' + : undefined, + } + } + } else { + const responseExcerpt = + typeof data === 'string' ? data.substring(0, 120) : JSON.stringify(data).substring(0, 120) + const reason = `x402 endpoint returned ${response.status}: ${responseExcerpt}` + broadcastFn?.({ + type: 'x402_retry', + agent: agent.name, + agentId: agent.id, + reason, + fallback: true, + timestamp: new Date().toISOString(), + }) + console.warn(` ${reason}`) } - - const responseExcerpt = - typeof data === 'string' ? data.substring(0, 120) : JSON.stringify(data).substring(0, 120) - const reason = `x402 endpoint returned ${response.status}: ${responseExcerpt}` - broadcastFn?.({ - type: 'x402_retry', - agent: agent.name, - agentId: agent.id, - reason, - fallback: true, - timestamp: new Date().toISOString(), - }) - console.warn(` ${reason}`)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/agents/orchestrator.js` around lines 198 - 242, The code treats a reported x402 settlement failure as a completed path by broadcasting an x402_retry with fallback: true and then immediately returning; instead, when parseSettlementHeader/extractTxHash indicate settlementFailed you should broadcast the failure without claiming fallback (remove or set fallback:false) and avoid returning from this x402 branch so the subsequent XLM fallback logic can run; concretely, keep the broadcastFn call (use agent.name/agent.id/reason) but remove the immediate return branch that builds and returns the x402 result, only return inside the successful (else) branch where verification is set, and let the function continue to the XLM fallback handling when settlementFailed is true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/lint.yml:
- Around line 12-14: The workflow's matrix syntax is invalid because
strategy.matrix.node-version is set to a scalar; either remove the matrix block
and set node-version directly under jobs.<job>.runs-on/steps, or change
strategy.matrix.node-version to an array (e.g., node-version: [22]); update the
YAML to use strategy.matrix.node-version: [22] if you want to keep the matrix,
or eliminate the entire strategy.matrix section and place node-version: 22
directly where the job's setup-node action reads it.
In `@convert-to-mp4.js`:
- Around line 60-64: The fallback path that uses execSync to create
tmpDir/frame_0000.png pushes a frame with only duration, causing writeFileSync
later to crash because frames[i].data is undefined; modify the fallback in
convert-to-mp4.js so after running execSync(`dwebp ... -o frame_0000.png`) you
read the generated PNG into memory (fs.readFileSync(path.join(tmpDir,
'frame_0000.png'))) and set frames.push({ duration: 1000, data: <buffer> }) so
subsequent code that calls writeFileSync(..., frames[i].data) succeeds; apply
the same change to the alternate fallback at lines 68-71.
- Line 63: Replace shell-string execSync calls with non-shell variants that pass
the program and arguments as an array and validate/escape input paths: stop
using execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir,
'frame_0000.png')}"`) and instead use child_process.execFileSync or spawnSync
with the executable ('dwebp') and an args array [inputWebp, '-o',
path.join(tmpDir, 'frame_0000.png')]; do the same for the per-frame ffmpeg
invocation (the loop that runs ffmpeg for each frame) and the final ffmpeg
stitch command (the calls building the full ffmpeg command near where outputMp4
is used). Also validate that inputWebp/outputMp4/tmpDir are safe (e.g.,
path.isAbsolute or whitelist) before executing and avoid shell:true so filenames
with metacharacters cannot be interpreted by the shell.
In `@package.json`:
- Around line 15-16: Remove the unsupported CLI option --ext from the npm
scripts "lint" and "lint:fix" in package.json because eslint is using flat
config (eslint.config.js) which already scopes files via files:
['**/*.{js,mjs,cjs}']; update the "lint" script to just run eslint . and the
"lint:fix" script to run eslint . --fix so ESLint runs with the flat config
without the incompatible --ext flag.
In `@README.md`:
- Around line 129-141: Add the missing npm script entry for "npm run
format:check" to the commands table so docs match the package/CI; specifically
update the README table (the Commands/Purpose rows shown) to include a row with
the unique script name "npm run format:check" and a concise purpose like "Check
formatting with Prettier (no file changes)" so readers and CI references align
with the repository's non-mutating Prettier check.
In `@src/agents/orchestrator.js`:
- Around line 231-232: The current return in the orchestrator rewrites
legitimate falsy agent results by using the || operator on data.result; change
the expression in the return object (the result field in the function that
returns { result: ... }) to use nullish coalescing (??) so that only null or
undefined trigger JSON.stringify(data), preserving '', 0, and false.
In `@src/server.js`:
- Around line 311-313: The current expression using parseFloat(budget) || 0.15
treats 0 as falsy and incorrectly substitutes the default; change it to parse
the budget and only fall back when the parsed value is NaN (e.g.
parseFloat/Number.parseFloat into a let/const and use Number.isNaN or
Number.isFinite to decide the default). Update the occurrence that defines
budgetNum (and the analogous occurrence around lines 323-325) so that a
caller-supplied 0 is preserved while non-numeric inputs still default to 0.15,
leaving the call to orchestrate(task, budgetNum, broadcast) unchanged.
In `@src/stellar/wallet.js`:
- Around line 84-86: The fundWithFriendbot helper currently returns { success:
true, data } unconditionally after calling response.json(); update
fundWithFriendbot to first check response.ok and only return success: true when
response.ok is true, otherwise read the error body (use response.text() or
response.json() safely) and return { success: false, status: response.status,
error: <body> } (or throw an Error) so callers can distinguish failure;
reference the fundWithFriendbot function, the response variable, and the
publicKey usage to locate and modify the logic.
---
Outside diff comments:
In `@src/agents/orchestrator.js`:
- Around line 198-242: The code treats a reported x402 settlement failure as a
completed path by broadcasting an x402_retry with fallback: true and then
immediately returning; instead, when parseSettlementHeader/extractTxHash
indicate settlementFailed you should broadcast the failure without claiming
fallback (remove or set fallback:false) and avoid returning from this x402
branch so the subsequent XLM fallback logic can run; concretely, keep the
broadcastFn call (use agent.name/agent.id/reason) but remove the immediate
return branch that builds and returns the x402 result, only return inside the
successful (else) branch where verification is set, and let the function
continue to the XLM fallback handling when settlementFailed is true.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 150f968a-fc7e-4cb3-a6b0-57bb1503768a
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (25)
.github/workflows/lint.yml.prettierignore.prettierrcCONTRIBUTING.mdDEMO_RECORDING_SCRIPT.mdREADME.mdconvert-to-mp4.jseslint.config.jspackage.jsonpublic/index.htmlrecord_demo.jssrc/agents/orchestrator.jssrc/agents/registry.jssrc/agents/services.jssrc/config.jssrc/demo-preflight.jssrc/demo.jssrc/generate-demo-voiceover.jssrc/middleware/errorHandler.jssrc/record-demo-video.jssrc/render-narrated-demo.jssrc/server.jssrc/setup-usdc.jssrc/setup-wallets.jssrc/stellar/wallet.js
| strategy: | ||
| matrix: | ||
| node-version: 22 |
There was a problem hiding this comment.
Fix matrix syntax error.
The node-version value should be an array when using a matrix strategy. Currently, it's a plain value which will cause the workflow to fail.
🔧 Proposed fix (Option 1 - recommended: remove matrix since only one version)
runs-on: ubuntu-latest
- strategy:
- matrix:
- node-version: 22
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
- node-version: ${{ matrix.node-version }}
+ node-version: 22
cache: "npm"🔧 Alternative fix (Option 2: keep matrix with proper syntax)
strategy:
matrix:
- node-version: 22
+ node-version: [22]📝 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.
| strategy: | |
| matrix: | |
| node-version: 22 | |
| strategy: | |
| matrix: | |
| node-version: [22] |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 14-14: expecting a single ${{...}} expression or array value for matrix variations, but found plain text node
(syntax-check)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/lint.yml around lines 12 - 14, The workflow's matrix
syntax is invalid because strategy.matrix.node-version is set to a scalar;
either remove the matrix block and set node-version directly under
jobs.<job>.runs-on/steps, or change strategy.matrix.node-version to an array
(e.g., node-version: [22]); update the YAML to use strategy.matrix.node-version:
[22] if you want to keep the matrix, or eliminate the entire strategy.matrix
section and place node-version: 22 directly where the job's setup-node action
reads it.
| if (frames.length === 0) { | ||
| console.error('No frames found. Trying alternative method...'); | ||
| console.error('No frames found. Trying alternative method...') | ||
| // Try using dwebp if available | ||
| execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir, 'frame_0000.png')}"`, { stdio: 'pipe' }); | ||
| frames.push({ duration: 1000 }); | ||
| execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir, 'frame_0000.png')}"`, { stdio: 'pipe' }) | ||
| frames.push({ duration: 1000 }) |
There was a problem hiding this comment.
Fix the zero-frame fallback path.
When no ANMF chunks are found, this creates a PNG directly with dwebp but still pushes a frame object with no data. The next loop then calls writeFileSync(..., frames[i].data) and the fallback path crashes instead of recovering.
Suggested fix
if (frames.length === 0) {
console.error('No frames found. Trying alternative method...')
// Try using dwebp if available
- execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir, 'frame_0000.png')}"`, { stdio: 'pipe' })
- frames.push({ duration: 1000 })
+ const fallbackPng = path.join(tmpDir, 'frame_00000.png')
+ execSync(`dwebp "${inputWebp}" -o "${fallbackPng}"`, { stdio: 'pipe' })
+ frames.push({ duration: 1000, pngReady: true })
}
@@
for (let i = 0; i < frames.length; i++) {
const framePath = path.join(tmpDir, `frame_${String(i).padStart(5, '0')}.webp`)
const pngPath = path.join(tmpDir, `frame_${String(i).padStart(5, '0')}.png`)
- fs.writeFileSync(framePath, frames[i].data)
+ if (frames[i].pngReady) continue
+ fs.writeFileSync(framePath, frames[i].data)Also applies to: 68-71
🧰 Tools
🪛 OpenGrep (1.22.0)
[ERROR] 63-63: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@convert-to-mp4.js` around lines 60 - 64, The fallback path that uses execSync
to create tmpDir/frame_0000.png pushes a frame with only duration, causing
writeFileSync later to crash because frames[i].data is undefined; modify the
fallback in convert-to-mp4.js so after running execSync(`dwebp ... -o
frame_0000.png`) you read the generated PNG into memory
(fs.readFileSync(path.join(tmpDir, 'frame_0000.png'))) and set frames.push({
duration: 1000, data: <buffer> }) so subsequent code that calls
writeFileSync(..., frames[i].data) succeeds; apply the same change to the
alternate fallback at lines 68-71.
| // Try using dwebp if available | ||
| execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir, 'frame_0000.png')}"`, { stdio: 'pipe' }); | ||
| frames.push({ duration: 1000 }); | ||
| execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir, 'frame_0000.png')}"`, { stdio: 'pipe' }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the file
fd -a "convert-to-mp4.js" . || true
# If found, print the relevant sections with line numbers
FILE="$(fd -a "convert-to-mp4.js" . | head -n1 || true)"
if [ -z "${FILE}" ]; then
echo "convert-to-mp4.js not found"
exit 0
fi
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,140p'
nl -ba "$FILE" | sed -n '140,260p'Repository: Flamki/stellarmind
Length of output: 210
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="$(fd -a "convert-to-mp4.js" . | head -n1 || true)"
echo "== File: $FILE =="
# Show file with line numbers around the reported areas
python3 - <<'PY'
import pathlib, itertools, sys, os
path = os.environ.get("FILE")
p = pathlib.Path(path)
lines = p.read_text(errors="replace").splitlines()
def show(a,b):
for i in range(a-1,b):
if 0 <= i < len(lines):
print(f"{i+1}:{lines[i]}")
show(50,110)
PY
echo "== execSync occurrences =="
rg -n --fixed-string "execSync" "$FILE" || true
echo "== execFileSync occurrences =="
rg -n --fixed-string "execFileSync" "$FILE" || true
echo "== Inputs (try to spot where inputWebp/framePath/pgnPath/outputMp4/fps come from) =="
rg -n "inputWebp|framePath|pngPath|outputMp4|fps" "$FILE" || trueRepository: Flamki/stellarmind
Length of output: 663
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="$(fd -a "convert-to-mp4.js" . | head -n1 || true)"
echo "== File: $FILE =="
python3 - <<'PY'
import os, pathlib
p = pathlib.Path(os.environ["FILE"])
lines = p.read_text(errors="replace").splitlines()
def show(a,b):
a=max(1,a); b=min(b,len(lines))
for i in range(a-1,b):
print(f"{i+1}:{lines[i]}")
show(1,130)
PY
echo "== execSync occurrences =="
rg -n --fixed-string "execSync" "$FILE" || true
echo "== execFileSync occurrences =="
rg -n --fixed-string "execFileSync" "$FILE" || true
echo "== Inputs (try to spot where inputWebp/framePath/pngPath/outputMp4/fps come from) =="
rg -n "inputWebp|framePath|pngPath|outputMp4|fps" "$FILE" || trueRepository: Flamki/stellarmind
Length of output: 266
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="$(fd -a "convert-to-mp4.js" . | head -n1 || true)"
echo "== File: $FILE =="
python3 - <<PY
import pathlib
p = pathlib.Path(r"""$FILE""")
lines = p.read_text(errors="replace").splitlines()
def show(a,b):
a=max(1,a); b=min(b,len(lines))
for i in range(a-1,b):
print(f"{i+1}:{lines[i]}")
# show the relevant ranges around the review comment
show(50,110)
print("== middle ==")
show(70,110)
print("== later ==")
show(90,130)
PY
echo "== execSync occurrences =="
rg -n --fixed-string "execSync" "$FILE" || true
echo "== execFileSync occurrences =="
rg -n --fixed-string "execFileSync" "$FILE" || true
echo "== relevant variable assignments/usages =="
rg -n "inputWebp|framePath|pngPath|outputMp4|fps" "$FILE" || true
echo "== any 'shell:' options in execSync calls =="
rg -n "execSync\\(|shell\\s*:" "$FILE" || trueRepository: Flamki/stellarmind
Length of output: 7693
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="$(fd -a "convert-to-mp4.js" . | head -n1 || true)"
echo "== File: $FILE =="
python3 - <<PY
import pathlib, os
p = pathlib.Path(r"""$FILE""")
lines = p.read_text(errors="replace").splitlines()
for i in range(1,50):
if i <= len(lines):
print(f"{i}:{lines[i-1]}")
PY
python3 - <<PY
import pathlib, os
p = pathlib.Path(r"""$FILE""")
lines = p.read_text(errors="replace").splitlines()
# show around where tmpDir/outputMp4 are defined
for i in range(1,30):
if i <= len(lines):
print(f"{i}:{lines[i-1]}")
print("---")
for i in range(10,40):
if i <= len(lines):
print(f"{i}:{lines[i-1]}")
PYRepository: Flamki/stellarmind
Length of output: 4407
Fix command injection risk in convert-to-mp4.js by avoiding execSync shell-interpreted command strings for CLI paths.
inputWebp and outputMp4 come directly from process.argv, and their derived paths are interpolated into template-literal command strings passed to execSync (shell-interpreted). Shell metacharacters (e.g., $(), backticks) and unescaped quotes in filenames can lead to arbitrary command execution. This occurs at the dwebp call (line 63), the per-frame ffmpeg call (line 74), and the final ffmpeg stitch call (lines 96-99).
Suggested fix
-import { execSync } from 'child_process'
+import { execFileSync } from 'child_process'
@@
- execSync(`dwebp "${inputWebp}" -o "${path.join(tmpDir, 'frame_0000.png')}"`, { stdio: 'pipe' })
+ execFileSync('dwebp', [inputWebp, '-o', path.join(tmpDir, 'frame_0000.png')], {
+ stdio: 'pipe',
+ })
@@
- execSync(`ffmpeg -y -i "${framePath}" "${pngPath}" 2>&1`, { stdio: 'pipe' })
+ execFileSync('ffmpeg', ['-y', '-i', framePath, pngPath], { stdio: 'pipe' })
@@
- execSync(
- `ffmpeg -y -framerate ${fps} -i "${path.join(tmpDir, 'frame_%05d.png')}" -c:v libx264 -pix_fmt yuv420p -crf 23 -movflags +faststart "${outputMp4}"`,
- { stdio: 'inherit' }
- )
+ execFileSync(
+ 'ffmpeg',
+ [
+ '-y',
+ '-framerate',
+ String(fps),
+ '-i',
+ path.join(tmpDir, 'frame_%05d.png'),
+ '-c:v',
+ 'libx264',
+ '-pix_fmt',
+ 'yuv420p',
+ '-crf',
+ '23',
+ '-movflags',
+ '+faststart',
+ outputMp4,
+ ],
+ { stdio: 'inherit' }
+ )🧰 Tools
🪛 OpenGrep (1.22.0)
[ERROR] 63-63: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@convert-to-mp4.js` at line 63, Replace shell-string execSync calls with
non-shell variants that pass the program and arguments as an array and
validate/escape input paths: stop using execSync(`dwebp "${inputWebp}" -o
"${path.join(tmpDir, 'frame_0000.png')}"`) and instead use
child_process.execFileSync or spawnSync with the executable ('dwebp') and an
args array [inputWebp, '-o', path.join(tmpDir, 'frame_0000.png')]; do the same
for the per-frame ffmpeg invocation (the loop that runs ffmpeg for each frame)
and the final ffmpeg stitch command (the calls building the full ffmpeg command
near where outputMp4 is used). Also validate that inputWebp/outputMp4/tmpDir are
safe (e.g., path.isAbsolute or whitelist) before executing and avoid shell:true
so filenames with metacharacters cannot be interpreted by the shell.
| "lint": "eslint . --ext .js,.mjs,.cjs", | ||
| "lint:fix": "eslint . --ext .js,.mjs,.cjs --fix", |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Is the --ext flag deprecated in ESLint 10 when using flat config?
💡 Result:
The --ext flag is not explicitly documented as deprecated in ESLint 10, but it is effectively obsolete and unnecessary when using flat config [1]. In the legacy configuration system (.eslintrc), the --ext flag was required to define which file extensions ESLint should process [2][1]. However, with flat config (which is the only supported configuration format in ESLint 10), file processing is controlled directly within the eslint.config.js file using the files property [1]. Because flat config makes file matching explicit via your configuration file, the CLI no longer relies on the --ext flag to determine which files to lint [1]. While the flag may still exist in the CLI interface [3], it serves no purpose in a flat config environment, as the configuration itself defines the scope and types of files that the linter should process [1]. Migrating to flat config means replacing --ext usage with explicit glob patterns in your configuration [1].
Citations:
- 1: https://raulmelo.me/en/blog/migration-eslint-to-flat-config
- 2: https://allalmohamedlamine.medium.com/eslint-flat-config-and-new-system-an-ultimate-deep-dive-2023-46aa151cbf2b
- 3: https://eslint.org/docs/latest/use/command-line-interface
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package.json scripts (lines ~1-120) =="
ls -la package.json || true
sed -n '1,120p' package.json | nl -ba | sed -n '1,120p'
echo
echo "== find eslint config files =="
ls -la eslint.config.* .eslintrc* 2>/dev/null || true
fd -t f -a -ejs -ejson -ejsx -ets -ejs -e.mjs -e.cjs -ects -ejs -g "eslint.config.*" . || true
fd -t f -g "*eslint*" . | head -n 50
echo
echo "== eslint.config.js / mjs / cjs (show matching files only) =="
for f in eslint.config.js eslint.config.mjs eslint.config.cjs; do
if [ -f "$f" ]; then
echo "--- $f (first 200 lines) ---"
sed -n '1,200p' "$f" | nl -ba
fi
doneRepository: Flamki/stellarmind
Length of output: 227
🌐 Web query:
ESLint CLI --ext flag flat config eslint.config.js deprecated
💡 Result:
The --ext CLI flag is no longer supported when using ESLint's flat config format (eslint.config.js), which became the default in ESLint v9.0.0 [1][2][3]. In the previous eslintrc-based configuration system, the --ext flag was used to specify which file extensions ESLint should process when a directory was passed as an argument [4][5][3]. With flat config, this functionality has been removed because file matching is now handled entirely within the configuration file itself [2][3]. To define which file extensions or patterns ESLint should lint, you must now use the files property within your eslint.config.js file [2][3]. For example, if you previously used --ext.jsx, you would update your configuration to include a pattern that matches those files [2]: export default [ { files: ["/.jsx", "/.js"], //... rules } ]; When you run ESLint (e.g., npx eslint.), it will automatically apply the configuration to the files that match the patterns defined in your files array [2][3]. If you are still using a legacy setup and require the --ext flag, you must be using the older eslintrc format, which may require setting the ESLINT_USE_FLAT_CONFIG environment variable to false (though support for legacy configurations has been removed as of ESLint v10.0.0) [1][6][7].
Citations:
- 1: https://eslint.org/docs/latest/use/configure/migration-guide
- 2: Docs: Documents state that
--extis no longer supported, but do not say what it is replaced by / how it works now. eslint/eslint#17931 - 3: https://raulmelo.me/en/blog/migration-eslint-to-flat-config
- 4: https://eslint.org/docs/latest/use/command-line-interface
- 5: https://archive.eslint.org/docs/user-guide/command-line-interface
- 6: https://www.pkgpulse.com/guides/eslint-10-flat-config-migration-guide-2026
- 7: https://eslint.org/blog/2023/11/whats-coming-in-eslint-9.0.0/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package.json (scripts section) =="
# Print scripts keys around lint entries (avoid assuming line numbers)
awk '
BEGIN{in_scripts=0}
/"scripts"\s*:/ {in_scripts=1}
in_scripts {print}
in_scripts && /^\s*},/ {in_scripts=0; exit}
' package.json
echo
echo "== package.json lint commands =="
rg -n '"lint' package.json || true
echo
echo "== find ESLint config files =="
ls -la eslint.config.* .eslintrc* 2>/dev/null || true
fd -t f -a -ejs -ejson -ejs -ejson -e.mjs -e.cjs -ects -g "eslint.config.*" . || true
fd -t f -g "*eslint*" . | head -n 50Repository: Flamki/stellarmind
Length of output: 1075
🌐 Web query:
ESLint flat config --ext flag eslint.config.js supported or deprecated
💡 Result:
The --ext flag is not supported when using ESLint flat configuration (eslint.config.js) [1][2]. While the CLI reference still lists --ext, it is explicitly marked as "eslintrc Mode Only" [1][3]. In the flat config system, you must specify the file patterns you want to lint directly within your eslint.config.js file using the files property [1][4]. For example, to lint files with specific extensions such as.js,.ts, and.tsx, you would define them in your configuration object like this [4][2]: export default [ { files: ["/.js", "/.ts", "/*.tsx"], rules: { // your rules here } } ]; Once these patterns are defined in your configuration file, ESLint will automatically include those files when you run the CLI, making the use of the --ext flag unnecessary [1][5][2].
Citations:
- 1: Docs: Documents state that
--extis no longer supported, but do not say what it is replaced by / how it works now. eslint/eslint#17931 - 2: https://raulmelo.me/en/blog/migration-eslint-to-flat-config
- 3: https://eslint.org/docs/latest/use/command-line-interface
- 4: https://eslint.org/docs/latest/use/configure/configuration-files
- 5: https://allalmohamedlamine.medium.com/eslint-flat-config-and-new-system-an-ultimate-deep-dive-2023-46aa151cbf2b
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== eslint.config.js: first 220 lines =="
sed -n '1,220p' eslint.config.js
echo
echo "== eslint.config.js: grep for files/ignores/extensions scope =="
rg -n --hidden --no-ignore -S '"files"\s*:|files\s*:|ignores\s*:|ignorePatterns|--ext' eslint.config.js || trueRepository: Flamki/stellarmind
Length of output: 1002
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n '"eslint"\s*:' package.json && sed -n '1,120p' package.jsonRepository: Flamki/stellarmind
Length of output: 1756
Remove --ext from ESLint scripts (flat config)
eslint.config.js is using flat config and already limits scope via files: ['**/*.{js,mjs,cjs}'], while the CLI --ext option is eslintrc-mode only (not supported with flat config).
✨ Proposed fix
- "lint": "eslint . --ext .js,.mjs,.cjs",
- "lint:fix": "eslint . --ext .js,.mjs,.cjs --fix",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix",📝 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.
| "lint": "eslint . --ext .js,.mjs,.cjs", | |
| "lint:fix": "eslint . --ext .js,.mjs,.cjs --fix", | |
| "lint": "eslint .", | |
| "lint:fix": "eslint . --fix", |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@package.json` around lines 15 - 16, Remove the unsupported CLI option --ext
from the npm scripts "lint" and "lint:fix" in package.json because eslint is
using flat config (eslint.config.js) which already scopes files via files:
['**/*.{js,mjs,cjs}']; update the "lint" script to just run eslint . and the
"lint:fix" script to run eslint . --fix so ESLint runs with the flat config
without the incompatible --ext flag.
| | Command | Purpose | | ||
| | ------------------------- | ------------------------------------------------------- | | ||
| | `npm run dev` | Start local server | | ||
| | `npm run demo` | Run end-to-end demo flow | | ||
| | `npm run preflight` | Validate readiness (x402, wallets, model, payment path) | | ||
| | `npm run setup` | Generate/fund Stellar testnet wallets | | ||
| | `npm run setup:usdc` | Add USDC trustlines for settlement | | ||
| | `npm run lint` | Run ESLint against the repository | | ||
| | `npm run lint:fix` | Fix ESLint issues automatically | | ||
| | `npm run format` | Format source and docs with Prettier | | ||
| | `npm run record:video` | Capture website-only demo video | | ||
| | `npm run voiceover` | Generate narration track | | ||
| | `npm run record:narrated` | Full narrated demo render pipeline | |
There was a problem hiding this comment.
Document npm run format:check here too.
This table looks like the canonical command list, but the PR also adds a non-mutating Prettier check script. Leaving it out makes the docs drift from the actual npm surface and from the CI workflow.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@README.md` around lines 129 - 141, Add the missing npm script entry for "npm
run format:check" to the commands table so docs match the package/CI;
specifically update the README table (the Commands/Purpose rows shown) to
include a row with the unique script name "npm run format:check" and a concise
purpose like "Check formatting with Prettier (no file changes)" so readers and
CI references align with the repository's non-mutating Prettier check.
| return { | ||
| result: data.result || JSON.stringify(data), |
There was a problem hiding this comment.
Preserve falsy agent results.
Line 232 treats '', 0, and false as missing and replaces them with JSON.stringify(data). If an agent legitimately returns a falsy result, the orchestrator will rewrite the payload. Use nullish coalescing here instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/agents/orchestrator.js` around lines 231 - 232, The current return in the
orchestrator rewrites legitimate falsy agent results by using the || operator on
data.result; change the expression in the return object (the result field in the
function that returns { result: ... }) to use nullish coalescing (??) so that
only null or undefined trigger JSON.stringify(data), preserving '', 0, and
false.
| const budgetNum = parseFloat(budget) || 0.15 | ||
| const result = await orchestrate(task, budgetNum, broadcast) | ||
| res.json(result) |
There was a problem hiding this comment.
Preserve explicit zero budgets.
parseFloat(...) || 0.15 treats 0 as missing, so a caller asking for a zero budget gets the default 0.15 instead.
Suggested fix
- const budgetNum = parseFloat(budget) || 0.15
+ const parsedBudget = Number.parseFloat(budget)
+ const budgetNum = Number.isFinite(parsedBudget) ? parsedBudget : 0.15
const result = await orchestrate(task, budgetNum, broadcast)- const budget = parseFloat(req.query.budget) || 0.15
- const result = await orchestrate(task, budget, broadcast)
+ const parsedBudget = Number.parseFloat(req.query.budget)
+ const budget = Number.isFinite(parsedBudget) ? parsedBudget : 0.15
+ const result = await orchestrate(task, budget, broadcast)Also applies to: 323-325
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/server.js` around lines 311 - 313, The current expression using
parseFloat(budget) || 0.15 treats 0 as falsy and incorrectly substitutes the
default; change it to parse the budget and only fall back when the parsed value
is NaN (e.g. parseFloat/Number.parseFloat into a let/const and use Number.isNaN
or Number.isFinite to decide the default). Update the occurrence that defines
budgetNum (and the analogous occurrence around lines 323-325) so that a
caller-supplied 0 is preserved while non-numeric inputs still default to 0.15,
leaving the call to orchestrate(task, budgetNum, broadcast) unchanged.
| const response = await fetch(`https://friendbot.stellar.org?addr=${publicKey}`) | ||
| const data = await response.json() | ||
| return { success: true, data } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and display the relevant section of src/stellar/wallet.js
ls -la
sed -n '1,200p' src/stellar/wallet.js | nl -ba | sed -n '1,200p'
echo "----"
# show around the reported lines 70-110 with line numbers
sed -n '60,130p' src/stellar/wallet.js | nl -ba | sed -n '60,130p'
echo "----"
# search for fundWithFriendbot usage
rg -n "fundWithFriendbot" -S .Repository: Flamki/stellarmind
Length of output: 2087
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ls -la
# show file with line numbers (limited)
sed -n '1,220p' src/stellar/wallet.js | nl -ba | sed -n '1,220p'
echo "----"
# show around reported lines
sed -n '70,130p' src/stellar/wallet.js | nl -ba | sed -n '70,130p'
echo "----"
# find callers
rg -n "fundWithFriendbot" -S .Repository: Flamki/stellarmind
Length of output: 2087
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Basic sanity
ls -la src/stellar || true
echo "----"
# Show wallet.js with line numbers around the reported region
awk 'NR>=1 && NR<=220 {printf "%4d\t%s\n", NR, $0}' src/stellar/wallet.js | sed -n '1,220p'
echo "---- region 70-130 ----"
awk 'NR>=60 && NR<=140 {printf "%4d\t%s\n", NR, $0}' src/stellar/wallet.js
echo "----"
# Find fundWithFriendbot definition and usages
rg -n "function fundWithFriendbot|fundWithFriendbot\s*\(" -S src/stellar/wallet.js src || true
rg -n "fundWithFriendbot" -S src || trueRepository: Flamki/stellarmind
Length of output: 9000
🏁 Script executed:
#!/bin/bash
set -euo pipefail
awk 'NR>=1 && NR<=140 {printf "%4d\t%s\n", NR, $0}' src/setup-wallets.js | sed -n '1,140p'
echo "----"
sed -n '1,120p' src/setup-wallets.js | nl -ba 2>/dev/null || trueRepository: Flamki/stellarmind
Length of output: 5634
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "export async function fundWithFriendbot|fundWithFriendbot\(" src
rg -n "from ['\"]\.{1,2}/stellar/wallet['\"]|from ['\"].*/stellar/wallet['\"]" src || true
rg -n "fundWithFriendbot" -S srcRepository: Flamki/stellarmind
Length of output: 872
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "from ['\"].*stellar/wallet['\"]" -S src . || true
rg -n "import\s*\{[^}]*\bfundWithFriendbot\b[^}]*\}\s*from\s*['\"].*stellar/wallet['\"]" -S src . || true
rg -n "import\s*['\"].*stellar/wallet['\"]" -S src . || true
rg -n "fundWithFriendbot\(" -S src . || trueRepository: Flamki/stellarmind
Length of output: 882
Check Friendbot HTTP status before marking funding as successful.
src/stellar/wallet.js’s exported fundWithFriendbot returns { success: true, data } after response.json() without checking response.ok, so non-2xx Friendbot responses would still be treated as success.
Note: this exported helper isn’t referenced elsewhere in the repo (the setup script uses its own res.ok-checked Friendbot call in src/setup-wallets.js), but fixing it prevents incorrect results for any external callers.
Suggested fix
try {
const response = await fetch(`https://friendbot.stellar.org?addr=${publicKey}`)
const data = await response.json()
+ if (!response.ok) {
+ return {
+ success: false,
+ error: data?.detail || data?.error || `Friendbot request failed with status ${response.status}`,
+ }
+ }
return { success: true, data }
} catch (err) {
return { success: false, error: err.message }
}📝 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.
| const response = await fetch(`https://friendbot.stellar.org?addr=${publicKey}`) | |
| const data = await response.json() | |
| return { success: true, data } | |
| const response = await fetch(`https://friendbot.stellar.org?addr=${publicKey}`) | |
| const data = await response.json() | |
| if (!response.ok) { | |
| return { | |
| success: false, | |
| error: data?.detail || data?.error || `Friendbot request failed with status ${response.status}`, | |
| } | |
| } | |
| return { success: true, data } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/stellar/wallet.js` around lines 84 - 86, The fundWithFriendbot helper
currently returns { success: true, data } unconditionally after calling
response.json(); update fundWithFriendbot to first check response.ok and only
return success: true when response.ok is true, otherwise read the error body
(use response.text() or response.json() safely) and return { success: false,
status: response.status, error: <body> } (or throw an Error) so callers can
distinguish failure; reference the fundWithFriendbot function, the response
variable, and the publicKey usage to locate and modify the logic.
|
@ChubbyMmoh could you plz resove this issues and fix conflicts |
|
@ChubbyMmoh Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
hello @Flamki |
feat: add ESLint + Prettier support, npm lint/format scripts, and CI format check
Summary
Added ESLint and Prettier integration for consistent code style. Added
npm run lint,npm run lint:fix,npm run format, andnpm run format:check. Updated lint.yml to run both ESLint and Prettier checks in CI.Validation
Checklist
Completed: Create .prettierignore file. (10/10)
Closes #8

Summary by CodeRabbit
New Features
Chores
Documentation
Bug Fixes