This skill should be used when the user asks to "write a JArchi script", "create an Archi script", "build an .ajs script", "add a dialog to a script", "use SWT widgets", "create a JFace dialog", "use Eclipse UI in JArchi", "extend a Java class in JavaScript", "use Java.type()", "work with ArchiMate elements", "use the jArchi API", "create a library module", "use GraalJS", mentions JArchi, Archi scripting, ArchiMate modeling scripts, SWT/JFace UI, or GraalVM JavaScript for Archi.
Procedural guide for writing JArchi scripts (GraalVM GraalJS, ECMAScript 2024). Requires Archi 5.7+, JArchi 1.11+.
load() for local files — never require() (it resolves to node_modules/)setTimeout (unless shimmed)fs, path, http) — use Java.type() for Java equivalentsthis inside Java.extend() refers to the Java proxy — use the object wrapper pattern belowEvery top-level .ajs script: clear console, load log.js, IIFE, try-catch, "use strict":
/**
* @name Script Name
* @description Brief description
* @version 1.0.0
* @author Author Name
* @lastModifiedDate YYYY-MM-DD
*/
console.clear();
console.show();
load(__DIR__ + "lib/log.js");
load(__DIR__ + "lib/swtImports.js");
(function () {
"use strict";
try {
log.header("Script Name");
// Main script logic
log.success("Script Name: Complete.");
} catch (error) {
log.error("Script failed: " + error.toString());
window.alert("Error: " + error.message);
}
})();
Use Title Case with spaces for .ajs filenames (e.g., ELK Layout.ajs). __DIR__ already includes trailing separator — don't add /.
To create a reusable module in lib/, use the dual-export IIFE with a double-load guard:
(function() {
"use strict";
if (typeof globalThis !== "undefined" && typeof globalThis.myModule !== "undefined") return;
// ... module code ...
if (typeof globalThis !== "undefined") globalThis.myModule = myModule;
if (typeof module !== "undefined" && module.exports) module.exports = myModule;
})();
To load a module: load(__DIR__ + "lib/myModule.js"); then destructure from the global.
To get the active view, use resolveSelection (never $(selection).filter("archimate-diagram-model")):
load(__DIR__ + "lib/resolveSelection.js");
var view = resolveSelection.activeView(); // current view
var elements = resolveSelection.selectedConcepts("element"); // selected elements
To query elements: $("business-process"). To create: model.createElement("business-process", "Name"). To create relationships: model.createRelationship("serving-relationship", source, target).
Always handle empty names: element.name && element.name.trim() ? element.name : "-- unnamed --".
To create a dialog, use swtImports.ExtendedTitleAreaDialog with the object wrapper pattern. Both isResizable and getShellStyle overrides are required — isResizable alone fails because the Java.extend proxy isn't wired during the Java constructor. Always call setHelpAvailable(false) before open().
load(__DIR__ + "lib/swtImports.js");
var { SWT, Text, GridDataFactory, ExtendedTitleAreaDialog } = swtImports;
var myDialog = {
dialog: new ExtendedTitleAreaDialog(shell, {
configureShell: function(newShell) {
Java.super(myDialog.dialog).configureShell(newShell);
newShell.setText("My Dialog");
},
isResizable: function() { return true; },
getShellStyle: function() {
return SWT.CLOSE | SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.MAX;
},
createDialogArea: function(parent) {
var area = Java.super(myDialog.dialog).createDialogArea(parent);
myDialog.dialog.setMessage("Enter information:");
var text = new Text(area, SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(text);
myDialog._nameText = text;
return area;
},
okPressed: function() {
var value = myDialog._nameText.getText().trim();
if (!value) { myDialog.dialog.setErrorMessage("Required"); return; }
Java.super(myDialog.dialog).okPressed();
}
})
};
myDialog.dialog.setHelpAvailable(false);
if (myDialog.dialog.open() === 0) { /* user clicked OK */ }
For simple prompts: window.prompt("Enter name:"), window.confirm("Sure?"), window.alert("Done.").
Java.super(this) fails — always use Java.super(myDialog.dialog) via stored object propertyrequire() fails for local files — use load(__DIR__ + "lib/file.js")$(selection) misses cases — use resolveSelection.selectedConcepts() / .activeView()isResizable() AND getShellStyle()dialog.setHelpAvailable(false) before open()name && name.trim() checklog.header/info/detail/success/warn/error from lib/log.js__DIR__ already has trailing separatorFor detailed API docs, SWT widget reference, layout patterns, and complete examples:
references/script-development-guide.md — Full guide with dialog patterns, model operations, widget reference, and migration checklistreferences/jarchi-api-reference.md — JArchi 1.11 API: collection methods, element types, view operationsreferences/graaljs-compatibility.md — GraalJS runtime: ECMAScript 2024 features, load() semanticsreferences/java-interop.md — Java.type(), Java.extend(), Java.super(), type mappings, array conversions