bosun 0.36.0 → 0.36.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.
- package/.env.example +98 -16
- package/README.md +27 -0
- package/agent-event-bus.mjs +5 -5
- package/agent-pool.mjs +129 -12
- package/agent-prompts.mjs +7 -1
- package/agent-sdk.mjs +13 -2
- package/agent-supervisor.mjs +2 -2
- package/agent-work-report.mjs +1 -1
- package/anomaly-detector.mjs +6 -6
- package/autofix.mjs +15 -15
- package/bosun-skills.mjs +4 -4
- package/bosun.schema.json +160 -4
- package/claude-shell.mjs +11 -11
- package/cli.mjs +21 -21
- package/codex-config.mjs +19 -19
- package/codex-shell.mjs +180 -29
- package/config-doctor.mjs +27 -2
- package/config.mjs +60 -7
- package/copilot-shell.mjs +4 -4
- package/error-detector.mjs +1 -1
- package/fleet-coordinator.mjs +2 -2
- package/gemini-shell.mjs +692 -0
- package/github-oauth-portal.mjs +1 -1
- package/github-reconciler.mjs +2 -2
- package/kanban-adapter.mjs +741 -168
- package/merge-strategy.mjs +25 -25
- package/monitor.mjs +123 -105
- package/opencode-shell.mjs +22 -22
- package/package.json +7 -1
- package/postinstall.mjs +22 -22
- package/pr-cleanup-daemon.mjs +6 -6
- package/prepublish-check.mjs +4 -4
- package/presence.mjs +2 -2
- package/primary-agent.mjs +85 -7
- package/publish.mjs +1 -1
- package/review-agent.mjs +1 -1
- package/session-tracker.mjs +11 -0
- package/setup-web-server.mjs +429 -21
- package/setup.mjs +367 -12
- package/shared-knowledge.mjs +1 -1
- package/startup-service.mjs +9 -9
- package/stream-resilience.mjs +58 -4
- package/sync-engine.mjs +2 -2
- package/task-assessment.mjs +9 -9
- package/task-cli.mjs +1 -1
- package/task-complexity.mjs +71 -2
- package/task-context.mjs +1 -2
- package/task-executor.mjs +104 -41
- package/telegram-bot.mjs +825 -494
- package/telegram-sentinel.mjs +28 -28
- package/ui/app.js +256 -23
- package/ui/app.monolith.js +1 -1
- package/ui/components/agent-selector.js +4 -3
- package/ui/components/chat-view.js +101 -28
- package/ui/components/diff-viewer.js +3 -3
- package/ui/components/kanban-board.js +3 -3
- package/ui/components/session-list.js +255 -35
- package/ui/components/workspace-switcher.js +3 -3
- package/ui/demo.html +209 -194
- package/ui/index.html +3 -3
- package/ui/modules/icon-utils.js +206 -142
- package/ui/modules/icons.js +2 -27
- package/ui/modules/settings-schema.js +29 -5
- package/ui/modules/streaming.js +30 -2
- package/ui/modules/vision-stream.js +275 -0
- package/ui/modules/voice-client.js +102 -9
- package/ui/modules/voice-fallback.js +62 -6
- package/ui/modules/voice-overlay.js +594 -59
- package/ui/modules/voice.js +31 -38
- package/ui/setup.html +284 -34
- package/ui/styles/components.css +47 -0
- package/ui/styles/sessions.css +75 -0
- package/ui/tabs/agents.js +73 -43
- package/ui/tabs/chat.js +37 -40
- package/ui/tabs/control.js +2 -2
- package/ui/tabs/dashboard.js +1 -1
- package/ui/tabs/infra.js +10 -10
- package/ui/tabs/library.js +8 -8
- package/ui/tabs/logs.js +10 -10
- package/ui/tabs/settings.js +20 -20
- package/ui/tabs/tasks.js +76 -47
- package/ui-server.mjs +1761 -124
- package/update-check.mjs +13 -13
- package/ve-kanban.mjs +1 -1
- package/whatsapp-channel.mjs +5 -5
- package/workflow-engine.mjs +20 -1
- package/workflow-nodes.mjs +904 -4
- package/workflow-templates/agents.mjs +321 -7
- package/workflow-templates/ci-cd.mjs +6 -6
- package/workflow-templates/github.mjs +156 -84
- package/workflow-templates/planning.mjs +8 -8
- package/workflow-templates/reliability.mjs +8 -8
- package/workflow-templates/security.mjs +3 -3
- package/workflow-templates.mjs +15 -9
- package/workspace-manager.mjs +85 -1
- package/workspace-monitor.mjs +2 -2
- package/workspace-registry.mjs +2 -2
- package/worktree-manager.mjs +1 -1
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* - Custom Agent Profile
|
|
8
8
|
* - Agent Session Monitor (recommended)
|
|
9
9
|
* - Backend Agent (recommended)
|
|
10
|
+
* - Voice + Video Rollout (Parallel Lanes)
|
|
11
|
+
* - Meeting Orchestrator + Subworkflow Chain
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
import { node, edge, resetLayout } from "./_helpers.mjs";
|
|
@@ -145,11 +147,11 @@ After completing your implementation:
|
|
|
145
147
|
}, { x: 200, y: 1080 }),
|
|
146
148
|
|
|
147
149
|
node("notify-success", "notify.telegram", "Notify Success", {
|
|
148
|
-
message: "
|
|
150
|
+
message: ":check: Frontend task **{{taskTitle}}** passed visual verification and is complete.",
|
|
149
151
|
}, { x: 200, y: 1200 }),
|
|
150
152
|
|
|
151
153
|
node("notify-failure", "notify.telegram", "Notify Review Failed", {
|
|
152
|
-
message: "
|
|
154
|
+
message: ":close: Frontend task **{{taskTitle}}** failed visual verification. Review evidence in .bosun/evidence/",
|
|
153
155
|
}, { x: 600, y: 1080 }),
|
|
154
156
|
|
|
155
157
|
node("log-failure", "notify.log", "Log Failure", {
|
|
@@ -240,7 +242,7 @@ Provide a structured review with specific file:line references.`,
|
|
|
240
242
|
}, { x: 400, y: 500 }),
|
|
241
243
|
|
|
242
244
|
node("notify", "notify.telegram", "Post Review", {
|
|
243
|
-
message: "
|
|
245
|
+
message: ":edit: PR review complete for {{branch}}",
|
|
244
246
|
}, { x: 400, y: 640 }),
|
|
245
247
|
],
|
|
246
248
|
edges: [
|
|
@@ -386,7 +388,7 @@ export const AGENT_SESSION_MONITOR_TEMPLATE = {
|
|
|
386
388
|
}, { x: 100, y: 800 }),
|
|
387
389
|
|
|
388
390
|
node("alert-hung", "notify.telegram", "Alert Hung Sessions", {
|
|
389
|
-
message: "
|
|
391
|
+
message: ":dot: Agent session appears hung — auto-continue attempted. Check status.",
|
|
390
392
|
}, { x: 100, y: 950 }),
|
|
391
393
|
|
|
392
394
|
node("all-healthy", "notify.log", "Sessions Healthy", {
|
|
@@ -530,7 +532,7 @@ Commit with message "feat: implement [feature]"`,
|
|
|
530
532
|
}, { x: 180, y: 1320 }),
|
|
531
533
|
|
|
532
534
|
node("notify-pr-failed", "notify.telegram", "Escalate Lifecycle Handoff Failure", {
|
|
533
|
-
message: "
|
|
535
|
+
message: ":alert: Backend agent passed validation for {{taskTitle}} but failed to record Bosun PR lifecycle handoff after retries. Manual follow-up required.",
|
|
534
536
|
}, { x: 420, y: 1320 }),
|
|
535
537
|
|
|
536
538
|
node("set-validation-summary", "action.set_variable", "Summarize Validation Output", {
|
|
@@ -599,11 +601,11 @@ Commit with message "fix: address backend workflow validation failures"`,
|
|
|
599
601
|
}, { x: 360, y: 1980 }),
|
|
600
602
|
|
|
601
603
|
node("notify-fail", "notify.telegram", "Checks Failed", {
|
|
602
|
-
message: "
|
|
604
|
+
message: ":alert: Backend agent: validation failed for task {{taskTitle}} even after remediation pass. Manual review needed.",
|
|
603
605
|
}, { x: 820, y: 1820 }),
|
|
604
606
|
|
|
605
607
|
node("notify-pr-failed-retry", "notify.telegram", "Escalate Lifecycle Failure (Retry Path)", {
|
|
606
|
-
message: "
|
|
608
|
+
message: ":alert: Backend agent remediation passed for {{taskTitle}} but Bosun PR lifecycle handoff failed after retries. Manual follow-up required.",
|
|
607
609
|
}, { x: 620, y: 1980 }),
|
|
608
610
|
],
|
|
609
611
|
edges: [
|
|
@@ -647,3 +649,315 @@ Commit with message "fix: address backend workflow validation failures"`,
|
|
|
647
649
|
},
|
|
648
650
|
},
|
|
649
651
|
};
|
|
652
|
+
|
|
653
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
654
|
+
// Voice + Video Rollout (Parallel Lanes)
|
|
655
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
656
|
+
|
|
657
|
+
resetLayout();
|
|
658
|
+
|
|
659
|
+
export const VOICE_VIDEO_PARALLEL_ROLLOUT_TEMPLATE = {
|
|
660
|
+
id: "template-voice-video-parallel-rollout",
|
|
661
|
+
name: "Voice + Video Rollout (Parallel Lanes)",
|
|
662
|
+
description:
|
|
663
|
+
"Launches three agent lanes in parallel (capture pipeline, provider adapters, " +
|
|
664
|
+
"and QA/rollout hardening) to accelerate Voice + Video delivery while keeping " +
|
|
665
|
+
"workstreams isolated by worktree.",
|
|
666
|
+
category: "agents",
|
|
667
|
+
enabled: false,
|
|
668
|
+
trigger: "trigger.manual",
|
|
669
|
+
variables: {
|
|
670
|
+
lane1Worktree: "{{worktreePath}}",
|
|
671
|
+
lane2Worktree: "{{worktreePath}}",
|
|
672
|
+
lane3Worktree: "{{worktreePath}}",
|
|
673
|
+
integrationBranch: "feat/voice-video-integration",
|
|
674
|
+
definitionOfDone:
|
|
675
|
+
"Voice + vision works end-to-end, provider fallback is explicit, and tests cover config + transport + failure paths.",
|
|
676
|
+
},
|
|
677
|
+
nodes: [
|
|
678
|
+
node("trigger", "trigger.manual", "Launch Parallel Rollout", {}, { x: 500, y: 50 }),
|
|
679
|
+
|
|
680
|
+
node("check-worktrees", "condition.expression", "Worktrees Distinct?", {
|
|
681
|
+
expression:
|
|
682
|
+
"(() => { " +
|
|
683
|
+
"const a = String($data?.lane1Worktree || '').trim(); " +
|
|
684
|
+
"const b = String($data?.lane2Worktree || '').trim(); " +
|
|
685
|
+
"const c = String($data?.lane3Worktree || '').trim(); " +
|
|
686
|
+
"if (!a || !b || !c) return false; " +
|
|
687
|
+
"return new Set([a, b, c]).size === 3; " +
|
|
688
|
+
"})()",
|
|
689
|
+
}, { x: 500, y: 170 }),
|
|
690
|
+
|
|
691
|
+
node("notify-worktree-error", "notify.telegram", "Invalid Worktree Setup", {
|
|
692
|
+
message:
|
|
693
|
+
"Parallel rollout aborted. Configure three distinct worktrees in " +
|
|
694
|
+
"`lane1Worktree`, `lane2Worktree`, and `lane3Worktree` before launching.",
|
|
695
|
+
}, { x: 860, y: 170 }),
|
|
696
|
+
|
|
697
|
+
node("kickoff-log", "notify.log", "Kickoff Parallel Lanes", {
|
|
698
|
+
message:
|
|
699
|
+
"Starting parallel rollout on branch {{integrationBranch}} with 3 lanes.",
|
|
700
|
+
level: "info",
|
|
701
|
+
}, { x: 500, y: 290 }),
|
|
702
|
+
|
|
703
|
+
node("lane-capture-core", "action.run_agent", "Lane 1: Capture Core", {
|
|
704
|
+
prompt:
|
|
705
|
+
"# Lane 1 - Capture Core\n\n" +
|
|
706
|
+
"Work only in this lane's worktree. Focus on:\n" +
|
|
707
|
+
"1. Voice video config/schema/env/settings keys\n" +
|
|
708
|
+
"2. Browser capture loop (screen/camera), adaptive FPS, compression, change detection\n" +
|
|
709
|
+
"3. Overlay controls + capture state indicators\n\n" +
|
|
710
|
+
"Guardrails:\n" +
|
|
711
|
+
"- Do not touch provider dispatch code owned by Lane 2\n" +
|
|
712
|
+
"- Keep changes bounded to UI/config paths\n" +
|
|
713
|
+
"- Add/extend tests for capture throttling and config behavior\n\n" +
|
|
714
|
+
"Target branch: {{integrationBranch}}\n" +
|
|
715
|
+
"Definition of done: {{definitionOfDone}}",
|
|
716
|
+
sdk: "auto",
|
|
717
|
+
cwd: "{{lane1Worktree}}",
|
|
718
|
+
timeoutMs: 5400000,
|
|
719
|
+
includeTaskContext: false,
|
|
720
|
+
failOnError: true,
|
|
721
|
+
}, { x: 120, y: 450 }),
|
|
722
|
+
|
|
723
|
+
node("lane-provider-bridge", "action.run_agent", "Lane 2: Provider Bridge", {
|
|
724
|
+
prompt:
|
|
725
|
+
"# Lane 2 - Provider Bridge\n\n" +
|
|
726
|
+
"Work only in this lane's worktree. Focus on:\n" +
|
|
727
|
+
"1. Server-side vision frame ingress route and validation\n" +
|
|
728
|
+
"2. Provider dispatch in voice relay (OpenAI image path, Gemini live path, Claude vision path)\n" +
|
|
729
|
+
"3. Rate-limits, payload caps, and fallback semantics\n\n" +
|
|
730
|
+
"Guardrails:\n" +
|
|
731
|
+
"- Do not edit overlay/capture UI owned by Lane 1\n" +
|
|
732
|
+
"- Keep provider logic behind explicit feature flags\n" +
|
|
733
|
+
"- Add/extend tests for endpoint validation and provider routing\n\n" +
|
|
734
|
+
"Target branch: {{integrationBranch}}\n" +
|
|
735
|
+
"Definition of done: {{definitionOfDone}}",
|
|
736
|
+
sdk: "auto",
|
|
737
|
+
cwd: "{{lane2Worktree}}",
|
|
738
|
+
timeoutMs: 5400000,
|
|
739
|
+
includeTaskContext: false,
|
|
740
|
+
failOnError: true,
|
|
741
|
+
}, { x: 500, y: 450 }),
|
|
742
|
+
|
|
743
|
+
node("lane-hardening", "action.run_agent", "Lane 3: QA + Rollout", {
|
|
744
|
+
prompt:
|
|
745
|
+
"# Lane 3 - QA + Rollout Hardening\n\n" +
|
|
746
|
+
"Work only in this lane's worktree. Focus on:\n" +
|
|
747
|
+
"1. Integration tests, resilience tests, and docs updates\n" +
|
|
748
|
+
"2. Migration/rollout notes and operator controls\n" +
|
|
749
|
+
"3. Conflict-free merge guidance across Lane 1 and Lane 2 outputs\n\n" +
|
|
750
|
+
"Guardrails:\n" +
|
|
751
|
+
"- Avoid touching core capture loop and provider dispatch internals unless a test proves breakage\n" +
|
|
752
|
+
"- Keep this lane focused on verification, docs, and release safety\n" +
|
|
753
|
+
"- Produce a concise verification summary\n\n" +
|
|
754
|
+
"Target branch: {{integrationBranch}}\n" +
|
|
755
|
+
"Definition of done: {{definitionOfDone}}",
|
|
756
|
+
sdk: "auto",
|
|
757
|
+
cwd: "{{lane3Worktree}}",
|
|
758
|
+
timeoutMs: 3600000,
|
|
759
|
+
includeTaskContext: false,
|
|
760
|
+
failOnError: true,
|
|
761
|
+
}, { x: 880, y: 450 }),
|
|
762
|
+
|
|
763
|
+
node("aggregate", "transform.aggregate", "Aggregate Lane Results", {
|
|
764
|
+
sources: ["lane-capture-core", "lane-provider-bridge", "lane-hardening"],
|
|
765
|
+
}, { x: 500, y: 640 }),
|
|
766
|
+
|
|
767
|
+
node("all-passed", "condition.expression", "All Lanes Passed?", {
|
|
768
|
+
expression:
|
|
769
|
+
"$ctx.getNodeOutput('lane-capture-core')?.success === true && " +
|
|
770
|
+
"$ctx.getNodeOutput('lane-provider-bridge')?.success === true && " +
|
|
771
|
+
"$ctx.getNodeOutput('lane-hardening')?.success === true",
|
|
772
|
+
}, { x: 500, y: 770 }),
|
|
773
|
+
|
|
774
|
+
node("notify-success", "notify.telegram", "Notify Success", {
|
|
775
|
+
message:
|
|
776
|
+
"Parallel Voice + Video rollout lanes completed successfully on {{integrationBranch}}. " +
|
|
777
|
+
"Proceed to integration and final verification.",
|
|
778
|
+
}, { x: 300, y: 910 }),
|
|
779
|
+
|
|
780
|
+
node("notify-failure", "notify.telegram", "Notify Failure", {
|
|
781
|
+
message:
|
|
782
|
+
"Parallel Voice + Video rollout has lane failures on {{integrationBranch}}. " +
|
|
783
|
+
"Inspect lane outputs before integration.",
|
|
784
|
+
}, { x: 700, y: 910 }),
|
|
785
|
+
],
|
|
786
|
+
edges: [
|
|
787
|
+
edge("trigger", "check-worktrees"),
|
|
788
|
+
edge("check-worktrees", "kickoff-log", { condition: "$output?.result === true" }),
|
|
789
|
+
edge("check-worktrees", "notify-worktree-error", { condition: "$output?.result !== true" }),
|
|
790
|
+
edge("kickoff-log", "lane-capture-core"),
|
|
791
|
+
edge("kickoff-log", "lane-provider-bridge"),
|
|
792
|
+
edge("kickoff-log", "lane-hardening"),
|
|
793
|
+
edge("lane-capture-core", "aggregate"),
|
|
794
|
+
edge("lane-provider-bridge", "aggregate"),
|
|
795
|
+
edge("lane-hardening", "aggregate"),
|
|
796
|
+
edge("aggregate", "all-passed"),
|
|
797
|
+
edge("all-passed", "notify-success", { condition: "$output?.result === true" }),
|
|
798
|
+
edge("all-passed", "notify-failure", { condition: "$output?.result !== true" }),
|
|
799
|
+
],
|
|
800
|
+
metadata: {
|
|
801
|
+
author: "bosun",
|
|
802
|
+
version: 1,
|
|
803
|
+
createdAt: "2026-02-28T00:00:00Z",
|
|
804
|
+
templateVersion: "1.0.0",
|
|
805
|
+
tags: ["voice", "video", "parallel", "subagents", "rollout"],
|
|
806
|
+
},
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
810
|
+
// Meeting Orchestrator + Subworkflow Chain
|
|
811
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
812
|
+
|
|
813
|
+
resetLayout();
|
|
814
|
+
|
|
815
|
+
export const MEETING_SUBWORKFLOW_CHAIN_TEMPLATE = {
|
|
816
|
+
id: "template-meeting-subworkflow-chain",
|
|
817
|
+
name: "Meeting Orchestrator + Subworkflow Chain",
|
|
818
|
+
description:
|
|
819
|
+
"Runs a meeting session start/send/vision/transcript/finalize flow, applies " +
|
|
820
|
+
"a wake-phrase trigger + transcript quality guard, then invokes a child " +
|
|
821
|
+
"workflow via action.execute_workflow for post-meeting automation.",
|
|
822
|
+
category: "agents",
|
|
823
|
+
enabled: false,
|
|
824
|
+
trigger: "trigger.manual",
|
|
825
|
+
variables: {
|
|
826
|
+
sessionTitle: "Sprint Planning Sync",
|
|
827
|
+
meetingExecutor: "codex",
|
|
828
|
+
wakePhrase: "bosun wake",
|
|
829
|
+
openingMessage:
|
|
830
|
+
"Kick off planning review. Capture decisions, blockers, and next actions.",
|
|
831
|
+
frameDataUrl: "",
|
|
832
|
+
visionSource: "screen",
|
|
833
|
+
visionPrompt:
|
|
834
|
+
"Summarize visible meeting context, shared docs, and any blockers shown.",
|
|
835
|
+
visionModel: "",
|
|
836
|
+
visionMinIntervalMs: 1500,
|
|
837
|
+
forceVisionAnalyze: false,
|
|
838
|
+
minTranscriptChars: 140,
|
|
839
|
+
childWorkflowId: "template-task-planner",
|
|
840
|
+
finalizeDisposition: "completed",
|
|
841
|
+
notifyPrefix: ":memo:",
|
|
842
|
+
},
|
|
843
|
+
nodes: [
|
|
844
|
+
node("trigger", "trigger.manual", "Start Meeting Orchestration", {}, { x: 450, y: 50 }),
|
|
845
|
+
|
|
846
|
+
node("meeting-start", "meeting.start", "Meeting Start", {
|
|
847
|
+
title: "{{sessionTitle}}",
|
|
848
|
+
executor: "{{meetingExecutor}}",
|
|
849
|
+
wakePhrase: "{{wakePhrase}}",
|
|
850
|
+
includeTaskContext: true,
|
|
851
|
+
}, { x: 450, y: 190 }),
|
|
852
|
+
|
|
853
|
+
node("meeting-send", "meeting.send", "Send Opening Prompt", {
|
|
854
|
+
message: "{{openingMessage}}",
|
|
855
|
+
role: "system",
|
|
856
|
+
}, { x: 450, y: 320 }),
|
|
857
|
+
|
|
858
|
+
node("meeting-vision", "meeting.vision", "Analyze Meeting Frame", {
|
|
859
|
+
frameDataUrl: "{{frameDataUrl}}",
|
|
860
|
+
source: "{{visionSource}}",
|
|
861
|
+
prompt: "{{visionPrompt}}",
|
|
862
|
+
visionModel: "{{visionModel}}",
|
|
863
|
+
minIntervalMs: "{{visionMinIntervalMs}}",
|
|
864
|
+
forceAnalyze: "{{forceVisionAnalyze}}",
|
|
865
|
+
failOnError: false,
|
|
866
|
+
}, { x: 450, y: 450 }),
|
|
867
|
+
|
|
868
|
+
node("meeting-transcript", "meeting.transcript", "Capture Transcript", {
|
|
869
|
+
includeMessages: true,
|
|
870
|
+
}, { x: 450, y: 580 }),
|
|
871
|
+
|
|
872
|
+
node("wake-phrase-trigger", "trigger.meeting.wake_phrase", "Wake Phrase Trigger", {
|
|
873
|
+
wakePhrase: "{{wakePhrase}}",
|
|
874
|
+
text: "{{meeting-transcript.transcript}}",
|
|
875
|
+
mode: "contains",
|
|
876
|
+
}, { x: 450, y: 710 }),
|
|
877
|
+
|
|
878
|
+
node("guard-transcript", "condition.expression", "Wake Phrase + Transcript Guard", {
|
|
879
|
+
expression:
|
|
880
|
+
"(() => { const transcript = String($ctx.getNodeOutput('meeting-transcript')?.transcript || ''); const minChars = Number($data?.minTranscriptChars || 0); const hasWake = $ctx.getNodeOutput('wake-phrase-trigger')?.triggered === true; return transcript.length >= minChars && hasWake; })()",
|
|
881
|
+
}, { x: 450, y: 840 }),
|
|
882
|
+
|
|
883
|
+
node("notify-guard-failed", "notify.telegram", "Notify Guard Failed", {
|
|
884
|
+
message:
|
|
885
|
+
"{{notifyPrefix}} Meeting transcript guard failed for **{{sessionTitle}}**. " +
|
|
886
|
+
"Wake phrase missing or transcript shorter than {{minTranscriptChars}} chars.",
|
|
887
|
+
}, { x: 840, y: 840 }),
|
|
888
|
+
|
|
889
|
+
node("execute-child-workflow", "action.execute_workflow", "Run Child Workflow", {
|
|
890
|
+
workflowId: "{{childWorkflowId}}",
|
|
891
|
+
mode: "sync",
|
|
892
|
+
inheritContext: true,
|
|
893
|
+
includeKeys: [
|
|
894
|
+
"meetingSessionId",
|
|
895
|
+
"sessionTitle",
|
|
896
|
+
"wakePhrase",
|
|
897
|
+
"meetingVisionSummary",
|
|
898
|
+
],
|
|
899
|
+
input: {
|
|
900
|
+
parentWorkflowId: "{{_workflowId}}",
|
|
901
|
+
parentRunId: "{{_workflowRunId}}",
|
|
902
|
+
sessionTitle: "{{sessionTitle}}",
|
|
903
|
+
wakePhrase: "{{wakePhrase}}",
|
|
904
|
+
transcript: "{{meeting-transcript.transcript}}",
|
|
905
|
+
visionSummary: "{{meeting-vision.summary}}",
|
|
906
|
+
},
|
|
907
|
+
outputVariable: "childWorkflowResult",
|
|
908
|
+
failOnChildError: false,
|
|
909
|
+
}, { x: 450, y: 980 }),
|
|
910
|
+
|
|
911
|
+
node("child-workflow-ok", "condition.expression", "Child Workflow Succeeded?", {
|
|
912
|
+
expression:
|
|
913
|
+
"$ctx.getNodeOutput('execute-child-workflow')?.success === true",
|
|
914
|
+
}, { x: 450, y: 1110 }),
|
|
915
|
+
|
|
916
|
+
node("notify-chain-success", "notify.telegram", "Notify Chain Success", {
|
|
917
|
+
message:
|
|
918
|
+
"{{notifyPrefix}} Meeting workflow chained into **{{childWorkflowId}}** " +
|
|
919
|
+
"successfully for **{{sessionTitle}}**.",
|
|
920
|
+
}, { x: 250, y: 1230 }),
|
|
921
|
+
|
|
922
|
+
node("notify-chain-failed", "notify.telegram", "Notify Chain Failure", {
|
|
923
|
+
message:
|
|
924
|
+
":alert: Meeting flow completed but child workflow **{{childWorkflowId}}** failed " +
|
|
925
|
+
"or timed out for **{{sessionTitle}}**.",
|
|
926
|
+
}, { x: 650, y: 1230 }),
|
|
927
|
+
|
|
928
|
+
node("meeting-finalize", "meeting.finalize", "Finalize Meeting Session", {
|
|
929
|
+
status: "{{finalizeDisposition}}",
|
|
930
|
+
note: "Meeting subworkflow chain finalized.",
|
|
931
|
+
}, { x: 450, y: 1360 }),
|
|
932
|
+
|
|
933
|
+
node("final-log", "notify.log", "Record Final Outcome", {
|
|
934
|
+
message:
|
|
935
|
+
"Meeting orchestration finalized for {{sessionTitle}} with child workflow {{childWorkflowId}}",
|
|
936
|
+
level: "info",
|
|
937
|
+
}, { x: 450, y: 1490 }),
|
|
938
|
+
],
|
|
939
|
+
edges: [
|
|
940
|
+
edge("trigger", "meeting-start"),
|
|
941
|
+
edge("meeting-start", "meeting-send"),
|
|
942
|
+
edge("meeting-send", "meeting-vision"),
|
|
943
|
+
edge("meeting-vision", "meeting-transcript"),
|
|
944
|
+
edge("meeting-transcript", "wake-phrase-trigger"),
|
|
945
|
+
edge("wake-phrase-trigger", "guard-transcript"),
|
|
946
|
+
edge("guard-transcript", "execute-child-workflow", { condition: "$output?.result === true", port: "yes" }),
|
|
947
|
+
edge("guard-transcript", "notify-guard-failed", { condition: "$output?.result !== true", port: "no" }),
|
|
948
|
+
edge("execute-child-workflow", "child-workflow-ok"),
|
|
949
|
+
edge("child-workflow-ok", "notify-chain-success", { condition: "$output?.result === true", port: "yes" }),
|
|
950
|
+
edge("child-workflow-ok", "notify-chain-failed", { condition: "$output?.result !== true", port: "no" }),
|
|
951
|
+
edge("notify-chain-success", "meeting-finalize"),
|
|
952
|
+
edge("notify-chain-failed", "meeting-finalize"),
|
|
953
|
+
edge("notify-guard-failed", "meeting-finalize"),
|
|
954
|
+
edge("meeting-finalize", "final-log"),
|
|
955
|
+
],
|
|
956
|
+
metadata: {
|
|
957
|
+
author: "bosun",
|
|
958
|
+
version: 1,
|
|
959
|
+
createdAt: "2026-02-28T00:00:00Z",
|
|
960
|
+
templateVersion: "1.0.0",
|
|
961
|
+
tags: ["meeting", "subworkflow", "chaining", "agents"],
|
|
962
|
+
},
|
|
963
|
+
};
|
|
@@ -52,7 +52,7 @@ export const BUILD_DEPLOY_TEMPLATE = {
|
|
|
52
52
|
}, { x: 400, y: 570 }),
|
|
53
53
|
|
|
54
54
|
node("notify", "notify.telegram", "Notify Deploy", {
|
|
55
|
-
message: "
|
|
55
|
+
message: ":rocket: Deployment to production completed for {{branch}}",
|
|
56
56
|
}, { x: 400, y: 700 }),
|
|
57
57
|
],
|
|
58
58
|
edges: [
|
|
@@ -173,11 +173,11 @@ Commit the result with message "docs: update changelog for vX.Y.Z".`,
|
|
|
173
173
|
}, { x: 250, y: 1220 }),
|
|
174
174
|
|
|
175
175
|
node("notify-success", "notify.telegram", "Notify: Released", {
|
|
176
|
-
message: "
|
|
176
|
+
message: ":box: **Release published!**\n\nVersion: v{{version}}\nnpm + GitHub release created.",
|
|
177
177
|
}, { x: 250, y: 1350 }),
|
|
178
178
|
|
|
179
179
|
node("notify-failure", "notify.telegram", "Notify: Release Failed", {
|
|
180
|
-
message: "
|
|
180
|
+
message: ":close: **Release pipeline failed** at test stage.\n\nVersion bump was {{bumpType}} but tests did not pass. Manual intervention required.",
|
|
181
181
|
}, { x: 600, y: 960 }),
|
|
182
182
|
],
|
|
183
183
|
edges: [
|
|
@@ -275,7 +275,7 @@ export const CANARY_DEPLOY_TEMPLATE = {
|
|
|
275
275
|
}, { x: 100, y: 960 }),
|
|
276
276
|
|
|
277
277
|
node("notify-success", "notify.telegram", "Deploy Succeeded", {
|
|
278
|
-
message: "
|
|
278
|
+
message: ":check: **Canary deploy promoted to production** successfully.",
|
|
279
279
|
}, { x: 100, y: 1090 }),
|
|
280
280
|
|
|
281
281
|
node("rollback", "action.run_command", "Rollback", {
|
|
@@ -284,11 +284,11 @@ export const CANARY_DEPLOY_TEMPLATE = {
|
|
|
284
284
|
}, { x: 550, y: 700 }),
|
|
285
285
|
|
|
286
286
|
node("notify-rollback", "notify.telegram", "Deploy Rolled Back", {
|
|
287
|
-
message: "
|
|
287
|
+
message: ":refresh: **Canary deploy rolled back.**\n\nSmoke tests or staging deploy failed. Production unchanged.",
|
|
288
288
|
}, { x: 550, y: 830 }),
|
|
289
289
|
|
|
290
290
|
node("notify-staging-fail", "notify.telegram", "Staging Failed", {
|
|
291
|
-
message: "
|
|
291
|
+
message: ":close: **Staging deploy failed.** Not proceeding to canary phase.",
|
|
292
292
|
}, { x: 600, y: 440 }),
|
|
293
293
|
],
|
|
294
294
|
edges: [
|