โ† Back to list
groeimetai

workspace-builder

by groeimetai

๐Ÿค– AI-powered ServiceNow development with 400+ MCP tools. Works with Claude, GPT, Gemini, Ollama & 75+ providers. Deploy widgets, manage incidents, automate workflows - all through natural language. Open-source Build Agent alternative.

โญ 42๐Ÿด 9๐Ÿ“… Jan 23, 2026

SKILL.md


name: workspace-builder description: This skill should be used when the user asks to "App Engine Studio", "workspace builder", "custom workspace", "AES", "low code", "app development", "studio", or any ServiceNow App Engine Studio development. license: Apache-2.0 compatibility: Designed for Snow-Code and ServiceNow development metadata: author: groeimetai version: "1.0.0" category: servicenow tools:

  • snow_query_table
  • snow_execute_script_with_output
  • snow_find_artifact
  • snow_update_set_create

App Engine Studio & Workspace Builder for ServiceNow

App Engine Studio (AES) enables low-code application development with custom workspaces.

AES Architecture

Application (sys_scope)
    โ”œโ”€โ”€ Tables & Forms
    โ”œโ”€โ”€ Workflows
    โ”œโ”€โ”€ Workspaces (sys_aw_workspace)
    โ”‚   โ”œโ”€โ”€ Lists
    โ”‚   โ”œโ”€โ”€ Forms
    โ”‚   โ””โ”€โ”€ Dashboards
    โ””โ”€โ”€ Portals

Key Tables

TablePurpose
sys_scopeApplication scope
sys_appApplication record
sys_aw_workspaceWorkspace definition
sys_ux_pageUI Builder pages
sys_ux_macroponentCustom components

Application Development (ES5)

Create Scoped Application

// Create scoped application (ES5 ONLY!)
var app = new GlideRecord('sys_scope');
app.initialize();

// Basic info
app.setValue('name', 'IT Asset Tracker');
app.setValue('scope', 'x_myco_asset_track');
app.setValue('short_description', 'Track IT assets across the organization');
app.setValue('version', '1.0.0');

// Vendor
app.setValue('vendor', 'My Company');
app.setValue('vendor_prefix', 'x_myco');

// License
app.setValue('licensable', true);

app.insert();

Create Application Table

// Create table in scoped app (ES5 ONLY!)
function createAppTable(scope, tableDef) {
    var table = new GlideRecord('sys_db_object');
    table.initialize();

    table.setValue('name', scope + '_' + tableDef.name);
    table.setValue('label', tableDef.label);
    table.setValue('super_class', tableDef.extends || 'task');

    // Scope assignment
    table.setValue('sys_scope', getAppSysId(scope));

    // Options
    table.setValue('is_extendable', tableDef.extendable || false);
    table.setValue('create_access_controls', true);

    table.insert();

    // Create fields
    if (tableDef.fields) {
        for (var i = 0; i < tableDef.fields.length; i++) {
            createField(scope + '_' + tableDef.name, tableDef.fields[i]);
        }
    }

    return table.getUniqueValue();
}

// Example
createAppTable('x_myco_asset_track', {
    name: 'asset_item',
    label: 'Asset Item',
    extends: 'cmdb_ci',
    fields: [
        { name: 'u_purchase_date', label: 'Purchase Date', type: 'glide_date' },
        { name: 'u_warranty_end', label: 'Warranty End', type: 'glide_date' },
        { name: 'u_assigned_user', label: 'Assigned User', type: 'reference', reference: 'sys_user' }
    ]
});

Workspace Configuration (ES5)

Create Custom Workspace

// Create workspace (ES5 ONLY!)
var workspace = new GlideRecord('sys_aw_workspace');
workspace.initialize();

workspace.setValue('name', 'asset_tracker_workspace');
workspace.setValue('title', 'Asset Tracker');
workspace.setValue('description', 'Workspace for IT asset management');

// Primary table
workspace.setValue('primary_table', 'x_myco_asset_track_asset_item');

// URL
workspace.setValue('url', 'asset-tracker');

// Branding
workspace.setValue('icon', 'laptop');
workspace.setValue('color', '#2E7D32');

// App scope
workspace.setValue('sys_scope', appScopeSysId);

// Features
workspace.setValue('agent_assist_enabled', false);
workspace.setValue('contextual_side_panel_enabled', true);

workspace.insert();

Configure Workspace Lists

// Create workspace list (ES5 ONLY!)
function createWorkspaceList(workspaceSysId, listDef) {
    var list = new GlideRecord('sys_aw_list');
    list.initialize();

    list.setValue('workspace', workspaceSysId);
    list.setValue('name', listDef.name);
    list.setValue('table', listDef.table);

    // Filter
    list.setValue('filter', listDef.filter || '');

    // Columns
    list.setValue('columns', listDef.columns.join(','));

    // Sorting
    if (listDef.orderBy) {
        list.setValue('order_by', listDef.orderBy);
        list.setValue('order_by_desc', listDef.orderDesc || false);
    }

    // Grouping
    if (listDef.groupBy) {
        list.setValue('group_by', listDef.groupBy);
    }

    list.insert();

    return list.getUniqueValue();
}

// Example lists
createWorkspaceList(workspaceSysId, {
    name: 'My Assets',
    table: 'x_myco_asset_track_asset_item',
    filter: 'u_assigned_user=javascript:gs.getUserID()',
    columns: ['number', 'name', 'u_purchase_date', 'u_warranty_end', 'state']
});

createWorkspaceList(workspaceSysId, {
    name: 'Expiring Warranties',
    table: 'x_myco_asset_track_asset_item',
    filter: 'u_warranty_endBETWEENjavascript:gs.daysAgoStart(0)@javascript:gs.daysAgoEnd(-30)',
    columns: ['number', 'name', 'u_assigned_user', 'u_warranty_end'],
    orderBy: 'u_warranty_end'
});

UI Builder Pages (ES5)

Page Configuration

// Create UI Builder page (ES5 ONLY!)
// Note: Full page creation typically done via UI Builder

var page = new GlideRecord('sys_ux_page');
page.initialize();

page.setValue('name', 'asset_dashboard');
page.setValue('title', 'Asset Dashboard');
page.setValue('description', 'Dashboard for asset overview');

// Page type
page.setValue('page_type', 'workspace');

// Workspace link
page.setValue('workspace', workspaceSysId);

// Scope
page.setValue('sys_scope', appScopeSysId);

page.insert();

Custom Component (Macroponent)

// Create custom macroponent definition (ES5 ONLY!)
// Note: Actual components created via UI Builder

var component = new GlideRecord('sys_ux_macroponent');
component.initialize();

component.setValue('name', 'asset_summary_card');
component.setValue('label', 'Asset Summary Card');
component.setValue('description', 'Displays asset summary information');

// Component category
component.setValue('category', 'data_visualization');

// Scope
component.setValue('sys_scope', appScopeSysId);

// Properties (inputs)
component.setValue('properties', JSON.stringify([
    { name: 'title', type: 'string', label: 'Card Title' },
    { name: 'assetTable', type: 'string', label: 'Asset Table' },
    { name: 'filter', type: 'string', label: 'Filter' }
]));

component.insert();

Data Brokers (ES5)

Create Data Broker

// Data broker for workspace data (ES5 ONLY!)
// Data brokers provide data to UI Builder pages

var broker = new GlideRecord('sys_ux_data_broker');
broker.initialize();

broker.setValue('name', 'asset_stats');
broker.setValue('label', 'Asset Statistics');

// Data source type
broker.setValue('type', 'script');

// Script to fetch data (ES5 ONLY!)
broker.setValue('script',
    '(function getData(inputs) {\n' +
    '    var result = {\n' +
    '        total: 0,\n' +
    '        assigned: 0,\n' +
    '        available: 0,\n' +
    '        expiring_warranty: 0\n' +
    '    };\n' +
    '    \n' +
    '    var ga = new GlideAggregate("x_myco_asset_track_asset_item");\n' +
    '    ga.addAggregate("COUNT");\n' +
    '    ga.groupBy("state");\n' +
    '    ga.query();\n' +
    '    \n' +
    '    while (ga.next()) {\n' +
    '        var count = parseInt(ga.getAggregate("COUNT"), 10);\n' +
    '        result.total += count;\n' +
    '        \n' +
    '        var state = ga.getValue("state");\n' +
    '        if (state === "in_use") {\n' +
    '            result.assigned = count;\n' +
    '        } else if (state === "available") {\n' +
    '            result.available = count;\n' +
    '        }\n' +
    '    }\n' +
    '    \n' +
    '    // Expiring warranties\n' +
    '    var expiring = new GlideAggregate("x_myco_asset_track_asset_item");\n' +
    '    expiring.addQuery("u_warranty_end", "BETWEEN", "javascript:gs.daysAgoStart(0)@javascript:gs.daysAgoEnd(-30)");\n' +
    '    expiring.addAggregate("COUNT");\n' +
    '    expiring.query();\n' +
    '    \n' +
    '    if (expiring.next()) {\n' +
    '        result.expiring_warranty = parseInt(expiring.getAggregate("COUNT"), 10);\n' +
    '    }\n' +
    '    \n' +
    '    return result;\n' +
    '})(inputs);'
);

broker.setValue('sys_scope', appScopeSysId);

broker.insert();

Application Deployment (ES5)

Create Update Set

// Create update set for app deployment (ES5 ONLY!)
function createAppUpdateSet(appName, description) {
    var updateSet = new GlideRecord('sys_update_set');
    updateSet.initialize();
    updateSet.setValue('name', appName + ' - ' + new GlideDateTime().getDate());
    updateSet.setValue('description', description);
    updateSet.setValue('application', getAppSysId(appName));
    updateSet.setValue('state', 'in progress');
    return updateSet.insert();
}

Export Application

// Prepare app for export (ES5 ONLY!)
function prepareAppExport(appScope) {
    // Validate all components
    var issues = [];

    // Check for missing dependencies
    var dependency = new GlideRecord('sys_app_dependency');
    dependency.addQuery('app.scope', appScope);
    dependency.query();

    while (dependency.next()) {
        if (!isDependencyInstalled(dependency.getValue('dependency'))) {
            issues.push('Missing dependency: ' + dependency.dependency.getDisplayValue());
        }
    }

    // Validate update sets
    var updateSet = new GlideRecord('sys_update_set');
    updateSet.addQuery('application.scope', appScope);
    updateSet.addQuery('state', 'in progress');
    updateSet.query();

    while (updateSet.next()) {
        issues.push('Open update set: ' + updateSet.getValue('name'));
    }

    return {
        ready: issues.length === 0,
        issues: issues
    };
}

MCP Tool Integration

Available Tools

ToolPurpose
snow_query_tableQuery app components
snow_execute_script_with_outputTest app scripts
snow_find_artifactFind configurations
snow_update_set_createCreate update sets

Example Workflow

// 1. Query applications
await snow_query_table({
    table: 'sys_scope',
    query: 'scopeSTARTSWITHx_',
    fields: 'name,scope,version,vendor'
});

// 2. Find app tables
await snow_query_table({
    table: 'sys_db_object',
    query: 'nameSTARTSWITHx_myco',
    fields: 'name,label,super_class'
});

// 3. Get workspace configs
await snow_query_table({
    table: 'sys_aw_workspace',
    query: 'sys_scope.scopeSTARTSWITHx_',
    fields: 'name,title,primary_table,url'
});

Best Practices

  1. Naming Conventions - Consistent prefixes
  2. Scoped Apps - Use scope isolation
  3. Reusable Components - Modular design
  4. Data Brokers - Efficient data fetching
  5. Workspace Design - User-focused layouts
  6. Testing - ATF tests for apps
  7. Documentation - App documentation
  8. ES5 Only - No modern JavaScript syntax

Score

Total Score

75/100

Based on repository quality metrics

โœ“SKILL.md

SKILL.mdใƒ•ใ‚กใ‚คใƒซใŒๅซใพใ‚Œใฆใ„ใ‚‹

+20
โœ“LICENSE

ใƒฉใ‚คใ‚ปใƒณใ‚นใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+10
โœ“่ชฌๆ˜Žๆ–‡

100ๆ–‡ๅญ—ไปฅไธŠใฎ่ชฌๆ˜ŽใŒใ‚ใ‚‹

+10
โ—‹ไบบๆฐ—

GitHub Stars 100ไปฅไธŠ

0/15
โœ“ๆœ€่ฟ‘ใฎๆดปๅ‹•

1ใƒถๆœˆไปฅๅ†…ใซๆ›ดๆ–ฐ

+10
โ—‹ใƒ•ใ‚ฉใƒผใ‚ฏ

10ๅ›žไปฅไธŠใƒ•ใ‚ฉใƒผใ‚ฏใ•ใ‚Œใฆใ„ใ‚‹

0/5
โœ“Issue็ฎก็†

ใ‚ชใƒผใƒ—ใƒณIssueใŒ50ๆœชๆบ€

+5
โœ“่จ€่ชž

ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐ่จ€่ชžใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+5
โœ“ใ‚ฟใ‚ฐ

1ใคไปฅไธŠใฎใ‚ฟใ‚ฐใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+5

Reviews

๐Ÿ’ฌ

Reviews coming soon