Skip to content

feat: chat wizard UI and validation stabilization#573

Open
felippepestana wants to merge 3 commits intoSynkraAI:mainfrom
felippepestana:codex/chat-wizard-interface
Open

feat: chat wizard UI and validation stabilization#573
felippepestana wants to merge 3 commits intoSynkraAI:mainfrom
felippepestana:codex/chat-wizard-interface

Conversation

@felippepestana
Copy link

@felippepestana felippepestana commented Mar 9, 2026

Summary

  • add a new interactive web-app chat interface with Preview/Code tabs
  • implement guided project-classification flow (PRD/playbook/stack/agents)
  • add parity/integration validation scripts for Claude/Codex/Gemini
  • adjust ESLint and Jest config for browser files and nested workspace handling
  • document the web planning UI as an optional UI Third layer and add web:install, web:dev, and web:build scripts

Validation

  • npm run lint
  • npm run typecheck
  • npm run validate:parity
  • npm run test:health-check
  • npm run web:build

Notes

  • the repository README already positions planning UI as part of the workflow, while keeping CLI as the source of truth
  • this PR aligns the new web-app/ with that architecture instead of treating it as a separate product

Summary by CodeRabbit

  • New Features

    • Introduced AIOS Studio Chat web UI with guided "Novo Projeto" wizard and local bridge server for document processing
    • Added several CLI validation tools for AI integrations and a parity validation suite
  • Documentation

    • Added comprehensive skill docs for multiple agent roles and updated IDE compatibility status
  • Chores

    • New npm scripts for web workflow and validation; updated ESLint and Jest configs for web-app integration

felippepestana and others added 2 commits March 1, 2026 21:25
…act violations

- Add npm run validate:parity script to package.json
- Add IDE compatibility status table to docs/ide-integration.md (Works/Limited)
- Generate 12 Codex skills in .codex/skills/ via codex-skills-sync

Fixes: codex-integration, codex-skills, and docs matrix checks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 9, 2026

@felippepestana is attempting to deploy a commit to the Pedro Valério Lopez's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d262d68-2c9a-4b55-98a3-7b84fba56c10

📥 Commits

Reviewing files that changed from the base of the PR and between 2fd6bb2 and a534119.

📒 Files selected for processing (2)
  • README.md
  • package.json
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

Walkthrough

Adds multiple IDE integration validators, numerous AIOS agent skill documents, a new web-app with guided project wizard and bridge server, ESLint/Jest/package.json updates, and a minor parameter rename in the LayerProcessor base class.

Changes

Cohort / File(s) Summary
IDE Integration Validators
.aios-core/infrastructure/scripts/validate-claude-integration.js, .aios-core/infrastructure/scripts/validate-codex-integration.js, .aios-core/infrastructure/scripts/validate-gemini-integration.js, .aios-core/infrastructure/scripts/validate-parity.js
Added four CLI/module validation scripts for Claude, Codex, Gemini, and overall parity. Implement arg parsing (--quiet, --json), file-count utilities, existence checks, human/JSON reports, and exported validator functions.
Agent Skill Documentation
.codex/skills/aios-*/SKILL.md
(e.g., aios-analyst, aios-architect, aios-data-engineer, aios-dev, aios-devops, aios-master, aios-pm, aios-po, aios-qa, aios-sm, aios-squad-creator, aios-ux-design-expert)
Added twelve new SKILL.md files defining personas, activation protocols, starter commands, and non-negotiables. Documentation-only additions with consistent structure across files.
Build & Config
eslint.config.js, jest.config.js, package.json
ESLint: added aios-core/** ignore and browser config for web-app/**/*.js. Jest: added modulePathIgnorePatterns to ignore <rootDir>/aios-core/. package.json: added web:install, web:build, web:dev, and validate:parity scripts.
Core minor change
.aios-core/core/synapse/layers/layer-processor.js
Renamed method parameter from process(context) to process(_context) to mark parameter as unused; wrapper behavior unchanged.
Web Application
web-app/index.html, web-app/main.js, web-app/style.css, web-app/bridge-server.cjs, web-app/package.json, web-app/.gitignore
New web UI and assets: index.html layout, main.js implements multi-step guided project wizard and artifact generation, style.css UI styling/responsive rules, bridge-server.cjs HTTP API for OCR + metadata + name generation, package.json for Vite, and .gitignore.
Documentation
docs/ide-integration.md, README.md
Added "AIOS Compatibility Status" table to docs and duplicated a brief "Interface Web de Planejamento" section in README.md.

Sequence Diagram(s)

sequenceDiagram
    participant Web as Web App
    participant Server as Bridge Server
    participant OCR as Document Processor
    participant Engine as NamingEngine

    Web->>Server: POST /api/process { filePath, lang }
    activate Server
    Server->>OCR: processDocument(filePath, lang)
    activate OCR
    OCR-->>Server: ocrResult (text)
    deactivate OCR

    Server->>Engine: extractMetadataAI(ocrText)
    activate Engine
    Engine-->>Server: metadata (object)
    deactivate Engine

    Server->>Engine: generateName(basename, metadata)
    activate Engine
    Engine-->>Server: suggestedName
    deactivate Engine

    Server-->>Web: { success, ocr, metadata, suggestedName }
    deactivate Server
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main additions: a new chat wizard UI component and multiple validation scripts for integration testing across IDE platforms.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🧹 Nitpick comments (3)
eslint.config.js (2)

169-182: Consider adding additional browser globals for completeness.

The browser app configuration covers essential globals, but the web-app may use additional browser APIs. Consider adding commonly used globals to prevent false no-undef errors as the app grows.

♻️ Optional enhancement for broader browser API coverage
   // Browser app files
   {
     files: ['web-app/**/*.js'],
     languageOptions: {
       sourceType: 'module',
       globals: {
         document: 'readonly',
         window: 'readonly',
         navigator: 'readonly',
         fetch: 'readonly',
         location: 'readonly',
+        localStorage: 'readonly',
+        sessionStorage: 'readonly',
+        history: 'readonly',
+        CustomEvent: 'readonly',
+        URLSearchParams: 'readonly',
+        URL: 'readonly',
+        console: 'readonly',
+        setTimeout: 'readonly',
+        setInterval: 'readonly',
+        clearTimeout: 'readonly',
+        clearInterval: 'readonly',
+        requestAnimationFrame: 'readonly',
       },
     },
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.js` around lines 169 - 182, The web-app ESLint config for files
matching 'web-app/**/*.js' currently defines a few browser globals under
languageOptions.globals; expand this list to include commonly used browser APIs
(e.g., localStorage, sessionStorage, console, alert, confirm, history, location
(already present), URL, navigator (already present), AbortController, DOMParser,
FormData, File, Blob) to avoid false no-undef errors as the app grows—update the
languageOptions.globals object in the ESLint config to add these entries with
'readonly' where appropriate.

192-193: Remove trailing blank lines.

Two empty lines at the end of the file. Most style guides prefer a single trailing newline.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.js` around lines 192 - 193, Remove the extra trailing blank
line(s) at the end of eslint.config.js so the file ends with a single newline
character; locate the end-of-file (EOF) and delete the extra empty lines so
there is only one final newline.
web-app/index.html (1)

40-48: Give the Preview/Código switch real tab semantics.

These controls are visually tabs but only toggle CSS classes. Without role="tablist", role="tab", role="tabpanel", aria-selected, and aria-controls, assistive tech cannot identify the active panel. Keep those ARIA states in sync in the click handler as well.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-app/index.html` around lines 40 - 48, Assign proper ARIA roles and
attributes to the tab markup and keep them in sync in the click handler: mark
the container with role="tablist" (the element with class "tabs"), give each
button role="tab" and add aria-selected="true"/"false" and aria-controls
referencing the panel IDs ("previewTab" and "codeTab"), and mark the panels with
role="tabpanel" and id attributes ("previewTab", "codeTab") and aria-hidden
toggled accordingly; update the click handler that toggles the "active" class on
elements with class "tab" and panels "previewTab"/"codeTab" to also set
aria-selected on the buttons and aria-hidden on the panels so assistive tech
sees the currently active tab and associated panel.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.aios-core/infrastructure/scripts/validate-parity.js:
- Around line 299-321: Wrap the potentially-throwing contract loads and
validator executions in try/catch so a single exception doesn't crash the CLI:
when calling loadContract (and the fallback deps.loadCompatibilityContract)
around resolvedContractPath and resolvedDiffPath, catch errors and push a
contract violation entry into the contractViolations array (include file/path
and error.message) and set the corresponding contract variable to null;
likewise, change the checks mapping so each check.exec() call (e.g., runSync,
runClaudeIntegration, runCodexIntegration, runGeminiIntegration, runCodexSkills,
runPaths, etc.) is invoked inside a try/catch and on error return a failed check
result object with id: check.id, success: false, errors: [error.message] (so
normalizeResult still handles it safely) instead of letting the exception bubble
up.

In @.codex/skills/aios-architect/SKILL.md:
- Line 3: The YAML frontmatter's description field in SKILL.md is truncated
("...API design (REST/GraphQL/tRPC/We..."); update the description line in the
YAML frontmatter (the `description:` value) to a full, readable sentence that
lists the intended topics (e.g., API design including REST, GraphQL, tRPC,
WebSockets), and any other key areas the skill covers such as fullstack
architecture, backend/frontend patterns, infrastructure, CI/CD, scalability, and
security so the frontmatter is complete and clear.
- Line 9: The "When To Use" section currently ends with a truncated list ("Use
for system architecture (fullstack, backend, frontend, infrastructure),
technology stack selection (technical evaluation), API design
(REST/GraphQL/tRPC/WebSocket), security architecture, performance
optimization,...") — expand this sentence to a complete, parallel list by
replacing the trailing ellipsis with concrete items (e.g., scalability planning,
fault tolerance, observability/monitoring, deployment/CI-CD strategies, cost/ops
tradeoffs) or end with a clear closing phrase like "and related architectural
and technical decision-making," ensuring the entry in SKILL.md's "When To Use"
section reads as a complete, grammatically correct sentence.

In @.codex/skills/aios-data-engineer/SKILL.md:
- Around line 17-25: The SKILL.md "Starter Commands" list (entries: *help,
*guide, *yolo, *exit, *doc-out, *execute-checklist, *create-schema,
*create-rls-policies) is not reflected in the canonical data-engineer agent
activation metadata (the data-engineer agent), so either add a proper "commands"
section to the data-engineer agent metadata that defines these exact commands
and their handlers, or prune SKILL.md to only list commands actually implemented
by the data-engineer agent; ensure the authoritative source (the data-engineer
agent metadata) and SKILL.md remain identical and include short descriptions for
each command.
- Line 12: Update the source-of-truth order so the local Codex agent is primary:
in .codex/skills/aios-data-engineer/SKILL.md replace the current "Load
`.aios-core/development/agents/data-engineer.md` as source of truth (fallback:
`.codex/agents/data-engineer.md`)" ordering with the local-first phrase "Load
`.codex/agents/data-engineer.md` as source of truth (fallback:
`.aios-core/development/agents/data-engineer.md`)" so the skill prefers the
versioned local agent before falling back to the .aios-core copy.

In @.codex/skills/aios-devops/SKILL.md:
- Around line 2-3: The front-matter "description" in
.codex/skills/aios-devops/SKILL.md is truncated with "..." so metadata views
show a cut-off summary; update the YAML front-matter "description" value to the
full, complete capability/authorization statement (remove the ellipsis and paste
the entire text used in the skill body or intended full sentence) so the skill
picker and metadata display the full description.

In @.codex/skills/aios-master/SKILL.md:
- Line 6: The top-level heading contains a duplicated "AIOS" ("# AIOS AIOS
Master Orchestrator & Framework Developer Activator"); update the heading to
remove the redundant token so it reads "# AIOS Master Orchestrator & Framework
Developer Activator" (i.e., delete the extra "AIOS" in the title string).

In @.codex/skills/aios-pm/SKILL.md:
- Line 3: The frontmatter "description" value in SKILL.md is truncated
("...roa..."); update the YAML frontmatter's description field to the full,
uncropped text (matching the complete phrasing used elsewhere, e.g., the similar
description on line 9) so it no longer contains ellipses and accurately
describes the Product Manager (Morgan) skill including PRD creation, epic
management, product strategy, feature prioritization (MoSCoW, RICE), roadmaps,
and any other intended items.
- Line 9: The "When To Use" sentence in .codex/skills/aios-pm/SKILL.md is
truncated at "go/no-go decisions, scop..."; open the "When To Use" section and
complete the phrase (e.g., "go/no-go decisions, scope definition and management,
release planning, and stakeholder alignment") so the list reads coherently;
update the truncated fragment where it appears and verify the sentence ends
cleanly and the rest of the paragraph is intact.

In @.codex/skills/aios-sm/SKILL.md:
- Around line 2-9: The YAML description for the skill (name: aios-sm) and the
"When To Use" paragraph under the "AIOS Scrum Master Activator" header contain
truncated text ending with "..."—replace these with complete, user-facing copy:
update the YAML description value (description:) to a concise one-line summary
without ellipses, and rewrite the "When To Use" paragraph to fully enumerate
intended use cases (user story creation from PRD, validation, acceptance
criteria, refinement, sprint planning, backlog grooming, retrospectives, daily
standups, etc.) so both the frontmatter and the body no longer contain trailing
ellipses or truncated sentences.

In `@docs/ide-integration.md`:
- Around line 18-27: The "AIOS Compatibility Status" table is incomplete vs the
guide claim of 9 platforms; either add the three missing IDE entries to the
table (using the same row format as existing entries for "Claude Code", "Gemini
CLI", "Codex CLI", "Cursor", "GitHub Copilot", "AntiGravity") and mark their
status as "Not yet validated" or appropriate statuses, or rename the
section/table to "Validated Platforms" and update the surrounding text to state
that the table only lists validated platforms (and that other platforms remain
unvalidated). Ensure you update the heading "AIOS Compatibility Status" and any
adjacent explanatory sentence to accurately reflect whichever approach you
choose.

In `@eslint.config.js`:
- Line 22: The ignore pattern 'aios-core/**' in eslint.config.js is inconsistent
with other entries that use '.aios-core/**'—update the pattern to match the
existing scope by replacing 'aios-core/**' with '.aios-core/**' (or conversely
make all occurrences top-level without the dot if the intent is to target a
top-level directory); ensure consistency across the file by aligning the pattern
used in the entry currently containing 'aios-core/**' with the other
'.aios-core/**' patterns.

In `@jest.config.js`:
- Line 132: The ignore pattern in modulePathIgnorePatterns is incorrect — update
the string value in modulePathIgnorePatterns to match the actual directory name
(include the leading dot) so the pattern will match (e.g., change
'<rootDir>/aios-core/' to '<rootDir>/.aios-core/'); ensure the
modulePathIgnorePatterns array contains the corrected pattern so Jest will
properly ignore the intended directory.

In `@web-app/bridge-server.cjs`:
- Around line 12-14: The CORS and file access are too permissive: replace the
wildcard res.setHeader('Access-Control-Allow-Origin', '*') with a configurable
allowed origin (e.g., process.env.ALLOWED_ORIGIN or the web UI origin) and keep
proper preflight handling via OPTIONS; additionally, validate any incoming
filePath before reading by resolving it (path.resolve) and ensuring it is within
an allowed workspace root (e.g., process.env.WORKSPACE_ROOT) — if the resolved
path is outside that root, respond with 400/403 and do not read or return file
contents. Ensure these checks are applied in the same request handler that
currently reads filePath and returns OCR (the route that uses filePath) and
fail-fast on invalid origins/paths.
- Around line 25-27: The request body is currently accumulated into the body
string without any size guard in the req.on('data', ...) handler; modify that
handler to track the accumulated byte length (e.g., a bytesReceived variable)
and if it exceeds a safe limit (choose a constant like MAX_BODY_BYTES)
immediately respond with status code 413 and destroy the socket/stop further
processing, ensuring the req.on('end', ...) path only processes when
bytesReceived <= MAX_BODY_BYTES; update the variables referenced (body,
req.on('data', ...), req.on('end', ...)) accordingly so oversized payloads are
rejected promptly.

In `@web-app/index.html`:
- Around line 30-35: Add accessible roles and labels: mark the chat transcript
element (`#chatMessages`) as a live region by adding role="log" and
aria-live="polite" (and optionally aria-atomic="false") so screen readers
announce new messages; give the composer input (`#chatInput`) a persistent
accessible name by adding an associated <label> or an aria-label/aria-labelledby
describing its purpose (e.g., "Mensagem" or "Compose message"), and ensure the
form (`#chatForm`) and submit button remain operable for keyboard/screen-reader
users; update attributes accordingly so new wizard prompts are exposed to
assistive tech and the input has a stable name.

In `@web-app/main.js`:
- Around line 162-170: handleWizardInput currently writes any free-form text
into wizard.answers and advances wizard.step without validating option-based
questions; add a validation guard inside handleWizardInput that, for the current
question (use wizardQuestions[wizard.step] and question.key), checks if
question.options exists and if so rejects/returns early when the provided text
is not one of question.options (or their allowed aliases), only writing to
wizard.answers and incrementing wizard.step when the value is valid; ensure this
prevents invalid values for keys like needsPlaybook so generateArtifacts sees
only validated values.
- Around line 107-148: The preview and code artifact are dropping collected
fields (problem, integrations, deadline): update the previewHtml to render
integrations (e.g., add a preview-card showing required/selected integrations
using escapeHtml and join) and ensure codeArtifact includes these fields (add
problem: answers.problem, integrations: answers.integrations (or integrations
variable), and deadline: answers.deadline) so the JSON persisted matches the UI
and downstream consumers; reference previewHtml, codeArtifact, answers,
requiredDocs, and agentPlan when making the changes.
- Around line 213-220: The inner forEach callback currently uses an
expression-bodied arrow that implicitly returns item.classList.remove('active'),
triggering the lint rule; change that callback in the tabs.forEach click handler
to a block-bodied arrow (e.g., (item) => { item.classList.remove('active'); })
so the function does not return a value, keeping the outer click handler and
dataset/tab logic unchanged (look for tabs.forEach, tab.addEventListener, and
item.classList.remove to locate the code).

In `@web-app/package.json`:
- Around line 11-12: The project lists "vite": "^7.3.1" in web-app package.json
which requires Node >=20.19 (dropping Node 18); update this mismatch by either
changing the repo's engines field (in the root package.json) to "node":
">=20.19.0" so it matches Vite 7 requirements, or pin Vite to a Node
18-compatible major (e.g., downgrade "vite" to a 6.x version) so it remains
compatible with the current "node >=18" engine declaration—pick one approach and
make the corresponding change to package.json and any CI/test matrix that
enforces the Node version.

---

Nitpick comments:
In `@eslint.config.js`:
- Around line 169-182: The web-app ESLint config for files matching
'web-app/**/*.js' currently defines a few browser globals under
languageOptions.globals; expand this list to include commonly used browser APIs
(e.g., localStorage, sessionStorage, console, alert, confirm, history, location
(already present), URL, navigator (already present), AbortController, DOMParser,
FormData, File, Blob) to avoid false no-undef errors as the app grows—update the
languageOptions.globals object in the ESLint config to add these entries with
'readonly' where appropriate.
- Around line 192-193: Remove the extra trailing blank line(s) at the end of
eslint.config.js so the file ends with a single newline character; locate the
end-of-file (EOF) and delete the extra empty lines so there is only one final
newline.

In `@web-app/index.html`:
- Around line 40-48: Assign proper ARIA roles and attributes to the tab markup
and keep them in sync in the click handler: mark the container with
role="tablist" (the element with class "tabs"), give each button role="tab" and
add aria-selected="true"/"false" and aria-controls referencing the panel IDs
("previewTab" and "codeTab"), and mark the panels with role="tabpanel" and id
attributes ("previewTab", "codeTab") and aria-hidden toggled accordingly; update
the click handler that toggles the "active" class on elements with class "tab"
and panels "previewTab"/"codeTab" to also set aria-selected on the buttons and
aria-hidden on the panels so assistive tech sees the currently active tab and
associated panel.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8d0a5cf0-4af2-41e1-a1cf-309076662595

📥 Commits

Reviewing files that changed from the base of the PR and between fcfb757 and 2fd6bb2.

⛔ Files ignored due to path filters (1)
  • web-app/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (27)
  • .aios-core/core/synapse/layers/layer-processor.js
  • .aios-core/infrastructure/scripts/validate-claude-integration.js
  • .aios-core/infrastructure/scripts/validate-codex-integration.js
  • .aios-core/infrastructure/scripts/validate-gemini-integration.js
  • .aios-core/infrastructure/scripts/validate-parity.js
  • .codex/skills/aios-analyst/SKILL.md
  • .codex/skills/aios-architect/SKILL.md
  • .codex/skills/aios-data-engineer/SKILL.md
  • .codex/skills/aios-dev/SKILL.md
  • .codex/skills/aios-devops/SKILL.md
  • .codex/skills/aios-master/SKILL.md
  • .codex/skills/aios-pm/SKILL.md
  • .codex/skills/aios-po/SKILL.md
  • .codex/skills/aios-qa/SKILL.md
  • .codex/skills/aios-sm/SKILL.md
  • .codex/skills/aios-squad-creator/SKILL.md
  • .codex/skills/aios-ux-design-expert/SKILL.md
  • docs/ide-integration.md
  • eslint.config.js
  • jest.config.js
  • package.json
  • web-app/.gitignore
  • web-app/bridge-server.cjs
  • web-app/index.html
  • web-app/main.js
  • web-app/package.json
  • web-app/style.css

Comment on lines +299 to +321
const loadContract = deps.loadCompatibilityContract || loadCompatibilityContract;
const contract = loadContract(resolvedContractPath);
const resolvedDiffPath = options.diffPath ? path.resolve(projectRoot, options.diffPath) : null;
const previousContract = resolvedDiffPath ? loadContract(resolvedDiffPath) : null;
const docsPath = path.join(projectRoot, 'docs', 'ide-integration.md');
const docsPathRelative = path.relative(projectRoot, docsPath);
const checks = [
{ id: 'claude-sync', exec: () => runSync('claude-code', projectRoot) },
{ id: 'claude-integration', exec: () => runClaudeIntegration({ projectRoot }) },
{ id: 'codex-sync', exec: () => runSync('codex', projectRoot) },
{ id: 'codex-integration', exec: () => runCodexIntegration({ projectRoot }) },
{ id: 'gemini-sync', exec: () => runSync('gemini', projectRoot) },
{ id: 'gemini-integration', exec: () => runGeminiIntegration({ projectRoot }) },
{ id: 'cursor-sync', exec: () => runSync('cursor', projectRoot) },
{ id: 'github-copilot-sync', exec: () => runSync('github-copilot', projectRoot) },
{ id: 'antigravity-sync', exec: () => runSync('antigravity', projectRoot) },
{ id: 'codex-skills', exec: () => runCodexSkills({ projectRoot, strict: true, quiet: true }) },
{ id: 'paths', exec: () => runPaths({ projectRoot }) },
];

const results = checks.map((check) => {
const normalized = normalizeResult(check.exec());
return { id: check.id, ...normalized };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't let contract loading or child validators crash the parity CLI.

Lines 299-321 call loadContract() and each check.exec() without guards. One thrown exception from a bad contract file or a validator-side filesystem error aborts the entire command before it can emit JSON or a readable failure report. Convert those exceptions into contractViolations and failed check results instead.

🛡️ Keep parity reporting alive on exceptions
-  const contract = loadContract(resolvedContractPath);
-  const resolvedDiffPath = options.diffPath ? path.resolve(projectRoot, options.diffPath) : null;
-  const previousContract = resolvedDiffPath ? loadContract(resolvedDiffPath) : null;
+  const contractLoadErrors = [];
+  let contract = null;
+  let previousContract = null;
+  try {
+    contract = loadContract(resolvedContractPath);
+  } catch (error) {
+    contractLoadErrors.push(
+      `Failed to load contract ${path.relative(projectRoot, resolvedContractPath)}: ${error.message}`,
+    );
+  }
+  const resolvedDiffPath = options.diffPath ? path.resolve(projectRoot, options.diffPath) : null;
+  if (resolvedDiffPath) {
+    try {
+      previousContract = loadContract(resolvedDiffPath);
+    } catch (error) {
+      contractLoadErrors.push(
+        `Failed to load diff contract ${path.relative(projectRoot, resolvedDiffPath)}: ${error.message}`,
+      );
+    }
+  }
@@
-  const results = checks.map((check) => {
-    const normalized = normalizeResult(check.exec());
+  const results = checks.map((check) => {
+    let output;
+    try {
+      output = check.exec();
+    } catch (error) {
+      output = {
+        ok: false,
+        errors: [`${check.id} threw: ${error.message}`],
+        warnings: [],
+      };
+    }
+    const normalized = normalizeResult(output);
     return { id: check.id, ...normalized };
   });
@@
-  const contractViolations = validateCompatibilityContract(contract, resultById, {
-    docsPath,
-    docsPathRelative,
-  });
+  const contractViolations = [
+    ...contractLoadErrors,
+    ...validateCompatibilityContract(contract, resultById, {
+      docsPath,
+      docsPathRelative,
+    }),
+  ];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aios-core/infrastructure/scripts/validate-parity.js around lines 299 - 321,
Wrap the potentially-throwing contract loads and validator executions in
try/catch so a single exception doesn't crash the CLI: when calling loadContract
(and the fallback deps.loadCompatibilityContract) around resolvedContractPath
and resolvedDiffPath, catch errors and push a contract violation entry into the
contractViolations array (include file/path and error.message) and set the
corresponding contract variable to null; likewise, change the checks mapping so
each check.exec() call (e.g., runSync, runClaudeIntegration,
runCodexIntegration, runGeminiIntegration, runCodexSkills, runPaths, etc.) is
invoked inside a try/catch and on error return a failed check result object with
id: check.id, success: false, errors: [error.message] (so normalizeResult still
handles it safely) instead of letting the exception bubble up.

@@ -0,0 +1,30 @@
---
name: aios-architect
description: Architect (Aria). Use for system architecture (fullstack, backend, frontend, infrastructure), technology stack selection (technical evaluation), API design (REST/GraphQL/tRPC/We...
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Truncated frontmatter description.

The YAML frontmatter description is truncated: ...API design (REST/GraphQL/tRPC/We.... Complete this for documentation clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.codex/skills/aios-architect/SKILL.md at line 3, The YAML frontmatter's
description field in SKILL.md is truncated ("...API design
(REST/GraphQL/tRPC/We..."); update the description line in the YAML frontmatter
(the `description:` value) to a full, readable sentence that lists the intended
topics (e.g., API design including REST, GraphQL, tRPC, WebSockets), and any
other key areas the skill covers such as fullstack architecture,
backend/frontend patterns, infrastructure, CI/CD, scalability, and security so
the frontmatter is complete and clear.

# AIOS Architect Activator

## When To Use
Use for system architecture (fullstack, backend, frontend, infrastructure), technology stack selection (technical evaluation), API design (REST/GraphQL/tRPC/WebSocket), security architecture, performance optimization,...
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Truncated "When To Use" section.

Similar truncation: ...performance optimization,.... Complete this text for clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.codex/skills/aios-architect/SKILL.md at line 9, The "When To Use" section
currently ends with a truncated list ("Use for system architecture (fullstack,
backend, frontend, infrastructure), technology stack selection (technical
evaluation), API design (REST/GraphQL/tRPC/WebSocket), security architecture,
performance optimization,...") — expand this sentence to a complete, parallel
list by replacing the trailing ellipsis with concrete items (e.g., scalability
planning, fault tolerance, observability/monitoring, deployment/CI-CD
strategies, cost/ops tradeoffs) or end with a clear closing phrase like "and
related architectural and technical decision-making," ensuring the entry in
SKILL.md's "When To Use" section reads as a complete, grammatically correct
sentence.

Use for database design, schema architecture, Supabase configuration, RLS policies, migrations, query optimization, data modeling, operations, and monitoring

## Activation Protocol
1. Load `.aios-core/development/agents/data-engineer.md` as source of truth (fallback: `.codex/agents/data-engineer.md`).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Prefer the local Codex agent as the primary source.

Line 12 points at .aios-core/development/agents/data-engineer.md first, which bypasses the versioned .codex/agents/data-engineer.md copy this repo wants Codex skills to prefer. Swap the order so the local agent is primary and .aios-core/... is only the fallback.

♻️ Suggested change
-1. Load `.aios-core/development/agents/data-engineer.md` as source of truth (fallback: `.codex/agents/data-engineer.md`).
+1. Load `.codex/agents/data-engineer.md` as source of truth (fallback: `.aios-core/development/agents/data-engineer.md`).
As per coding guidelines, "Prefer local-first approach: use `.codex/skills` versioned in the project for skills and agents".
📝 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.

Suggested change
1. Load `.aios-core/development/agents/data-engineer.md` as source of truth (fallback: `.codex/agents/data-engineer.md`).
1. Load `.codex/agents/data-engineer.md` as source of truth (fallback: `.aios-core/development/agents/data-engineer.md`).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.codex/skills/aios-data-engineer/SKILL.md at line 12, Update the
source-of-truth order so the local Codex agent is primary: in
.codex/skills/aios-data-engineer/SKILL.md replace the current "Load
`.aios-core/development/agents/data-engineer.md` as source of truth (fallback:
`.codex/agents/data-engineer.md`)" ordering with the local-first phrase "Load
`.codex/agents/data-engineer.md` as source of truth (fallback:
`.aios-core/development/agents/data-engineer.md`)" so the skill prefers the
versioned local agent before falling back to the .aios-core copy.

Comment on lines +17 to +25
## Starter Commands
- `*help` - Show all available commands with descriptions
- `*guide` - Show comprehensive usage guide for this agent
- `*yolo` - Toggle permission mode (cycle: ask > auto > explore)
- `*exit` - Exit data-engineer mode
- `*doc-out` - Output complete document
- `*execute-checklist {checklist}` - Run DBA checklist
- `*create-schema` - Design database schema
- `*create-rls-policies` - Design RLS policies
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The advertised starter commands are not backed by the declared source agent.

.aios-core/development/agents/data-engineer.md:1-60 currently contains activation metadata but no commands section, so the commands in Lines 17-25 can drift from the actual agent behavior. Either add these commands to the canonical agent file or trim this list to the commands that file really defines.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.codex/skills/aios-data-engineer/SKILL.md around lines 17 - 25, The SKILL.md
"Starter Commands" list (entries: *help, *guide, *yolo, *exit, *doc-out,
*execute-checklist, *create-schema, *create-rls-policies) is not reflected in
the canonical data-engineer agent activation metadata (the data-engineer agent),
so either add a proper "commands" section to the data-engineer agent metadata
that defines these exact commands and their handlers, or prune SKILL.md to only
list commands actually implemented by the data-engineer agent; ensure the
authoritative source (the data-engineer agent metadata) and SKILL.md remain
identical and include short descriptions for each command.

Comment on lines +30 to +35
<div id="chatMessages" class="chat-messages"></div>
<div id="quickReplies" class="quick-replies"></div>

<form id="chatForm" class="chat-form">
<input id="chatInput" type="text" placeholder="Descreva sua solicitação..." autocomplete="off" />
<button type="submit" class="btn btn-primary">Enviar</button>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Expose the chat transcript and composer to assistive tech.

#chatMessages is the live transcript, but it has no role="log"/aria-live, and #chatInput only has placeholder text. Screen-reader users will not reliably hear new wizard prompts or get a stable name for the input field.

Suggested markup update
-        <div id="chatMessages" class="chat-messages"></div>
+        <div
+          id="chatMessages"
+          class="chat-messages"
+          role="log"
+          aria-live="polite"
+          aria-relevant="additions text"
+        ></div>
         <div id="quickReplies" class="quick-replies"></div>

         <form id="chatForm" class="chat-form">
-          <input id="chatInput" type="text" placeholder="Descreva sua solicitação..." autocomplete="off" />
+          <input
+            id="chatInput"
+            type="text"
+            aria-label="Descreva sua solicitação"
+            placeholder="Descreva sua solicitação..."
+            autocomplete="off"
+          />
           <button type="submit" class="btn btn-primary">Enviar</button>
         </form>
📝 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.

Suggested change
<div id="chatMessages" class="chat-messages"></div>
<div id="quickReplies" class="quick-replies"></div>
<form id="chatForm" class="chat-form">
<input id="chatInput" type="text" placeholder="Descreva sua solicitação..." autocomplete="off" />
<button type="submit" class="btn btn-primary">Enviar</button>
<div
id="chatMessages"
class="chat-messages"
role="log"
aria-live="polite"
aria-relevant="additions text"
></div>
<div id="quickReplies" class="quick-replies"></div>
<form id="chatForm" class="chat-form">
<input
id="chatInput"
type="text"
aria-label="Descreva sua solicitação"
placeholder="Descreva sua solicitação..."
autocomplete="off"
/>
<button type="submit" class="btn btn-primary">Enviar</button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-app/index.html` around lines 30 - 35, Add accessible roles and labels:
mark the chat transcript element (`#chatMessages`) as a live region by adding
role="log" and aria-live="polite" (and optionally aria-atomic="false") so screen
readers announce new messages; give the composer input (`#chatInput`) a persistent
accessible name by adding an associated <label> or an aria-label/aria-labelledby
describing its purpose (e.g., "Mensagem" or "Compose message"), and ensure the
form (`#chatForm`) and submit button remain operable for keyboard/screen-reader
users; update attributes accordingly so new wizard prompts are exposed to
assistive tech and the input has a stable name.

Comment on lines +107 to +148
const previewHtml = `
<div class="preview-card">
<h3>${escapeHtml(answers.projectName || 'Novo Projeto')}</h3>
<p><strong>Problema:</strong> ${escapeHtml(answers.problem || '-')}</p>
<p><strong>Tipo:</strong> ${escapeHtml(answers.projectType || '-')}</p>
<p><strong>Frontend:</strong> ${escapeHtml(answers.frontend || '-')}</p>
<p><strong>Backend:</strong> ${escapeHtml(answers.backend || '-')}</p>
<p><strong>Database:</strong> ${escapeHtml(answers.database || '-')}</p>
<p><strong>Prazo:</strong> ${escapeHtml(answers.deadline || '-')}</p>
</div>
<div class="preview-card">
<h3>Documentação Inicial Obrigatória</h3>
<ul>${requiredDocs.map((doc) => `<li>${escapeHtml(doc)}</li>`).join('')}</ul>
</div>
<div class="preview-card">
<h3>Agentes Sugeridos</h3>
<p>${agentPlan.join(', ')}</p>
</div>
`;

const codeArtifact = {
project: answers.projectName,
classification: {
type: answers.projectType,
has_prd: answers.hasPrd,
needs_playbook: answers.needsPlaybook,
},
stack: {
frontend: answers.frontend,
backend: answers.backend,
database: answers.database,
auth: answers.auth,
},
documentation: requiredDocs,
agents: agentPlan,
next_steps: [
'Gerar PRD estruturado com requisitos funcionais e não funcionais',
'Definir arquitetura e contratos de API',
'Planejar backlog por épicos/stories com critérios de aceite',
'Iniciar implementação full stack após aprovação documental',
],
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The generated artifact is dropping answers the wizard already collected.

problem, integrations, and deadline are gathered earlier in the flow, but codeArtifact never persists them, and integrations is not surfaced in the preview either. That discards user input and leaves the JSON incomplete for downstream use.

Suggested artifact expansion
   const previewHtml = `
     <div class="preview-card">
       <h3>${escapeHtml(answers.projectName || 'Novo Projeto')}</h3>
       <p><strong>Problema:</strong> ${escapeHtml(answers.problem || '-')}</p>
       <p><strong>Tipo:</strong> ${escapeHtml(answers.projectType || '-')}</p>
       <p><strong>Frontend:</strong> ${escapeHtml(answers.frontend || '-')}</p>
       <p><strong>Backend:</strong> ${escapeHtml(answers.backend || '-')}</p>
       <p><strong>Database:</strong> ${escapeHtml(answers.database || '-')}</p>
+      <p><strong>Integrações críticas:</strong> ${escapeHtml(answers.integrations || '-')}</p>
       <p><strong>Prazo:</strong> ${escapeHtml(answers.deadline || '-')}</p>
     </div>
@@
   const codeArtifact = {
     project: answers.projectName,
+    problem: answers.problem,
     classification: {
       type: answers.projectType,
       has_prd: answers.hasPrd,
       needs_playbook: answers.needsPlaybook,
     },
     stack: {
       frontend: answers.frontend,
       backend: answers.backend,
       database: answers.database,
       auth: answers.auth,
     },
+    integrations: answers.integrations,
+    deadline: answers.deadline,
     documentation: requiredDocs,
     agents: agentPlan,
📝 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.

Suggested change
const previewHtml = `
<div class="preview-card">
<h3>${escapeHtml(answers.projectName || 'Novo Projeto')}</h3>
<p><strong>Problema:</strong> ${escapeHtml(answers.problem || '-')}</p>
<p><strong>Tipo:</strong> ${escapeHtml(answers.projectType || '-')}</p>
<p><strong>Frontend:</strong> ${escapeHtml(answers.frontend || '-')}</p>
<p><strong>Backend:</strong> ${escapeHtml(answers.backend || '-')}</p>
<p><strong>Database:</strong> ${escapeHtml(answers.database || '-')}</p>
<p><strong>Prazo:</strong> ${escapeHtml(answers.deadline || '-')}</p>
</div>
<div class="preview-card">
<h3>Documentação Inicial Obrigatória</h3>
<ul>${requiredDocs.map((doc) => `<li>${escapeHtml(doc)}</li>`).join('')}</ul>
</div>
<div class="preview-card">
<h3>Agentes Sugeridos</h3>
<p>${agentPlan.join(', ')}</p>
</div>
`;
const codeArtifact = {
project: answers.projectName,
classification: {
type: answers.projectType,
has_prd: answers.hasPrd,
needs_playbook: answers.needsPlaybook,
},
stack: {
frontend: answers.frontend,
backend: answers.backend,
database: answers.database,
auth: answers.auth,
},
documentation: requiredDocs,
agents: agentPlan,
next_steps: [
'Gerar PRD estruturado com requisitos funcionais e não funcionais',
'Definir arquitetura e contratos de API',
'Planejar backlog por épicos/stories com critérios de aceite',
'Iniciar implementação full stack após aprovação documental',
],
};
const previewHtml = `
<div class="preview-card">
<h3>${escapeHtml(answers.projectName || 'Novo Projeto')}</h3>
<p><strong>Problema:</strong> ${escapeHtml(answers.problem || '-')}</p>
<p><strong>Tipo:</strong> ${escapeHtml(answers.projectType || '-')}</p>
<p><strong>Frontend:</strong> ${escapeHtml(answers.frontend || '-')}</p>
<p><strong>Backend:</strong> ${escapeHtml(answers.backend || '-')}</p>
<p><strong>Database:</strong> ${escapeHtml(answers.database || '-')}</p>
<p><strong>Integrações críticas:</strong> ${escapeHtml(answers.integrations || '-')}</p>
<p><strong>Prazo:</strong> ${escapeHtml(answers.deadline || '-')}</p>
</div>
<div class="preview-card">
<h3>Documentação Inicial Obrigatória</h3>
<ul>${requiredDocs.map((doc) => `<li>${escapeHtml(doc)}</li>`).join('')}</ul>
</div>
<div class="preview-card">
<h3>Agentes Sugeridos</h3>
<p>${agentPlan.join(', ')}</p>
</div>
`;
const codeArtifact = {
project: answers.projectName,
problem: answers.problem,
classification: {
type: answers.projectType,
has_prd: answers.hasPrd,
needs_playbook: answers.needsPlaybook,
},
stack: {
frontend: answers.frontend,
backend: answers.backend,
database: answers.database,
auth: answers.auth,
},
integrations: answers.integrations,
deadline: answers.deadline,
documentation: requiredDocs,
agents: agentPlan,
next_steps: [
'Gerar PRD estruturado com requisitos funcionais e não funcionais',
'Definir arquitetura e contratos de API',
'Planejar backlog por épicos/stories com critérios de aceite',
'Iniciar implementação full stack após aprovação documental',
],
};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-app/main.js` around lines 107 - 148, The preview and code artifact are
dropping collected fields (problem, integrations, deadline): update the
previewHtml to render integrations (e.g., add a preview-card showing
required/selected integrations using escapeHtml and join) and ensure
codeArtifact includes these fields (add problem: answers.problem, integrations:
answers.integrations (or integrations variable), and deadline: answers.deadline)
so the JSON persisted matches the UI and downstream consumers; reference
previewHtml, codeArtifact, answers, requiredDocs, and agentPlan when making the
changes.

Comment on lines +162 to +170
function handleWizardInput(text) {
const question = wizardQuestions[wizard.step];
if (!question) {
return;
}

wizard.answers[question.key] = text;
wizard.step += 1;
askWizardQuestion();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Reject invalid free-form values for option-based steps.

Lines 162-170 advance unconditionally, even when the current question has a closed set of options. A value like talvez will still be accepted for needsPlaybook, and generateArtifacts() will then silently treat it as Não.

Suggested validation guard
 function handleWizardInput(text) {
   const question = wizardQuestions[wizard.step];
   if (!question) {
     return;
   }

-  wizard.answers[question.key] = text;
+  const normalizedText = text.trim();
+
+  if (
+    question.options &&
+    !question.options.some((option) => option.toLowerCase() === normalizedText.toLowerCase())
+  ) {
+    addMessage(`Escolha uma das opções disponíveis: ${question.options.join(', ')}.`, 'agent');
+    setQuickReplies(question.options);
+    return;
+  }
+
+  wizard.answers[question.key] = normalizedText;
   wizard.step += 1;
   askWizardQuestion();
 }
📝 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.

Suggested change
function handleWizardInput(text) {
const question = wizardQuestions[wizard.step];
if (!question) {
return;
}
wizard.answers[question.key] = text;
wizard.step += 1;
askWizardQuestion();
function handleWizardInput(text) {
const question = wizardQuestions[wizard.step];
if (!question) {
return;
}
const normalizedText = text.trim();
if (
question.options &&
!question.options.some((option) => option.toLowerCase() === normalizedText.toLowerCase())
) {
addMessage(`Escolha uma das opções disponíveis: ${question.options.join(', ')}.`, 'agent');
setQuickReplies(question.options);
return;
}
wizard.answers[question.key] = normalizedText;
wizard.step += 1;
askWizardQuestion();
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-app/main.js` around lines 162 - 170, handleWizardInput currently writes
any free-form text into wizard.answers and advances wizard.step without
validating option-based questions; add a validation guard inside
handleWizardInput that, for the current question (use
wizardQuestions[wizard.step] and question.key), checks if question.options
exists and if so rejects/returns early when the provided text is not one of
question.options (or their allowed aliases), only writing to wizard.answers and
incrementing wizard.step when the value is valid; ensure this prevents invalid
values for keys like needsPlaybook so generateArtifacts sees only validated
values.

Comment on lines +213 to +220
tabs.forEach((tab) => {
tab.addEventListener('click', () => {
tabs.forEach((item) => item.classList.remove('active'));
tab.classList.add('active');
const target = tab.dataset.tab;
previewTab.classList.toggle('active', target === 'preview');
codeTab.classList.toggle('active', target === 'code');
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "main.js" | grep -E "web-app|similar"

Repository: SynkraAI/aiox-core

Length of output: 79


🏁 Script executed:

git ls-files | grep -E "main\.js|biome"

Repository: SynkraAI/aiox-core

Length of output: 138


🏁 Script executed:

fd "main.js" --type f

Repository: SynkraAI/aiox-core

Length of output: 77


🏁 Script executed:

wc -l ./web-app/main.js

Repository: SynkraAI/aiox-core

Length of output: 83


🏁 Script executed:

sed -n '210,225p' ./web-app/main.js

Repository: SynkraAI/aiox-core

Length of output: 850


🏁 Script executed:

find . -type f \( -name "biome.json*" -o -name ".eslintrc*" -o -name "package.json" \) | head -20

Repository: SynkraAI/aiox-core

Length of output: 372


🏁 Script executed:

cat ./biome.json

Repository: SynkraAI/aiox-core

Length of output: 1836


🏁 Script executed:

head -100 ./web-app/main.js

Repository: SynkraAI/aiox-core

Length of output: 3727


🏁 Script executed:

rg "useIterableCallbackReturn" . --type js --type json

Repository: SynkraAI/aiox-core

Length of output: 44


Convert the forEach callback to block-bodied arrow to fix the Biome lint error.

The expression-bodied arrow on Line 215 returns the result of classList.remove(), which triggers lint/suspicious/useIterableCallbackReturn. This blocks the lint pass.

Suggested fix
-    tabs.forEach((item) => item.classList.remove('active'));
+    tabs.forEach((item) => {
+      item.classList.remove('active');
+    });
📝 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.

Suggested change
tabs.forEach((tab) => {
tab.addEventListener('click', () => {
tabs.forEach((item) => item.classList.remove('active'));
tab.classList.add('active');
const target = tab.dataset.tab;
previewTab.classList.toggle('active', target === 'preview');
codeTab.classList.toggle('active', target === 'code');
});
tabs.forEach((tab) => {
tab.addEventListener('click', () => {
tabs.forEach((item) => {
item.classList.remove('active');
});
tab.classList.add('active');
const target = tab.dataset.tab;
previewTab.classList.toggle('active', target === 'preview');
codeTab.classList.toggle('active', target === 'code');
});
🧰 Tools
🪛 Biome (2.4.4)

[error] 215-215: This callback passed to forEach() iterable method should not return a value.

(lint/suspicious/useIterableCallbackReturn)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-app/main.js` around lines 213 - 220, The inner forEach callback currently
uses an expression-bodied arrow that implicitly returns
item.classList.remove('active'), triggering the lint rule; change that callback
in the tabs.forEach click handler to a block-bodied arrow (e.g., (item) => {
item.classList.remove('active'); }) so the function does not return a value,
keeping the outer click handler and dataset/tab logic unchanged (look for
tabs.forEach, tab.addEventListener, and item.classList.remove to locate the
code).

Comment on lines +11 to +12
"devDependencies": {
"vite": "^7.3.1"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

What Node.js versions are supported by Vite 7.3.x, and does Vite 7 still support Node.js 18?

💡 Result:

Vite 7.3.x declares this Node.js engine range:

  • Node ^20.19.0 (i.e., 20.19.0 and later 20.x)
  • Node >=22.12.0 (22.12.0 and later, including newer majors like 23/24, etc.) [1]

And noVite 7 does not support Node.js 18 (it was dropped; Vite 7 requires Node 20.19+ / 22.12+). [2]

Sources: [1] [2]


🏁 Script executed:

cd web-app && cat -n package.json

Repository: SynkraAI/aiox-core

Length of output: 389


Vite 7.3.x requires Node 20.19+ or 22.12+, incompatible with the repo's declared minimum of Node 18.

Vite 7 dropped Node 18 support. The current pin of vite ^7.3.1 will fail on Node 18—the minimum the repo currently advertises. Either update the root package.json engines field to node >=20.19.0 or downgrade to a Vite major version that still supports Node 18.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web-app/package.json` around lines 11 - 12, The project lists "vite":
"^7.3.1" in web-app package.json which requires Node >=20.19 (dropping Node 18);
update this mismatch by either changing the repo's engines field (in the root
package.json) to "node": ">=20.19.0" so it matches Vite 7 requirements, or pin
Vite to a Node 18-compatible major (e.g., downgrade "vite" to a 6.x version) so
it remains compatible with the current "node >=18" engine declaration—pick one
approach and make the corresponding change to package.json and any CI/test
matrix that enforces the Node version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant