ultravisor 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/.claude/launch.json +11 -0
  2. package/.claude/ultravisor-dev-config.json +3 -0
  3. package/.ultravisor.json +426 -0
  4. package/docs/README.md +63 -0
  5. package/package.json +12 -8
  6. package/source/Ultravisor.cjs +22 -3
  7. package/source/cli/Ultravisor-CLIProgram.cjs +35 -23
  8. package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
  9. package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
  10. package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
  11. package/source/config/Ultravisor-Default-Command-Configuration.cjs +5 -3
  12. package/source/services/Ultravisor-ExecutionEngine.cjs +1039 -0
  13. package/source/services/Ultravisor-ExecutionManifest.cjs +399 -0
  14. package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
  15. package/source/services/Ultravisor-Hypervisor.cjs +38 -83
  16. package/source/services/Ultravisor-StateManager.cjs +241 -0
  17. package/source/services/Ultravisor-TaskTypeRegistry.cjs +143 -0
  18. package/source/services/tasks/Ultravisor-TaskType-Base.cjs +105 -0
  19. package/source/services/tasks/control/Ultravisor-TaskType-IfConditional.cjs +148 -0
  20. package/source/services/tasks/control/Ultravisor-TaskType-LaunchOperation.cjs +187 -0
  21. package/source/services/tasks/control/Ultravisor-TaskType-SplitExecute.cjs +184 -0
  22. package/source/services/tasks/data/Ultravisor-TaskType-ReplaceString.cjs +82 -0
  23. package/source/services/tasks/data/Ultravisor-TaskType-SetValues.cjs +81 -0
  24. package/source/services/tasks/data/Ultravisor-TaskType-StringAppender.cjs +101 -0
  25. package/source/services/tasks/file-io/Ultravisor-TaskType-ReadFile.cjs +103 -0
  26. package/source/services/tasks/file-io/Ultravisor-TaskType-WriteFile.cjs +117 -0
  27. package/source/services/tasks/interaction/Ultravisor-TaskType-ErrorMessage.cjs +54 -0
  28. package/source/services/tasks/interaction/Ultravisor-TaskType-ValueInput.cjs +62 -0
  29. package/source/web_server/Ultravisor-API-Server.cjs +237 -124
  30. package/test/Ultravisor_browser_tests.js +2226 -0
  31. package/test/Ultravisor_tests.js +1143 -5830
  32. package/webinterface/css/ultravisor.css +23 -0
  33. package/webinterface/package.json +6 -3
  34. package/webinterface/source/Pict-Application-Ultravisor.js +93 -73
  35. package/webinterface/source/cards/FlowCard-CSVTransform.js +43 -0
  36. package/webinterface/source/cards/FlowCard-Command.js +86 -0
  37. package/webinterface/source/cards/FlowCard-ComprehensionIntersect.js +40 -0
  38. package/webinterface/source/cards/FlowCard-Conditional.js +87 -0
  39. package/webinterface/source/cards/FlowCard-CopyFile.js +55 -0
  40. package/webinterface/source/cards/FlowCard-End.js +29 -0
  41. package/webinterface/source/cards/FlowCard-GetJSON.js +55 -0
  42. package/webinterface/source/cards/FlowCard-GetText.js +54 -0
  43. package/webinterface/source/cards/FlowCard-Histogram.js +176 -0
  44. package/webinterface/source/cards/FlowCard-LaunchOperation.js +82 -0
  45. package/webinterface/source/cards/FlowCard-ListFiles.js +55 -0
  46. package/webinterface/source/cards/FlowCard-MeadowCount.js +44 -0
  47. package/webinterface/source/cards/FlowCard-MeadowCreate.js +44 -0
  48. package/webinterface/source/cards/FlowCard-MeadowDelete.js +45 -0
  49. package/webinterface/source/cards/FlowCard-MeadowRead.js +46 -0
  50. package/webinterface/source/cards/FlowCard-MeadowReads.js +46 -0
  51. package/webinterface/source/cards/FlowCard-MeadowUpdate.js +44 -0
  52. package/webinterface/source/cards/FlowCard-ParseCSV.js +85 -0
  53. package/webinterface/source/cards/FlowCard-ReadJSON.js +54 -0
  54. package/webinterface/source/cards/FlowCard-ReadText.js +54 -0
  55. package/webinterface/source/cards/FlowCard-RestRequest.js +59 -0
  56. package/webinterface/source/cards/FlowCard-SendJSON.js +57 -0
  57. package/webinterface/source/cards/FlowCard-Solver.js +77 -0
  58. package/webinterface/source/cards/FlowCard-Start.js +29 -0
  59. package/webinterface/source/cards/FlowCard-TemplateString.js +77 -0
  60. package/webinterface/source/cards/FlowCard-WriteJSON.js +54 -0
  61. package/webinterface/source/cards/FlowCard-WriteText.js +54 -0
  62. package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
  63. package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
  64. package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
  65. package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +8 -8
  66. package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +6 -6
  67. package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +436 -0
  68. package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +45 -43
  69. package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +34 -89
  70. package/webinterface/source/views/PictView-Ultravisor-OperationList.js +128 -13
  71. package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
  72. package/webinterface/source/views/PictView-Ultravisor-Schedule.js +18 -53
  73. package/webinterface/source/views/PictView-Ultravisor-TimingView.js +27 -14
  74. package/webinterface/source/views/PictView-Ultravisor-TopBar.js +2 -1
  75. package/.babelrc +0 -6
  76. package/.browserslistrc +0 -1
  77. package/.browserslistrc-BACKUP +0 -1
  78. package/.gulpfile-quackage-config.json +0 -7
  79. package/.gulpfile-quackage.js +0 -2
  80. package/debug/Harness.js +0 -5
  81. package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
  82. package/source/services/Ultravisor-Operation.cjs +0 -200
  83. package/source/services/Ultravisor-Task.cjs +0 -349
  84. package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
  85. package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
  86. package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
  87. package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
  88. package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
  89. package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
  90. package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
  91. package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
  92. package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
  93. package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
  94. package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
  95. package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
  96. package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
  97. package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
  98. package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
  99. package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
  100. package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
  101. package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
  102. package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
  103. package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
  104. package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
  105. package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
  106. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
  107. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
  108. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
  109. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
  110. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
  111. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
  112. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
  113. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
  114. package/webinterface/.babelrc +0 -6
  115. package/webinterface/.browserslistrc +0 -1
  116. package/webinterface/.browserslistrc-BACKUP +0 -1
  117. package/webinterface/.gulpfile-quackage-config.json +0 -7
  118. package/webinterface/.gulpfile-quackage.js +0 -2
  119. package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
  120. package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
  121. /package/docs/{cover.md → _cover.md} +0 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": "0.0.1",
3
+ "configurations": [
4
+ {
5
+ "name": "ultravisor-dev",
6
+ "runtimeExecutable": "node",
7
+ "runtimeArgs": ["source/cli/Ultravisor-Run.cjs", "start", "--config", ".claude/ultravisor-dev-config.json"],
8
+ "port": 54321
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "UltravisorWebInterfacePath": "webinterface/dist"
3
+ }
@@ -0,0 +1,426 @@
1
+ {
2
+ "UltravisorAPIServerPort": 54321,
3
+ "UltravisorFileStorePath": "/Users/stevenvelozo/Code/retold/modules/apps/ultravisor/dist/ultravisor_datastore",
4
+ "UltravisorStagingRoot": "/Users/stevenvelozo/Code/retold/modules/apps/ultravisor/dist/ultravisor_staging",
5
+ "UltravisorTickIntervalMilliseconds": 60000,
6
+ "UltravisorCommandTimeoutMilliseconds": 300000,
7
+ "UltravisorCommandMaxBufferBytes": 10485760,
8
+ "UltravisorWebInterfacePath": "/Users/stevenvelozo/Code/retold/modules/apps/ultravisor/webinterface/dist",
9
+ "NodeTemplates": {},
10
+ "Operations": {
11
+ "OPR-0003": {
12
+ "Name": "Example: File Processor",
13
+ "Description": "Search and replace pipeline with user input, looping, and file I/O.",
14
+ "Graph": {
15
+ "Nodes": [
16
+ {
17
+ "Hash": "fp-start",
18
+ "Type": "start",
19
+ "X": 50,
20
+ "Y": 200,
21
+ "Width": 140,
22
+ "Height": 80,
23
+ "Title": "Start",
24
+ "Ports": [
25
+ {
26
+ "Hash": "fp-start-out",
27
+ "Direction": "output",
28
+ "Side": "right",
29
+ "Label": "Out"
30
+ }
31
+ ],
32
+ "Data": {}
33
+ },
34
+ {
35
+ "Hash": "fp-input",
36
+ "Type": "value-input",
37
+ "X": 280,
38
+ "Y": 180,
39
+ "Width": 220,
40
+ "Height": 100,
41
+ "Title": "Enter File Path",
42
+ "Ports": [
43
+ {
44
+ "Hash": "fp-input-req",
45
+ "Direction": "input",
46
+ "Side": "left-bottom",
47
+ "Label": "RequestInput"
48
+ },
49
+ {
50
+ "Hash": "fp-input-done",
51
+ "Direction": "output",
52
+ "Side": "right",
53
+ "Label": "ValueInputComplete"
54
+ },
55
+ {
56
+ "Hash": "fp-input-filepath",
57
+ "Direction": "output",
58
+ "Side": "right-top",
59
+ "Label": "InputFilePath"
60
+ }
61
+ ],
62
+ "Data": {
63
+ "PromptMessage": "Enter a file path and name",
64
+ "OutputAddress": "Operation.InputFilePath"
65
+ }
66
+ },
67
+ {
68
+ "Hash": "fp-read",
69
+ "Type": "read-file",
70
+ "X": 590,
71
+ "Y": 180,
72
+ "Width": 200,
73
+ "Height": 100,
74
+ "Title": "Load File",
75
+ "Ports": [
76
+ {
77
+ "Hash": "fp-read-begin",
78
+ "Direction": "input",
79
+ "Side": "left-bottom",
80
+ "Label": "BeginRead"
81
+ },
82
+ {
83
+ "Hash": "fp-read-filepath",
84
+ "Direction": "input",
85
+ "Side": "left-top",
86
+ "Label": "FilePath"
87
+ },
88
+ {
89
+ "Hash": "fp-read-done",
90
+ "Direction": "output",
91
+ "Side": "right",
92
+ "Label": "ReadComplete"
93
+ },
94
+ {
95
+ "Hash": "fp-read-content",
96
+ "Direction": "output",
97
+ "Side": "right-top",
98
+ "Label": "FileContent"
99
+ },
100
+ {
101
+ "Hash": "fp-read-err",
102
+ "Direction": "output",
103
+ "Side": "bottom",
104
+ "Label": "Error"
105
+ }
106
+ ],
107
+ "Data": {
108
+ "FilePath": "{~D:Record.Operation.InputFilePath~}",
109
+ "Encoding": "utf8"
110
+ }
111
+ },
112
+ {
113
+ "Hash": "fp-error",
114
+ "Type": "error-message",
115
+ "X": 590,
116
+ "Y": 420,
117
+ "Width": 220,
118
+ "Height": 80,
119
+ "Title": "Read Error",
120
+ "Ports": [
121
+ {
122
+ "Hash": "fp-error-in",
123
+ "Direction": "input",
124
+ "Side": "left-bottom",
125
+ "Label": "Trigger"
126
+ },
127
+ {
128
+ "Hash": "fp-error-done",
129
+ "Direction": "output",
130
+ "Side": "right",
131
+ "Label": "Complete"
132
+ }
133
+ ],
134
+ "Data": {
135
+ "MessageTemplate": "Failed to read file: {~D:Record.Operation.InputFilePath~}"
136
+ }
137
+ },
138
+ {
139
+ "Hash": "fp-split",
140
+ "Type": "split-execute",
141
+ "X": 890,
142
+ "Y": 160,
143
+ "Width": 240,
144
+ "Height": 120,
145
+ "Title": "Split Lines",
146
+ "Ports": [
147
+ {
148
+ "Hash": "fp-split-begin",
149
+ "Direction": "input",
150
+ "Side": "left-bottom",
151
+ "Label": "PerformSplit"
152
+ },
153
+ {
154
+ "Hash": "fp-split-step",
155
+ "Direction": "input",
156
+ "Side": "left-bottom",
157
+ "Label": "StepComplete"
158
+ },
159
+ {
160
+ "Hash": "fp-split-inputstr",
161
+ "Direction": "input",
162
+ "Side": "left-top",
163
+ "Label": "InputString"
164
+ },
165
+ {
166
+ "Hash": "fp-split-token",
167
+ "Direction": "output",
168
+ "Side": "right",
169
+ "Label": "TokenDataSent"
170
+ },
171
+ {
172
+ "Hash": "fp-split-alldone",
173
+ "Direction": "output",
174
+ "Side": "right-bottom",
175
+ "Label": "CompletedAllSubtasks"
176
+ }
177
+ ],
178
+ "Data": {
179
+ "InputString": "{~D:Record.TaskOutput.fp-read.FileContent~}",
180
+ "SplitDelimiter": "\n"
181
+ }
182
+ },
183
+ {
184
+ "Hash": "fp-replace",
185
+ "Type": "replace-string",
186
+ "X": 1230,
187
+ "Y": 160,
188
+ "Width": 220,
189
+ "Height": 100,
190
+ "Title": "Replace John with Jane",
191
+ "Ports": [
192
+ {
193
+ "Hash": "fp-replace-in",
194
+ "Direction": "input",
195
+ "Side": "left-bottom",
196
+ "Label": "Replace"
197
+ },
198
+ {
199
+ "Hash": "fp-replace-done",
200
+ "Direction": "output",
201
+ "Side": "right",
202
+ "Label": "ReplaceComplete"
203
+ },
204
+ {
205
+ "Hash": "fp-replace-result",
206
+ "Direction": "output",
207
+ "Side": "right-top",
208
+ "Label": "ReplacedString"
209
+ }
210
+ ],
211
+ "Data": {
212
+ "InputString": "{~D:Record.TaskOutput.fp-split.CurrentToken~}",
213
+ "SearchString": "John",
214
+ "ReplaceString": "Jane"
215
+ }
216
+ },
217
+ {
218
+ "Hash": "fp-append",
219
+ "Type": "string-appender",
220
+ "X": 1540,
221
+ "Y": 160,
222
+ "Width": 220,
223
+ "Height": 100,
224
+ "Title": "Append Line",
225
+ "Ports": [
226
+ {
227
+ "Hash": "fp-append-in",
228
+ "Direction": "input",
229
+ "Side": "left-bottom",
230
+ "Label": "Append"
231
+ },
232
+ {
233
+ "Hash": "fp-append-inputstr",
234
+ "Direction": "input",
235
+ "Side": "left-top",
236
+ "Label": "InputString"
237
+ },
238
+ {
239
+ "Hash": "fp-append-done",
240
+ "Direction": "output",
241
+ "Side": "right",
242
+ "Label": "Completed"
243
+ }
244
+ ],
245
+ "Data": {
246
+ "InputString": "{~D:Record.TaskOutput.fp-replace.ReplacedString~}",
247
+ "OutputAddress": "Operation.OutputFileContents",
248
+ "AppendNewline": true
249
+ }
250
+ },
251
+ {
252
+ "Hash": "fp-write",
253
+ "Type": "write-file",
254
+ "X": 1230,
255
+ "Y": 420,
256
+ "Width": 220,
257
+ "Height": 80,
258
+ "Title": "Save File",
259
+ "Ports": [
260
+ {
261
+ "Hash": "fp-write-begin",
262
+ "Direction": "input",
263
+ "Side": "left-bottom",
264
+ "Label": "BeginWrite"
265
+ },
266
+ {
267
+ "Hash": "fp-write-done",
268
+ "Direction": "output",
269
+ "Side": "right",
270
+ "Label": "WriteComplete"
271
+ },
272
+ {
273
+ "Hash": "fp-write-err",
274
+ "Direction": "output",
275
+ "Side": "bottom",
276
+ "Label": "Error"
277
+ }
278
+ ],
279
+ "Data": {
280
+ "FilePath": "{~D:Record.Operation.InputFilePath~}.ultracopy",
281
+ "Content": "{~D:Record.Operation.OutputFileContents~}",
282
+ "Encoding": "utf8"
283
+ }
284
+ },
285
+ {
286
+ "Hash": "fp-end",
287
+ "Type": "end",
288
+ "X": 1540,
289
+ "Y": 420,
290
+ "Width": 140,
291
+ "Height": 80,
292
+ "Title": "End",
293
+ "Ports": [
294
+ {
295
+ "Hash": "fp-end-in",
296
+ "Direction": "input",
297
+ "Side": "left-bottom",
298
+ "Label": "In"
299
+ }
300
+ ],
301
+ "Data": {}
302
+ }
303
+ ],
304
+ "Connections": [
305
+ {
306
+ "Hash": "fp-ev1",
307
+ "SourceNodeHash": "fp-start",
308
+ "SourcePortHash": "fp-start-out",
309
+ "TargetNodeHash": "fp-input",
310
+ "TargetPortHash": "fp-input-req",
311
+ "Data": {}
312
+ },
313
+ {
314
+ "Hash": "fp-ev2",
315
+ "SourceNodeHash": "fp-input",
316
+ "SourcePortHash": "fp-input-done",
317
+ "TargetNodeHash": "fp-read",
318
+ "TargetPortHash": "fp-read-begin",
319
+ "Data": {}
320
+ },
321
+ {
322
+ "Hash": "fp-ev3",
323
+ "SourceNodeHash": "fp-read",
324
+ "SourcePortHash": "fp-read-done",
325
+ "TargetNodeHash": "fp-split",
326
+ "TargetPortHash": "fp-split-begin",
327
+ "Data": {}
328
+ },
329
+ {
330
+ "Hash": "fp-ev4",
331
+ "SourceNodeHash": "fp-read",
332
+ "SourcePortHash": "fp-read-err",
333
+ "TargetNodeHash": "fp-error",
334
+ "TargetPortHash": "fp-error-in",
335
+ "Data": {}
336
+ },
337
+ {
338
+ "Hash": "fp-ev5",
339
+ "SourceNodeHash": "fp-error",
340
+ "SourcePortHash": "fp-error-done",
341
+ "TargetNodeHash": "fp-end",
342
+ "TargetPortHash": "fp-end-in",
343
+ "Data": {}
344
+ },
345
+ {
346
+ "Hash": "fp-ev6",
347
+ "SourceNodeHash": "fp-split",
348
+ "SourcePortHash": "fp-split-token",
349
+ "TargetNodeHash": "fp-replace",
350
+ "TargetPortHash": "fp-replace-in",
351
+ "Data": {}
352
+ },
353
+ {
354
+ "Hash": "fp-ev7",
355
+ "SourceNodeHash": "fp-replace",
356
+ "SourcePortHash": "fp-replace-done",
357
+ "TargetNodeHash": "fp-append",
358
+ "TargetPortHash": "fp-append-in",
359
+ "Data": {}
360
+ },
361
+ {
362
+ "Hash": "fp-ev8",
363
+ "SourceNodeHash": "fp-append",
364
+ "SourcePortHash": "fp-append-done",
365
+ "TargetNodeHash": "fp-split",
366
+ "TargetPortHash": "fp-split-step",
367
+ "Data": {}
368
+ },
369
+ {
370
+ "Hash": "fp-ev9",
371
+ "SourceNodeHash": "fp-split",
372
+ "SourcePortHash": "fp-split-alldone",
373
+ "TargetNodeHash": "fp-write",
374
+ "TargetPortHash": "fp-write-begin",
375
+ "Data": {}
376
+ },
377
+ {
378
+ "Hash": "fp-ev10",
379
+ "SourceNodeHash": "fp-write",
380
+ "SourcePortHash": "fp-write-done",
381
+ "TargetNodeHash": "fp-end",
382
+ "TargetPortHash": "fp-end-in",
383
+ "Data": {}
384
+ },
385
+ {
386
+ "Hash": "fp-st1",
387
+ "SourceNodeHash": "fp-input",
388
+ "SourcePortHash": "fp-input-filepath",
389
+ "TargetNodeHash": "fp-read",
390
+ "TargetPortHash": "fp-read-filepath",
391
+ "Data": {}
392
+ },
393
+ {
394
+ "Hash": "fp-st2",
395
+ "SourceNodeHash": "fp-read",
396
+ "SourcePortHash": "fp-read-content",
397
+ "TargetNodeHash": "fp-split",
398
+ "TargetPortHash": "fp-split-inputstr",
399
+ "Data": {}
400
+ },
401
+ {
402
+ "Hash": "fp-st3",
403
+ "SourceNodeHash": "fp-replace",
404
+ "SourcePortHash": "fp-replace-result",
405
+ "TargetNodeHash": "fp-append",
406
+ "TargetPortHash": "fp-append-inputstr",
407
+ "Data": {}
408
+ }
409
+ ],
410
+ "ViewState": {
411
+ "PanX": 0,
412
+ "PanY": 0,
413
+ "Zoom": 1,
414
+ "SelectedNodeHash": null,
415
+ "SelectedConnectionHash": null
416
+ }
417
+ },
418
+ "Hash": "OPR-0003",
419
+ "CreatedAt": "2026-03-09T00:54:04.820Z",
420
+ "UpdatedAt": "2026-03-09T00:54:04.820Z"
421
+ }
422
+ },
423
+ "GlobalState": {},
424
+ "OperationCounter": 3,
425
+ "TemplateCounters": {}
426
+ }
package/docs/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Ultravisor Overview
2
+
3
+ Ultravisor is a cyclic process execution tool with AI integration. It runs commands, HTTP requests and other tasks on schedule, producing structured output manifests that track timing, success/failure and logs for every execution.
4
+
5
+ ## What It Does
6
+
7
+ Ultravisor manages two core primitives -- **Tasks** and **Operations** -- and provides multiple ways to run them: immediately via CLI or API, or on a recurring schedule via cron expressions.
8
+
9
+ **Tasks** are individual units of work: shell commands, HTTP requests or other executable actions. **Operations** compose multiple tasks into a sequential pipeline with a unified output manifest.
10
+
11
+ ## How It Runs
12
+
13
+ Ultravisor can be used in three modes:
14
+
15
+ 1. **CLI** -- run individual tasks or operations from the command line
16
+ 2. **API Server** -- start a Restify-based HTTP server exposing full CRUD and execution endpoints for tasks, operations, schedules and manifests
17
+ 3. **Scheduled** -- define cron schedules that automatically execute tasks or operations at the configured intervals
18
+
19
+ ## Configuration
20
+
21
+ Ultravisor uses a layered configuration system. The default configuration ships with the module and can be overridden by a `.ultravisor.json` file in the working directory. Tasks and operations are persisted into this same configuration file.
22
+
23
+ ```json
24
+ {
25
+ "UltravisorAPIServerPort": 54321,
26
+ "UltravisorFileStorePath": "/path/to/datastore",
27
+ "UltravisorTickIntervalMilliseconds": 60000,
28
+ "Tasks": {},
29
+ "Operations": {}
30
+ }
31
+ ```
32
+
33
+ ## Key Concepts
34
+
35
+ | Concept | Description |
36
+ |---------|-------------|
37
+ | Task | A single executable unit (shell command, HTTP request, etc.) |
38
+ | Operation | An ordered set of tasks executed sequentially |
39
+ | Schedule | A cron-based trigger that runs a task or operation on a timer |
40
+ | Manifest | The output record from executing an operation |
41
+ | Hypervisor | The central scheduler that manages the schedule and dispatches executions |
42
+ | State | Persistent storage of task and operation definitions in `.ultravisor.json` |
43
+
44
+ ## Module Dependencies
45
+
46
+ Ultravisor is built on the Retold ecosystem:
47
+
48
+ - **pict** / **pict-serviceproviderbase** -- service provider pattern and CLI framework
49
+ - **pict-service-commandlineutility** -- CLI command registration
50
+ - **orator** / **orator-serviceserver-restify** -- REST API server
51
+ - **cron** -- cron expression scheduling
52
+
53
+ ## Documentation Map
54
+
55
+ - [Architecture](architecture.md) -- service structure and data flow
56
+ - [Quick Start](quickstart.md) -- get running in five minutes
57
+ - [Tasks](features/tasks.md) -- task types, model and execution
58
+ - [Operations](features/operations.md) -- composing tasks into pipelines
59
+ - [Scheduling](features/scheduling.md) -- cron-based recurring execution
60
+ - [API Server](features/api.md) -- REST endpoint reference
61
+ - [CLI Commands](features/cli.md) -- command line interface reference
62
+ - [Manifests](features/manifests.md) -- execution output and logging
63
+ - [Configuration](features/configuration.md) -- configuration file format and options
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultravisor",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Cyclic process execution with ai integration.",
5
5
  "main": "source/Ultravisor.js",
6
6
  "bin": {
@@ -8,9 +8,9 @@
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node source/cli/Ultravisor-Run.cjs",
11
- "test": "npx mocha -u tdd -R spec",
11
+ "test": "npx quack test",
12
12
  "tests": "npx mocha -u tdd --exit -R spec --grep",
13
- "coverage": "npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec",
13
+ "coverage": "npx quack coverage",
14
14
  "build": "npx quack build",
15
15
  "docs": "npx quack prepare-docs ./docs -d ./modules",
16
16
  "docs-serve": "npx quack docs-serve ./docs"
@@ -27,11 +27,15 @@
27
27
  "homepage": "https://github.com/stevenvelozo/ultravisor#readme",
28
28
  "dependencies": {
29
29
  "cron": "^4.4.0",
30
- "orator": "^5.0.1",
31
- "orator-serviceserver-restify": "^2.0.5",
32
- "pict": "^1.0.343",
33
- "pict-service-commandlineutility": "^1.0.17",
34
- "pict-serviceproviderbase": "^1.0.0"
30
+ "orator": "^6.0.4",
31
+ "orator-serviceserver-restify": "^2.0.9",
32
+ "pict": "^1.0.357",
33
+ "pict-service-commandlineutility": "^1.0.19",
34
+ "pict-serviceproviderbase": "^1.0.4"
35
+ },
36
+ "devDependencies": {
37
+ "puppeteer": "^24.38.0",
38
+ "quackage": "^1.0.64"
35
39
  },
36
40
  "mocha": {
37
41
  "diff": true,
@@ -1,5 +1,24 @@
1
1
  module.exports = (
2
2
  {
3
- Operation: require(`./services/Ultravisor-Operation.cjs`),
4
- Task: require(`./services/Ultravisor-Task.cjs`),
5
- });
3
+ TaskTypeBase: require('./services/tasks/Ultravisor-TaskType-Base.cjs'),
4
+ TaskTypeRegistry: require('./services/Ultravisor-TaskTypeRegistry.cjs'),
5
+ StateManager: require('./services/Ultravisor-StateManager.cjs'),
6
+ ExecutionEngine: require('./services/Ultravisor-ExecutionEngine.cjs'),
7
+ ExecutionManifest: require('./services/Ultravisor-ExecutionManifest.cjs'),
8
+ HypervisorState: require('./services/Ultravisor-Hypervisor-State.cjs'),
9
+ Hypervisor: require('./services/Ultravisor-Hypervisor.cjs'),
10
+
11
+ // Task type classes
12
+ TaskTypes:
13
+ {
14
+ ReadFile: require('./services/tasks/file-io/Ultravisor-TaskType-ReadFile.cjs'),
15
+ WriteFile: require('./services/tasks/file-io/Ultravisor-TaskType-WriteFile.cjs'),
16
+ SetValues: require('./services/tasks/data/Ultravisor-TaskType-SetValues.cjs'),
17
+ ReplaceString: require('./services/tasks/data/Ultravisor-TaskType-ReplaceString.cjs'),
18
+ StringAppender: require('./services/tasks/data/Ultravisor-TaskType-StringAppender.cjs'),
19
+ IfConditional: require('./services/tasks/control/Ultravisor-TaskType-IfConditional.cjs'),
20
+ SplitExecute: require('./services/tasks/control/Ultravisor-TaskType-SplitExecute.cjs'),
21
+ ValueInput: require('./services/tasks/interaction/Ultravisor-TaskType-ValueInput.cjs'),
22
+ ErrorMessage: require('./services/tasks/interaction/Ultravisor-TaskType-ErrorMessage.cjs')
23
+ }
24
+ });
@@ -2,24 +2,22 @@ const libCLIProgram = require('pict-service-commandlineutility');
2
2
  const libFS = require('fs');
3
3
  const libPath = require('path');
4
4
 
5
- const libServiceHypervisor = require(`../services/Ultravisor-Hypervisor.cjs`);
6
- const libServiceHypervisorState = require(`../services/Ultravisor-Hypervisor-State.cjs`);
5
+ const libServiceHypervisor = require('../services/Ultravisor-Hypervisor.cjs');
6
+ const libServiceHypervisorState = require('../services/Ultravisor-Hypervisor-State.cjs');
7
7
 
8
- const libServiceHypervisorEventBase = require(`../services/Ultravisor-Hypervisor-Event-Base.cjs`);
9
- const libServiceHypervisorEventCron = require(`../services/events/Ultravisor-Hypervisor-Event-Cron.cjs`);
10
- const libServiceHypervisorEventSolver = require(`../services/events/Ultravisor-Hypervisor-Event-Solver.cjs`);
8
+ const libServiceHypervisorEventBase = require('../services/Ultravisor-Hypervisor-Event-Base.cjs');
9
+ const libServiceHypervisorEventCron = require('../services/events/Ultravisor-Hypervisor-Event-Cron.cjs');
11
10
 
12
- const libServiceOperation = require(`../services/Ultravisor-Operation.cjs`);
13
- const libServiceOperationManifest = require(`../services/Ultravisor-Operation-Manifest.cjs`);
14
-
15
- const libServiceTask = require(`../services/Ultravisor-Task.cjs`);
11
+ const libServiceTaskTypeRegistry = require('../services/Ultravisor-TaskTypeRegistry.cjs');
12
+ const libServiceStateManager = require('../services/Ultravisor-StateManager.cjs');
13
+ const libServiceExecutionEngine = require('../services/Ultravisor-ExecutionEngine.cjs');
14
+ const libServiceExecutionManifest = require('../services/Ultravisor-ExecutionManifest.cjs');
16
15
 
17
16
  // TODO: Remove this when Restify is fixed.
18
17
  process.removeAllListeners('warning')
19
18
 
20
- const libWebServerAPIServer = require(`../web_server/Ultravisor-API-Server.cjs`);
19
+ const libWebServerAPIServer = require('../web_server/Ultravisor-API-Server.cjs');
21
20
 
22
- // TODO: Add a way to do this cleanly from the pict-service-commandlineutility package itself, maybe via a "pre-initialization" function or something like that?
23
21
  // Check for an optional --config / -c command line parameter to load a config file
24
22
  let _ConfigFileOverride = false;
25
23
  for (let i = 0; i < process.argv.length; i++)
@@ -59,7 +57,7 @@ let _Ultravisor_Pict = new libCLIProgram(
59
57
 
60
58
  "Command": "ultravisor",
61
59
 
62
- "DefaultProgramConfiguration": require(`../config/Ultravisor-Default-Command-Configuration.cjs`),
60
+ "DefaultProgramConfiguration": require('../config/Ultravisor-Default-Command-Configuration.cjs'),
63
61
 
64
62
  "ProgramConfigurationFileName": ".ultravisor.json",
65
63
 
@@ -85,8 +83,6 @@ let _Ultravisor_Pict = new libCLIProgram(
85
83
  ]);
86
84
 
87
85
  // Register --config / -c as a known global option so Commander doesn't reject it.
88
- // The actual file loading happens in the pre-initialization block above; this just
89
- // prevents Commander from throwing "unknown option '--config'".
90
86
  _Ultravisor_Pict.CommandLineUtility.command.option('-c, --config <path>', 'Load configuration from a JSON file');
91
87
 
92
88
  // If a config file override was passed via --config / -c, apply it on top of the gathered config
@@ -100,18 +96,34 @@ _Ultravisor_Pict.instantiateServiceProvider('FilePersistence');
100
96
  // Instantiate the data generation service
101
97
  _Ultravisor_Pict.instantiateServiceProvider('DataGeneration');
102
98
 
103
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor', libServiceHypervisor);
104
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-State', libServiceHypervisorState);
99
+ // --- Core services ---
100
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorHypervisor', libServiceHypervisor);
101
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorHypervisorState', libServiceHypervisorState);
102
+
103
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorHypervisorEventBase', libServiceHypervisorEventBase);
104
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorHypervisorEventCron', libServiceHypervisorEventCron);
105
+
106
+ // --- New engine services ---
107
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorTaskTypeRegistry', libServiceTaskTypeRegistry);
108
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorStateManager', libServiceStateManager);
109
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorExecutionEngine', libServiceExecutionEngine);
110
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorExecutionManifest', libServiceExecutionManifest);
105
111
 
106
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-Event-Base', libServiceHypervisorEventBase);
107
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-Event-Cron', libServiceHypervisorEventCron);
108
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-Event-Solver', libServiceHypervisorEventSolver);
112
+ // Register built-in task types
113
+ let tmpRegistry = Object.values(_Ultravisor_Pict.fable.servicesMap['UltravisorTaskTypeRegistry'])[0];
114
+ if (tmpRegistry)
115
+ {
116
+ tmpRegistry.registerBuiltInTaskTypes();
117
+ }
109
118
 
110
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Operation', libServiceOperation);
111
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Operation-Manifest', libServiceOperationManifest);
119
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('UltravisorAPIServer', libWebServerAPIServer);
112
120
 
113
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Task', libServiceTask);
121
+ // ── Service name aliases ────────────────────────────────
122
+ // Some CLI commands access services by hyphenated names via this.fable['Name'].
123
+ // Bridge the camelCase registration to hyphenated access.
124
+ let _Fable = _Ultravisor_Pict.fable;
114
125
 
115
- _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-API-Server', libWebServerAPIServer);
126
+ _Fable['Ultravisor-Hypervisor'] = Object.values(_Fable.servicesMap['UltravisorHypervisor'])[0];
127
+ _Fable['Ultravisor-API-Server'] = Object.values(_Fable.servicesMap['UltravisorAPIServer'])[0];
116
128
 
117
129
  module.exports = _Ultravisor_Pict;