dewebix
v1.0.0
Published
CLI tool for assessing and migrating Webix codebases to React
Maintainers
Readme
dewebix
A CLI tool for AI agents (and human engineers) to assess and migrate a Webix v6+ codebase to React with vanilla ES6 JavaScript, preferring dependency-light output wherever practical.
Purpose
Webix is a DOM-manipulation framework (jQuery-adjacent) with several mechanisms
that create invisible coupling across module boundaries — a global widget ID
registry ($$("id")), a prototype-based custom widget API (webix.protoUI)
with lifecycle and layout-math overrides, a pixel-computing layout engine, and a
proxy/data layer that hides client-server contracts inside string prefixes and
callback transforms. Ad-hoc exploration (grep, file-by-file reading) is slow,
token-expensive, and blind to these implicit couplings.
dewebix sweeps the codebase once, builds a persistent, queryable fact index, and exposes analysis, planning, refactoring, and verification commands whose outputs are designed for machine consumption first. The tool surfaces blast radius, migration categories, risk scores, API contracts, data-fetching behavior, styling dependencies, and React-integration traps — making agents and engineers more efficient, safer, and more consistent throughout a migration.
dewebix does not fully automate every migration. Its primary job is to make the next person or agent dramatically more effective by providing the data they need, not just the code.
Key Concepts
Entities and Findings
A sweep parses every file in scope and records two kinds of facts:
- Entities — named Webix constructs: views
(
webix.ui({ view: "datatable" })), custom widgets (webix.protoUI(...)), proxies, collections, React wrappers, event handlers, styles, and templates. Every entity has a stable human-readable ID (e.g.id:ordersGrid,proto:kanbanBoard,wrapper:src/shared/Host.jsx). - Findings — occurrences of known Webix patterns, each tagged with a rule ID
(e.g.
WX-ID-REF,WX-PROXY-URL,WX-EVENT). Each finding carries a risk score, confidence level, a snippet, and a suggested action.
The sweep writes these facts to an embedded SQLite index (.dewebix/index.db,
WASM-compiled via sql.js). All subsequent commands query the index — they never
re-parse source files unless performing a write.
Risk Model
dewebix computes two complementary risk scores:
| Score | Range | Purpose |
| --------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Entity risk | 0–5 | Per-widget or per-path, driven by additive factors (proto-UI lifecycle overrides, leaky wrappers, registry fan-out, sync chains, CSS internals, dynamic IDs, etc.) |
| File risk | 0–100 | Roll-up per file for triage: 0–20 low, 21–45 medium, 46–70 high, 71–100 critical |
A file whose worst entity is risk-5 can never land in the "low" file-risk band. The two scores are always consistent in direction.
Wrapper Leakage Classes
React components that mount Webix widgets are classified by how tightly coupled they are to the Webix internals:
| Class | Meaning |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| L0 sealed | Data in via props, events out via callbacks. The contract is clean. |
| L1 instance-leaky | The Webix instance is exposed via ref, imperative handle, or callback. |
| L2 registry-leaky | The widget registers a global id that other modules reach via $$. |
| L3 data-entangled | The widget participates in sync/bind/DataProcessor chains that cross the wrapper boundary. |
L2 and L3 wrappers are first-class migration risks. The refactor wrapper
command refuses to rewrite them without --force and prints a blast-radius
summary first.
The Index
The SQLite index stores:
files— path, content hash, language, lines-of-codeentities— kind, name, defining file/span, normalized data JSONrelations— typed edges between entities (references,syncs_with,binds,saves_to,leaks,styles, etc.)findings— rule, file/span, entity link, risk, confidence, snippetmeta— tool version, Webix version, config hash, git commit at scan time
Indexing is incremental: files are keyed by content hash; unchanged files are skipped on re-sweeps. The index is queryable by any command without re-parsing.
Architecture
┌───────────┐ ┌──────────────┐ ┌──────────────────────────────┐
│ CLI │──▶│ Orchestrator │──▶│ Index store (SQLite) │
│ (cmd tree)│ │ auto-sweep │ │ entities / relations / │
└───────────┘ │ staleness mgr │ │ findings / file-hash cache │
└──────┬───────┘ └──────────────▲───────────────┘
│ │
┌──────────────┼──────────────┐ │
▼ ▼ ▼ │
┌──────────┐ ┌────────────┐ ┌───────────┐ │
│ Scanners │ │ Analyzers │ │ Codemods │────┘ (read index,
│ JS/TS AST│ │ blast-rad. │ │ diff-first│ write files
│ CSS, HTML│ │ layout, │ │ scaffold, │ only w/ --write)
│ (rule │ │ proxies, │ │ ids, proxy│
│ catalog)│ │ styles, │ │ wrapper… │
└──────────┘ │ wrappers, │ └───────────┘
│ graph, plan│ ┌───────────┐ ┌────────────────┐
└────────────┘ │ Reporters │ │ Ledger │
│ json/csv/ │ │ .dewebix/ │
│ md/table/ │ │ state.json │
│ sarif │ └────────────────┘
└───────────┘- Scanners run rule visitors over parsed files and write facts to the index. Incremental: unchanged files (by content hash) are skipped.
- Analyzers are pure queries/graph algorithms over the index — no re-parsing.
- Codemods re-parse target files at mutation time and produce
format-preserving diffs. Default
--dry-run;--writeapplies. - Orchestrator auto-runs an incremental sweep before any analyze/refactor
command when the index is stale (override with
--no-auto-index).
Configuration
Run dewebix init to probe the repository and generate a starter
dewebix.config.json. The config controls what is scanned, how Webix globals
are named, target language preferences, and which shell commands
verify project runs.
{
"roots": ["."],
"include": ["src/**/*.{js,jsx,ts,tsx}"],
"exclude": ["**/node_modules/**", "**/vendor/**"],
"webixGlobals": ["webix", "$$"],
"webix": { "version": "auto" },
"aliases": "auto",
"customProxyPrefixes": [],
"wrapperHints": [],
"knownReactWrapperNames": [],
"targets": {
"table": "vanilla",
"data": "fetch",
"state": "module",
"forms": "vanilla",
"styles": "css-modules"
},
"react": { "version": 18, "style": "function-components" },
"verify": {
"allowTodos": true,
"typecheckCommand": "npm run typecheck",
"lintCommand": "npm run lint",
"testCommand": "npm test"
},
"ledger": ".dewebix/state.json"
}Key config knobs:
| Key | Default | Description |
| ------------------------ | ----------------- | ----------------------------------------------- |
| roots | ["."] | Directories to scan |
| include / exclude | standard set | Glob patterns for files to include or skip |
| webixGlobals | ["webix", "$$"] | Identifiers treated as Webix globals |
| webix.version | "auto" | Override auto-detected Webix version |
| aliases | "auto" | Resolve path aliases from tsconfig/webpack/vite |
| wrapperHints | [] | File paths suspected to be React/Webix wrappers |
| knownReactWrapperNames | [] | Component names known to be wrappers |
| targets.* | vanilla-first | Preferred output patterns per category |
| verify.*Command | null | Shell commands run by verify project |
Quick Start
npm install
npm run build
./dist/bin/dewebix.js --versionCommand Reference
Index management
dewebix init # Probe repo and write dewebix.config.json
dewebix sweep [--incremental] # Build or refresh the fact index
dewebix inventory [--kind …] # List indexed entities (JSON/CSV/table)
dewebix doctor # Environment sanity check
dewebix cache clear # Reset the indexAnalysis
dewebix analyze component <entity> # Full dossier: config, events, data, styles, layout, contracts
dewebix analyze blast-radius <entity> # Transitive impact set with risk (CSV/JSON)
dewebix analyze layout <entity|file> # Normalized layout tree + CSS suggestions + hazards
dewebix analyze proxies # All data pathways, endpoint table, transform bodies verbatim
dewebix analyze styles [--for <entity>] # Style coupling in both directions
dewebix analyze wrappers # All wrappers with leakage class (L0–L3) and contracts
dewebix graph [--around <entity>] # Typed dependency graph (dot/mermaid/JSON)
dewebix brief # Generate agent-brief.md: narrative migration overview
dewebix explain <ruleId|recipe:name> # Rule documentation or migration recipe with code sketch
dewebix inspect <file> # Single-file summary: all entities, risk score, strategy notes
dewebix suggest <file> # Non-mutating migration approach for one filePlanning and progress
dewebix plan [--waves] [--unit <entity>] # Ordered migration waves (leaf-first dependency order)
dewebix status # Ledger + coverage summary, suggested next unit
dewebix mark <entity> --status <status> # Update ledger status (pending|in-progress|migrated|verified|blocked|deferred)
dewebix todos [path…] # List DEWEBIX-TODO markers left by scaffoldsRefactoring
dewebix refactor scaffold <entity> --out <dir> # Generate React skeleton + sidecars (MIGRATION.md, CSS, data)
dewebix refactor ids [--mode shim|registry] # Break $$() cross-references (wave-0 friendly shim by default)
dewebix refactor proxy <name> --out <dir> # Generate fetch-based ES6 data module from a proxy's endpoint table
dewebix refactor template <entity> # Convert #prop# templates to JSX render functions
dewebix refactor wrapper <entity> # Swap wrapper innards preserving the external contract (guarded by leakage class)Verification
dewebix verify contract <wrapper> [--baseline <file>] # Snapshot/diff a wrapper's external prop+callback API
dewebix verify no-webix <path…> [--allow <ruleId,…>] # Assert zero Webix findings in given paths (exit 1 on findings)
dewebix verify project # Run configured typecheck/lint/test commands; report Webix-usage deltaGlobal flags
| Flag | Effect |
| -------------------------------------- | --------------------------------------------------------- |
| --format json\|csv\|md\|table\|sarif | Output format (default: table on TTY, json otherwise) |
| --fields a,b,c | Limit output columns |
| --max-results N | Cap results (default 100); --cursor for pagination |
| --full | Emit all available detail |
| --config <path> | Use a specific config file |
| --no-auto-index | Do not auto-sweep; exit code 3 if index is stale |
| --quiet | Suppress non-essential output |
| -C <dir> | Run as if in a different directory |
Exit codes
| Code | Meaning |
| ---- | -------------------------------------------------------------------- |
| 0 | Success (and, for verify, no violations) |
| 1 | Verify/sweep found violations, or --fail-on <n> threshold breached |
| 2 | Usage or config error |
| 3 | Stale index with --no-auto-index |
| 4 | Internal error |
Canonical Agent Loop
A typical migration session using dewebix as the primary planning and verification interface:
# ── Orientation ───────────────────────────────────────────
dewebix sweep # Build/refresh the index; get inventory summary
dewebix brief # Narrative agent-brief.md: first targets, hazards, avoid-list
dewebix status # What's done, what's pending, suggested next unit
dewebix plan --waves # Ordered migration waves (leaf-first)
# ── Per migration unit ─────────────────────────────────────
dewebix analyze component ordersGrid # Dossier: config, events, data, styles
dewebix analyze blast-radius ordersGrid # Who breaks if this changes (CSV output)
dewebix explain recipe:datatable # Migration recipe with code sketch
dewebix refactor scaffold ordersGrid --out src/orders/ # React skeleton + mapping notes
# … agent implements, guided by structured DEWEBIX-TODO markers …
dewebix todos src/orders/ # Remaining structured TODOs
dewebix verify contract OrdersGridWrapper # External prop/callback API unchanged
dewebix verify no-webix src/orders/ # Zero webix references remain
dewebix mark ordersGrid --status migratedMilestone Status
| Milestone | Status | Notes |
| -------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| M1 | ✅ Done | Config, scanner framework, index, init/sweep/inventory/doctor/cache, JSON/CSV/table reporters. Acceptance M1 gate satisfied. |
| M2 | ✅ Done | Analyzers: component dossier, blast-radius, layout, proxies, styles, wrappers, graph; file-risk roll-up + risk matrix; brief; explain + cookbook v1. Acceptance M2 gate satisfied. |
| M3 | ✅ Done | plan, ledger (mark/status/todos), verify family (no-webix/contract/project), SARIF output. Acceptance M3 gate satisfied. |
| M4 | ✅ Done | Codemods: scaffold, ids, proxy, template, wrapper + conservative helpers. Acceptance M4 gate satisfied. |
| M5 stretch | ✅ Done | experimental-layout-skeleton, parity (Playwright skeleton generation), Jet inventory deep-dive, watch mode, help --format json (M1–M5 coverage). No formal acceptance gate per spec §18. |
Documentation
- Initial Specification — Full project specification
- M1 Implementation Plan — Phase-by-phase implementation plan
Requirements
- Node.js ≥ 20
No native compilation required — dewebix uses sql.js
(WASM-compiled SQLite) for its embedded database. pnpm install works on all
platforms without a C++ toolchain.
License
MIT
