A client-side web application for ServiceNow development. Features code formatting, task management, note-taking, and visual planning - all running offline in your browser. Your data never leaves your machine.
GlideAware Studioβ’ provides two primary modes accessible via the top-level toggle:
| Mode | Description |
|---|---|
| Plan | Task management, note-taking, and sketching for project planning |
| Develop | Code formatting, comparison, and visualization for JavaScript/JSON |
Plan mode provides offline-first project management tools with automatic data persistence via IndexedDB.
A full-featured Kanban board for managing development tasks:
| Feature | Description |
|---|---|
| Drag & Drop | Move tasks between columns by dragging |
| Columns | To Do, In Progress, On Hold, In Review, Completed |
| Backlog | Collapsible sidebar for backlog items |
| Priorities | Low, Medium, High, Critical with color coding |
| External Links | Link tasks to Jira, ServiceNow, Monday, ClickUp, Asana, Trello, Motion, or custom URLs |
| Tags | Organize tasks with custom tags |
| Auto-save | Every change persists instantly to IndexedDB |
WYSIWYG rich text note-taking with formatting:
| Feature | Description |
|---|---|
| Rich Text Editor | Bold, italic, headings, lists, checklists, code blocks, links, quotes |
| WYSIWYG Editing | See formatted text as you type |
| Syntax Highlighting | Code blocks with language highlighting |
| Search | Filter notes by title or content |
| Auto-save | Debounced saving with visual indicator |
| Sidebar Navigation | Quick access to all notes with previews |
Canvas-based drawing tool for diagrams and visual notes:
| Feature | Description |
|---|---|
| Drawing Tools | Text (click to add labels), Pen, Line, Rectangle, Ellipse, Arrow, Eraser |
| Color Palette | 9 preset colors |
| Stroke Widths | 4 size options |
| Multiple Sketches | Create and manage multiple drawings |
| Grid Background | Visual alignment guide |
All Plan mode data is stored in IndexedDB and persists across:
- Tab close
- Browser close
- Computer restart
- Power off
| Action | Description |
|---|---|
| Export | Download all Plan data as JSON (glideaware-plan-YYYY-MM-DD-HHMMSS.json) |
| Import | Load Plan data from a previously exported JSON file |
Use export/import to transfer your planning data between computers or create backups.
Develop mode provides tools for ServiceNow JavaScript and JSON development.
Switch between JavaScript (ServiceNow) and JSON modes with one click. Each mode provides:
- Polish (JavaScript) / Format (JSON): Format, fix, and validate code/JSON
- Compare: Side-by-side comparison with visual diff highlighting
- Visualize (JavaScript only): Interactive flow diagram visualization
Formats code using Prettier with ServiceNow-friendly settings (JavaScript) or clean JSON formatting.
| Fix | Description |
|---|---|
| Line endings | Normalizes Windows \r\n to Unix \n |
| Trailing whitespace | Removes spaces/tabs at end of lines |
| Multiple semicolons | Fixes ;; or ;;; β ; |
| Empty statements | Removes standalone ; on their own line |
| Keyword spacing | if(, for(, while(, switch(, catch( β adds space |
| Excessive blank lines | Reduces 4+ consecutive blank lines to 2 |
| Boolean simplification | == true β removes comparison |
GlideAware Studioβ’ uses a two-pass approach for typo detection:
- Fast regex patterns for common known typos (instant)
- Fuzzy matching using Damerau-Levenshtein edit distance for any remaining typos
Features:
- Context-aware corrections: Detects variable types (
var gr = new GlideRecord(...)) and only suggests methods valid for that class - Confidence tiers: High confidence (auto-fix), Medium confidence (auto-fix with note), Low confidence (warning only)
- Guardrails: Only corrects in method-call context (
.method(), requires winner to beat runner-up by margin
Example: gr.addQuerry() β gr.addQuery() (detected because gr is known to be a GlideRecord)
| Category | Examples |
|---|---|
| GlideRecord | addQeury β addQuery, getValeu β getValue, udpate β update, getRefrence β getReference |
| GlideElement | chnages β changes, getJournlaEntry β getJournalEntry, toStirng β toString |
| GlideDateTime | addSecnods β addSeconds, comparTo β compareTo, getDayOfWek β getDayOfWeek |
| GlideUser | hasRoel β hasRole, isMemberOF β isMemberOf, getEmial β getEmail |
| Class names | GlideReocrd β GlideRecord, GlideDateTiem β GlideDateTime, ArrayUitl β ArrayUtil |
| g_form | setMandaotry β setMandatory, setVisble β setVisible, addOptin β addOption |
| GlideAjax | addParm β addParam, getXMLWiat β getXMLWait, getParamater β getParameter |
| gs | gs.getPrefernce β gs.getPreference, gs.addInfoMessge β gs.addInfoMessage |
| REST/SOAP | setRequestBdoy β setRequestBody, setHttpMehtod β setHttpMethod, excute β execute |
The dictionary includes 60+ classes and 400+ methods across GlideRecord, GlideAggregate, GlideElement, GlideDateTime, GlideSchedule, GlideDuration, GlideUser, GlideSession, GlideAjax, g_form, g_user, gs, RESTMessageV2, SOAPMessageV2, ArrayUtil, GlideSysAttachment, XMLDocument2, GlideEmailOutbound, Workflow, and more.
| Fix | Description |
|---|---|
| gs.now() | Replaces with new GlideDateTime().getDisplayValue() |
| gs.nowDateTime() | Replaces with new GlideDateTime().getValue() |
| getValue('sys_id') | Optimizes to getUniqueValue() |
| gs.print() | Replaces with gs.info() |
| String concat in addQuery | addQuery('field=' + val) β addQuery('field', val) |
| Simple addEncodedQuery | Simplifies single-condition encoded queries to addQuery() |
| String literal equality | Converts 'string' == 'string' to === (safe patterns only) |
| Warning | Description |
|---|---|
| TODO/FIXME comments | Counts TODO, FIXME, XXX, HACK, BUG comments |
| Long lines | Lines exceeding 150 characters |
| Empty catch blocks | catch(e) {} - errors silently ignored |
| Empty code blocks | Empty if, for, while bodies |
| Deeply nested code | 6+ levels of nesting |
| Unreachable code | Code after return statement |
| Long functions | Functions averaging 50+ lines |
| Too many parameters | Functions with 5+ parameters |
| Assignment in conditional | if (x = y) - possible mistake |
| Nested ternary | a ? b ? c : d : e |
| Hardcoded credentials | Detects password, apiKey, secret, token patterns |
| Warning | Description |
|---|---|
| update() in while loop | Each update is a separate DB call - consider batch operations |
| getRowCount() without setLimit() | Performance issue on large tables |
| deleteRecord() in loop | Suggest using deleteMultiple() for performance |
| getReference() in loop | N+1 query problem - suggest join or caching |
| Missing setLimit(1) | For existence checks, add setLimit(1) |
| query() without conditions | Full table scan warning |
| updateMultiple/deleteMultiple without conditions | Will affect ALL records |
| get() followed by query() | get() already positions record, query() is redundant |
| next() with updateMultiple() | updateMultiple() ignores per-row changes from iteration |
| Warning | Description |
|---|---|
| setWorkflow(false) not re-enabled | Workflows will be permanently skipped |
| setAbortAction without return | Business Rule may not stop properly |
| Direct field assignment | current.field = value - suggest setValue() |
| current.update() in BR | Risks recursion - use Before BR or setWorkflow(false) |
| current.insert() in BR | Unusual pattern - verify intentional |
| Warning | Description |
|---|---|
| Hardcoded sys_id | Use system properties for portability |
| eval() or GlideEvaluator | Security risk - avoid dynamic code execution |
| new Function() | Security risk similar to eval() |
| GlideRecordSecure + privileged ops | setWorkflow(false)/updateMultiple undermines security intent |
| Warning | Description |
|---|---|
| GlideAggregate without aggregate | No aggregate function called |
| getXMLWait() usage | Blocks UI thread - suggest async pattern |
| gs.sleep() usage | Blocks thread - avoid in production |
| gs.getProperty() without default | Consider adding fallback value |
| gs.include() legacy | Use Script Includes with Class.create() pattern |
| addEncodedQuery with sys_id | Prefer addQuery('sys_id', value) for clarity |
| g_form.getReference() no callback | Synchronous call - use callback for async |
| GlideAjax without sysparm_name | Processor method will not be invoked |
| DOM manipulation with g_form | Prefer g_form APIs - DOM may break on upgrades |
| Fix | Description |
|---|---|
| Remove comments | Strips single-line (//) and multi-line (/* */) comments |
| Remove trailing commas | Fixes [1, 2, 3,] β [1, 2, 3] |
| Single to double quotes | Converts 'value' β "value" |
| Quote unquoted keys | Fixes {key: value} β {"key": value} |
| Multiple commas | Fixes ,, β , |
| Normalize line endings | Windows \r\n β Unix \n |
| Trailing whitespace | Removes spaces/tabs at end of lines |
| Missing braces/brackets | Adds missing } or ] to complete structure |
| Error | Description |
|---|---|
| Syntax errors | Detailed location (line, column) of JSON parsing failures |
| Trailing commas | Not valid in JSON spec |
| Single quotes | JSON requires double quotes |
| Comments | Not allowed in standard JSON |
| Warning | Description |
|---|---|
| Duplicate keys | Later value will override earlier |
| Deep nesting | 10+ levels of nesting |
| Long strings | Strings over 1000 characters |
| Many empty containers | 5+ empty arrays/objects |
| Excessive nulls | 10+ null values |
| Numeric keys | Suggests using array instead |
| Large file | Files over 1000 lines |
| Control characters | Unescaped special characters |
Compare two JSON objects and visualize their differences:
- Side-by-side editors for left and right JSON
- Visual diff output with color-coded changes
- Change statistics showing additions, deletions, and modifications
- Swap button to quickly reverse comparison direction
- Sample data to demonstrate the feature
Compare and polish JavaScript code side-by-side:
- Monaco DiffEditor with real-time visual comparison
- Color-coded highlighting for additions, deletions, and modifications
- Polish both codes (Code A and Code B) simultaneously with per-panel fix summaries
- Toggle highlighting on/off to focus on code or differences
- Download both files (Code A and Code B) with timestamps
- Swap button to reverse comparison direction
Generate interactive flow diagrams from your ServiceNow code:
- Interactive canvas with zoom, pan, and minimap navigation
- Click-to-code: Click any node to see its code location and details
- Automatic layout: Sequential statements flow vertically, branches flow horizontally
- Real-time generation: Instantly visualize code structure
Toggle between two visualization modes using the βοΈ settings button:
| Mode | Description | Shows |
|---|---|---|
| Full Ops View (default) | Everything that executes | All nodes with detailed labels |
| Logic View | Control flow focus | Only control flow, database ops, high-impact behavior |
| Node | Description |
|---|---|
| Function | Function declarations and expressions |
| Condition | If/else statements (diamond shape) |
| Loop | For, while, do-while, for-in, for-of loops |
| Switch | Switch statements |
| Case | Switch case clauses |
| Try | Try blocks |
| Catch | Catch blocks |
| Finally | Finally blocks |
| Return | Return statements |
| Throw | Throw statements |
| Break/Continue | Loop control statements |
| ServiceNow | GlideRecord, gs., g_form., etc. |
| Variable | Variable declarations (Full Ops only) |
| Call | Generic function calls (Full Ops only) |
| Assignment | Variable assignments (Full Ops only) |
| Style | Description |
|---|---|
| Solid gray | Normal control flow |
| Solid green | True branch (condition met) |
| Solid red | False branch (else path) |
| Animated cyan | Loop body flow |
| Dashed red | Exception path (catch block) |
The visualizer recognizes ServiceNow-specific patterns:
- GlideRecord operations:
new GlideRecord(),query(),next(),update(), etc. - GlideSystem calls:
gs.info(),gs.getUser(),gs.getProperty(), etc. - Client-side APIs:
g_form,g_list,g_user,spUtil,$sp - IIFE patterns: Correctly parses
(function executeRule() {...})()wrappers - Business Rule context: Handles
current,previousparameters
Click any node to see:
- Node type (e.g., CONDITION, LOOP, SERVICENOW-CALL)
- Generic label (e.g.,
if(),while(),gr.query()) - Detailed code snippet with arguments
Ctrl+Enter/Cmd+Enter- Context-aware action:- Polish mode (JS): Polish the code
- Format mode (JSON): Format the JSON
- Compare mode (JSON): Compare the two JSON objects
- Compare mode (JS): Polish both codes
- Visualize mode (JS): Generate flow diagram
- Polish/Format mode: Downloads both original and polished/formatted files with timestamps
- Compare mode: Downloads both Code A and Code B files with timestamps
- Filenames:
original_YYYYMMDD_HHMMSS.jsandpolished_YYYYMMDD_HHMMSS.js(orcode_a_YYYYMMDD_HHMMSS.jsandcode_b_YYYYMMDD_HHMMSS.jsfor Compare)
- Works offline after initial load
- No server required - code stays in browser
- No data collection or tracking
- Node.js 22+
- npm
npm install
npm run devnpm run build
npm run previewAfter building, the dist/ folder contains static files that can be deployed to any hosting service.
- Click Plan in the top-level toggle
- Select Tasks to open the Kanban board
- Create tasks by clicking the + button on any column
- Drag tasks between columns to update status
- Click a task to edit details, add links, tags, and description
- Use the collapsible Backlog sidebar for items not yet in progress
- Click Export to save all Plan data as JSON
- Click Plan β Notes β Write
- Create a new note using the + button
- Use the WYSIWYG toolbar for formatting (bold, italic, code, checklists, etc.)
- See formatted text immediately as you type
- Notes save automatically as you type
- Search notes using the sidebar search box
- Click Plan β Notes β Sketch
- Create a new sketch using the + button
- Select a drawing tool from the toolbar (Text, Pen, Line, Rectangle, Ellipse, Arrow, Eraser)
- For Text tool: click on canvas to place text labels
- Choose color and stroke width for drawing tools
- Draw on the canvas - changes save automatically
- Use Clear to reset the canvas
- Click Develop in the top-level toggle
- Select mode: JavaScript or JSON using the toggle
- Paste your code/JSON in the input panel (left)
- Click Polish Code (JavaScript) or Format JSON (JSON), or press
Ctrl+Enter - View formatted output in the output panel (right) with highlighted changes
- Click the fixes/warnings badge to see details
- Click Copy or Download to export the output
- Select JavaScript mode and click Compare
- Enter Code A on the left and Code B on the right
- See real-time visual diff highlighting
- Click Polish Codes to format both panels simultaneously
- View per-panel fix summaries and change tracking
- Toggle highlighting on/off as needed
- Click Download to save both files
- Select JSON mode and click Compare
- Enter JSON on the left and modified JSON on the right
- Click Compare JSON to see the visual difference breakdown
- Use the swap button to reverse comparison direction
- Select JavaScript mode and click Visualize
- Paste your ServiceNow code in the editor (or click Load Sample)
- Click Generate Flow or press
Ctrl+Enter - Explore the diagram:
- Zoom: Use mouse wheel or +/- controls
- Pan: Click and drag the canvas
- Minimap: Navigate large diagrams quickly
- Click nodes: View code details in the info panel
- Toggle View Mode using the βοΈ settings button:
- Full Ops View: See all operations with detailed labels
- Logic View: Focus on control flow with simplified labels
- Use the Legend (top-right) to understand node colors and edge types
| Technology | Version | Purpose |
|---|---|---|
| React | 19.x | UI framework |
| Vite | 7.x | Build tool |
| Monaco Editor | 4.x | Code editor (VS Code engine) |
| TipTap | 3.x | WYSIWYG rich text editor (Notes) |
| Lowlight | 3.x | Syntax highlighting for code blocks |
| Prettier | 3.x | Code formatting |
| React Flow | 11.x | Interactive flow diagrams |
| Acorn | 8.x | JavaScript AST parsing |
| jsondiffpatch | 0.7.x | JSON comparison and diff |
| IndexedDB | Native | Offline data persistence (Plan mode) |
src/
βββ App.jsx # Main React component
βββ index.css # Application styles
βββ main.jsx # React entry point
βββ components/
β βββ FlowNode.jsx # Custom React Flow node component
β βββ Icon.jsx # SVG icon library component
β βββ Plan/
β βββ TaskBoard.jsx # Kanban board for task management
β βββ NoteEditor.jsx # Rich text note editor (Write)
β βββ DrawingCanvas.jsx # Canvas-based drawing tool (Sketch)
βββ utils/
βββ codePolish.js # Main orchestrator (JS + JSON)
βββ astParser.js # JavaScript AST parsing & control flow extraction
βββ flowGenerator.js # React Flow diagram generation
βββ storage/
β βββ planStorage.js # IndexedDB persistence for Plan mode
βββ fixes/
β βββ genericFixes.js # Generic JavaScript fixes
β βββ servicenowFixes.js # ServiceNow-specific fixes
β βββ servicenowDictionary.js # ServiceNow API dictionary (classes, methods)
β βββ fuzzyMatcher.js # Damerau-Levenshtein fuzzy matching
β βββ jsonFixes.js # JSON-specific fixes
βββ warnings/
βββ genericWarnings.js # Generic JavaScript warnings
βββ servicenowWarnings.js # ServiceNow warnings & errors
βββ jsonWarnings.js # JSON warnings & errors
- Business Rules (before, after, async)
- Client Scripts (onLoad, onChange, onSubmit)
- Script Includes
- UI Actions
- Scheduled Jobs
- Scripted REST APIs
- UI Policies
- Portal widgets
- Any JavaScript code
- Configuration files
- API payloads
- Import/export data
- Any JSON content
This project is licensed under the GNU General Public License v3.0 (GPLv3).
Copyright (c) 2026 Ioannis E. Kosmadakis
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.