sentinelayer-cli 0.8.12 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/package.json +7 -2
  2. package/src/agents/backend/tools/timeout-audit.js +33 -17
  3. package/src/agents/devtestbot/config/definition.js +100 -0
  4. package/src/agents/devtestbot/config/system-prompt.js +92 -0
  5. package/src/agents/devtestbot/index.js +9 -0
  6. package/src/agents/devtestbot/runner.js +775 -0
  7. package/src/agents/devtestbot/tool.js +707 -0
  8. package/src/commands/legacy-args.js +4 -0
  9. package/src/commands/omargate.js +4 -0
  10. package/src/commands/session.js +960 -159
  11. package/src/commands/swarm.js +11 -2
  12. package/src/guide/generator.js +14 -0
  13. package/src/legacy-cli.js +35 -18
  14. package/src/prompt/generator.js +4 -16
  15. package/src/review/ai-review.js +95 -6
  16. package/src/review/dd-report-email-client.js +148 -0
  17. package/src/review/investor-dd-devtestbot.js +599 -0
  18. package/src/review/investor-dd-orchestrator.js +135 -3
  19. package/src/review/omargate-orchestrator.js +20 -2
  20. package/src/review/persona-prompts.js +34 -1
  21. package/src/review/report.js +61 -2
  22. package/src/scan/generator.js +1 -1
  23. package/src/session/coordination-guidance.js +49 -0
  24. package/src/session/daemon.js +3 -2
  25. package/src/session/event-identity.js +139 -0
  26. package/src/session/listener.js +330 -0
  27. package/src/session/live-source.js +11 -2
  28. package/src/session/mentions.js +130 -0
  29. package/src/session/remote-hydrate.js +223 -8
  30. package/src/session/setup-guides.js +3 -15
  31. package/src/session/store.js +117 -5
  32. package/src/session/stream.js +17 -7
  33. package/src/session/sync.js +375 -26
  34. package/src/session/title-sync.js +107 -0
  35. package/src/spec/generator.js +8 -10
  36. package/src/swarm/registry.js +20 -0
  37. package/src/swarm/runtime.js +139 -1
@@ -10,6 +10,13 @@ function normalizeString(value) {
10
10
  return String(value || "").trim();
11
11
  }
12
12
 
13
+ function sanitizeRuntimeError(error) {
14
+ return String(error?.message || error || "Runtime failed.")
15
+ .replace(/\b(?:authorization|cookie|token|secret|password|otp|reset)\s*[:=]\s*["']?[^"'\s&]+/gi, (match) =>
16
+ match.replace(/[:=]\s*["']?.*$/u, "=[REDACTED]")
17
+ );
18
+ }
19
+
13
20
  function formatTimestampToken() {
14
21
  const now = new Date();
15
22
  const pad = (value) => String(value).padStart(2, "0");
@@ -298,6 +305,9 @@ export async function runSwarmRuntime({
298
305
  execute = false,
299
306
  maxSteps = 20,
300
307
  startUrl = "about:blank",
308
+ identityId = "",
309
+ devTestBotScope = "",
310
+ devTestBotRunSession = null,
301
311
  playbookActions = [],
302
312
  outputDir = "",
303
313
  env,
@@ -321,6 +331,9 @@ export async function runSwarmRuntime({
321
331
  const runtimeRunDirectory = path.join(resolvedOutputRoot, "swarms", runId);
322
332
  const runStartedAt = Date.now();
323
333
  const events = [];
334
+ const findings = [];
335
+ const artifactBundles = [];
336
+ const devTestBotRuns = [];
324
337
  let step = 0;
325
338
 
326
339
  const usage = {
@@ -409,7 +422,128 @@ export async function runSwarmRuntime({
409
422
  })
410
423
  );
411
424
 
412
- if (normalizedEngine === "mock" || !execute) {
425
+ if (assignment.agentId === "devtestbot") {
426
+ const scope = normalizeString(devTestBotScope || plan.scenario || "smoke") || "smoke";
427
+ const toolInput = {
428
+ scope,
429
+ identityId: normalizeString(identityId),
430
+ baseUrl: normalizeString(startUrl),
431
+ recordVideo: Boolean(execute),
432
+ execute: Boolean(execute),
433
+ targetPath: normalizedTargetPath,
434
+ outputRoot: resolvedOutputRoot,
435
+ outputDir: path.join(runtimeRunDirectory, "devtestbot", assignment.assignmentId),
436
+ runId: `${runId}-${assignment.assignmentId}`,
437
+ };
438
+
439
+ usage.toolCalls += 1;
440
+ usage.outputTokens += estimateTokens(`devtestbot.run_session:${scope}:${Boolean(execute)}`);
441
+ step += 1;
442
+ events.push(
443
+ createEvent({
444
+ runId,
445
+ step,
446
+ eventType: "tool_call",
447
+ agentId: assignment.agentId,
448
+ message: "devtestbot.run_session started",
449
+ metadata: {
450
+ tool: "devtestbot.run_session",
451
+ scope,
452
+ identityId: toolInput.identityId || null,
453
+ baseUrl: toolInput.baseUrl,
454
+ execute: toolInput.execute,
455
+ recordVideo: toolInput.recordVideo,
456
+ },
457
+ usage,
458
+ })
459
+ );
460
+
461
+ try {
462
+ const runner = devTestBotRunSession || (await import("../agents/devtestbot/tool.js")).runDevTestBotSession;
463
+ const result = await runner(toolInput, {
464
+ targetPath: normalizedTargetPath,
465
+ outputRoot: resolvedOutputRoot,
466
+ runId: toolInput.runId,
467
+ execute: Boolean(execute),
468
+ env,
469
+ });
470
+ const resultFindings = Array.isArray(result.findings) ? result.findings : [];
471
+ findings.push(...resultFindings);
472
+ if (result.artifactBundle) {
473
+ artifactBundles.push(result.artifactBundle);
474
+ }
475
+ devTestBotRuns.push({
476
+ assignmentId: assignment.assignmentId,
477
+ runId: result.runId || toolInput.runId,
478
+ completed: Boolean(result.completed),
479
+ dryRun: Boolean(result.dryRun),
480
+ findingCount: resultFindings.length,
481
+ artifactBundle: result.artifactBundle || null,
482
+ });
483
+ usage.outputTokens += estimateTokens(
484
+ JSON.stringify({
485
+ findingCount: resultFindings.length,
486
+ artifactBundle: result.artifactBundle ? "present" : "missing",
487
+ })
488
+ );
489
+ step += 1;
490
+ events.push(
491
+ createEvent({
492
+ runId,
493
+ step,
494
+ eventType: "tool_result",
495
+ agentId: assignment.agentId,
496
+ message: "devtestbot.run_session completed",
497
+ metadata: {
498
+ tool: "devtestbot.run_session",
499
+ success: true,
500
+ dryRun: Boolean(result.dryRun),
501
+ findingCount: resultFindings.length,
502
+ artifactBundle: result.artifactBundle || null,
503
+ },
504
+ usage,
505
+ })
506
+ );
507
+ for (const finding of resultFindings) {
508
+ step += 1;
509
+ events.push(
510
+ createEvent({
511
+ runId,
512
+ step,
513
+ eventType: "finding",
514
+ agentId: assignment.agentId,
515
+ message: normalizeString(finding.title || "devTestBot finding"),
516
+ metadata: {
517
+ finding,
518
+ },
519
+ usage,
520
+ })
521
+ );
522
+ }
523
+ } catch (error) {
524
+ stop = {
525
+ stopClass: error?.code || "DEVTESTBOT_RUN_FAILED",
526
+ reason: sanitizeRuntimeError(error),
527
+ blocking: true,
528
+ };
529
+ step += 1;
530
+ events.push(
531
+ createEvent({
532
+ runId,
533
+ step,
534
+ eventType: "agent_error",
535
+ agentId: assignment.agentId,
536
+ message: stop.reason,
537
+ metadata: {
538
+ tool: "devtestbot.run_session",
539
+ stopClass: stop.stopClass,
540
+ },
541
+ usage,
542
+ })
543
+ );
544
+ break;
545
+ }
546
+ } else if (normalizedEngine === "mock" || !execute) {
413
547
  usage.toolCalls += 1;
414
548
  usage.outputTokens += estimateTokens(`mock:${assignment.agentId}`);
415
549
  step += 1;
@@ -558,6 +692,10 @@ export async function runSwarmRuntime({
558
692
  usage,
559
693
  eventCount: events.length,
560
694
  selectedAgents: Array.isArray(plan.selectedAgents) ? [...plan.selectedAgents] : [],
695
+ findingCount: findings.length,
696
+ findings,
697
+ artifactBundles,
698
+ devTestBotRuns,
561
699
  };
562
700
 
563
701
  return writeRuntimeArtifacts({