Valueztech Maximo DeveloperThe developer toolkit for IBM Maximo / MAS: automation scripts, integration scripts and Maximo Mobile apps in VS Code and Git, without ever losing a local change. Valueztech Maximo Developer pulls code from Maximo into the folders of a VS Code workspace and shows you every server change as a diff before it touches your files. It uses only the standard Maximo REST API: nothing to deploy on the server. Features
Quick start
A ready-made multi-project workspace is in Change statuses
Local edits where the server has not changed are not listed: they are yours.
Configuration reference (
|
| Key | Description |
|---|---|
name |
Label in the view |
server.url |
Maximo context root |
server.apiKeySecret |
Name of the key stored with Set API Key |
server.apiKeyEnv |
Environment variable with the key (checked first) |
server.allowSelfSigned |
Accept self-signed TLS. Non-production only |
server.timeoutSeconds |
Request timeout |
ignoreLineEndings |
Treat CRLF and LF as equal (default true) |
sources[].server |
Per-source server override |
sources[].targetPath |
Sub folder for this source's files (. = folder root) |
sources[].headers |
Extra request headers |
type: "automationScripts"
Uses only the standard REST API. Reads MXAPIAUTOSCRIPT with each script's launch points in the same call (oslc.select=autoscript,source,scriptlanguage,status,rel.scriptlaunchpoint{launchpointname,launchpointtype,objectname,attributename,active}) and writes:
scripts/
Object/WORKORDER/VZ_WO_SAVE.py
Attribute/ASSET/VZ_ASSET_STATUS.py
Action/WORKORDER/VZ_WO_ROUTE.py
CustomCondition/PO/VZ_PO_CHECK.py
Integration/ObjectStructure/MXWO/OSIN.MXWO.py
Integration/PublishChannel/MXWOINTERFACE/PUBLISH.MXWOINTERFACE.EXTEXIT.OUT.py
Integration/PublishChannel/MXWOINTERFACE/PUBLISH.MXWOINTERFACE.EVENTFILTER.py
Integration/InvocationChannel/GETWEATHER/INVOKE.GETWEATHER.EXTEXIT.IN.py
Integration/EnterpriseService/MXASSETINTERFACE/SYNC.MXASSETINTERFACE.USEREXIT.IN.BEFORE.py
Standalone/VZ_LIBRARY.py (no launch point, not an integration script)
_manifest.json (every script with all of its launch points)
Integration framework scripts have no launch point; Maximo binds them by name, so they are recognised by IBM's naming convention:
| Name pattern | Folder |
|---|---|
OSIN.<OS>, OSOUT.<OS>, OSACTION.<OS>.<ACTION> |
Integration/ObjectStructure/<OS> |
PUBLISH.<CHANNEL>.EXTEXIT.OUT, PUBLISH.<CHANNEL>.USEREXIT.OUT.BEFORE / .AFTER, PUBLISH.<CHANNEL>.EVENTFILTER |
Integration/PublishChannel/<CHANNEL> |
INVOKE.<CHANNEL>.EXTEXIT.IN / .OUT, INVOKE.<CHANNEL>.USEREXIT... |
Integration/InvocationChannel/<CHANNEL> |
SYNC/CREATE/UPDATE/DELETE/QUERY.<SERVICE>.EXTEXIT... or .USEREXIT... |
Integration/EnterpriseService/<SERVICE> |
any other <PREFIX>.<NAME>.EXTEXIT/USEREXIT/...EVENTFILTER |
Integration/Other/<NAME> |
Endpoint handler scripts are named freely and linked from the endpoint configuration, so they stay in Standalone/.
Nothing is written until you apply. A script with several launch points goes to the folder of its first active launch point (order Object, Attribute, Action, Custom Condition, then object name); all of them are listed in _manifest.json. If a launch point moves to another object, the review shows the old path as removed and the new one as added.
| Key | Default | Description |
|---|---|---|
where |
none | OSLC filter, e.g. autoscript="VZ_%" |
keys |
none | Only these script names |
groupBy |
launchPoint |
none for a flat folder |
folderNames |
Rename type folders, e.g. {"OBJECT": "ObjectLaunchPoints"} |
|
standaloneFolder |
Standalone |
Folder for scripts with no launch point |
detectIntegration |
true |
Put integration framework scripts in the integration folder |
integrationFolder |
Integration |
Name of that folder |
integrationGroupBy |
type |
none puts every integration script directly in Integration/ |
manifest |
true |
Write _manifest.json |
launchPointRelation |
auto |
auto tries rel.scriptlaunchpoint{} then scriptlaunchpoint{}; the log says which one worked |
extensionMap, defaultExtension |
python/jython py, javascript/nashorn js |
File extension by script language |
type: "mafApp"
Uses only the standard REST API. Queries OSLCMAFAPPDATA with appid="<app>", takes the highest version (or the one you pin), downloads app-source.zip from the record's attachments (.../doclinks), and extracts it into targetPath. If the record has no such attachment, any attribute holding a base64 zip is used instead.
| Key | Default | Description |
|---|---|---|
app |
required | App name, e.g. TECHMOBILE |
version |
highest | Pin a version, e.g. 8.10.0.0 |
appAttribute |
appid |
Attribute holding the app name |
fileName |
app-source.zip |
Attachment to look for |
extractNestedZip |
true |
If the attachment is a zip that wraps app-source.zip, extract the inner archive so its files land directly in targetPath |
include / exclude |
Glob filters on the extracted files |
Inspect Source (right-click a folder in the Maximo Developer view, or node cli.js inspect <folder>) calls the API and shows the result in a JSON tab without writing anything. For a mafApp source it shows the record's attributes, its attachments and where the zip was found. For automationScripts it shows script counts, launch points by type and scripts with several launch points.
type: "objectStructure"
Calls GET {url}/api/os/{objectStructure}?lean=1&oslc.select=...&oslc.where=...&pageno=n with the apikey header and follows paging.
| Key | Example | Description |
|---|---|---|
objectStructure |
MXAPIAUTOSCRIPT |
Object structure to read |
keyAttribute |
autoscript |
Record key, used in the file name |
contentAttribute |
source |
Attribute holding the code |
keys |
["VZ_WO_SAVE"] |
Only fetch these keys |
where |
autoscript="VZ_%" |
OSLC filter: attr="PREFIX%" starts with, attr="%TEXT%" contains, and between conditions. Combined with keys. SQL style like is converted automatically |
fileName |
${autoscript}.${ext} |
Template; any selected attribute plus ${ext}. May include / to create sub folders |
extensionAttribute / extensionMap / defaultExtension |
scriptlanguage, {"python":"py"}, txt |
Choose the file extension |
select |
["scriptlanguage"] |
Extra attributes to fetch for the template |
contentEncoding |
text or base64 |
Use base64 for binary attributes |
pageSize, orderBy, skipEmpty |
Paging and ordering |
Other ideas for this source type: XML presentations through a custom object structure on MAXPRESENTATION, or conditions, escalation scripts and integration scripts, by pointing objectStructure, keyAttribute and contentAttribute at them.
type: "zip"
| Key | Example | Description |
|---|---|---|
endpoint |
https://host/exports/code.zip |
Relative to server.url, or an absolute URL |
method / body |
POST, { "app": "WOTRACK" } |
Request body is sent as JSON |
responseFormat |
auto |
zip, base64, json-base64 or auto (detects all three) |
jsonField |
data.zip |
Path to the base64 field when the JSON has several fields |
stripRootFolder |
auto |
Drop a single top level folder inside the archive |
include / exclude |
["**/*.py"], ["**/.DS_Store"] |
Glob filters applied after stripping |
A JSON reply of the form {"error": "..."} is shown as the source's error.
Settings
| Setting | Default | |
|---|---|---|
maximoSync.autoApplyNonConflicting |
false |
Apply safe changes immediately on check. Conflicts always wait for you |
maximoSync.checkOnStartup |
false |
Check when the workspace opens (never changes files) |
maximoSync.checkIntervalMinutes |
0 |
Background check interval (never changes files, notifies when something new arrives) |
What is stored where
Inside each synced folder, .maximo-sync/ (keep it out of Git; Create Sync Config adds it to .gitignore for you):
| Path | Purpose |
|---|---|
incoming/ |
Latest server snapshot, used for diffs |
incoming.json |
Hashes and status of each source from the last check |
state.json |
Last synced server version of each file (the base for conflict detection) |
backups/<timestamp>/ |
Local files saved before being overwritten or removed |
If a source fails (wrong key, server down), its previous snapshot is kept and none of its files are reported as removed.
Command line (same engine, for scripts and CI)
Run from a clone of this repository (Node.js 18 or later, no install step):
export MAXIMO_API_KEY=... # or the variable named in server.apiKeyEnv
node cli.js check ./maximo-automation-scripts # list incoming changes, write nothing
node cli.js pull ./maximo-automation-scripts # apply safe changes, exit code 2 if conflicts remain
node cli.js accept ./maximo-automation-scripts scripts/VZ_WO_SAVE.py
node cli.js keep ./maximo-automation-scripts scripts/VZ_ASSET_INIT.py
node cli.js status ./maximo-automation-scripts # offline compare against the last check
node cli.js inspect ./maximo-code-package # show what the API returns for a source
Maximo access checklist
- Use a dedicated integration account for the API key, not a personal admin login.
- Grant read access only:
MXAPIAUTOSCRIPT(includingSCRIPTLAUNCHPOINT) andOSLCMAFAPPDATA. - One key per environment, with an expiry. Revoke keys that are no longer needed.
- Keep API activity on that account auditable in Maximo.
The extension only reads from Maximo. Pushing local changes back is not part of this release.
Developing
git clone https://github.com/valueztech/maximo-developer.git
cd maximo-developer
npm test # sync engine and extension tests against a mock Maximo server
npm run mock # mock Maximo on http://127.0.0.1:8765/maximo (API key: test-key)
npm run package # build the .vsix
Press F5 in VS Code to launch the extension against examples/workspace. See CONTRIBUTING.md.
Limits
- Pull only; no push back to Maximo yet.
- Zip archives above 4 GB (ZIP64) and encrypted zip entries are not supported.
Support
- Bugs and feature requests: GitHub Issues
- Security issues: see SECURITY.md
- Implementation help, Maximo and MAS services: support@valueztech.com
Licence and trademarks
Released under the MIT Licence.
IBM, Maximo and Maximo Application Suite are trademarks of International Business Machines Corporation. This extension is built by Valueztech, an IBM Silver Partner, and is not produced or endorsed by IBM.
Valueztech · Maximising Asset Intelligence Valueztech Pty Ltd · ABN 81 677 255 300 · www.valueztech.com · Melbourne, Australia