ultravisor 1.0.0 → 1.0.2

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 (96) hide show
  1. package/.babelrc +6 -0
  2. package/.browserslistrc +1 -0
  3. package/.browserslistrc-BACKUP +1 -0
  4. package/.gulpfile-quackage-config.json +7 -0
  5. package/.gulpfile-quackage.js +2 -0
  6. package/CONTRIBUTING.md +50 -0
  7. package/README.md +34 -0
  8. package/debug/Harness.js +2 -1
  9. package/docs/.nojekyll +0 -0
  10. package/docs/_sidebar.md +18 -0
  11. package/docs/_topbar.md +7 -0
  12. package/docs/architecture.md +103 -0
  13. package/docs/cover.md +15 -0
  14. package/docs/features/api.md +230 -0
  15. package/docs/features/cli.md +182 -0
  16. package/docs/features/configuration.md +245 -0
  17. package/docs/features/manifests.md +177 -0
  18. package/docs/features/operations.md +292 -0
  19. package/docs/features/scheduling.md +179 -0
  20. package/docs/features/tasks.md +1857 -0
  21. package/docs/index.html +39 -0
  22. package/docs/overview.md +75 -0
  23. package/docs/quickstart.md +167 -0
  24. package/docs/retold-catalog.json +24 -0
  25. package/docs/retold-keyword-index.json +19 -0
  26. package/package.json +5 -2
  27. package/source/Ultravisor.cjs +2 -2
  28. package/source/cli/Ultravisor-CLIProgram.cjs +38 -0
  29. package/source/cli/commands/Ultravisor-Command-ScheduleOperation.cjs +26 -2
  30. package/source/cli/commands/Ultravisor-Command-ScheduleTask.cjs +26 -2
  31. package/source/cli/commands/Ultravisor-Command-ScheduleView.cjs +22 -0
  32. package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +49 -1
  33. package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +51 -1
  34. package/source/cli/commands/Ultravisor-Command-Stop.cjs +4 -0
  35. package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +91 -0
  36. package/source/config/Ultravisor-Default-Command-Configuration.cjs +6 -1
  37. package/source/services/Ultravisor-Hypervisor-Event-Base.cjs +18 -1
  38. package/source/services/Ultravisor-Hypervisor-State.cjs +213 -0
  39. package/source/services/Ultravisor-Hypervisor.cjs +225 -1
  40. package/source/services/Ultravisor-Operation-Manifest.cjs +150 -1
  41. package/source/services/Ultravisor-Operation.cjs +190 -1
  42. package/source/services/Ultravisor-Task.cjs +339 -1
  43. package/source/services/events/Ultravisor-Hypervisor-Event-Cron.cjs +71 -1
  44. package/source/services/tasks/Ultravisor-Task-Base.cjs +264 -0
  45. package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +188 -0
  46. package/source/services/tasks/Ultravisor-Task-Command.cjs +65 -0
  47. package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +190 -0
  48. package/source/services/tasks/Ultravisor-Task-Conditional.cjs +104 -0
  49. package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +72 -0
  50. package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +336 -0
  51. package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +143 -0
  52. package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +146 -0
  53. package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +158 -0
  54. package/source/services/tasks/Ultravisor-Task-Request.cjs +56 -0
  55. package/source/services/tasks/Ultravisor-Task-Solver.cjs +89 -0
  56. package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +93 -0
  57. package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +127 -0
  58. package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +119 -0
  59. package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +109 -0
  60. package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +112 -0
  61. package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +499 -0
  62. package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +150 -0
  63. package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +110 -0
  64. package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +89 -0
  65. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +87 -0
  66. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +67 -0
  67. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +66 -0
  68. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +69 -0
  69. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +95 -0
  70. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +96 -0
  71. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +99 -0
  72. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +102 -0
  73. package/source/web_server/Ultravisor-API-Server.cjs +463 -3
  74. package/test/Ultravisor_tests.js +6097 -1
  75. package/webinterface/.babelrc +6 -0
  76. package/webinterface/.browserslistrc +1 -0
  77. package/webinterface/.browserslistrc-BACKUP +1 -0
  78. package/webinterface/.gulpfile-quackage-config.json +7 -0
  79. package/webinterface/.gulpfile-quackage.js +2 -0
  80. package/webinterface/css/ultravisor.css +121 -0
  81. package/webinterface/html/index.html +32 -0
  82. package/webinterface/package.json +39 -0
  83. package/webinterface/source/Pict-Application-Ultravisor-Configuration.json +15 -0
  84. package/webinterface/source/Pict-Application-Ultravisor.js +414 -0
  85. package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +42 -0
  86. package/webinterface/source/views/PictView-Ultravisor-BottomBar.js +65 -0
  87. package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +236 -0
  88. package/webinterface/source/views/PictView-Ultravisor-Layout.js +83 -0
  89. package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +273 -0
  90. package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +243 -0
  91. package/webinterface/source/views/PictView-Ultravisor-OperationList.js +141 -0
  92. package/webinterface/source/views/PictView-Ultravisor-Schedule.js +280 -0
  93. package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +220 -0
  94. package/webinterface/source/views/PictView-Ultravisor-TaskList.js +248 -0
  95. package/webinterface/source/views/PictView-Ultravisor-TimingView.js +420 -0
  96. package/webinterface/source/views/PictView-Ultravisor-TopBar.js +147 -0
@@ -0,0 +1,39 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7
+ <meta name="description" content="Documentation powered by pict-docuserve">
8
+
9
+ <title>Documentation</title>
10
+
11
+ <!-- Application Stylesheet -->
12
+ <link href="https://cdn.jsdelivr.net/npm/pict-docuserve@0/dist/css/docuserve.css" rel="stylesheet">
13
+ <!-- KaTeX stylesheet for LaTeX equation rendering -->
14
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css">
15
+ <!-- PICT Dynamic View CSS Container -->
16
+ <style id="PICT-CSS"></style>
17
+
18
+ <!-- Load the PICT library from jsDelivr CDN -->
19
+ <script src="https://cdn.jsdelivr.net/npm/pict@1/dist/pict.min.js" type="text/javascript"></script>
20
+ <!-- Bootstrap the Application -->
21
+ <script type="text/javascript">
22
+ //<![CDATA[
23
+ Pict.safeOnDocumentReady(() => { Pict.safeLoadPictApplication(PictDocuserve, 2)});
24
+ //]]>
25
+ </script>
26
+ </head>
27
+ <body>
28
+ <!-- The root container for the Pict application -->
29
+ <div id="Docuserve-Application-Container"></div>
30
+
31
+ <!-- Mermaid diagram rendering -->
32
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
33
+ <script>mermaid.initialize({ startOnLoad: false, theme: 'default' });</script>
34
+ <!-- KaTeX for LaTeX equation rendering -->
35
+ <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.js"></script>
36
+ <!-- Load the Docuserve PICT Application Bundle from jsDelivr CDN -->
37
+ <script src="https://cdn.jsdelivr.net/npm/pict-docuserve@0/dist/pict-docuserve.min.js" type="text/javascript"></script>
38
+ </body>
39
+ </html>
@@ -0,0 +1,75 @@
1
+ # Ultravisor Overview
2
+
3
+ Ultravisor is a cyclic process execution tool with AI integration. It runs
4
+ commands, HTTP requests and other tasks on schedule, producing structured
5
+ output manifests that track timing, success/failure and logs for every
6
+ execution.
7
+
8
+ ## What It Does
9
+
10
+ Ultravisor manages two core primitives -- **Tasks** and **Operations** --
11
+ and provides multiple ways to run them: immediately via CLI or API, or on a
12
+ recurring schedule via cron expressions.
13
+
14
+ **Tasks** are individual units of work: shell commands, HTTP requests or
15
+ other executable actions. **Operations** compose multiple tasks into a
16
+ sequential pipeline with a unified output manifest.
17
+
18
+ ## How It Runs
19
+
20
+ Ultravisor can be used in three modes:
21
+
22
+ 1. **CLI** -- run individual tasks or operations from the command line
23
+ 2. **API Server** -- start a Restify-based HTTP server exposing full CRUD
24
+ and execution endpoints for tasks, operations, schedules and manifests
25
+ 3. **Scheduled** -- define cron schedules that automatically execute tasks
26
+ or operations at the configured intervals
27
+
28
+ ## Configuration
29
+
30
+ Ultravisor uses a layered configuration system. The default configuration
31
+ ships with the module and can be overridden by a `.ultravisor.json` file in
32
+ the working directory. Tasks and operations are persisted into this same
33
+ configuration file.
34
+
35
+ ```json
36
+ {
37
+ "UltravisorAPIServerPort": 54321,
38
+ "UltravisorFileStorePath": "/path/to/datastore",
39
+ "UltravisorTickIntervalMilliseconds": 60000,
40
+ "Tasks": {},
41
+ "Operations": {}
42
+ }
43
+ ```
44
+
45
+ ## Key Concepts
46
+
47
+ | Concept | Description |
48
+ |---------|-------------|
49
+ | Task | A single executable unit (shell command, HTTP request, etc.) |
50
+ | Operation | An ordered set of tasks executed sequentially |
51
+ | Schedule | A cron-based trigger that runs a task or operation on a timer |
52
+ | Manifest | The output record from executing an operation |
53
+ | Hypervisor | The central scheduler that manages the schedule and dispatches executions |
54
+ | State | Persistent storage of task and operation definitions in `.ultravisor.json` |
55
+
56
+ ## Module Dependencies
57
+
58
+ Ultravisor is built on the Retold ecosystem:
59
+
60
+ - **pict** / **pict-serviceproviderbase** -- service provider pattern and CLI framework
61
+ - **pict-service-commandlineutility** -- CLI command registration
62
+ - **orator** / **orator-serviceserver-restify** -- REST API server
63
+ - **cron** -- cron expression scheduling
64
+
65
+ ## Documentation Map
66
+
67
+ - [Architecture](architecture.md) -- service structure and data flow
68
+ - [Quick Start](quickstart.md) -- get running in five minutes
69
+ - [Tasks](features/tasks.md) -- task types, model and execution
70
+ - [Operations](features/operations.md) -- composing tasks into pipelines
71
+ - [Scheduling](features/scheduling.md) -- cron-based recurring execution
72
+ - [API Server](features/api.md) -- REST endpoint reference
73
+ - [CLI Commands](features/cli.md) -- command line interface reference
74
+ - [Manifests](features/manifests.md) -- execution output and logging
75
+ - [Configuration](features/configuration.md) -- configuration file format and options
@@ -0,0 +1,167 @@
1
+ # Ultravisor Quick Start
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install
7
+ ```
8
+
9
+ ## 1. Define a Task
10
+
11
+ Create or edit `.ultravisor.json` in your project root:
12
+
13
+ ```json
14
+ {
15
+ "UltravisorAPIServerPort": 54321,
16
+ "Tasks": {
17
+ "disk-usage": {
18
+ "GUIDTask": "disk-usage",
19
+ "Name": "Check Disk Usage",
20
+ "Type": "Command",
21
+ "Command": "df -h"
22
+ }
23
+ },
24
+ "Operations": {}
25
+ }
26
+ ```
27
+
28
+ Or use the CLI:
29
+
30
+ ```bash
31
+ ultravisor updatetask -g disk-usage -n "Check Disk Usage" -t Command -p "df -h"
32
+ ```
33
+
34
+ ## 2. Run a Task Immediately
35
+
36
+ ```bash
37
+ ultravisor singletask disk-usage
38
+ ```
39
+
40
+ Output:
41
+
42
+ ```
43
+ Executing task: disk-usage
44
+
45
+ Task Result:
46
+ Status: Complete
47
+ Success: true
48
+ Start: 2026-02-10T12:00:00.000Z
49
+ Stop: 2026-02-10T12:00:00.050Z
50
+ Output: Filesystem Size Used Avail Use% Mounted on ...
51
+ ```
52
+
53
+ Dry run (shows what would happen without executing):
54
+
55
+ ```bash
56
+ ultravisor singletask disk-usage --dry_run
57
+ ```
58
+
59
+ ## 3. Create an Operation
60
+
61
+ Add an operation that chains multiple tasks:
62
+
63
+ ```json
64
+ {
65
+ "Tasks": {
66
+ "check-disk": {
67
+ "GUIDTask": "check-disk",
68
+ "Name": "Check Disk",
69
+ "Type": "Command",
70
+ "Command": "df -h /"
71
+ },
72
+ "check-memory": {
73
+ "GUIDTask": "check-memory",
74
+ "Name": "Check Memory",
75
+ "Type": "Command",
76
+ "Command": "vm_stat"
77
+ }
78
+ },
79
+ "Operations": {
80
+ "system-health": {
81
+ "GUIDOperation": "system-health",
82
+ "Name": "System Health Check",
83
+ "Tasks": ["check-disk", "check-memory"]
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ Run it:
90
+
91
+ ```bash
92
+ ultravisor singleoperation system-health
93
+ ```
94
+
95
+ ## 4. Start the API Server
96
+
97
+ ```bash
98
+ ultravisor start
99
+ ```
100
+
101
+ The server starts on the configured port (default 54321). Now you can
102
+ interact via HTTP:
103
+
104
+ ```bash
105
+ # List all tasks
106
+ curl http://localhost:54321/Task
107
+
108
+ # Execute a task
109
+ curl http://localhost:54321/Task/disk-usage/Execute
110
+
111
+ # Create a new task via API
112
+ curl -X POST http://localhost:54321/Task \
113
+ -H "Content-Type: application/json" \
114
+ -d '{"GUIDTask":"uptime","Name":"Uptime","Type":"Command","Command":"uptime"}'
115
+
116
+ # Execute an operation
117
+ curl http://localhost:54321/Operation/system-health/Execute
118
+
119
+ # View recent execution manifests
120
+ curl http://localhost:54321/Manifest
121
+ ```
122
+
123
+ ## 5. Schedule Recurring Execution
124
+
125
+ Schedule a task to run every 5 minutes:
126
+
127
+ ```bash
128
+ ultravisor schedule_task check-disk -t cron -p "*/5 * * * *"
129
+ ```
130
+
131
+ Schedule an operation to run daily at midnight:
132
+
133
+ ```bash
134
+ ultravisor schedule_operation system-health -t daily -p "0 0 * * *"
135
+ ```
136
+
137
+ View the current schedule:
138
+
139
+ ```bash
140
+ ultravisor schedule
141
+ ```
142
+
143
+ Start the schedule (activates all cron jobs):
144
+
145
+ ```bash
146
+ # Via API
147
+ curl http://localhost:54321/Schedule/Start
148
+
149
+ # The schedule also runs when the API server is started
150
+ ```
151
+
152
+ ## 6. Stop
153
+
154
+ ```bash
155
+ # Stop the scheduler
156
+ ultravisor stop
157
+
158
+ # Stop the API server
159
+ curl http://localhost:54321/stop
160
+ ```
161
+
162
+ ## Next Steps
163
+
164
+ - See [Tasks](features/tasks.md) for all task types and options
165
+ - See [Operations](features/operations.md) for composing task pipelines
166
+ - See [API](features/api.md) for the full endpoint reference
167
+ - See [Configuration](features/configuration.md) for all config options
@@ -0,0 +1,24 @@
1
+ {
2
+ "Generated": "2026-02-11T17:45:35.255Z",
3
+ "GitHubOrg": "stevenvelozo",
4
+ "DefaultBranch": "master",
5
+ "Groups": [
6
+ {
7
+ "Name": "Dist",
8
+ "Key": "dist",
9
+ "Description": "",
10
+ "Modules": [
11
+ {
12
+ "Name": "indoctrinate_content_staging",
13
+ "Repo": "indoctrinate_content_staging",
14
+ "Group": "dist",
15
+ "Branch": "master",
16
+ "HasDocs": false,
17
+ "HasCover": false,
18
+ "Sidebar": [],
19
+ "DocFiles": []
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "Generated": "2026-02-11T17:45:35.330Z",
3
+ "DocumentCount": 0,
4
+ "LunrIndex": {
5
+ "version": "2.3.9",
6
+ "fields": [
7
+ "title",
8
+ "module",
9
+ "group",
10
+ "body"
11
+ ],
12
+ "fieldVectors": [],
13
+ "invertedIndex": [],
14
+ "pipeline": [
15
+ "stemmer"
16
+ ]
17
+ },
18
+ "Documents": {}
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultravisor",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Cyclic process execution with ai integration.",
5
5
  "main": "source/Ultravisor.js",
6
6
  "bin": {
@@ -11,7 +11,9 @@
11
11
  "test": "npx mocha -u tdd -R spec",
12
12
  "tests": "npx mocha -u tdd --exit -R spec --grep",
13
13
  "coverage": "npx nyc --reporter=lcov --reporter=text-lcov npx mocha -- -u tdd -R spec",
14
- "build": "npx quack build"
14
+ "build": "npx quack build",
15
+ "docs": "npx quack prepare-docs ./docs -d ./modules",
16
+ "docs-serve": "npx quack docs-serve ./docs"
15
17
  },
16
18
  "repository": {
17
19
  "type": "git",
@@ -24,6 +26,7 @@
24
26
  },
25
27
  "homepage": "https://github.com/stevenvelozo/ultravisor#readme",
26
28
  "dependencies": {
29
+ "cron": "^4.4.0",
27
30
  "orator": "^5.0.1",
28
31
  "orator-serviceserver-restify": "^2.0.5",
29
32
  "pict": "^1.0.343",
@@ -1,5 +1,5 @@
1
1
  module.exports = (
2
2
  {
3
- Operation: requestAnimationFrame(`./services/Ultravisor-Operation.cjs`),
4
- Task: requestAnimationFrame(`./services/Ultravisor-Task.cjs`),
3
+ Operation: require(`./services/Ultravisor-Operation.cjs`),
4
+ Task: require(`./services/Ultravisor-Task.cjs`),
5
5
  });
@@ -1,6 +1,9 @@
1
1
  const libCLIProgram = require('pict-service-commandlineutility');
2
+ const libFS = require('fs');
3
+ const libPath = require('path');
2
4
 
3
5
  const libServiceHypervisor = require(`../services/Ultravisor-Hypervisor.cjs`);
6
+ const libServiceHypervisorState = require(`../services/Ultravisor-Hypervisor-State.cjs`);
4
7
 
5
8
  const libServiceHypervisorEventBase = require(`../services/Ultravisor-Hypervisor-Event-Base.cjs`);
6
9
  const libServiceHypervisorEventCron = require(`../services/events/Ultravisor-Hypervisor-Event-Cron.cjs`);
@@ -16,6 +19,28 @@ process.removeAllListeners('warning')
16
19
 
17
20
  const libWebServerAPIServer = require(`../web_server/Ultravisor-API-Server.cjs`);
18
21
 
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
+ // Check for an optional --config / -c command line parameter to load a config file
24
+ let _ConfigFileOverride = false;
25
+ for (let i = 0; i < process.argv.length; i++)
26
+ {
27
+ if ((process.argv[i] === '--config' || process.argv[i] === '-c') && process.argv[i + 1])
28
+ {
29
+ let tmpConfigFilePath = libPath.resolve(process.argv[i + 1]);
30
+ try
31
+ {
32
+ let tmpConfigFileContent = libFS.readFileSync(tmpConfigFilePath, 'utf8');
33
+ _ConfigFileOverride = JSON.parse(tmpConfigFileContent);
34
+ }
35
+ catch (pError)
36
+ {
37
+ console.error(`Error loading configuration file [${tmpConfigFilePath}]: ${pError.message}`);
38
+ process.exit(1);
39
+ }
40
+ break;
41
+ }
42
+ }
43
+
19
44
  let _Ultravisor_Pict = new libCLIProgram(
20
45
  {
21
46
  "Product": "Ultravisor-CLI",
@@ -48,6 +73,7 @@ let _Ultravisor_Pict = new libCLIProgram(
48
73
  // Add a task or operation to the current ultravisor schedule
49
74
  require('./commands/Ultravisor-Command-ScheduleOperation.cjs'),
50
75
  require('./commands/Ultravisor-Command-ScheduleTask.cjs'),
76
+ require('./commands/Ultravisor-Command-UpdateTask.cjs'),
51
77
 
52
78
  // Execute a single operation or task immediately, no matter what
53
79
  require('./commands/Ultravisor-Command-SingleOperation.cjs'),
@@ -58,12 +84,24 @@ let _Ultravisor_Pict = new libCLIProgram(
58
84
  require('./commands/Ultravisor-Command-Stop.cjs')
59
85
  ]);
60
86
 
87
+ // 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
+ _Ultravisor_Pict.CommandLineUtility.command.option('-c, --config <path>', 'Load configuration from a JSON file');
91
+
92
+ // If a config file override was passed via --config / -c, apply it on top of the gathered config
93
+ if (_ConfigFileOverride)
94
+ {
95
+ _Ultravisor_Pict.ProgramConfiguration = Object.assign(_Ultravisor_Pict.ProgramConfiguration || {}, _ConfigFileOverride);
96
+ }
97
+
61
98
  // Instantiate the file persistence service
62
99
  _Ultravisor_Pict.instantiateServiceProvider('FilePersistence');
63
100
  // Instantiate the data generation service
64
101
  _Ultravisor_Pict.instantiateServiceProvider('DataGeneration');
65
102
 
66
103
  _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor', libServiceHypervisor);
104
+ _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-State', libServiceHypervisorState);
67
105
 
68
106
  _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-Event-Base', libServiceHypervisorEventBase);
69
107
  _Ultravisor_Pict.fable.addAndInstantiateServiceTypeIfNotExists('Ultravisor-Hypervisor-Event-Cron', libServiceHypervisorEventCron);
@@ -9,7 +9,7 @@ class UltravisorCommandScheduleOperation extends libCommandLineCommand
9
9
  this.options.CommandKeyword = 'schedule_operation';
10
10
  this.options.Description = 'Add an operation to the schedule.';
11
11
 
12
- this.options.CommandArguments.push({ Name: '<operation>', Description: 'The operation to add to the schedule.' });
12
+ this.options.CommandArguments.push({ Name: '<operation_guid>', Description: 'The operation to add to the schedule.' });
13
13
 
14
14
  this.options.CommandOptions.push({ Name: '-t, --type [event_schedule_type]', Description: 'The event schedule type (cron, daily, hourly, solver).', Default: 'cron' });
15
15
  this.options.CommandOptions.push({ Name: '-p, --parameters [event_schedule_parameters]', Description: 'The parameters for the schedule (e.g. the crontab entry or solver string).', Default: '' });
@@ -21,7 +21,31 @@ class UltravisorCommandScheduleOperation extends libCommandLineCommand
21
21
 
22
22
  onRunAsync(fCallback)
23
23
  {
24
- return fCallback();
24
+ let tmpOperationGUID = this.ArgumentString;
25
+ let tmpType = this.CommandOptions.event_schedule_type || 'cron';
26
+ let tmpParameters = this.CommandOptions.event_schedule_parameters || '';
27
+
28
+ if (!tmpOperationGUID)
29
+ {
30
+ console.log(`Error: operation_guid argument is required.`);
31
+ return fCallback();
32
+ }
33
+
34
+ let tmpHypervisor = this.fable['Ultravisor-Hypervisor'];
35
+
36
+ tmpHypervisor.scheduleOperation(tmpOperationGUID, tmpType, tmpParameters,
37
+ function (pError, pEntry)
38
+ {
39
+ if (pError)
40
+ {
41
+ console.log(`Error scheduling operation: ${pError.message}`);
42
+ return fCallback();
43
+ }
44
+ console.log(`Operation ${tmpOperationGUID} scheduled successfully.`);
45
+ console.log(` Schedule GUID: ${pEntry.GUID}`);
46
+ console.log(` Cron Expression: ${pEntry.CronExpression}`);
47
+ return fCallback();
48
+ });
25
49
  }
26
50
  }
27
51
 
@@ -9,7 +9,7 @@ class UltravisorCommandScheduleTask extends libCommandLineCommand
9
9
  this.options.CommandKeyword = 'schedule_task';
10
10
  this.options.Description = 'Add a task to the schedule.';
11
11
 
12
- this.options.CommandArguments.push({ Name: '<task>', Description: 'The task to add to the schedule.' });
12
+ this.options.CommandArguments.push({ Name: '<task_guid>', Description: 'The task to add to the schedule.' });
13
13
 
14
14
  this.options.CommandOptions.push({ Name: '-t, --type [event_schedule_type]', Description: 'The event schedule type (cron, daily, hourly, solver).', Default: 'cron' });
15
15
  this.options.CommandOptions.push({ Name: '-p, --parameters [event_schedule_parameters]', Description: 'The parameters for the schedule (e.g. the crontab entry or solver string).', Default: '' });
@@ -21,7 +21,31 @@ class UltravisorCommandScheduleTask extends libCommandLineCommand
21
21
 
22
22
  onRunAsync(fCallback)
23
23
  {
24
- return fCallback();
24
+ let tmpTaskGUID = this.ArgumentString;
25
+ let tmpType = this.CommandOptions.event_schedule_type || 'cron';
26
+ let tmpParameters = this.CommandOptions.event_schedule_parameters || '';
27
+
28
+ if (!tmpTaskGUID)
29
+ {
30
+ console.log(`Error: task_guid argument is required.`);
31
+ return fCallback();
32
+ }
33
+
34
+ let tmpHypervisor = this.fable['Ultravisor-Hypervisor'];
35
+
36
+ tmpHypervisor.scheduleTask(tmpTaskGUID, tmpType, tmpParameters,
37
+ function (pError, pEntry)
38
+ {
39
+ if (pError)
40
+ {
41
+ console.log(`Error scheduling task: ${pError.message}`);
42
+ return fCallback();
43
+ }
44
+ console.log(`Task ${tmpTaskGUID} scheduled successfully.`);
45
+ console.log(` Schedule GUID: ${pEntry.GUID}`);
46
+ console.log(` Cron Expression: ${pEntry.CronExpression}`);
47
+ return fCallback();
48
+ });
25
49
  }
26
50
  }
27
51
 
@@ -18,6 +18,28 @@ class UltravisorCommandScheduleView extends libCommandLineCommand
18
18
 
19
19
  onRunAsync(fCallback)
20
20
  {
21
+ let tmpHypervisor = this.fable['Ultravisor-Hypervisor'];
22
+ let tmpSchedule = tmpHypervisor.getSchedule();
23
+
24
+ if (tmpSchedule.length === 0)
25
+ {
26
+ console.log(`No schedule entries found.`);
27
+ console.log(`Use 'schedule_task' or 'schedule_operation' to add entries.`);
28
+ return fCallback();
29
+ }
30
+
31
+ console.log(`\n=== Ultravisor Schedule (${tmpSchedule.length} entries) ===\n`);
32
+
33
+ for (let i = 0; i < tmpSchedule.length; i++)
34
+ {
35
+ let tmpEntry = tmpSchedule[i];
36
+ let tmpStatus = tmpEntry.Active ? 'ACTIVE' : 'INACTIVE';
37
+ console.log(` [${tmpStatus}] ${tmpEntry.TargetType}: ${tmpEntry.TargetGUID}`);
38
+ console.log(` Schedule: ${tmpEntry.ScheduleType} (${tmpEntry.CronExpression})`);
39
+ console.log(` GUID: ${tmpEntry.GUID}`);
40
+ console.log(``);
41
+ }
42
+
21
43
  return fCallback();
22
44
  }
23
45
  }
@@ -19,7 +19,55 @@ class UltravisorCommandSingleOperationRun extends libCommandLineCommand
19
19
 
20
20
  onRunAsync(fCallback)
21
21
  {
22
- return fCallback();
22
+ let tmpOperationGUID = this.ArgumentString;
23
+
24
+ if (!tmpOperationGUID)
25
+ {
26
+ console.log(`Error: operation argument is required.`);
27
+ return fCallback();
28
+ }
29
+
30
+ let tmpDryRun = this.CommandOptions.dry_run || false;
31
+
32
+ if (tmpDryRun)
33
+ {
34
+ console.log(`[DRY RUN] Would execute operation: ${tmpOperationGUID}`);
35
+ return fCallback();
36
+ }
37
+
38
+ console.log(`Executing operation: ${tmpOperationGUID}`);
39
+
40
+ let tmpStateService = this.fable['Ultravisor-Hypervisor-State'];
41
+ let tmpOperationService = this.fable['Ultravisor-Operation'];
42
+
43
+ tmpStateService.getOperation(tmpOperationGUID,
44
+ function (pError, pOperation)
45
+ {
46
+ if (pError)
47
+ {
48
+ console.log(`Error: ${pError.message}`);
49
+ return fCallback();
50
+ }
51
+
52
+ tmpOperationService.executeOperation(pOperation,
53
+ function (pExecError, pManifest)
54
+ {
55
+ if (pExecError)
56
+ {
57
+ console.log(`Execution error: ${pExecError.message}`);
58
+ return fCallback();
59
+ }
60
+
61
+ console.log(`\nOperation Result:`);
62
+ console.log(` Status: ${pManifest.Status}`);
63
+ console.log(` Success: ${pManifest.Success}`);
64
+ console.log(` Start: ${pManifest.StartTime}`);
65
+ console.log(` Stop: ${pManifest.StopTime}`);
66
+ console.log(` Tasks Executed: ${pManifest.TaskResults.length}`);
67
+ console.log(` Summary: ${pManifest.Summary}`);
68
+ return fCallback();
69
+ });
70
+ });
23
71
  }
24
72
  }
25
73
 
@@ -20,7 +20,57 @@ class UltravisorCommandSingleTaskRun extends libCommandLineCommand
20
20
 
21
21
  onRunAsync(fCallback)
22
22
  {
23
- return fCallback();
23
+ let tmpTaskGUID = this.ArgumentString;
24
+
25
+ if (!tmpTaskGUID)
26
+ {
27
+ console.log(`Error: task argument is required.`);
28
+ return fCallback();
29
+ }
30
+
31
+ let tmpDryRun = this.CommandOptions.dry_run || false;
32
+
33
+ if (tmpDryRun)
34
+ {
35
+ console.log(`[DRY RUN] Would execute task: ${tmpTaskGUID}`);
36
+ return fCallback();
37
+ }
38
+
39
+ console.log(`Executing task: ${tmpTaskGUID}`);
40
+
41
+ let tmpStateService = this.fable['Ultravisor-Hypervisor-State'];
42
+ let tmpTaskService = this.fable['Ultravisor-Task'];
43
+
44
+ tmpStateService.getTask(tmpTaskGUID,
45
+ function (pError, pTask)
46
+ {
47
+ if (pError)
48
+ {
49
+ console.log(`Error: ${pError.message}`);
50
+ return fCallback();
51
+ }
52
+
53
+ tmpTaskService.executeTask(pTask, {},
54
+ function (pExecError, pResult)
55
+ {
56
+ if (pExecError)
57
+ {
58
+ console.log(`Execution error: ${pExecError.message}`);
59
+ return fCallback();
60
+ }
61
+
62
+ console.log(`\nTask Result:`);
63
+ console.log(` Status: ${pResult.Status}`);
64
+ console.log(` Success: ${pResult.Success}`);
65
+ console.log(` Start: ${pResult.StartTime}`);
66
+ console.log(` Stop: ${pResult.StopTime}`);
67
+ if (pResult.Output)
68
+ {
69
+ console.log(` Output: ${pResult.Output.substring(0, 1000)}`);
70
+ }
71
+ return fCallback();
72
+ });
73
+ });
24
74
  }
25
75
  }
26
76
 
@@ -14,6 +14,10 @@ class UltravisorCommandStopService extends libCommandLineCommand
14
14
 
15
15
  onRunAsync(fCallback)
16
16
  {
17
+ console.log(`Stopping Ultravisor...`);
18
+ let tmpHypervisor = this.fable['Ultravisor-Hypervisor'];
19
+ tmpHypervisor.stopSchedule();
20
+ console.log(`Ultravisor schedule stopped.`);
17
21
  return fCallback();
18
22
  }
19
23
  }