nowaikit 3.0.0 → 4.0.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 (235) hide show
  1. package/LICENSE +10 -10
  2. package/README.md +8 -6
  3. package/desktop/renderer/dist/assets/index-D46KUWoj.js +49 -0
  4. package/desktop/renderer/dist/index.html +5 -5
  5. package/desktop/serve.cjs +134 -10
  6. package/dist/a2a/agent-card.d.ts +8 -0
  7. package/dist/a2a/agent-card.d.ts.map +1 -0
  8. package/dist/a2a/agent-card.js +82 -0
  9. package/dist/a2a/agent-card.js.map +1 -0
  10. package/dist/a2a/index.d.ts +13 -0
  11. package/dist/a2a/index.d.ts.map +1 -0
  12. package/dist/a2a/index.js +74 -0
  13. package/dist/a2a/index.js.map +1 -0
  14. package/dist/a2a/task-manager.d.ts +20 -0
  15. package/dist/a2a/task-manager.d.ts.map +1 -0
  16. package/dist/a2a/task-manager.js +148 -0
  17. package/dist/a2a/task-manager.js.map +1 -0
  18. package/dist/a2a/types.d.ts +73 -0
  19. package/dist/a2a/types.d.ts.map +1 -0
  20. package/dist/a2a/types.js +6 -0
  21. package/dist/a2a/types.js.map +1 -0
  22. package/dist/api/index.d.ts +16 -0
  23. package/dist/api/index.d.ts.map +1 -0
  24. package/dist/api/index.js +106 -0
  25. package/dist/api/index.js.map +1 -0
  26. package/dist/cli/config-store.d.ts +31 -0
  27. package/dist/cli/config-store.d.ts.map +1 -1
  28. package/dist/cli/config-store.js +44 -1
  29. package/dist/cli/config-store.js.map +1 -1
  30. package/dist/cli/index.js +115 -9
  31. package/dist/cli/index.js.map +1 -1
  32. package/dist/cli/setup.d.ts.map +1 -1
  33. package/dist/cli/setup.js +669 -49
  34. package/dist/cli/setup.js.map +1 -1
  35. package/dist/cli/shortcuts.d.ts +2 -0
  36. package/dist/cli/shortcuts.d.ts.map +1 -0
  37. package/dist/cli/shortcuts.js +122 -0
  38. package/dist/cli/shortcuts.js.map +1 -0
  39. package/dist/dashboard/index.d.ts +7 -0
  40. package/dist/dashboard/index.d.ts.map +1 -0
  41. package/dist/dashboard/index.js +111 -0
  42. package/dist/dashboard/index.js.map +1 -0
  43. package/dist/direct/llm-client.d.ts +1 -1
  44. package/dist/direct/llm-client.d.ts.map +1 -1
  45. package/dist/direct/llm-client.js +9 -4
  46. package/dist/direct/llm-client.js.map +1 -1
  47. package/dist/prompts/capabilities/build-app.d.ts.map +1 -1
  48. package/dist/prompts/capabilities/build-app.js +2 -0
  49. package/dist/prompts/capabilities/build-app.js.map +1 -1
  50. package/dist/prompts/capabilities/build-atf-suite.d.ts +4 -0
  51. package/dist/prompts/capabilities/build-atf-suite.d.ts.map +1 -0
  52. package/dist/prompts/capabilities/build-atf-suite.js +143 -0
  53. package/dist/prompts/capabilities/build-atf-suite.js.map +1 -0
  54. package/dist/prompts/capabilities/build-business-rule.d.ts.map +1 -1
  55. package/dist/prompts/capabilities/build-business-rule.js +2 -0
  56. package/dist/prompts/capabilities/build-business-rule.js.map +1 -1
  57. package/dist/prompts/capabilities/build-catalog.d.ts.map +1 -1
  58. package/dist/prompts/capabilities/build-catalog.js +2 -0
  59. package/dist/prompts/capabilities/build-catalog.js.map +1 -1
  60. package/dist/prompts/capabilities/build-client-script.d.ts.map +1 -1
  61. package/dist/prompts/capabilities/build-client-script.js +2 -0
  62. package/dist/prompts/capabilities/build-client-script.js.map +1 -1
  63. package/dist/prompts/capabilities/build-flow.d.ts.map +1 -1
  64. package/dist/prompts/capabilities/build-flow.js +2 -0
  65. package/dist/prompts/capabilities/build-flow.js.map +1 -1
  66. package/dist/prompts/capabilities/build-portal.d.ts.map +1 -1
  67. package/dist/prompts/capabilities/build-portal.js +2 -0
  68. package/dist/prompts/capabilities/build-portal.js.map +1 -1
  69. package/dist/prompts/capabilities/build-rest-api.d.ts.map +1 -1
  70. package/dist/prompts/capabilities/build-rest-api.js +2 -0
  71. package/dist/prompts/capabilities/build-rest-api.js.map +1 -1
  72. package/dist/prompts/capabilities/build-test-plan.d.ts.map +1 -1
  73. package/dist/prompts/capabilities/build-test-plan.js +2 -0
  74. package/dist/prompts/capabilities/build-test-plan.js.map +1 -1
  75. package/dist/prompts/capabilities/build-uib.d.ts.map +1 -1
  76. package/dist/prompts/capabilities/build-uib.js +2 -0
  77. package/dist/prompts/capabilities/build-uib.js.map +1 -1
  78. package/dist/prompts/capabilities/docs-app.d.ts.map +1 -1
  79. package/dist/prompts/capabilities/docs-app.js +2 -0
  80. package/dist/prompts/capabilities/docs-app.js.map +1 -1
  81. package/dist/prompts/capabilities/docs-release.d.ts.map +1 -1
  82. package/dist/prompts/capabilities/docs-release.js +2 -0
  83. package/dist/prompts/capabilities/docs-release.js.map +1 -1
  84. package/dist/prompts/capabilities/docs-runbook.d.ts.map +1 -1
  85. package/dist/prompts/capabilities/docs-runbook.js +2 -0
  86. package/dist/prompts/capabilities/docs-runbook.js.map +1 -1
  87. package/dist/prompts/capabilities/docs-script.d.ts.map +1 -1
  88. package/dist/prompts/capabilities/docs-script.js +2 -0
  89. package/dist/prompts/capabilities/docs-script.js.map +1 -1
  90. package/dist/prompts/capabilities/ops-deploy.d.ts.map +1 -1
  91. package/dist/prompts/capabilities/ops-deploy.js +2 -0
  92. package/dist/prompts/capabilities/ops-deploy.js.map +1 -1
  93. package/dist/prompts/capabilities/ops-risk.d.ts.map +1 -1
  94. package/dist/prompts/capabilities/ops-risk.js +2 -0
  95. package/dist/prompts/capabilities/ops-risk.js.map +1 -1
  96. package/dist/prompts/capabilities/ops-triage.d.ts.map +1 -1
  97. package/dist/prompts/capabilities/ops-triage.js +2 -0
  98. package/dist/prompts/capabilities/ops-triage.js.map +1 -1
  99. package/dist/prompts/capabilities/review-acls.d.ts.map +1 -1
  100. package/dist/prompts/capabilities/review-acls.js +2 -0
  101. package/dist/prompts/capabilities/review-acls.js.map +1 -1
  102. package/dist/prompts/capabilities/review-code.d.ts.map +1 -1
  103. package/dist/prompts/capabilities/review-code.js +2 -0
  104. package/dist/prompts/capabilities/review-code.js.map +1 -1
  105. package/dist/prompts/capabilities/review-flows.d.ts.map +1 -1
  106. package/dist/prompts/capabilities/review-flows.js +2 -0
  107. package/dist/prompts/capabilities/review-flows.js.map +1 -1
  108. package/dist/prompts/capabilities/review-scripts.d.ts.map +1 -1
  109. package/dist/prompts/capabilities/review-scripts.js +2 -0
  110. package/dist/prompts/capabilities/review-scripts.js.map +1 -1
  111. package/dist/prompts/capabilities/scan-automation.d.ts.map +1 -1
  112. package/dist/prompts/capabilities/scan-automation.js +2 -0
  113. package/dist/prompts/capabilities/scan-automation.js.map +1 -1
  114. package/dist/prompts/capabilities/scan-cmdb.d.ts.map +1 -1
  115. package/dist/prompts/capabilities/scan-cmdb.js +2 -0
  116. package/dist/prompts/capabilities/scan-cmdb.js.map +1 -1
  117. package/dist/prompts/capabilities/scan-debt.d.ts.map +1 -1
  118. package/dist/prompts/capabilities/scan-debt.js +2 -0
  119. package/dist/prompts/capabilities/scan-debt.js.map +1 -1
  120. package/dist/prompts/capabilities/scan-health.d.ts.map +1 -1
  121. package/dist/prompts/capabilities/scan-health.js +2 -0
  122. package/dist/prompts/capabilities/scan-health.js.map +1 -1
  123. package/dist/prompts/capabilities/scan-security.d.ts.map +1 -1
  124. package/dist/prompts/capabilities/scan-security.js +2 -0
  125. package/dist/prompts/capabilities/scan-security.js.map +1 -1
  126. package/dist/prompts/capabilities/scan-upgrade.d.ts.map +1 -1
  127. package/dist/prompts/capabilities/scan-upgrade.js +2 -0
  128. package/dist/prompts/capabilities/scan-upgrade.js.map +1 -1
  129. package/dist/prompts/index.d.ts.map +1 -1
  130. package/dist/prompts/index.js +47 -8
  131. package/dist/prompts/index.js.map +1 -1
  132. package/dist/reports/brand.d.ts +79 -0
  133. package/dist/reports/brand.d.ts.map +1 -0
  134. package/dist/reports/brand.js +204 -0
  135. package/dist/reports/brand.js.map +1 -0
  136. package/dist/reports/charts.d.ts +11 -0
  137. package/dist/reports/charts.d.ts.map +1 -0
  138. package/dist/reports/charts.js +91 -0
  139. package/dist/reports/charts.js.map +1 -0
  140. package/dist/reports/index.d.ts +13 -0
  141. package/dist/reports/index.d.ts.map +1 -0
  142. package/dist/reports/index.js +65 -0
  143. package/dist/reports/index.js.map +1 -0
  144. package/dist/reports/parser.d.ts +13 -0
  145. package/dist/reports/parser.d.ts.map +1 -0
  146. package/dist/reports/parser.js +202 -0
  147. package/dist/reports/parser.js.map +1 -0
  148. package/dist/reports/pdf-generator.d.ts +8 -0
  149. package/dist/reports/pdf-generator.d.ts.map +1 -0
  150. package/dist/reports/pdf-generator.js +244 -0
  151. package/dist/reports/pdf-generator.js.map +1 -0
  152. package/dist/reports/pptx-generator.d.ts +8 -0
  153. package/dist/reports/pptx-generator.d.ts.map +1 -0
  154. package/dist/reports/pptx-generator.js +273 -0
  155. package/dist/reports/pptx-generator.js.map +1 -0
  156. package/dist/reports/types.d.ts +60 -0
  157. package/dist/reports/types.d.ts.map +1 -0
  158. package/dist/reports/types.js +7 -0
  159. package/dist/reports/types.js.map +1 -0
  160. package/dist/resources/index.d.ts.map +1 -1
  161. package/dist/resources/index.js +10 -0
  162. package/dist/resources/index.js.map +1 -1
  163. package/dist/resources/query-syntax.d.ts +6 -0
  164. package/dist/resources/query-syntax.d.ts.map +1 -0
  165. package/dist/resources/query-syntax.js +113 -0
  166. package/dist/resources/query-syntax.js.map +1 -0
  167. package/dist/sdk/index.d.ts +51 -0
  168. package/dist/sdk/index.d.ts.map +1 -0
  169. package/dist/sdk/index.js +55 -0
  170. package/dist/sdk/index.js.map +1 -0
  171. package/dist/server.d.ts +2 -1
  172. package/dist/server.d.ts.map +1 -1
  173. package/dist/server.js +103 -92
  174. package/dist/server.js.map +1 -1
  175. package/dist/servicenow/client.js +1 -1
  176. package/dist/servicenow/client.js.map +1 -1
  177. package/dist/tools/ai-agents.d.ts +145 -0
  178. package/dist/tools/ai-agents.d.ts.map +1 -0
  179. package/dist/tools/ai-agents.js +185 -0
  180. package/dist/tools/ai-agents.js.map +1 -0
  181. package/dist/tools/cmdb-reconciliation.d.ts +112 -0
  182. package/dist/tools/cmdb-reconciliation.d.ts.map +1 -0
  183. package/dist/tools/cmdb-reconciliation.js +267 -0
  184. package/dist/tools/cmdb-reconciliation.js.map +1 -0
  185. package/dist/tools/discovery.d.ts +34 -0
  186. package/dist/tools/discovery.d.ts.map +1 -0
  187. package/dist/tools/discovery.js +168 -0
  188. package/dist/tools/discovery.js.map +1 -0
  189. package/dist/tools/fluent.d.ts +105 -11
  190. package/dist/tools/fluent.d.ts.map +1 -1
  191. package/dist/tools/fluent.js +118 -1
  192. package/dist/tools/fluent.js.map +1 -1
  193. package/dist/tools/index.d.ts +840 -0
  194. package/dist/tools/index.d.ts.map +1 -1
  195. package/dist/tools/index.js +44 -6
  196. package/dist/tools/index.js.map +1 -1
  197. package/dist/tools/ml.d.ts +104 -0
  198. package/dist/tools/ml.d.ts.map +1 -1
  199. package/dist/tools/ml.js +139 -0
  200. package/dist/tools/ml.js.map +1 -1
  201. package/dist/tools/now-assist-skills.d.ts +129 -0
  202. package/dist/tools/now-assist-skills.d.ts.map +1 -0
  203. package/dist/tools/now-assist-skills.js +128 -0
  204. package/dist/tools/now-assist-skills.js.map +1 -0
  205. package/dist/tools/orchestration.d.ts +132 -0
  206. package/dist/tools/orchestration.d.ts.map +1 -0
  207. package/dist/tools/orchestration.js +320 -0
  208. package/dist/tools/orchestration.js.map +1 -0
  209. package/dist/tools/reporting.d.ts +127 -1
  210. package/dist/tools/reporting.d.ts.map +1 -1
  211. package/dist/tools/reporting.js +64 -0
  212. package/dist/tools/reporting.js.map +1 -1
  213. package/dist/tools/schema-cache.d.ts +44 -0
  214. package/dist/tools/schema-cache.d.ts.map +1 -0
  215. package/dist/tools/schema-cache.js +127 -0
  216. package/dist/tools/schema-cache.js.map +1 -0
  217. package/dist/tools-manifest.json +1250 -25
  218. package/dist/transport/auth-middleware.d.ts +16 -0
  219. package/dist/transport/auth-middleware.d.ts.map +1 -0
  220. package/dist/transport/auth-middleware.js +31 -0
  221. package/dist/transport/auth-middleware.js.map +1 -0
  222. package/dist/transport/http-server.d.ts +44 -0
  223. package/dist/transport/http-server.d.ts.map +1 -0
  224. package/dist/transport/http-server.js +172 -0
  225. package/dist/transport/http-server.js.map +1 -0
  226. package/dist/transport/index.d.ts +19 -0
  227. package/dist/transport/index.d.ts.map +1 -0
  228. package/dist/transport/index.js +105 -0
  229. package/dist/transport/index.js.map +1 -0
  230. package/dist/utils/permissions.d.ts +2 -0
  231. package/dist/utils/permissions.d.ts.map +1 -1
  232. package/dist/utils/permissions.js +8 -0
  233. package/dist/utils/permissions.js.map +1 -1
  234. package/package.json +27 -4
  235. package/desktop/renderer/dist/assets/index-B-6BYnh8.js +0 -49
@@ -4,13 +4,13 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>NowAIKit</title>
7
- <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
8
- <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
9
- <link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon.png" />
7
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
8
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
9
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
10
10
  <!-- CSP: script-src unsafe-inline needed for Vite HMR in dev; style-src unsafe-inline needed for React inline styles -->
11
11
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://*.service-now.com https://*.servicenowservices.com https://generativelanguage.googleapis.com ws://localhost:* http://localhost:*; img-src 'self' data:; frame-ancestors 'none'; form-action 'self';" />
12
- <script type="module" crossorigin src="./assets/index-B-6BYnh8.js"></script>
13
- <link rel="stylesheet" crossorigin href="./assets/index-Bb0ncZQl.css">
12
+ <script type="module" crossorigin src="/assets/index-D46KUWoj.js"></script>
13
+ <link rel="stylesheet" crossorigin href="/assets/index-Bb0ncZQl.css">
14
14
  </head>
15
15
  <body>
16
16
  <div id="root"></div>
package/desktop/serve.cjs CHANGED
@@ -56,11 +56,13 @@ const MIME = {
56
56
  // ─── AI provider proxy config ────────────────────────────────────────────────
57
57
 
58
58
  const AI_PROXIES = {
59
- '/api/ai/anthropic': { target: 'https://api.anthropic.com', strip: '/api/ai/anthropic' },
60
- '/api/ai/openai': { target: 'https://api.openai.com', strip: '/api/ai/openai' },
61
- '/api/ai/google': { target: 'https://generativelanguage.googleapis.com', strip: '/api/ai/google' },
62
- '/api/ai/groq': { target: 'https://api.groq.com', strip: '/api/ai/groq' },
63
- '/api/ai/openrouter': { target: 'https://openrouter.ai', strip: '/api/ai/openrouter' },
59
+ '/api/ai/anthropic': { target: 'https://api.anthropic.com', strip: '/api/ai/anthropic' },
60
+ '/api/ai/openai': { target: 'https://api.openai.com', strip: '/api/ai/openai' },
61
+ '/api/ai/google': { target: 'https://generativelanguage.googleapis.com', strip: '/api/ai/google' },
62
+ '/api/ai/groq': { target: 'https://api.groq.com', strip: '/api/ai/groq' },
63
+ '/api/ai/openrouter': { target: 'https://openrouter.ai', strip: '/api/ai/openrouter' },
64
+ '/api/ai/ollama': { target: 'http://localhost:11434', strip: '/api/ai/ollama' },
65
+ '/api/ai/lmstudio': { target: 'http://localhost:1234', strip: '/api/ai/lmstudio' },
64
66
  };
65
67
 
66
68
  // Headers that are safe to forward to upstream AI providers
@@ -159,9 +161,11 @@ function proxyRequest(req, res, proxyConfig) {
159
161
  }
160
162
  }
161
163
 
164
+ const isTargetHttps = target.protocol === 'https:';
165
+ const mod = isTargetHttps ? https : http;
162
166
  const options = {
163
167
  hostname: target.hostname,
164
- port: 443,
168
+ port: isTargetHttps ? 443 : (parseInt(target.port, 10) || 80),
165
169
  path: target.pathname + target.search,
166
170
  method: req.method,
167
171
  headers,
@@ -170,7 +174,7 @@ function proxyRequest(req, res, proxyConfig) {
170
174
  const origin = req.headers.origin;
171
175
  const allowedOrigin = isAllowedOrigin(origin) ? (origin || '*') : '';
172
176
 
173
- const proxyReq = https.request(options, (proxyRes) => {
177
+ const proxyReq = mod.request(options, (proxyRes) => {
174
178
  // Set CORS headers for the allowed origin
175
179
  if (allowedOrigin) {
176
180
  res.setHeader('Access-Control-Allow-Origin', allowedOrigin);
@@ -370,6 +374,87 @@ function serveStatic(req, res) {
370
374
  });
371
375
  }
372
376
 
377
+ // ─── Report generation handler ───────────────────────────────────────────────
378
+
379
+ /**
380
+ * POST /api/report/generate
381
+ * Body: { markdown, format, title, instanceUrl, instanceName, capability }
382
+ * Returns: binary file with appropriate Content-Type
383
+ */
384
+ function handleReportGenerate(req, res) {
385
+ const chunks = [];
386
+ let totalSize = 0;
387
+ const MAX_BODY = 10 * 1024 * 1024;
388
+
389
+ req.on('data', chunk => {
390
+ totalSize += chunk.length;
391
+ if (totalSize > MAX_BODY) {
392
+ res.writeHead(413, { 'Content-Type': 'application/json' });
393
+ res.end(JSON.stringify({ error: 'Request body too large' }));
394
+ req.destroy();
395
+ return;
396
+ }
397
+ chunks.push(chunk);
398
+ });
399
+
400
+ req.on('end', async () => {
401
+ if (totalSize > MAX_BODY) return;
402
+
403
+ try {
404
+ const body = JSON.parse(Buffer.concat(chunks).toString());
405
+ const { markdown, format, title, instanceUrl, instanceName, capability } = body;
406
+
407
+ if (!markdown || !format || !title) {
408
+ res.writeHead(400, { 'Content-Type': 'application/json' });
409
+ res.end(JSON.stringify({ error: 'markdown, format, and title are required' }));
410
+ return;
411
+ }
412
+
413
+ if (format !== 'pdf' && format !== 'pptx') {
414
+ res.writeHead(400, { 'Content-Type': 'application/json' });
415
+ res.end(JSON.stringify({ error: 'format must be "pdf" or "pptx"' }));
416
+ return;
417
+ }
418
+
419
+ // Dynamic import of the report module (ESM from CJS)
420
+ const reportModule = await import(path.resolve(__dirname, '..', 'dist', 'reports', 'index.js'));
421
+ const result = await reportModule.generateReport(markdown, format, {
422
+ title,
423
+ instanceUrl: instanceUrl || '',
424
+ instanceName: instanceName || 'instance',
425
+ capability: capability || '',
426
+ });
427
+
428
+ // Read generated file and send it
429
+ const fileBuffer = fs.readFileSync(result.filePath);
430
+ const contentType = format === 'pdf' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
431
+ const fileName = path.basename(result.filePath);
432
+
433
+ const origin = req.headers.origin;
434
+ const allowedOrigin = isAllowedOrigin(origin) ? (origin || '*') : '';
435
+
436
+ const headers = {
437
+ 'Content-Type': contentType,
438
+ 'Content-Disposition': `attachment; filename="${fileName}"`,
439
+ 'Content-Length': fileBuffer.length,
440
+ };
441
+ if (allowedOrigin) {
442
+ headers['Access-Control-Allow-Origin'] = allowedOrigin;
443
+ }
444
+
445
+ res.writeHead(200, headers);
446
+ res.end(fileBuffer);
447
+
448
+ // Cleanup temp file
449
+ try { fs.unlinkSync(result.filePath); } catch { /* ignore */ }
450
+ } catch (err) {
451
+ console.error('Report generation error:', err.message || err);
452
+ res.writeHead(500, { 'Content-Type': 'application/json' });
453
+ res.end(JSON.stringify({ error: 'Report generation failed: ' + (err.message || 'unknown error') }));
454
+ }
455
+ });
456
+ }
457
+
373
458
  // ─── HTTP server ─────────────────────────────────────────────────────────────
374
459
 
375
460
  const server = http.createServer((req, res) => {
@@ -430,16 +515,36 @@ const server = http.createServer((req, res) => {
430
515
  return;
431
516
  }
432
517
 
518
+ // Report generation endpoint
519
+ if (req.url === '/api/report/generate' && req.method === 'POST') {
520
+ if (!proxySecurityCheck()) return;
521
+ handleReportGenerate(req, res);
522
+ return;
523
+ }
524
+
433
525
  // Serve static files
434
526
  serveStatic(req, res);
435
527
  });
436
528
 
437
- server.listen(PORT, HOST, () => {
529
+ // Try preferred port, fall back to alternatives if busy
530
+ const FALLBACK_PORTS = [PORT, PORT + 1, PORT + 2, PORT + 3, PORT + 10, 0];
531
+ let portIndex = 0;
532
+
533
+ function tryListen() {
534
+ const tryPort = FALLBACK_PORTS[portIndex];
535
+ server.listen(tryPort, HOST);
536
+ }
537
+
538
+ server.on('listening', () => {
539
+ const actualPort = server.address().port;
540
+ if (actualPort !== PORT) {
541
+ console.log(`\n ⚠ Port ${PORT} was in use, using port ${actualPort} instead.`);
542
+ }
438
543
  console.log(`\n NowAIKit Web Server`);
439
544
  console.log(` ───────────────────────────────`);
440
- console.log(` Local: http://localhost:${PORT}`);
545
+ console.log(` Local: http://localhost:${actualPort}`);
441
546
  if (HOST !== '127.0.0.1' && HOST !== 'localhost') {
442
- console.log(` Network: http://${HOST}:${PORT}`);
547
+ console.log(` Network: http://${HOST}:${actualPort}`);
443
548
  }
444
549
  console.log(`\n AI proxy: /api/ai/* -> provider APIs (CORS proxied)`);
445
550
  console.log(` Snow proxy: /api/snow/* -> ServiceNow instances (CORS proxied)`);
@@ -447,3 +552,22 @@ server.listen(PORT, HOST, () => {
447
552
  console.log(`\n All AI providers + ServiceNow instances supported.`);
448
553
  console.log(` Press Ctrl+C to stop.\n`);
449
554
  });
555
+
556
+ server.on('error', (err) => {
557
+ if (err.code === 'EADDRINUSE') {
558
+ portIndex++;
559
+ if (portIndex < FALLBACK_PORTS.length) {
560
+ const next = FALLBACK_PORTS[portIndex] || 'random';
561
+ console.log(` Port ${FALLBACK_PORTS[portIndex - 1]} is in use, trying ${next}…`);
562
+ tryListen();
563
+ } else {
564
+ console.error(` ✕ All ports are in use. Set PORT=<number> to specify a port.`);
565
+ process.exit(1);
566
+ }
567
+ } else {
568
+ console.error(` ✕ Server error: ${err.message}`);
569
+ process.exit(1);
570
+ }
571
+ });
572
+
573
+ tryListen();
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A2A Agent Card generator — exposes NowAIKit capabilities as an A2A agent.
3
+ * Maps MCP tool domains to A2A skills.
4
+ */
5
+ import type { AgentCard } from './types.js';
6
+ /** Build agent card from current tool definitions. */
7
+ export declare function buildAgentCard(): AgentCard;
8
+ //# sourceMappingURL=agent-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-card.d.ts","sourceRoot":"","sources":["../../src/a2a/agent-card.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AA4BxD,sDAAsD;AACtD,wBAAgB,cAAc,IAAI,SAAS,CAyC1C"}
@@ -0,0 +1,82 @@
1
+ import { getTools } from '../tools/index.js';
2
+ import { isAuthRequired } from '../transport/auth-middleware.js';
3
+ /** Categorize tools into skills by domain prefix. */
4
+ const DOMAIN_MAP = {
5
+ incident: { name: 'Incident Management', description: 'Create, update, resolve, and close incidents. Triage P1/P2 issues.', tags: ['itsm', 'incident'] },
6
+ problem: { name: 'Problem Management', description: 'Create and manage problem records, find root causes.', tags: ['itsm', 'problem'] },
7
+ change: { name: 'Change Management', description: 'Create, approve, and manage change requests. Risk assessment and CAB.', tags: ['itsm', 'change'] },
8
+ knowledge: { name: 'Knowledge Management', description: 'Search, create, and publish knowledge articles.', tags: ['knowledge', 'kb'] },
9
+ catalog: { name: 'Service Catalog', description: 'Browse, manage, and order catalog items.', tags: ['catalog', 'request'] },
10
+ cmdb: { name: 'CMDB Management', description: 'Search CIs, view relationships, health dashboards, reconciliation.', tags: ['cmdb', 'itom'] },
11
+ security: { name: 'Security Operations', description: 'Manage security incidents, vulnerabilities, compliance, GRC risks.', tags: ['secops', 'security', 'grc'] },
12
+ hrsd: { name: 'HR Service Delivery', description: 'HR cases, onboarding, offboarding, employee lifecycle.', tags: ['hrsd', 'hr'] },
13
+ csm: { name: 'Customer Service Management', description: 'CSM cases, accounts, contacts, SLAs.', tags: ['csm', 'customer'] },
14
+ flow: { name: 'Flow Designer', description: 'Create and manage flows, subflows, and process automations.', tags: ['flow', 'automation'] },
15
+ script: { name: 'Platform Scripting', description: 'Business rules, script includes, client scripts, ACLs.', tags: ['scripting', 'development'] },
16
+ ml: { name: 'Machine Learning', description: 'Anomaly detection, change risk prediction, incident forecasting.', tags: ['ml', 'ai'] },
17
+ atf: { name: 'Automated Testing', description: 'ATF test suites, test execution, failure analysis.', tags: ['testing', 'atf'] },
18
+ devops: { name: 'DevOps', description: 'Pipelines, deployments, DevOps insights.', tags: ['devops', 'cicd'] },
19
+ report: { name: 'Reporting & Analytics', description: 'Generate reports, dashboards, KPIs, trend analysis.', tags: ['reporting', 'analytics'] },
20
+ fluent: { name: 'Fluent Query & SDK', description: 'GlideQuery-style queries, batch operations, now-sdk integration.', tags: ['fluent', 'query', 'sdk'] },
21
+ now_assist: { name: 'Now Assist Skills', description: 'Create, manage, and test Now Assist AI skills.', tags: ['now-assist', 'ai', 'skills'] },
22
+ ai_agent: { name: 'AI Agents', description: 'Create and manage AI agents with automatic ACL generation.', tags: ['ai-agent', 'aiaf'] },
23
+ orchestration: { name: 'Multi-Agent Orchestration', description: 'Create and execute multi-step playbooks chaining tools.', tags: ['orchestration', 'playbook'] },
24
+ discover: { name: 'Schema Discovery', description: 'Discover table schemas and generate dynamic CRUD tools.', tags: ['discovery', 'schema'] },
25
+ };
26
+ /** Build agent card from current tool definitions. */
27
+ export function buildAgentCard() {
28
+ const tools = getTools();
29
+ const baseUrl = `http://${process.env.HOST || 'localhost'}:${process.env.PORT || '3000'}`;
30
+ // Group tools by domain
31
+ const skillMap = new Map();
32
+ for (const tool of tools) {
33
+ const prefix = getDomainPrefix(tool.name);
34
+ if (!skillMap.has(prefix))
35
+ skillMap.set(prefix, []);
36
+ skillMap.get(prefix).push(tool.name);
37
+ }
38
+ // Convert to A2A skills
39
+ const skills = [];
40
+ for (const [prefix, toolNames] of skillMap) {
41
+ const domain = DOMAIN_MAP[prefix] || { name: capitalize(prefix), description: `${capitalize(prefix)} tools`, tags: [prefix] };
42
+ skills.push({
43
+ id: `nowaikit-${prefix}`,
44
+ name: domain.name,
45
+ description: `${domain.description} (${toolNames.length} tools)`,
46
+ tags: domain.tags,
47
+ });
48
+ }
49
+ return {
50
+ name: 'NowAIKit',
51
+ description: 'The most comprehensive ServiceNow AI toolkit — 400+ tools covering ITSM, CMDB, HRSD, CSM, SecOps, GRC, DevOps, and more.',
52
+ url: baseUrl,
53
+ version: '4.0.0',
54
+ capabilities: {
55
+ streaming: true,
56
+ pushNotifications: false,
57
+ stateTransitionHistory: true,
58
+ },
59
+ authentication: {
60
+ schemes: isAuthRequired() ? ['bearer'] : [],
61
+ },
62
+ defaultInputModes: ['text'],
63
+ defaultOutputModes: ['text', 'data'],
64
+ skills,
65
+ };
66
+ }
67
+ function getDomainPrefix(toolName) {
68
+ // Match known prefixes
69
+ for (const prefix of Object.keys(DOMAIN_MAP)) {
70
+ if (toolName.startsWith(prefix + '_') || toolName.startsWith(prefix))
71
+ return prefix;
72
+ }
73
+ // Generic tools
74
+ if (['query_records', 'get_record', 'create_record', 'update_record', 'delete_record', 'get_table_schema', 'get_user', 'get_group'].includes(toolName))
75
+ return 'core';
76
+ // Fallback: use first word
77
+ return toolName.split('_')[0];
78
+ }
79
+ function capitalize(s) {
80
+ return s.charAt(0).toUpperCase() + s.slice(1);
81
+ }
82
+ //# sourceMappingURL=agent-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-card.js","sourceRoot":"","sources":["../../src/a2a/agent-card.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * A2A Protocol routes — mount on the HTTP server.
3
+ *
4
+ * Endpoints:
5
+ * GET /.well-known/agent.json — Agent card (no auth)
6
+ * POST /a2a/tasks/send — Send a task (synchronous)
7
+ * POST /a2a/tasks/sendSubscribe — Send a task (SSE streaming)
8
+ * GET /a2a/tasks/:taskId — Get task status
9
+ * POST /a2a/tasks/:taskId/cancel — Cancel a task
10
+ */
11
+ import type { NowAIKitHttpServer } from '../transport/http-server.js';
12
+ export declare function mountA2ARoutes(httpServer: NowAIKitHttpServer): void;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAKtE,wBAAgB,cAAc,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI,CAoFnE"}
@@ -0,0 +1,74 @@
1
+ import { buildAgentCard } from './agent-card.js';
2
+ import { taskManager } from './task-manager.js';
3
+ export function mountA2ARoutes(httpServer) {
4
+ // Agent card — no auth required for discovery
5
+ httpServer.get('/.well-known/agent.json', async (_req, res) => {
6
+ const card = buildAgentCard();
7
+ res.writeHead(200, { 'Content-Type': 'application/json' });
8
+ res.end(JSON.stringify(card, null, 2));
9
+ }, false);
10
+ // Send task (synchronous)
11
+ httpServer.post('/a2a/tasks/send', async (req, res) => {
12
+ const body = req.body;
13
+ if (!body?.message?.parts?.length) {
14
+ res.writeHead(400, { 'Content-Type': 'application/json' });
15
+ res.end(JSON.stringify({ error: 'Missing message with parts' }));
16
+ return;
17
+ }
18
+ const result = await taskManager.sendTask(body);
19
+ res.writeHead(200, { 'Content-Type': 'application/json' });
20
+ res.end(JSON.stringify(result));
21
+ });
22
+ // Send task with SSE streaming
23
+ httpServer.post('/a2a/tasks/sendSubscribe', async (req, res) => {
24
+ const body = req.body;
25
+ if (!body?.message?.parts?.length) {
26
+ res.writeHead(400, { 'Content-Type': 'application/json' });
27
+ res.end(JSON.stringify({ error: 'Missing message with parts' }));
28
+ return;
29
+ }
30
+ // Set up SSE
31
+ res.writeHead(200, {
32
+ 'Content-Type': 'text/event-stream',
33
+ 'Cache-Control': 'no-cache',
34
+ 'Connection': 'keep-alive',
35
+ });
36
+ // Send working status
37
+ const { randomUUID } = await import('crypto');
38
+ const taskId = body.id || randomUUID();
39
+ res.write(`event: task-status-update\ndata: ${JSON.stringify({ id: taskId, status: { state: 'working', timestamp: new Date().toISOString() } })}\n\n`);
40
+ // Execute
41
+ const result = await taskManager.sendTask({ ...body, id: taskId });
42
+ // Send result
43
+ if (result.artifacts?.length) {
44
+ res.write(`event: task-artifact-update\ndata: ${JSON.stringify({ id: taskId, artifact: result.artifacts[0] })}\n\n`);
45
+ }
46
+ res.write(`event: task-status-update\ndata: ${JSON.stringify({ id: taskId, status: result.status })}\n\n`);
47
+ res.end();
48
+ });
49
+ // Get task status
50
+ httpServer.get('/a2a/tasks/:taskId', async (req, res) => {
51
+ const taskId = req.params.taskId;
52
+ const task = taskManager.getTask(taskId);
53
+ if (!task) {
54
+ res.writeHead(404, { 'Content-Type': 'application/json' });
55
+ res.end(JSON.stringify({ error: 'Task not found' }));
56
+ return;
57
+ }
58
+ res.writeHead(200, { 'Content-Type': 'application/json' });
59
+ res.end(JSON.stringify(task));
60
+ });
61
+ // Cancel task
62
+ httpServer.post('/a2a/tasks/:taskId/cancel', async (req, res) => {
63
+ const taskId = req.params.taskId;
64
+ const success = taskManager.cancelTask(taskId);
65
+ if (!success) {
66
+ res.writeHead(404, { 'Content-Type': 'application/json' });
67
+ res.end(JSON.stringify({ error: 'Task not found or already completed' }));
68
+ return;
69
+ }
70
+ res.writeHead(200, { 'Content-Type': 'application/json' });
71
+ res.end(JSON.stringify({ id: taskId, status: { state: 'canceled' } }));
72
+ });
73
+ }
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/a2a/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Task, SendTaskRequest, SendTaskResponse } from './types.js';
2
+ declare class TaskManager {
3
+ private tasks;
4
+ /** Send a task synchronously — execute and return the result. */
5
+ sendTask(request: SendTaskRequest): Promise<SendTaskResponse>;
6
+ /** Get a task by ID. */
7
+ getTask(taskId: string): Task | undefined;
8
+ /** Cancel a task. */
9
+ cancelTask(taskId: string): boolean;
10
+ /**
11
+ * Parse an A2A message to determine which tool to call.
12
+ * Strategy: look for tool name in the text, or match keywords to tools.
13
+ */
14
+ private parseMessage;
15
+ private extractArgsFromText;
16
+ private getHelpText;
17
+ }
18
+ export declare const taskManager: TaskManager;
19
+ export {};
20
+ //# sourceMappingURL=task-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-manager.d.ts","sourceRoot":"","sources":["../../src/a2a/task-manager.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,gBAAgB,EAAyC,MAAM,YAAY,CAAC;AAKjH,cAAM,WAAW;IACf,OAAO,CAAC,KAAK,CAA2B;IAExC,iEAAiE;IAC3D,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqEnE,wBAAwB;IACxB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIzC,qBAAqB;IACrB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAUnC;;;OAGG;IACH,OAAO,CAAC,YAAY;IAiCpB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,WAAW;CASpB;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * A2A Task Manager — handles the lifecycle of A2A tasks.
3
+ * Maps incoming A2A messages to NowAIKit tool invocations.
4
+ */
5
+ import { randomUUID } from 'crypto';
6
+ import { getTools, executeTool } from '../tools/index.js';
7
+ import { instanceManager } from '../servicenow/instances.js';
8
+ import { logger } from '../utils/logging.js';
9
+ class TaskManager {
10
+ tasks = new Map();
11
+ /** Send a task synchronously — execute and return the result. */
12
+ async sendTask(request) {
13
+ const taskId = request.id || randomUUID();
14
+ const sessionId = request.sessionId || randomUUID();
15
+ const task = {
16
+ id: taskId,
17
+ sessionId,
18
+ status: { state: 'submitted', timestamp: new Date().toISOString() },
19
+ history: [request.message],
20
+ artifacts: [],
21
+ };
22
+ this.tasks.set(taskId, task);
23
+ // Update to working
24
+ task.status = { state: 'working', timestamp: new Date().toISOString() };
25
+ try {
26
+ // Parse the message to determine tool and arguments
27
+ const { toolName, toolArgs } = this.parseMessage(request.message);
28
+ if (!toolName) {
29
+ // No specific tool found — return a helpful response
30
+ task.status = {
31
+ state: 'completed',
32
+ message: { role: 'agent', parts: [{ type: 'text', text: this.getHelpText() }] },
33
+ timestamp: new Date().toISOString(),
34
+ };
35
+ this.tasks.set(taskId, task);
36
+ return { id: taskId, sessionId, status: task.status };
37
+ }
38
+ // Execute the tool
39
+ const client = instanceManager.getClient();
40
+ const result = await executeTool(client, toolName, toolArgs);
41
+ const artifact = {
42
+ name: toolName,
43
+ description: `Result from ${toolName}`,
44
+ parts: [{ type: 'data', data: result, mimeType: 'application/json' }],
45
+ index: 0,
46
+ };
47
+ task.artifacts = [artifact];
48
+ task.status = {
49
+ state: 'completed',
50
+ message: {
51
+ role: 'agent',
52
+ parts: [
53
+ { type: 'text', text: typeof result === 'string' ? result : JSON.stringify(result, null, 2) },
54
+ ],
55
+ },
56
+ timestamp: new Date().toISOString(),
57
+ };
58
+ }
59
+ catch (error) {
60
+ logger.error(`A2A task failed: ${taskId}`, error);
61
+ task.status = {
62
+ state: 'failed',
63
+ message: {
64
+ role: 'agent',
65
+ parts: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}` }],
66
+ },
67
+ timestamp: new Date().toISOString(),
68
+ };
69
+ }
70
+ this.tasks.set(taskId, task);
71
+ return { id: taskId, sessionId, status: task.status, artifacts: task.artifacts };
72
+ }
73
+ /** Get a task by ID. */
74
+ getTask(taskId) {
75
+ return this.tasks.get(taskId);
76
+ }
77
+ /** Cancel a task. */
78
+ cancelTask(taskId) {
79
+ const task = this.tasks.get(taskId);
80
+ if (!task)
81
+ return false;
82
+ if (task.status.state === 'completed' || task.status.state === 'failed')
83
+ return false;
84
+ task.status = { state: 'canceled', timestamp: new Date().toISOString() };
85
+ this.tasks.set(taskId, task);
86
+ return true;
87
+ }
88
+ /**
89
+ * Parse an A2A message to determine which tool to call.
90
+ * Strategy: look for tool name in the text, or match keywords to tools.
91
+ */
92
+ parseMessage(message) {
93
+ const tools = getTools();
94
+ const textParts = message.parts.filter(p => p.type === 'text');
95
+ const dataParts = message.parts.filter(p => p.type === 'data');
96
+ const text = textParts.map(p => p.text).join(' ').toLowerCase();
97
+ // Check if data part contains explicit tool name and args
98
+ for (const part of dataParts) {
99
+ if (part.data && typeof part.data === 'object') {
100
+ const data = part.data;
101
+ if (data.tool_name && tools.find(t => t.name === data.tool_name)) {
102
+ return { toolName: data.tool_name, toolArgs: data.arguments || {} };
103
+ }
104
+ }
105
+ }
106
+ // Try exact tool name match in text
107
+ for (const tool of tools) {
108
+ if (text.includes(tool.name)) {
109
+ return { toolName: tool.name, toolArgs: this.extractArgsFromText(text, tool.name) };
110
+ }
111
+ }
112
+ // Keyword matching for common operations
113
+ if (text.includes('incident') && (text.includes('create') || text.includes('new')))
114
+ return { toolName: 'create_incident', toolArgs: {} };
115
+ if (text.includes('incident') && text.includes('list'))
116
+ return { toolName: 'query_records', toolArgs: { table: 'incident', query: 'active=true', limit: 20 } };
117
+ if (text.includes('change') && text.includes('list'))
118
+ return { toolName: 'list_change_requests', toolArgs: {} };
119
+ if (text.includes('knowledge') && text.includes('search'))
120
+ return { toolName: 'search_knowledge', toolArgs: { query: text } };
121
+ if (text.includes('cmdb') && text.includes('health'))
122
+ return { toolName: 'cmdb_health_dashboard', toolArgs: {} };
123
+ return { toolName: null, toolArgs: {} };
124
+ }
125
+ extractArgsFromText(text, _toolName) {
126
+ // Simple extraction — look for key=value patterns
127
+ const args = {};
128
+ const kvPattern = /(\w+)\s*[=:]\s*["']?([^"',\s]+)["']?/g;
129
+ let match;
130
+ while ((match = kvPattern.exec(text)) !== null) {
131
+ if (match[1] !== _toolName.split('_')[0]) {
132
+ args[match[1]] = match[2];
133
+ }
134
+ }
135
+ return args;
136
+ }
137
+ getHelpText() {
138
+ const tools = getTools();
139
+ return `I'm NowAIKit, a ServiceNow AI agent with ${tools.length}+ tools. ` +
140
+ `You can send me tasks like:\n` +
141
+ `- "List active incidents"\n` +
142
+ `- "Search knowledge for VPN setup"\n` +
143
+ `- "CMDB health dashboard"\n` +
144
+ `- Or specify a tool directly: { "tool_name": "query_records", "arguments": { "table": "incident" } }`;
145
+ }
146
+ }
147
+ export const taskManager = new TaskManager();
148
+ //# sourceMappingURL=task-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-manager.js","sourceRoot":"","sources":["../../src/a2a/task-manager.ts"],"names":[],"mappings":"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"}