snow-flow 1.1.0

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 (240) hide show
  1. package/.env.example +49 -0
  2. package/.mcp.json +106 -0
  3. package/.mcp.json.template +106 -0
  4. package/LICENSE +21 -0
  5. package/README.md +236 -0
  6. package/bin/snow-flow +4 -0
  7. package/bin/snow-flow.js +3 -0
  8. package/claude-flow +79 -0
  9. package/claude-flow.bat +18 -0
  10. package/claude-flow.config.json +20 -0
  11. package/claude-flow.ps1 +24 -0
  12. package/dist/agents/app-creator.agent.d.ts +55 -0
  13. package/dist/agents/app-creator.agent.d.ts.map +1 -0
  14. package/dist/agents/app-creator.agent.js +1292 -0
  15. package/dist/agents/app-creator.agent.js.map +1 -0
  16. package/dist/agents/base-snow-agent.d.ts +63 -0
  17. package/dist/agents/base-snow-agent.d.ts.map +1 -0
  18. package/dist/agents/base-snow-agent.js +296 -0
  19. package/dist/agents/base-snow-agent.js.map +1 -0
  20. package/dist/agents/script-generator.agent.d.ts +32 -0
  21. package/dist/agents/script-generator.agent.d.ts.map +1 -0
  22. package/dist/agents/script-generator.agent.js +772 -0
  23. package/dist/agents/script-generator.agent.js.map +1 -0
  24. package/dist/agents/ui-builder.agent.d.ts +50 -0
  25. package/dist/agents/ui-builder.agent.d.ts.map +1 -0
  26. package/dist/agents/ui-builder.agent.js +1539 -0
  27. package/dist/agents/ui-builder.agent.js.map +1 -0
  28. package/dist/agents/widget-builder.agent.d.ts +32 -0
  29. package/dist/agents/widget-builder.agent.d.ts.map +1 -0
  30. package/dist/agents/widget-builder.agent.js +439 -0
  31. package/dist/agents/widget-builder.agent.js.map +1 -0
  32. package/dist/agents/workflow-designer.agent.d.ts +31 -0
  33. package/dist/agents/workflow-designer.agent.d.ts.map +1 -0
  34. package/dist/agents/workflow-designer.agent.js +583 -0
  35. package/dist/agents/workflow-designer.agent.js.map +1 -0
  36. package/dist/api/error-handling.d.ts +214 -0
  37. package/dist/api/error-handling.d.ts.map +1 -0
  38. package/dist/api/error-handling.js +594 -0
  39. package/dist/api/error-handling.js.map +1 -0
  40. package/dist/api/flow-designer-api.d.ts +167 -0
  41. package/dist/api/flow-designer-api.d.ts.map +1 -0
  42. package/dist/api/flow-designer-api.js +555 -0
  43. package/dist/api/flow-designer-api.js.map +1 -0
  44. package/dist/api/natural-language-mapper.d.ts +126 -0
  45. package/dist/api/natural-language-mapper.d.ts.map +1 -0
  46. package/dist/api/natural-language-mapper.js +498 -0
  47. package/dist/api/natural-language-mapper.js.map +1 -0
  48. package/dist/api/performance-optimizer.d.ts +240 -0
  49. package/dist/api/performance-optimizer.d.ts.map +1 -0
  50. package/dist/api/performance-optimizer.js +701 -0
  51. package/dist/api/performance-optimizer.js.map +1 -0
  52. package/dist/api/transaction-manager.d.ts +189 -0
  53. package/dist/api/transaction-manager.d.ts.map +1 -0
  54. package/dist/api/transaction-manager.js +576 -0
  55. package/dist/api/transaction-manager.js.map +1 -0
  56. package/dist/cli/deploy-artifact.d.ts +7 -0
  57. package/dist/cli/deploy-artifact.d.ts.map +1 -0
  58. package/dist/cli/deploy-artifact.js +279 -0
  59. package/dist/cli/deploy-artifact.js.map +1 -0
  60. package/dist/cli.d.ts +6 -0
  61. package/dist/cli.d.ts.map +1 -0
  62. package/dist/cli.js +2057 -0
  63. package/dist/cli.js.map +1 -0
  64. package/dist/index.d.ts +10 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +35 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/managers/scope-manager.d.ts +75 -0
  69. package/dist/managers/scope-manager.d.ts.map +1 -0
  70. package/dist/managers/scope-manager.js +448 -0
  71. package/dist/managers/scope-manager.js.map +1 -0
  72. package/dist/mcp/mcp-wrapper.d.ts +8 -0
  73. package/dist/mcp/mcp-wrapper.d.ts.map +1 -0
  74. package/dist/mcp/mcp-wrapper.js +77 -0
  75. package/dist/mcp/mcp-wrapper.js.map +1 -0
  76. package/dist/mcp/servicenow-automation-mcp.d.ts +8 -0
  77. package/dist/mcp/servicenow-automation-mcp.d.ts.map +1 -0
  78. package/dist/mcp/servicenow-automation-mcp.js +683 -0
  79. package/dist/mcp/servicenow-automation-mcp.js.map +1 -0
  80. package/dist/mcp/servicenow-deployment-mcp.d.ts +7 -0
  81. package/dist/mcp/servicenow-deployment-mcp.d.ts.map +1 -0
  82. package/dist/mcp/servicenow-deployment-mcp.js +972 -0
  83. package/dist/mcp/servicenow-deployment-mcp.js.map +1 -0
  84. package/dist/mcp/servicenow-flow-composer-mcp.d.ts +7 -0
  85. package/dist/mcp/servicenow-flow-composer-mcp.d.ts.map +1 -0
  86. package/dist/mcp/servicenow-flow-composer-mcp.js +1121 -0
  87. package/dist/mcp/servicenow-flow-composer-mcp.js.map +1 -0
  88. package/dist/mcp/servicenow-graph-memory-mcp.d.ts +7 -0
  89. package/dist/mcp/servicenow-graph-memory-mcp.d.ts.map +1 -0
  90. package/dist/mcp/servicenow-graph-memory-mcp.js +703 -0
  91. package/dist/mcp/servicenow-graph-memory-mcp.js.map +1 -0
  92. package/dist/mcp/servicenow-integration-mcp.d.ts +8 -0
  93. package/dist/mcp/servicenow-integration-mcp.d.ts.map +1 -0
  94. package/dist/mcp/servicenow-integration-mcp.js +689 -0
  95. package/dist/mcp/servicenow-integration-mcp.js.map +1 -0
  96. package/dist/mcp/servicenow-intelligent-mcp.d.ts +7 -0
  97. package/dist/mcp/servicenow-intelligent-mcp.d.ts.map +1 -0
  98. package/dist/mcp/servicenow-intelligent-mcp.js +1138 -0
  99. package/dist/mcp/servicenow-intelligent-mcp.js.map +1 -0
  100. package/dist/mcp/servicenow-mcp-server.d.ts +37 -0
  101. package/dist/mcp/servicenow-mcp-server.d.ts.map +1 -0
  102. package/dist/mcp/servicenow-mcp-server.js +648 -0
  103. package/dist/mcp/servicenow-mcp-server.js.map +1 -0
  104. package/dist/mcp/servicenow-operations-mcp.d.ts +15 -0
  105. package/dist/mcp/servicenow-operations-mcp.d.ts.map +1 -0
  106. package/dist/mcp/servicenow-operations-mcp.js +1287 -0
  107. package/dist/mcp/servicenow-operations-mcp.js.map +1 -0
  108. package/dist/mcp/servicenow-platform-development-mcp.d.ts +8 -0
  109. package/dist/mcp/servicenow-platform-development-mcp.d.ts.map +1 -0
  110. package/dist/mcp/servicenow-platform-development-mcp.js +557 -0
  111. package/dist/mcp/servicenow-platform-development-mcp.js.map +1 -0
  112. package/dist/mcp/servicenow-progressive-indexer.d.ts +79 -0
  113. package/dist/mcp/servicenow-progressive-indexer.d.ts.map +1 -0
  114. package/dist/mcp/servicenow-progressive-indexer.js +320 -0
  115. package/dist/mcp/servicenow-progressive-indexer.js.map +1 -0
  116. package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts +8 -0
  117. package/dist/mcp/servicenow-reporting-analytics-mcp.d.ts.map +1 -0
  118. package/dist/mcp/servicenow-reporting-analytics-mcp.js +888 -0
  119. package/dist/mcp/servicenow-reporting-analytics-mcp.js.map +1 -0
  120. package/dist/mcp/servicenow-security-compliance-mcp.d.ts +8 -0
  121. package/dist/mcp/servicenow-security-compliance-mcp.d.ts.map +1 -0
  122. package/dist/mcp/servicenow-security-compliance-mcp.js +812 -0
  123. package/dist/mcp/servicenow-security-compliance-mcp.js.map +1 -0
  124. package/dist/mcp/servicenow-update-set-mcp.d.ts +7 -0
  125. package/dist/mcp/servicenow-update-set-mcp.d.ts.map +1 -0
  126. package/dist/mcp/servicenow-update-set-mcp.js +599 -0
  127. package/dist/mcp/servicenow-update-set-mcp.js.map +1 -0
  128. package/dist/mcp/start-all-mcp-servers.d.ts +6 -0
  129. package/dist/mcp/start-all-mcp-servers.d.ts.map +1 -0
  130. package/dist/mcp/start-all-mcp-servers.js +65 -0
  131. package/dist/mcp/start-all-mcp-servers.js.map +1 -0
  132. package/dist/mcp/start-servicenow-mcp.d.ts +7 -0
  133. package/dist/mcp/start-servicenow-mcp.d.ts.map +1 -0
  134. package/dist/mcp/start-servicenow-mcp.js +64 -0
  135. package/dist/mcp/start-servicenow-mcp.js.map +1 -0
  136. package/dist/mcp/test-simple-mcp.d.ts +6 -0
  137. package/dist/mcp/test-simple-mcp.d.ts.map +1 -0
  138. package/dist/mcp/test-simple-mcp.js +64 -0
  139. package/dist/mcp/test-simple-mcp.js.map +1 -0
  140. package/dist/orchestrator/flow-composer.d.ts +269 -0
  141. package/dist/orchestrator/flow-composer.d.ts.map +1 -0
  142. package/dist/orchestrator/flow-composer.js +2221 -0
  143. package/dist/orchestrator/flow-composer.js.map +1 -0
  144. package/dist/orchestrator/flow-pattern-templates.d.ts +260 -0
  145. package/dist/orchestrator/flow-pattern-templates.d.ts.map +1 -0
  146. package/dist/orchestrator/flow-pattern-templates.js +906 -0
  147. package/dist/orchestrator/flow-pattern-templates.js.map +1 -0
  148. package/dist/orchestrator/flow-subflow-decision-engine.d.ts +202 -0
  149. package/dist/orchestrator/flow-subflow-decision-engine.d.ts.map +1 -0
  150. package/dist/orchestrator/flow-subflow-decision-engine.js +769 -0
  151. package/dist/orchestrator/flow-subflow-decision-engine.js.map +1 -0
  152. package/dist/orchestrator/flow-validation-engine.d.ts +145 -0
  153. package/dist/orchestrator/flow-validation-engine.d.ts.map +1 -0
  154. package/dist/orchestrator/flow-validation-engine.js +663 -0
  155. package/dist/orchestrator/flow-validation-engine.js.map +1 -0
  156. package/dist/orchestrator/snow-orchestrator.d.ts +49 -0
  157. package/dist/orchestrator/snow-orchestrator.d.ts.map +1 -0
  158. package/dist/orchestrator/snow-orchestrator.js +235 -0
  159. package/dist/orchestrator/snow-orchestrator.js.map +1 -0
  160. package/dist/orchestrator/subflow-creation-handler.d.ts +230 -0
  161. package/dist/orchestrator/subflow-creation-handler.d.ts.map +1 -0
  162. package/dist/orchestrator/subflow-creation-handler.js +791 -0
  163. package/dist/orchestrator/subflow-creation-handler.js.map +1 -0
  164. package/dist/strategies/global-scope-strategy.d.ts +123 -0
  165. package/dist/strategies/global-scope-strategy.d.ts.map +1 -0
  166. package/dist/strategies/global-scope-strategy.js +585 -0
  167. package/dist/strategies/global-scope-strategy.js.map +1 -0
  168. package/dist/types/index.d.ts +138 -0
  169. package/dist/types/index.d.ts.map +1 -0
  170. package/dist/types/index.js +4 -0
  171. package/dist/types/index.js.map +1 -0
  172. package/dist/types/servicenow.types.d.ts +260 -0
  173. package/dist/types/servicenow.types.d.ts.map +1 -0
  174. package/dist/types/servicenow.types.js +3 -0
  175. package/dist/types/servicenow.types.js.map +1 -0
  176. package/dist/types/snow-flow.types.d.ts +114 -0
  177. package/dist/types/snow-flow.types.d.ts.map +1 -0
  178. package/dist/types/snow-flow.types.js +3 -0
  179. package/dist/types/snow-flow.types.js.map +1 -0
  180. package/dist/utils/action-type-cache.d.ts +66 -0
  181. package/dist/utils/action-type-cache.d.ts.map +1 -0
  182. package/dist/utils/action-type-cache.js +237 -0
  183. package/dist/utils/action-type-cache.js.map +1 -0
  184. package/dist/utils/agent-detector.d.ts +35 -0
  185. package/dist/utils/agent-detector.d.ts.map +1 -0
  186. package/dist/utils/agent-detector.js +353 -0
  187. package/dist/utils/agent-detector.js.map +1 -0
  188. package/dist/utils/flow-api-discovery.d.ts +151 -0
  189. package/dist/utils/flow-api-discovery.d.ts.map +1 -0
  190. package/dist/utils/flow-api-discovery.js +440 -0
  191. package/dist/utils/flow-api-discovery.js.map +1 -0
  192. package/dist/utils/flow-xml-generator.d.ts +41 -0
  193. package/dist/utils/flow-xml-generator.d.ts.map +1 -0
  194. package/dist/utils/flow-xml-generator.js +258 -0
  195. package/dist/utils/flow-xml-generator.js.map +1 -0
  196. package/dist/utils/logger.d.ts +13 -0
  197. package/dist/utils/logger.d.ts.map +1 -0
  198. package/dist/utils/logger.js +51 -0
  199. package/dist/utils/logger.js.map +1 -0
  200. package/dist/utils/mcp-auth-middleware.d.ts +58 -0
  201. package/dist/utils/mcp-auth-middleware.d.ts.map +1 -0
  202. package/dist/utils/mcp-auth-middleware.js +227 -0
  203. package/dist/utils/mcp-auth-middleware.js.map +1 -0
  204. package/dist/utils/mcp-config-manager.d.ts +126 -0
  205. package/dist/utils/mcp-config-manager.d.ts.map +1 -0
  206. package/dist/utils/mcp-config-manager.js +209 -0
  207. package/dist/utils/mcp-config-manager.js.map +1 -0
  208. package/dist/utils/mcp-server-manager.d.ts +91 -0
  209. package/dist/utils/mcp-server-manager.d.ts.map +1 -0
  210. package/dist/utils/mcp-server-manager.js +338 -0
  211. package/dist/utils/mcp-server-manager.js.map +1 -0
  212. package/dist/utils/scope-utils.d.ts +72 -0
  213. package/dist/utils/scope-utils.d.ts.map +1 -0
  214. package/dist/utils/scope-utils.js +386 -0
  215. package/dist/utils/scope-utils.js.map +1 -0
  216. package/dist/utils/servicenow-client.d.ts +233 -0
  217. package/dist/utils/servicenow-client.d.ts.map +1 -0
  218. package/dist/utils/servicenow-client.js +1465 -0
  219. package/dist/utils/servicenow-client.js.map +1 -0
  220. package/dist/utils/snow-oauth-old.d.ts +65 -0
  221. package/dist/utils/snow-oauth-old.d.ts.map +1 -0
  222. package/dist/utils/snow-oauth-old.js +345 -0
  223. package/dist/utils/snow-oauth-old.js.map +1 -0
  224. package/dist/utils/snow-oauth.d.ts +85 -0
  225. package/dist/utils/snow-oauth.d.ts.map +1 -0
  226. package/dist/utils/snow-oauth.js +512 -0
  227. package/dist/utils/snow-oauth.js.map +1 -0
  228. package/dist/utils/template-engine.d.ts +76 -0
  229. package/dist/utils/template-engine.d.ts.map +1 -0
  230. package/dist/utils/template-engine.js +391 -0
  231. package/dist/utils/template-engine.js.map +1 -0
  232. package/dist/version.d.ts +35 -0
  233. package/dist/version.d.ts.map +1 -0
  234. package/dist/version.js +72 -0
  235. package/dist/version.js.map +1 -0
  236. package/mcp-wrapper.sh +12 -0
  237. package/package.json +77 -0
  238. package/reports/swarm-auto-centralized-1752649029776.json +13 -0
  239. package/scripts/postinstall.js +30 -0
  240. package/scripts/setup-mcp.js +89 -0
@@ -0,0 +1,1292 @@
1
+ "use strict";
2
+ /**
3
+ * App Creator Agent for Scoped Applications
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AppCreatorAgent = void 0;
7
+ const base_agent_js_1 = require("../core/base-agent.js");
8
+ class AppCreatorAgent extends base_agent_js_1.BaseServiceNowAgent {
9
+ constructor(config) {
10
+ super('app-creator', servicenow_types_js_1.AgentType.APP_CREATOR, [
11
+ 'create_application',
12
+ 'add_tables',
13
+ 'create_menus',
14
+ 'generate_app_structure',
15
+ 'create_security_rules',
16
+ 'package_application',
17
+ 'generate_app_documentation'
18
+ ], config);
19
+ }
20
+ async execute(task) {
21
+ this.logger.info(`Executing app creation task: ${task.description}`);
22
+ try {
23
+ switch (task.type) {
24
+ case 'create_application':
25
+ return await this.createApplication(task);
26
+ case 'generate_from_requirements':
27
+ return await this.generateFromRequirements(task);
28
+ case 'add_app_components':
29
+ return await this.addAppComponents(task);
30
+ case 'package_application':
31
+ return await this.packageApplication(task);
32
+ default:
33
+ throw new Error(`Unknown task type: ${task.type}`);
34
+ }
35
+ }
36
+ catch (error) {
37
+ this.logger.error(`App creation task failed: ${error.message}`);
38
+ return {
39
+ taskId: task.id,
40
+ success: false,
41
+ error: error.message
42
+ };
43
+ }
44
+ }
45
+ async createApplication(task) {
46
+ const { name, scope, vendor, description, initialTables } = task.payload;
47
+ const app = {
48
+ name,
49
+ scope: scope || this.generateScope(name),
50
+ version: '1.0.0',
51
+ vendor: vendor || 'Custom',
52
+ vendorPrefix: this.generateVendorPrefix(vendor || 'Custom'),
53
+ shortDescription: description || `${name} Application`,
54
+ description: description || `Scoped application: ${name}`,
55
+ tables: initialTables || [],
56
+ menus: []
57
+ };
58
+ // Generate application structure
59
+ const appStructure = this.generateApplicationStructure(app);
60
+ // Generate orchestration commands
61
+ const commands = [
62
+ // Create base directory structure
63
+ this.generateCommand('Bash', 'create', {
64
+ command: `mkdir -p /Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}/{sys_app,tables,menus,security,scripts,ui,docs}`,
65
+ description: `Create application directory structure for ${name}`
66
+ }, 'Create directories'),
67
+ // Application manifest
68
+ this.generateCommand('Write', 'create', {
69
+ file_path: `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}/sys_app/manifest.json`,
70
+ content: JSON.stringify(appStructure.manifest, null, 2)
71
+ }, 'Create application manifest'),
72
+ // Application properties
73
+ this.generateCommand('Write', 'create', {
74
+ file_path: `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}/sys_app/properties.json`,
75
+ content: JSON.stringify(appStructure.properties, null, 2)
76
+ }, 'Create application properties'),
77
+ // README
78
+ this.generateCommand('Write', 'create', {
79
+ file_path: `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}/README.md`,
80
+ content: this.generateApplicationReadme(app)
81
+ }, 'Create application README')
82
+ ];
83
+ // Store in memory for coordination
84
+ await this.storeInMemory(`applications:${app.scope}`, app);
85
+ return {
86
+ taskId: task.id,
87
+ success: true,
88
+ output: {
89
+ application: app,
90
+ structure: appStructure
91
+ },
92
+ artifacts: [
93
+ this.createArtifact('scoped_application', app.name, app, {
94
+ scope: app.scope,
95
+ version: app.version
96
+ })
97
+ ],
98
+ commands
99
+ };
100
+ }
101
+ async generateFromRequirements(task) {
102
+ const { requirements, appType, businessDomain } = task.payload;
103
+ // Analyze requirements to determine app structure
104
+ const analysis = this.analyzeAppRequirements(requirements, appType, businessDomain);
105
+ // Generate application based on analysis
106
+ const app = {
107
+ name: analysis.suggestedName,
108
+ scope: this.generateScope(analysis.suggestedName),
109
+ version: '1.0.0',
110
+ vendor: 'Auto-Generated',
111
+ vendorPrefix: 'x',
112
+ shortDescription: analysis.description,
113
+ description: `Application generated from requirements: ${requirements.substring(0, 200)}...`,
114
+ tables: this.generateTablesFromAnalysis(analysis),
115
+ menus: this.generateMenusFromAnalysis(analysis)
116
+ };
117
+ // Generate complete application package
118
+ const appPackage = await this.generateCompleteApplication(app, analysis);
119
+ // Generate comprehensive commands for all app components
120
+ const commands = this.generateApplicationCommands(app, appPackage);
121
+ return {
122
+ taskId: task.id,
123
+ success: true,
124
+ output: {
125
+ application: app,
126
+ package: appPackage,
127
+ analysis
128
+ },
129
+ artifacts: [
130
+ this.createArtifact('scoped_application', app.name, app),
131
+ ...appPackage.artifacts
132
+ ],
133
+ commands
134
+ };
135
+ }
136
+ async addAppComponents(task) {
137
+ const { appScope, components } = task.payload;
138
+ // Retrieve existing application
139
+ const app = await this.retrieveFromMemory(`applications:${appScope}`);
140
+ if (!app) {
141
+ throw new Error(`Application ${appScope} not found`);
142
+ }
143
+ const addedComponents = {
144
+ tables: [],
145
+ menus: [],
146
+ scripts: [],
147
+ ui: []
148
+ };
149
+ // Add tables
150
+ if (components.tables) {
151
+ components.tables.forEach((table) => {
152
+ const appTable = this.createApplicationTable(table, app.scope);
153
+ app.tables.push(appTable);
154
+ addedComponents.tables.push(appTable);
155
+ });
156
+ }
157
+ // Add menus
158
+ if (components.menus) {
159
+ components.menus.forEach((menu) => {
160
+ const appMenu = this.createApplicationMenu(menu, app.scope);
161
+ app.menus.push(appMenu);
162
+ addedComponents.menus.push(appMenu);
163
+ });
164
+ }
165
+ // Update stored application
166
+ await this.storeInMemory(`applications:${appScope}`, app);
167
+ // Generate commands for new components
168
+ const commands = this.generateComponentCommands(app.scope, addedComponents);
169
+ return {
170
+ taskId: task.id,
171
+ success: true,
172
+ output: {
173
+ application: app,
174
+ addedComponents
175
+ },
176
+ artifacts: [
177
+ ...addedComponents.tables.map((table) => this.createArtifact('application_table', table.name, table)),
178
+ ...addedComponents.menus.map((menu) => this.createArtifact('application_menu', menu.name, menu))
179
+ ],
180
+ commands
181
+ };
182
+ }
183
+ async packageApplication(task) {
184
+ const { appScope, includeData, format } = task.payload;
185
+ const app = await this.retrieveFromMemory(`applications:${appScope}`);
186
+ if (!app) {
187
+ throw new Error(`Application ${appScope} not found`);
188
+ }
189
+ // Generate application package
190
+ const appPackage = {
191
+ manifest: this.generateManifest(app),
192
+ metadata: this.generateMetadata(app),
193
+ components: {
194
+ tables: app.tables,
195
+ menus: app.menus,
196
+ security: this.generateSecurityRules(app),
197
+ scripts: this.generateApplicationScripts(app),
198
+ ui: this.generateApplicationUI(app)
199
+ },
200
+ data: includeData ? this.generateSampleData(app) : null
201
+ };
202
+ // Generate export based on format
203
+ let exportContent;
204
+ let fileName;
205
+ switch (format) {
206
+ case 'xml':
207
+ exportContent = this.generateXMLExport(appPackage);
208
+ fileName = `${app.scope}.xml`;
209
+ break;
210
+ case 'json':
211
+ exportContent = JSON.stringify(appPackage, null, 2);
212
+ fileName = `${app.scope}.json`;
213
+ break;
214
+ default:
215
+ exportContent = this.generateUpdateSetXML(appPackage);
216
+ fileName = `${app.scope}_update_set.xml`;
217
+ }
218
+ const commands = [
219
+ this.generateCommand('Write', 'create', {
220
+ file_path: `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}/export/${fileName}`,
221
+ content: exportContent
222
+ }, `Export application package as ${format}`),
223
+ this.generateCommand('Write', 'create', {
224
+ file_path: `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}/export/install-guide.md`,
225
+ content: this.generateInstallationGuide(app)
226
+ }, 'Create installation guide')
227
+ ];
228
+ return {
229
+ taskId: task.id,
230
+ success: true,
231
+ output: {
232
+ package: appPackage,
233
+ exportFile: fileName
234
+ },
235
+ artifacts: [
236
+ this.createArtifact('application_package', fileName, exportContent),
237
+ this.createArtifact('documentation', 'install-guide.md', this.generateInstallationGuide(app))
238
+ ],
239
+ commands
240
+ };
241
+ }
242
+ // Helper methods
243
+ generateScope(name) {
244
+ return 'x_' + name.toLowerCase()
245
+ .replace(/[^a-z0-9]/g, '_')
246
+ .replace(/_+/g, '_')
247
+ .substring(0, 18);
248
+ }
249
+ generateVendorPrefix(vendor) {
250
+ return vendor.toLowerCase()
251
+ .split(/\s+/)
252
+ .map(word => word.charAt(0))
253
+ .join('')
254
+ .substring(0, 3) || 'x';
255
+ }
256
+ generateApplicationStructure(app) {
257
+ return {
258
+ manifest: {
259
+ name: app.name,
260
+ scope: app.scope,
261
+ version: app.version,
262
+ vendor: app.vendor,
263
+ vendor_prefix: app.vendorPrefix,
264
+ created: new Date().toISOString(),
265
+ dependencies: [],
266
+ components: {
267
+ tables: app.tables.length,
268
+ menus: app.menus.length
269
+ }
270
+ },
271
+ properties: {
272
+ js_level: 'helsinki',
273
+ logo: '',
274
+ private: false,
275
+ offline_mobile: false,
276
+ active: true,
277
+ enforce_license: 'none',
278
+ short_description: app.shortDescription,
279
+ description: app.description
280
+ }
281
+ };
282
+ }
283
+ generateApplicationReadme(app) {
284
+ return `# ${app.name}
285
+
286
+ ## Overview
287
+ ${app.description}
288
+
289
+ ## Scope
290
+ - **Application Scope**: ${app.scope}
291
+ - **Version**: ${app.version}
292
+ - **Vendor**: ${app.vendor}
293
+ - **Vendor Prefix**: ${app.vendorPrefix}
294
+
295
+ ## Components
296
+
297
+ ### Tables
298
+ ${app.tables.map(table => `- **${table.label}** (${table.name})
299
+ - Extends: ${table.extends}
300
+ - Fields: ${table.fields.length}`).join('\n')}
301
+
302
+ ### Menus
303
+ ${app.menus.map(menu => `- **${menu.label}**
304
+ - Modules: ${menu.modules.length}`).join('\n')}
305
+
306
+ ## Installation
307
+ 1. Import the application package into your ServiceNow instance
308
+ 2. Navigate to System Applications > Applications
309
+ 3. Find "${app.name}" and click Install
310
+ 4. Follow the installation wizard
311
+
312
+ ## Configuration
313
+ After installation:
314
+ 1. Configure security rules as needed
315
+ 2. Set up any required integrations
316
+ 3. Customize UI as desired
317
+
318
+ ## Usage
319
+ ${this.generateUsageInstructions(app)}
320
+
321
+ ## Support
322
+ For issues or questions, contact the application vendor.
323
+
324
+ Generated on: ${new Date().toISOString()}
325
+ Generated by: ServiceNow Multi-Agent Framework
326
+ `;
327
+ }
328
+ generateUsageInstructions(app) {
329
+ let instructions = '';
330
+ if (app.tables.length > 0) {
331
+ instructions += '\n### Working with Tables\n';
332
+ app.tables.forEach(table => {
333
+ instructions += `\n**${table.label}**:\n`;
334
+ instructions += `- Navigate to ${app.name} > ${table.label}\n`;
335
+ instructions += `- Use the New button to create records\n`;
336
+ instructions += `- Click on existing records to view/edit\n`;
337
+ });
338
+ }
339
+ if (app.menus.length > 0) {
340
+ instructions += '\n### Navigation\n';
341
+ app.menus.forEach(menu => {
342
+ instructions += `\n**${menu.label}** menu contains:\n`;
343
+ menu.modules.forEach(module => {
344
+ instructions += `- ${module.label}: ${module.table ? `View ${module.table} records` : 'Custom module'}\n`;
345
+ });
346
+ });
347
+ }
348
+ return instructions || 'See application menus for available features.';
349
+ }
350
+ analyzeAppRequirements(requirements, appType, businessDomain) {
351
+ const analysis = {
352
+ suggestedName: '',
353
+ description: '',
354
+ tables: [],
355
+ features: [],
356
+ workflows: [],
357
+ integrations: []
358
+ };
359
+ // Extract app name suggestion
360
+ const words = requirements.split(/\s+/).slice(0, 3);
361
+ analysis.suggestedName = words.join(' ') + ' App';
362
+ // Detect required tables
363
+ if (requirements.toLowerCase().includes('track') || requirements.toLowerCase().includes('manage')) {
364
+ analysis.tables.push({
365
+ purpose: 'main',
366
+ suggestedName: 'Main Records',
367
+ fields: ['name', 'description', 'status', 'assigned_to']
368
+ });
369
+ }
370
+ if (requirements.toLowerCase().includes('approve') || requirements.toLowerCase().includes('approval')) {
371
+ analysis.tables.push({
372
+ purpose: 'approval',
373
+ suggestedName: 'Approvals',
374
+ fields: ['request', 'approver', 'status', 'comments']
375
+ });
376
+ analysis.features.push('approval_workflow');
377
+ }
378
+ if (requirements.toLowerCase().includes('report') || requirements.toLowerCase().includes('dashboard')) {
379
+ analysis.features.push('reporting');
380
+ analysis.features.push('dashboard');
381
+ }
382
+ // Detect workflows
383
+ if (requirements.toLowerCase().includes('workflow') || requirements.toLowerCase().includes('process')) {
384
+ analysis.workflows.push('main_process');
385
+ }
386
+ // Detect integrations
387
+ if (requirements.toLowerCase().includes('integrate') || requirements.toLowerCase().includes('api')) {
388
+ analysis.integrations.push('rest_api');
389
+ }
390
+ // Set description
391
+ analysis.description = `${businessDomain || 'Business'} application for ${requirements.substring(0, 100)}...`;
392
+ return analysis;
393
+ }
394
+ generateTablesFromAnalysis(analysis) {
395
+ const tables = [];
396
+ analysis.tables.forEach((tableSpec, index) => {
397
+ const table = {
398
+ name: `u_${tableSpec.suggestedName.toLowerCase().replace(/\s+/g, '_')}`,
399
+ label: tableSpec.suggestedName,
400
+ parent: tableSpec.purpose === 'approval' ? 'sysapproval_approver' : 'task',
401
+ fields: this.generateFieldsFromSpec(tableSpec.fields)
402
+ };
403
+ tables.push(table);
404
+ });
405
+ // Add default table if none specified
406
+ if (tables.length === 0) {
407
+ tables.push({
408
+ name: 'u_main_table',
409
+ label: 'Main Table',
410
+ parent: 'task',
411
+ fields: this.generateDefaultFields()
412
+ });
413
+ }
414
+ return tables;
415
+ }
416
+ generateFieldsFromSpec(fieldNames) {
417
+ const fields = [];
418
+ fieldNames.forEach(fieldName => {
419
+ fields.push(this.createFieldFromName(fieldName));
420
+ });
421
+ return fields;
422
+ }
423
+ createFieldFromName(fieldName) {
424
+ const field = {
425
+ name: `u_${fieldName.toLowerCase().replace(/\s+/g, '_')}`,
426
+ label: fieldName.charAt(0).toUpperCase() + fieldName.slice(1).replace(/_/g, ' '),
427
+ type: 'string',
428
+ max_length: 255
429
+ };
430
+ // Detect field types
431
+ if (fieldName.includes('date') || fieldName.includes('time')) {
432
+ field.type = 'glide_date_time';
433
+ delete field.max_length;
434
+ }
435
+ else if (fieldName.includes('user') || fieldName.includes('assigned')) {
436
+ field.type = 'reference';
437
+ field.reference = 'sys_user';
438
+ delete field.max_length;
439
+ }
440
+ else if (fieldName.includes('group')) {
441
+ field.type = 'reference';
442
+ field.reference = 'sys_user_group';
443
+ delete field.max_length;
444
+ }
445
+ else if (fieldName.includes('status') || fieldName.includes('state')) {
446
+ field.type = 'choice';
447
+ delete field.max_length;
448
+ }
449
+ else if (fieldName.includes('description') || fieldName.includes('comments')) {
450
+ field.type = 'string';
451
+ field.max_length = 4000;
452
+ }
453
+ else if (fieldName.includes('amount') || fieldName.includes('cost') || fieldName.includes('price')) {
454
+ field.type = 'currency';
455
+ delete field.max_length;
456
+ }
457
+ return field;
458
+ }
459
+ generateDefaultFields() {
460
+ return [
461
+ {
462
+ name: 'u_description',
463
+ label: 'Description',
464
+ type: 'string',
465
+ max_length: 4000
466
+ },
467
+ {
468
+ name: 'u_status',
469
+ label: 'Status',
470
+ type: 'choice'
471
+ },
472
+ {
473
+ name: 'u_priority',
474
+ label: 'Priority',
475
+ type: 'integer',
476
+ default_value: 3
477
+ },
478
+ {
479
+ name: 'u_assigned_user',
480
+ label: 'Assigned User',
481
+ type: 'reference',
482
+ reference: 'sys_user'
483
+ }
484
+ ];
485
+ }
486
+ generateMenusFromAnalysis(analysis) {
487
+ const menus = [];
488
+ // Main application menu
489
+ const mainMenu = {
490
+ name: 'main_menu',
491
+ label: analysis.suggestedName,
492
+ application: 'custom',
493
+ modules: []
494
+ };
495
+ // Add modules for each table
496
+ analysis.tables.forEach((tableSpec, index) => {
497
+ const tableName = `u_${tableSpec.suggestedName.toLowerCase().replace(/\s+/g, '_')}`;
498
+ mainMenu.modules.push({
499
+ name: `${tableName}_list`,
500
+ label: `All ${tableSpec.suggestedName}`,
501
+ table: tableName,
502
+ order: (index + 1) * 100
503
+ });
504
+ mainMenu.modules.push({
505
+ name: `${tableName}_new`,
506
+ label: `Create New`,
507
+ table: tableName,
508
+ view: 'new',
509
+ order: (index + 1) * 100 + 10
510
+ });
511
+ });
512
+ // Add reporting module if needed
513
+ if (analysis.features.includes('reporting')) {
514
+ mainMenu.modules.push({
515
+ name: 'reports',
516
+ label: 'Reports',
517
+ table: 'sys_report',
518
+ filter: `table=u_main_table`,
519
+ order: 900
520
+ });
521
+ }
522
+ // Add dashboard module if needed
523
+ if (analysis.features.includes('dashboard')) {
524
+ mainMenu.modules.push({
525
+ name: 'dashboard',
526
+ label: 'Dashboard',
527
+ table: 'pa_dashboards',
528
+ order: 50
529
+ });
530
+ }
531
+ menus.push(mainMenu);
532
+ return menus;
533
+ }
534
+ async generateCompleteApplication(app, analysis) {
535
+ const appPackage = {
536
+ tables: {},
537
+ menus: {},
538
+ security: {},
539
+ scripts: {},
540
+ ui: {},
541
+ workflows: {},
542
+ artifacts: []
543
+ };
544
+ // Generate table definitions
545
+ app.tables.forEach(table => {
546
+ appPackage.tables[table.name] = {
547
+ definition: table,
548
+ dictionary: this.generateTableDictionary(table),
549
+ acls: this.generateTableACLs(table, app.scope)
550
+ };
551
+ appPackage.artifacts.push(this.createArtifact('table_definition', table.name, appPackage.tables[table.name]));
552
+ });
553
+ // Generate menu definitions
554
+ app.menus.forEach(menu => {
555
+ appPackage.menus[menu.name] = {
556
+ definition: menu,
557
+ modules: menu.modules
558
+ };
559
+ appPackage.artifacts.push(this.createArtifact('menu_definition', menu.name, appPackage.menus[menu.name]));
560
+ });
561
+ // Generate security rules
562
+ appPackage.security = this.generateSecurityRules(app);
563
+ // Generate application scripts
564
+ appPackage.scripts = this.generateApplicationScripts(app);
565
+ // Generate UI components
566
+ appPackage.ui = this.generateApplicationUI(app);
567
+ // Generate workflows if needed
568
+ if (analysis.workflows.length > 0) {
569
+ appPackage.workflows = this.generateApplicationWorkflows(app, analysis);
570
+ }
571
+ return appPackage;
572
+ }
573
+ generateTableDictionary(table) {
574
+ return table.fields.map(field => ({
575
+ element: field.name,
576
+ column_label: field.label,
577
+ type: field.type,
578
+ max_length: field.max_length,
579
+ reference: field.reference,
580
+ mandatory: field.mandatory || false,
581
+ default_value: field.default_value,
582
+ attributes: this.getFieldAttributes(field)
583
+ }));
584
+ }
585
+ getFieldAttributes(field) {
586
+ const attributes = [];
587
+ if (field.type === 'reference') {
588
+ attributes.push(`ref_auto_completer=AJAXTableCompleter`);
589
+ attributes.push(`ref_ac_columns=${field.reference}.name`);
590
+ }
591
+ if (field.type === 'choice') {
592
+ attributes.push('edge_encryption_enabled=false');
593
+ }
594
+ return attributes.join(',');
595
+ }
596
+ generateTableACLs(table, scope) {
597
+ const operations = ['create', 'read', 'write', 'delete'];
598
+ const acls = [];
599
+ operations.forEach(operation => {
600
+ acls.push({
601
+ name: `${table.name}.${operation}`,
602
+ operation,
603
+ admin_overrides: true,
604
+ active: true,
605
+ condition: '',
606
+ description: `${operation} access to ${table.label}`,
607
+ script: '',
608
+ type: 'record'
609
+ });
610
+ });
611
+ return acls;
612
+ }
613
+ generateSecurityRules(app) {
614
+ return {
615
+ roles: [
616
+ {
617
+ name: `${app.scope}.user`,
618
+ description: `User role for ${app.name}`,
619
+ assignable_by: 'admin'
620
+ },
621
+ {
622
+ name: `${app.scope}.admin`,
623
+ description: `Admin role for ${app.name}`,
624
+ assignable_by: 'admin',
625
+ contains_roles: [`${app.scope}.user`]
626
+ }
627
+ ],
628
+ acls: app.tables.map(table => ({
629
+ table: table.name,
630
+ rules: this.generateTableACLs(table, app.scope)
631
+ }))
632
+ };
633
+ }
634
+ generateApplicationScripts(app) {
635
+ const scripts = {
636
+ script_includes: [],
637
+ business_rules: [],
638
+ client_scripts: []
639
+ };
640
+ // Generate utility script include
641
+ scripts.script_includes.push({
642
+ name: `${app.vendorPrefix}_${app.scope}_Utils`,
643
+ api_name: `${app.vendorPrefix}_${app.scope}_Utils`,
644
+ description: `Utility functions for ${app.name}`,
645
+ script: this.generateUtilityScriptInclude(app),
646
+ access: 'public'
647
+ });
648
+ // Generate business rules for main tables
649
+ app.tables.forEach(table => {
650
+ if (table.fields.some(f => f.name.includes('number'))) {
651
+ scripts.business_rules.push({
652
+ name: `Generate ${table.label} Number`,
653
+ table: table.name,
654
+ when: 'before',
655
+ insert: true,
656
+ script: this.generateNumberingBusinessRule(table),
657
+ order: 100
658
+ });
659
+ }
660
+ });
661
+ return scripts;
662
+ }
663
+ generateUtilityScriptInclude(app) {
664
+ return `var ${app.vendorPrefix}_${app.scope}_Utils = Class.create();
665
+ ${app.vendorPrefix}_${app.scope}_Utils.prototype = {
666
+ initialize: function() {
667
+ },
668
+
669
+ /**
670
+ * Get application properties
671
+ */
672
+ getAppProperties: function() {
673
+ return {
674
+ scope: '${app.scope}',
675
+ version: '${app.version}',
676
+ name: '${app.name}'
677
+ };
678
+ },
679
+
680
+ /**
681
+ * Log application message
682
+ */
683
+ log: function(message, source) {
684
+ gs.info('[${app.name}] ' + (source || 'General') + ': ' + message);
685
+ },
686
+
687
+ /**
688
+ * Check user role
689
+ */
690
+ hasRole: function(role) {
691
+ return gs.hasRole(role) || gs.hasRole('${app.scope}.admin') || gs.hasRole('admin');
692
+ },
693
+
694
+ type: '${app.vendorPrefix}_${app.scope}_Utils'
695
+ };`;
696
+ }
697
+ generateNumberingBusinessRule(table) {
698
+ return `(function executeRule(current, previous /*null when async*/) {
699
+ // Generate unique number for ${table.label}
700
+ if (!current.number) {
701
+ var prefix = '${table.label.substring(0, 3).toUpperCase()}';
702
+ var gr = new GlideRecord('${table.name}');
703
+ gr.orderByDesc('sys_created_on');
704
+ gr.setLimit(1);
705
+ gr.query();
706
+
707
+ var lastNumber = 1000;
708
+ if (gr.next() && gr.number) {
709
+ var num = parseInt(gr.number.replace(/[^0-9]/g, ''));
710
+ if (!isNaN(num)) {
711
+ lastNumber = num;
712
+ }
713
+ }
714
+
715
+ current.number = prefix + String(lastNumber + 1).padStart(7, '0');
716
+ }
717
+ })(current, previous);`;
718
+ }
719
+ generateApplicationUI(app) {
720
+ return {
721
+ ui_pages: [],
722
+ ui_macros: [],
723
+ widgets: [
724
+ {
725
+ name: `${app.scope}_dashboard`,
726
+ title: `${app.name} Dashboard`,
727
+ template: this.generateDashboardWidget(app),
728
+ css: this.generateDashboardCSS(),
729
+ server_script: this.generateDashboardServerScript(app),
730
+ client_script: this.generateDashboardClientScript()
731
+ }
732
+ ]
733
+ };
734
+ }
735
+ generateDashboardWidget(app) {
736
+ return `<div class="app-dashboard">
737
+ <div class="dashboard-header">
738
+ <h2>${app.name} Dashboard</h2>
739
+ </div>
740
+
741
+ <div class="dashboard-stats">
742
+ ${app.tables.map(table => `
743
+ <div class="stat-card">
744
+ <h3>${table.label}</h3>
745
+ <div class="stat-value">{{data.${table.name}_count || 0}}</div>
746
+ <a href="?id=${table.name}_list" class="stat-link">View All</a>
747
+ </div>
748
+ `).join('')}
749
+ </div>
750
+
751
+ <div class="dashboard-charts">
752
+ <div class="chart-container">
753
+ <canvas id="main-chart"></canvas>
754
+ </div>
755
+ </div>
756
+ </div>`;
757
+ }
758
+ generateDashboardCSS() {
759
+ return `.app-dashboard {
760
+ padding: 20px;
761
+ }
762
+
763
+ .dashboard-header {
764
+ margin-bottom: 30px;
765
+ }
766
+
767
+ .dashboard-stats {
768
+ display: grid;
769
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
770
+ gap: 20px;
771
+ margin-bottom: 30px;
772
+ }
773
+
774
+ .stat-card {
775
+ background: #fff;
776
+ padding: 20px;
777
+ border-radius: 8px;
778
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
779
+ text-align: center;
780
+ }
781
+
782
+ .stat-value {
783
+ font-size: 36px;
784
+ font-weight: bold;
785
+ color: #0078d4;
786
+ margin: 10px 0;
787
+ }
788
+
789
+ .stat-link {
790
+ color: #0078d4;
791
+ text-decoration: none;
792
+ }
793
+
794
+ .chart-container {
795
+ background: #fff;
796
+ padding: 20px;
797
+ border-radius: 8px;
798
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
799
+ }`;
800
+ }
801
+ generateDashboardServerScript(app) {
802
+ return `(function() {
803
+ data.tables = [];
804
+
805
+ ${app.tables.map(table => `
806
+ // Count ${table.label} records
807
+ var ${table.name}_count = new GlideAggregate('${table.name}');
808
+ ${table.name}_count.addAggregate('COUNT');
809
+ ${table.name}_count.query();
810
+ if (${table.name}_count.next()) {
811
+ data.${table.name}_count = ${table.name}_count.getAggregate('COUNT');
812
+ }
813
+ `).join('\n')}
814
+ })();`;
815
+ }
816
+ generateDashboardClientScript() {
817
+ return `function() {
818
+ var c = this;
819
+
820
+ c.$onInit = function() {
821
+ initializeCharts();
822
+ };
823
+
824
+ function initializeCharts() {
825
+ // Initialize dashboard charts
826
+ console.log('Dashboard initialized');
827
+ }
828
+ }`;
829
+ }
830
+ generateApplicationWorkflows(app, analysis) {
831
+ const workflows = {};
832
+ if (analysis.features.includes('approval_workflow')) {
833
+ workflows.approval = {
834
+ name: `${app.scope}_approval_workflow`,
835
+ table: app.tables[0]?.name,
836
+ description: `Approval workflow for ${app.name}`,
837
+ stages: [
838
+ {
839
+ name: 'Submit for Approval',
840
+ type: 'begin'
841
+ },
842
+ {
843
+ name: 'Manager Approval',
844
+ type: 'approval',
845
+ approvers: 'current.opened_by.manager'
846
+ },
847
+ {
848
+ name: 'Update Status',
849
+ type: 'script',
850
+ script: 'current.state = "approved"; current.update();'
851
+ },
852
+ {
853
+ name: 'Send Notification',
854
+ type: 'notification',
855
+ recipients: 'current.opened_by'
856
+ }
857
+ ]
858
+ };
859
+ }
860
+ return workflows;
861
+ }
862
+ generateApplicationCommands(app, appPackage) {
863
+ const commands = [];
864
+ const baseDir = `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${app.scope}`;
865
+ // Create directory structure
866
+ commands.push(this.generateCommand('Bash', 'create', {
867
+ command: `mkdir -p ${baseDir}/{sys_app,tables,menus,security,scripts,ui,workflows,docs,export}`,
868
+ description: 'Create complete application directory structure'
869
+ }, 'Create directories'));
870
+ // Generate table files
871
+ Object.entries(appPackage.tables).forEach(([tableName, tableData]) => {
872
+ commands.push(this.generateCommand('Write', 'create', {
873
+ file_path: `${baseDir}/tables/${tableName}.json`,
874
+ content: JSON.stringify(tableData, null, 2)
875
+ }, `Create table definition: ${tableName}`));
876
+ });
877
+ // Generate menu files
878
+ Object.entries(appPackage.menus).forEach(([menuName, menuData]) => {
879
+ commands.push(this.generateCommand('Write', 'create', {
880
+ file_path: `${baseDir}/menus/${menuName}.json`,
881
+ content: JSON.stringify(menuData, null, 2)
882
+ }, `Create menu definition: ${menuName}`));
883
+ });
884
+ // Generate security files
885
+ commands.push(this.generateCommand('Write', 'create', {
886
+ file_path: `${baseDir}/security/roles.json`,
887
+ content: JSON.stringify(appPackage.security.roles, null, 2)
888
+ }, 'Create security roles'), this.generateCommand('Write', 'create', {
889
+ file_path: `${baseDir}/security/acls.json`,
890
+ content: JSON.stringify(appPackage.security.acls, null, 2)
891
+ }, 'Create access control lists'));
892
+ // Generate script files
893
+ if (appPackage.scripts.script_includes.length > 0) {
894
+ appPackage.scripts.script_includes.forEach((script) => {
895
+ commands.push(this.generateCommand('Write', 'create', {
896
+ file_path: `${baseDir}/scripts/script_includes/${script.api_name}.js`,
897
+ content: script.script
898
+ }, `Create script include: ${script.api_name}`));
899
+ });
900
+ }
901
+ // Generate UI files
902
+ if (appPackage.ui.widgets.length > 0) {
903
+ appPackage.ui.widgets.forEach((widget) => {
904
+ commands.push(this.generateCommand('Write', 'create', {
905
+ file_path: `${baseDir}/ui/widgets/${widget.name}.json`,
906
+ content: JSON.stringify(widget, null, 2)
907
+ }, `Create widget: ${widget.name}`));
908
+ });
909
+ }
910
+ // Generate documentation
911
+ commands.push(this.generateCommand('Write', 'create', {
912
+ file_path: `${baseDir}/README.md`,
913
+ content: this.generateApplicationReadme(app)
914
+ }, 'Create application README'), this.generateCommand('Write', 'create', {
915
+ file_path: `${baseDir}/docs/developer-guide.md`,
916
+ content: this.generateDeveloperGuide(app)
917
+ }, 'Create developer guide'));
918
+ return commands;
919
+ }
920
+ generateComponentCommands(scope, components) {
921
+ const commands = [];
922
+ const baseDir = `/Users/nielsvanderwerf/Projects/servicenow_multiagent/output/applications/${scope}`;
923
+ // Generate commands for tables
924
+ components.tables.forEach((table) => {
925
+ commands.push(this.generateCommand('Write', 'create', {
926
+ file_path: `${baseDir}/tables/${table.name}.json`,
927
+ content: JSON.stringify({
928
+ definition: table,
929
+ dictionary: this.generateTableDictionary(table),
930
+ acls: this.generateTableACLs(table, scope)
931
+ }, null, 2)
932
+ }, `Create table: ${table.name}`));
933
+ });
934
+ // Generate commands for menus
935
+ components.menus.forEach((menu) => {
936
+ commands.push(this.generateCommand('Write', 'create', {
937
+ file_path: `${baseDir}/menus/${menu.name}.json`,
938
+ content: JSON.stringify({
939
+ definition: menu,
940
+ modules: menu.modules
941
+ }, null, 2)
942
+ }, `Create menu: ${menu.name}`));
943
+ });
944
+ return commands;
945
+ }
946
+ createApplicationTable(tableSpec, scope) {
947
+ return {
948
+ name: tableSpec.name || `u_${tableSpec.label.toLowerCase().replace(/\s+/g, '_')}`,
949
+ label: tableSpec.label,
950
+ parent: tableSpec.extends || 'task',
951
+ fields: tableSpec.fields?.map((field) => this.createFieldFromSpec(field)) || this.generateDefaultFields()
952
+ };
953
+ }
954
+ createFieldFromSpec(fieldSpec) {
955
+ return {
956
+ name: fieldSpec.name || `u_${fieldSpec.label.toLowerCase().replace(/\s+/g, '_')}`,
957
+ label: fieldSpec.label,
958
+ type: fieldSpec.type || 'string',
959
+ max_length: fieldSpec.max_length,
960
+ reference: fieldSpec.reference,
961
+ mandatory: fieldSpec.mandatory || false,
962
+ default_value: fieldSpec.default_value
963
+ };
964
+ }
965
+ createApplicationMenu(menuSpec, scope) {
966
+ return {
967
+ name: menuSpec.name || 'custom_menu',
968
+ label: menuSpec.label,
969
+ application: menuSpec.application || scope,
970
+ modules: menuSpec.modules?.map((module, index) => ({
971
+ name: module.name,
972
+ label: module.label,
973
+ table: module.table,
974
+ view: module.view,
975
+ filter: module.filter,
976
+ order: module.order || (index + 1) * 100
977
+ })) || []
978
+ };
979
+ }
980
+ generateManifest(app) {
981
+ return {
982
+ name: app.name,
983
+ scope: app.scope,
984
+ version: app.version,
985
+ vendor: app.vendor,
986
+ vendor_prefix: app.vendorPrefix,
987
+ runtime_access_tracking: 'permissive',
988
+ install_date: new Date().toISOString(),
989
+ dependencies: [],
990
+ repository_url: ''
991
+ };
992
+ }
993
+ generateMetadata(app) {
994
+ return {
995
+ sys_id: this.generateSysId(),
996
+ sys_created_on: new Date().toISOString(),
997
+ sys_created_by: 'admin',
998
+ sys_updated_on: new Date().toISOString(),
999
+ sys_updated_by: 'admin',
1000
+ sys_class_name: 'sys_app',
1001
+ sys_scope: app.scope
1002
+ };
1003
+ }
1004
+ generateSysId() {
1005
+ // Generate a mock sys_id (32 character hex string)
1006
+ return Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
1007
+ }
1008
+ generateSampleData(app) {
1009
+ const sampleData = {};
1010
+ app.tables.forEach(table => {
1011
+ sampleData[table.name] = this.generateTableSampleData(table);
1012
+ });
1013
+ return sampleData;
1014
+ }
1015
+ generateTableSampleData(table) {
1016
+ const samples = [];
1017
+ for (let i = 1; i <= 5; i++) {
1018
+ const record = {
1019
+ number: `${table.label.substring(0, 3).toUpperCase()}000000${i}`,
1020
+ short_description: `Sample ${table.label} ${i}`,
1021
+ sys_created_on: new Date().toISOString(),
1022
+ sys_created_by: 'admin'
1023
+ };
1024
+ // Add field values
1025
+ table.fields.forEach(field => {
1026
+ if (!record[field.name]) {
1027
+ record[field.name] = this.generateFieldSampleValue(field, i);
1028
+ }
1029
+ });
1030
+ samples.push(record);
1031
+ }
1032
+ return samples;
1033
+ }
1034
+ generateFieldSampleValue(field, index) {
1035
+ switch (field.type) {
1036
+ case 'string':
1037
+ return `Sample ${field.label} ${index}`;
1038
+ case 'integer':
1039
+ return index;
1040
+ case 'boolean':
1041
+ return index % 2 === 0;
1042
+ case 'reference':
1043
+ return ''; // Empty reference
1044
+ case 'choice':
1045
+ return 'option_' + index;
1046
+ case 'glide_date_time':
1047
+ return new Date().toISOString();
1048
+ case 'currency':
1049
+ return (index * 100).toFixed(2);
1050
+ default:
1051
+ return `Value ${index}`;
1052
+ }
1053
+ }
1054
+ generateXMLExport(appPackage) {
1055
+ let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
1056
+ xml += '<unload unload_date="' + new Date().toISOString() + '">\n';
1057
+ // Add application record
1058
+ xml += ' <sys_app>\n';
1059
+ xml += ' ' + this.objectToXML(appPackage.manifest) + '\n';
1060
+ xml += ' </sys_app>\n';
1061
+ // Add tables
1062
+ Object.values(appPackage.tables).forEach((table) => {
1063
+ xml += ' <sys_db_object>\n';
1064
+ xml += ' ' + this.objectToXML(table.definition) + '\n';
1065
+ xml += ' </sys_db_object>\n';
1066
+ });
1067
+ xml += '</unload>';
1068
+ return xml;
1069
+ }
1070
+ generateUpdateSetXML(appPackage) {
1071
+ // Simplified update set XML
1072
+ return this.generateXMLExport(appPackage);
1073
+ }
1074
+ objectToXML(obj, indent = '') {
1075
+ let xml = '';
1076
+ Object.entries(obj).forEach(([key, value]) => {
1077
+ if (typeof value === 'object' && !Array.isArray(value)) {
1078
+ xml += `${indent}<${key}>\n${this.objectToXML(value, indent + ' ')}\n${indent}</${key}>`;
1079
+ }
1080
+ else if (Array.isArray(value)) {
1081
+ xml += `${indent}<${key}>${JSON.stringify(value)}</${key}>`;
1082
+ }
1083
+ else {
1084
+ xml += `${indent}<${key}>${value}</${key}>`;
1085
+ }
1086
+ });
1087
+ return xml;
1088
+ }
1089
+ generateInstallationGuide(app) {
1090
+ return `# Installation Guide - ${app.name}
1091
+
1092
+ ## Prerequisites
1093
+ - ServiceNow instance (version Madrid or later)
1094
+ - Admin access to the instance
1095
+ - Update set or application repository access
1096
+
1097
+ ## Installation Steps
1098
+
1099
+ ### Method 1: Update Set Installation
1100
+ 1. Download the update set file: ${app.scope}_update_set.xml
1101
+ 2. Log in to your ServiceNow instance as an administrator
1102
+ 3. Navigate to **System Update Sets > Retrieved Update Sets**
1103
+ 4. Click **Import Update Set from XML**
1104
+ 5. Choose the downloaded file and click **Upload**
1105
+ 6. Preview the update set to check for conflicts
1106
+ 7. Commit the update set
1107
+
1108
+ ### Method 2: Application Repository
1109
+ 1. Navigate to **System Applications > Applications**
1110
+ 2. Click **New** > **Import from Source Control**
1111
+ 3. Enter the repository URL (if available)
1112
+ 4. Follow the import wizard
1113
+
1114
+ ### Method 3: Manual Installation
1115
+ 1. Navigate to **System Applications > Studio**
1116
+ 2. Create a new application with scope: ${app.scope}
1117
+ 3. Import the application files from the export directory
1118
+
1119
+ ## Post-Installation Configuration
1120
+
1121
+ ### 1. Security Setup
1122
+ - Navigate to **User Administration > Roles**
1123
+ - Verify the following roles were created:
1124
+ - ${app.scope}.user
1125
+ - ${app.scope}.admin
1126
+ - Assign roles to appropriate users or groups
1127
+
1128
+ ### 2. Data Migration (if applicable)
1129
+ - If migrating existing data, use the Transform Maps feature
1130
+ - Map fields from legacy tables to new application tables
1131
+
1132
+ ### 3. Integration Setup
1133
+ - Configure any required integrations
1134
+ - Update REST endpoints if needed
1135
+ - Set up scheduled jobs if applicable
1136
+
1137
+ ## Verification Steps
1138
+
1139
+ 1. **Check Application Status**
1140
+ - Navigate to **System Applications > Applications**
1141
+ - Verify ${app.name} shows as "Installed"
1142
+
1143
+ 2. **Test Basic Functionality**
1144
+ - Access the application menu
1145
+ - Create a test record
1146
+ - Verify workflows trigger correctly
1147
+
1148
+ 3. **Validate Security**
1149
+ - Test with different user roles
1150
+ - Verify access controls work as expected
1151
+
1152
+ ## Troubleshooting
1153
+
1154
+ ### Common Issues
1155
+
1156
+ **Issue**: Application menu not visible
1157
+ - **Solution**: Clear browser cache and refresh, check role assignments
1158
+
1159
+ **Issue**: Tables not accessible
1160
+ - **Solution**: Verify ACLs are active, check user roles
1161
+
1162
+ **Issue**: Workflows not triggering
1163
+ - **Solution**: Check workflow status, verify conditions
1164
+
1165
+ ## Support
1166
+ For issues or questions:
1167
+ - Check application logs in System Logs
1168
+ - Contact your ServiceNow administrator
1169
+ - Refer to the developer guide for customization
1170
+
1171
+ Generated on: ${new Date().toISOString()}
1172
+ `;
1173
+ }
1174
+ generateDeveloperGuide(app) {
1175
+ return `# Developer Guide - ${app.name}
1176
+
1177
+ ## Application Overview
1178
+ - **Scope**: ${app.scope}
1179
+ - **Version**: ${app.version}
1180
+ - **Tables**: ${app.tables.length}
1181
+ - **Menus**: ${app.menus.length}
1182
+
1183
+ ## Architecture
1184
+
1185
+ ### Data Model
1186
+ ${app.tables.map(table => `
1187
+ #### ${table.label} (${table.name})
1188
+ - **Extends**: ${table.extends}
1189
+ - **Purpose**: Primary table for storing ${table.label.toLowerCase()} records
1190
+
1191
+ **Fields**:
1192
+ ${table.fields.map(field => `- **${field.label}** (${field.name}): ${field.type}${field.reference ? ` -> ${field.reference}` : ''}`).join('\n')}
1193
+ `).join('\n')}
1194
+
1195
+ ### Security Model
1196
+ - **Roles**:
1197
+ - ${app.scope}.user: Basic user access
1198
+ - ${app.scope}.admin: Administrative access
1199
+ - **ACLs**: Table-level access controls for CRUD operations
1200
+
1201
+ ## Development Guidelines
1202
+
1203
+ ### Naming Conventions
1204
+ - Tables: u_[descriptive_name]
1205
+ - Fields: u_[field_name]
1206
+ - Script Includes: ${app.vendorPrefix}_[ClassName]
1207
+ - Business Rules: [Table] - [Action] - [Description]
1208
+
1209
+ ### Coding Standards
1210
+ \`\`\`javascript
1211
+ // Use the application's utility class
1212
+ var utils = new ${app.vendorPrefix}_${app.scope}_Utils();
1213
+ utils.log('Debug message', 'MethodName');
1214
+
1215
+ // Check permissions
1216
+ if (!utils.hasRole('${app.scope}.user')) {
1217
+ gs.addErrorMessage('Insufficient permissions');
1218
+ return;
1219
+ }
1220
+ \`\`\`
1221
+
1222
+ ### Best Practices
1223
+ 1. Always use scoped APIs when available
1224
+ 2. Implement proper error handling
1225
+ 3. Log important operations for debugging
1226
+ 4. Follow ServiceNow development best practices
1227
+
1228
+ ## Extending the Application
1229
+
1230
+ ### Adding New Tables
1231
+ 1. Create table extending appropriate base table
1232
+ 2. Add necessary fields with u_ prefix
1233
+ 3. Create ACLs for the new table
1234
+ 4. Update navigation menus
1235
+
1236
+ ### Creating Business Rules
1237
+ \`\`\`javascript
1238
+ (function executeRule(current, previous /*null when async*/) {
1239
+ // Your business logic here
1240
+ var utils = new ${app.vendorPrefix}_${app.scope}_Utils();
1241
+ utils.log('Business rule triggered', 'RuleName');
1242
+ })(current, previous);
1243
+ \`\`\`
1244
+
1245
+ ### Adding UI Components
1246
+ 1. Service Portal Widgets: Use provided dashboard widget as template
1247
+ 2. UI Pages: Follow existing UI page patterns
1248
+ 3. Client Scripts: Ensure proper form context usage
1249
+
1250
+ ## API Reference
1251
+
1252
+ ### ${app.vendorPrefix}_${app.scope}_Utils
1253
+ Main utility class for the application.
1254
+
1255
+ **Methods**:
1256
+ - getAppProperties(): Returns application metadata
1257
+ - log(message, source): Logs application messages
1258
+ - hasRole(role): Checks user permissions
1259
+
1260
+ ## Testing
1261
+
1262
+ ### Unit Testing
1263
+ \`\`\`javascript
1264
+ // Test script for Script Includes
1265
+ var utils = new ${app.vendorPrefix}_${app.scope}_Utils();
1266
+ gs.info('Testing utility class: ' + utils.type);
1267
+ \`\`\`
1268
+
1269
+ ### Integration Testing
1270
+ 1. Test all CRUD operations
1271
+ 2. Verify workflow execution
1272
+ 3. Check security controls
1273
+ 4. Validate UI functionality
1274
+
1275
+ ## Deployment
1276
+
1277
+ ### Moving Between Instances
1278
+ 1. Use Update Sets for controlled deployments
1279
+ 2. Export application to source control
1280
+ 3. Use application repository for version control
1281
+
1282
+ ### Version Management
1283
+ - Follow semantic versioning (MAJOR.MINOR.PATCH)
1284
+ - Document all changes in release notes
1285
+ - Test thoroughly before version updates
1286
+
1287
+ Generated by: ServiceNow Multi-Agent Framework
1288
+ `;
1289
+ }
1290
+ }
1291
+ exports.AppCreatorAgent = AppCreatorAgent;
1292
+ //# sourceMappingURL=app-creator.agent.js.map