bosun 0.41.2 → 0.41.4

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 (73) hide show
  1. package/.env.example +1 -1
  2. package/agent/agent-pool.mjs +9 -2
  3. package/agent/agent-prompt-catalog.mjs +971 -0
  4. package/agent/agent-prompts.mjs +2 -970
  5. package/agent/agent-supervisor.mjs +119 -6
  6. package/agent/autofix-git.mjs +33 -0
  7. package/agent/autofix-prompts.mjs +151 -0
  8. package/agent/autofix.mjs +11 -175
  9. package/agent/bosun-skills.mjs +3 -2
  10. package/bosun.config.example.json +17 -0
  11. package/bosun.schema.json +87 -188
  12. package/cli.mjs +34 -1
  13. package/config/config-doctor.mjs +5 -250
  14. package/config/config-file-names.mjs +5 -0
  15. package/config/config.mjs +89 -493
  16. package/config/executor-config.mjs +493 -0
  17. package/config/repo-root.mjs +1 -2
  18. package/config/workspace-health.mjs +242 -0
  19. package/git/git-safety.mjs +15 -0
  20. package/github/github-oauth-portal.mjs +46 -0
  21. package/infra/library-manager-utils.mjs +22 -0
  22. package/infra/library-manager-well-known-sources.mjs +578 -0
  23. package/infra/library-manager.mjs +512 -1030
  24. package/infra/monitor.mjs +35 -9
  25. package/infra/session-tracker.mjs +10 -7
  26. package/kanban/kanban-adapter.mjs +17 -1
  27. package/lib/codebase-audit-manifests.mjs +117 -0
  28. package/lib/codebase-audit.mjs +18 -115
  29. package/package.json +18 -3
  30. package/server/setup-web-server.mjs +58 -5
  31. package/server/ui-server.mjs +1394 -79
  32. package/shell/codex-config-file.mjs +178 -0
  33. package/shell/codex-config.mjs +538 -575
  34. package/task/task-cli.mjs +54 -3
  35. package/task/task-executor.mjs +143 -13
  36. package/task/task-store.mjs +409 -1
  37. package/telegram/telegram-bot.mjs +127 -0
  38. package/tools/apply-pr-suggestions.mjs +401 -0
  39. package/tools/syntax-check.mjs +28 -9
  40. package/ui/app.js +3 -14
  41. package/ui/components/kanban-board.js +227 -4
  42. package/ui/components/session-list.js +85 -5
  43. package/ui/demo-defaults.js +338 -84
  44. package/ui/demo.html +155 -0
  45. package/ui/modules/session-api.js +96 -0
  46. package/ui/modules/settings-schema.js +1 -2
  47. package/ui/modules/state.js +43 -3
  48. package/ui/setup.html +4 -5
  49. package/ui/styles/components.css +58 -4
  50. package/ui/tabs/agents.js +12 -15
  51. package/ui/tabs/control.js +1 -0
  52. package/ui/tabs/library.js +484 -22
  53. package/ui/tabs/manual-flows.js +105 -29
  54. package/ui/tabs/tasks.js +848 -141
  55. package/ui/tabs/telemetry.js +129 -11
  56. package/ui/tabs/workflow-canvas-utils.mjs +130 -0
  57. package/ui/tabs/workflows.js +293 -23
  58. package/voice/voice-tool-definitions.mjs +757 -0
  59. package/voice/voice-tools.mjs +34 -778
  60. package/workflow/manual-flow-audit.mjs +165 -0
  61. package/workflow/manual-flows.mjs +164 -259
  62. package/workflow/workflow-engine.mjs +147 -58
  63. package/workflow/workflow-nodes/definitions.mjs +1207 -0
  64. package/workflow/workflow-nodes/transforms.mjs +612 -0
  65. package/workflow/workflow-nodes.mjs +358 -63
  66. package/workflow/workflow-templates.mjs +313 -191
  67. package/workflow-templates/_helpers.mjs +154 -0
  68. package/workflow-templates/agents.mjs +61 -4
  69. package/workflow-templates/code-quality.mjs +7 -7
  70. package/workflow-templates/github.mjs +20 -10
  71. package/workflow-templates/task-batch.mjs +44 -11
  72. package/workflow-templates/task-lifecycle.mjs +31 -6
  73. package/workspace/worktree-manager.mjs +277 -3
package/bosun.schema.json CHANGED
@@ -12,10 +12,7 @@
12
12
  },
13
13
  "mode": {
14
14
  "type": "string",
15
- "enum": [
16
- "virtengine",
17
- "generic"
18
- ]
15
+ "enum": ["virtengine", "generic"]
19
16
  },
20
17
  "orchestratorScript": {
21
18
  "type": "string"
@@ -38,11 +35,7 @@
38
35
  },
39
36
  "telegramVerbosity": {
40
37
  "type": "string",
41
- "enum": [
42
- "minimal",
43
- "summary",
44
- "detailed"
45
- ],
38
+ "enum": ["minimal", "summary", "detailed"],
46
39
  "description": "Notification verbosity: minimal (critical+error), summary (default), detailed (everything)",
47
40
  "default": "summary"
48
41
  },
@@ -68,6 +61,52 @@
68
61
  "default": false,
69
62
  "description": "Delegate task finalization and recovery to workflow automation instead of the legacy TaskExecutor. Automatically set to true when workflowFirst is enabled."
70
63
  },
64
+ "workflowWorktreeRecoveryCooldownMin": {
65
+ "type": "number",
66
+ "default": 15,
67
+ "description": "Minutes to keep a task blocked after a non-retryable worktree acquisition failure before Bosun returns it to todo automatically."
68
+ },
69
+ "worktreeBootstrap": {
70
+ "type": "object",
71
+ "additionalProperties": true,
72
+ "description": "Bootstrap policy for managed worktrees, including optional shared dependency links and per-ecosystem install/restore commands.",
73
+ "properties": {
74
+ "enabled": {
75
+ "type": "boolean",
76
+ "default": true
77
+ },
78
+ "linkSharedPaths": {
79
+ "type": "boolean",
80
+ "default": true,
81
+ "description": "Link reusable dependency directories from the repo root into each managed worktree when possible."
82
+ },
83
+ "commandTimeoutMs": {
84
+ "type": "number",
85
+ "default": 600000,
86
+ "description": "Maximum time to allow each bootstrap command to run inside a managed worktree."
87
+ },
88
+ "commandsByStack": {
89
+ "type": "object",
90
+ "additionalProperties": {
91
+ "oneOf": [
92
+ { "type": "string" },
93
+ { "type": "array", "items": { "type": "string" } }
94
+ ]
95
+ },
96
+ "description": "Override bootstrap commands by detected ecosystem id such as node, python, go, rust, java, dotnet, ruby, php, or make."
97
+ },
98
+ "sharedPathsByStack": {
99
+ "type": "object",
100
+ "additionalProperties": {
101
+ "oneOf": [
102
+ { "type": "string" },
103
+ { "type": "array", "items": { "type": "string" } }
104
+ ]
105
+ },
106
+ "description": "Override reusable relative paths to link from the repo root into a managed worktree for each detected ecosystem."
107
+ }
108
+ }
109
+ },
71
110
  "workflowDefaults": {
72
111
  "type": "object",
73
112
  "additionalProperties": true,
@@ -118,7 +157,10 @@
118
157
  ]
119
158
  },
120
159
  "stuckThresholdMs": { "type": "number" },
121
- "onStuck": { "type": "string", "enum": ["retry", "escalate", "pause"] },
160
+ "onStuck": {
161
+ "type": "string",
162
+ "enum": ["retry", "escalate", "pause"]
163
+ },
122
164
  "continuePrompt": { "type": "string" },
123
165
  "retryPrompt": { "type": "string" },
124
166
  "sdk": { "type": "string" },
@@ -148,13 +190,7 @@
148
190
  },
149
191
  "telegramUiTunnel": {
150
192
  "type": "string",
151
- "enum": [
152
- "named",
153
- "quick",
154
- "auto",
155
- "cloudflared",
156
- "disabled"
157
- ],
193
+ "enum": ["named", "quick", "auto", "cloudflared", "disabled"],
158
194
  "default": "named",
159
195
  "description": "Mini App tunnel mode. named is the default permanent hostname mode."
160
196
  },
@@ -181,10 +217,7 @@
181
217
  },
182
218
  "cloudflareUsernameHostnamePolicy": {
183
219
  "type": "string",
184
- "enum": [
185
- "per-user-fixed",
186
- "fixed"
187
- ],
220
+ "enum": ["per-user-fixed", "fixed"],
188
221
  "default": "per-user-fixed",
189
222
  "description": "Policy for deriving named tunnel hostname from workstation identity."
190
223
  },
@@ -258,14 +291,7 @@
258
291
  },
259
292
  "provider": {
260
293
  "type": "string",
261
- "enum": [
262
- "openai",
263
- "azure",
264
- "claude",
265
- "gemini",
266
- "fallback",
267
- "auto"
268
- ],
294
+ "enum": ["openai", "azure", "claude", "gemini", "fallback", "auto"],
269
295
  "default": "auto",
270
296
  "description": "Voice provider: openai/azure (Tier 1 realtime), claude/gemini (Tier 2 voice + provider vision), fallback (browser STT/TTS), auto (detect from env)"
271
297
  },
@@ -276,13 +302,7 @@
276
302
  "anyOf": [
277
303
  {
278
304
  "type": "string",
279
- "enum": [
280
- "openai",
281
- "azure",
282
- "claude",
283
- "gemini",
284
- "fallback"
285
- ]
305
+ "enum": ["openai", "azure", "claude", "gemini", "fallback"]
286
306
  },
287
307
  {
288
308
  "type": "object",
@@ -290,13 +310,7 @@
290
310
  "properties": {
291
311
  "provider": {
292
312
  "type": "string",
293
- "enum": [
294
- "openai",
295
- "azure",
296
- "claude",
297
- "gemini",
298
- "fallback"
299
- ]
313
+ "enum": ["openai", "azure", "claude", "gemini", "fallback"]
300
314
  },
301
315
  "model": {
302
316
  "type": "string"
@@ -328,9 +342,7 @@
328
342
  "description": "ID of the voice endpoint to use for this provider slot"
329
343
  }
330
344
  },
331
- "required": [
332
- "provider"
333
- ]
345
+ "required": ["provider"]
334
346
  }
335
347
  ]
336
348
  }
@@ -406,11 +418,7 @@
406
418
  },
407
419
  "turnDetection": {
408
420
  "type": "string",
409
- "enum": [
410
- "server_vad",
411
- "semantic_vad",
412
- "none"
413
- ],
421
+ "enum": ["server_vad", "semantic_vad", "none"],
414
422
  "default": "semantic_vad",
415
423
  "description": "Turn detection mode for voice activity detection"
416
424
  },
@@ -420,10 +428,7 @@
420
428
  },
421
429
  "fallbackMode": {
422
430
  "type": "string",
423
- "enum": [
424
- "browser",
425
- "disabled"
426
- ],
431
+ "enum": ["browser", "disabled"],
427
432
  "default": "browser",
428
433
  "description": "Fallback when Realtime API unavailable: browser (Web Speech API) or disabled"
429
434
  },
@@ -449,9 +454,7 @@
449
454
  "items": {
450
455
  "type": "object",
451
456
  "additionalProperties": false,
452
- "required": [
453
- "provider"
454
- ],
457
+ "required": ["provider"],
455
458
  "properties": {
456
459
  "id": {
457
460
  "type": "string",
@@ -463,12 +466,7 @@
463
466
  },
464
467
  "provider": {
465
468
  "type": "string",
466
- "enum": [
467
- "azure",
468
- "openai",
469
- "claude",
470
- "gemini"
471
- ],
469
+ "enum": ["azure", "openai", "claude", "gemini"],
472
470
  "description": "Provider type"
473
471
  },
474
472
  "endpoint": {
@@ -495,10 +493,7 @@
495
493
  },
496
494
  "role": {
497
495
  "type": "string",
498
- "enum": [
499
- "primary",
500
- "backup"
501
- ],
496
+ "enum": ["primary", "backup"],
502
497
  "default": "primary"
503
498
  },
504
499
  "weight": {
@@ -535,19 +530,11 @@
535
530
  "properties": {
536
531
  "backend": {
537
532
  "type": "string",
538
- "enum": [
539
- "internal",
540
- "vk",
541
- "github",
542
- "jira"
543
- ]
533
+ "enum": ["internal", "vk", "github", "jira"]
544
534
  },
545
535
  "syncPolicy": {
546
536
  "type": "string",
547
- "enum": [
548
- "internal-primary",
549
- "bidirectional"
550
- ],
537
+ "enum": ["internal-primary", "bidirectional"],
551
538
  "default": "internal-primary"
552
539
  },
553
540
  "projectId": {
@@ -564,10 +551,7 @@
564
551
  "properties": {
565
552
  "mode": {
566
553
  "type": "string",
567
- "enum": [
568
- "issues",
569
- "kanban"
570
- ],
554
+ "enum": ["issues", "kanban"],
571
555
  "default": "issues",
572
556
  "description": "Task source mode: 'issues' for repo issues only, 'kanban' for project board sync"
573
557
  },
@@ -576,10 +560,7 @@
576
560
  "description": "GitHub org/user that owns the project board"
577
561
  },
578
562
  "number": {
579
- "type": [
580
- "string",
581
- "number"
582
- ],
563
+ "type": ["string", "number"],
583
564
  "description": "GitHub project number"
584
565
  },
585
566
  "title": {
@@ -770,11 +751,7 @@
770
751
  },
771
752
  "plannerMode": {
772
753
  "type": "string",
773
- "enum": [
774
- "codex-sdk",
775
- "kanban",
776
- "disabled"
777
- ]
754
+ "enum": ["codex-sdk", "kanban", "disabled"]
778
755
  },
779
756
  "triggerSystem": {
780
757
  "type": "object",
@@ -805,10 +782,7 @@
805
782
  },
806
783
  "action": {
807
784
  "type": "string",
808
- "enum": [
809
- "task-planner",
810
- "create-task"
811
- ]
785
+ "enum": ["task-planner", "create-task"]
812
786
  },
813
787
  "minIntervalMinutes": {
814
788
  "type": "number",
@@ -826,31 +800,17 @@
826
800
  "properties": {
827
801
  "kind": {
828
802
  "type": "string",
829
- "enum": [
830
- "metric",
831
- "interval"
832
- ]
803
+ "enum": ["metric", "interval"]
833
804
  },
834
805
  "metric": {
835
806
  "type": "string"
836
807
  },
837
808
  "operator": {
838
809
  "type": "string",
839
- "enum": [
840
- "lt",
841
- "lte",
842
- "gt",
843
- "gte",
844
- "eq",
845
- "neq"
846
- ]
810
+ "enum": ["lt", "lte", "gt", "gte", "eq", "neq"]
847
811
  },
848
812
  "value": {
849
- "type": [
850
- "number",
851
- "string",
852
- "boolean"
853
- ]
813
+ "type": ["number", "string", "boolean"]
854
814
  },
855
815
  "minutes": {
856
816
  "type": "number",
@@ -867,11 +827,7 @@
867
827
  "properties": {
868
828
  "plannerMode": {
869
829
  "type": "string",
870
- "enum": [
871
- "codex-sdk",
872
- "kanban",
873
- "disabled"
874
- ]
830
+ "enum": ["codex-sdk", "kanban", "disabled"]
875
831
  },
876
832
  "defaultTaskCount": {
877
833
  "type": "number",
@@ -921,10 +877,7 @@
921
877
  "items": {
922
878
  "type": "object",
923
879
  "additionalProperties": true,
924
- "required": [
925
- "id",
926
- "name"
927
- ],
880
+ "required": ["id", "name"],
928
881
  "properties": {
929
882
  "id": {
930
883
  "type": "string",
@@ -940,9 +893,7 @@
940
893
  "items": {
941
894
  "type": "object",
942
895
  "additionalProperties": true,
943
- "required": [
944
- "name"
945
- ],
896
+ "required": ["name"],
946
897
  "properties": {
947
898
  "name": {
948
899
  "type": "string",
@@ -968,10 +919,7 @@
968
919
  }
969
920
  },
970
921
  "activeRepo": {
971
- "type": [
972
- "string",
973
- "null"
974
- ],
922
+ "type": ["string", "null"],
975
923
  "description": "Currently active repository name within the workspace"
976
924
  },
977
925
  "createdAt": {
@@ -1027,11 +975,7 @@
1027
975
  "properties": {
1028
976
  "mode": {
1029
977
  "type": "string",
1030
- "enum": [
1031
- "vk",
1032
- "internal",
1033
- "hybrid"
1034
- ]
978
+ "enum": ["vk", "internal", "hybrid"]
1035
979
  },
1036
980
  "maxParallel": {
1037
981
  "type": "number"
@@ -1044,14 +988,7 @@
1044
988
  },
1045
989
  "sdk": {
1046
990
  "type": "string",
1047
- "enum": [
1048
- "auto",
1049
- "codex",
1050
- "copilot",
1051
- "claude",
1052
- "gemini",
1053
- "opencode"
1054
- ]
991
+ "enum": ["auto", "codex", "copilot", "claude", "gemini", "opencode"]
1055
992
  },
1056
993
  "taskTimeoutMs": {
1057
994
  "type": "number"
@@ -1117,11 +1054,7 @@
1117
1054
  },
1118
1055
  "distribution": {
1119
1056
  "type": "string",
1120
- "enum": [
1121
- "weighted",
1122
- "round-robin",
1123
- "primary-only"
1124
- ]
1057
+ "enum": ["weighted", "round-robin", "primary-only"]
1125
1058
  },
1126
1059
  "agentPrompts": {
1127
1060
  "type": "object",
@@ -1204,12 +1137,7 @@
1204
1137
  "type": "array",
1205
1138
  "items": {
1206
1139
  "type": "string",
1207
- "enum": [
1208
- "env",
1209
- "cli",
1210
- "vscode",
1211
- "interactive"
1212
- ]
1140
+ "enum": ["env", "cli", "vscode", "interactive"]
1213
1141
  },
1214
1142
  "description": "Auth source priority: env (tokens), cli (gh auth), vscode (extension), interactive (prompt)"
1215
1143
  },
@@ -1226,11 +1154,7 @@
1226
1154
  "type": "array",
1227
1155
  "items": {
1228
1156
  "type": "string",
1229
- "enum": [
1230
- "env",
1231
- "cli",
1232
- "interactive"
1233
- ]
1157
+ "enum": ["env", "cli", "interactive"]
1234
1158
  },
1235
1159
  "description": "Auth source priority: env (API key), cli (config file), interactive (prompt)"
1236
1160
  },
@@ -1247,11 +1171,7 @@
1247
1171
  "type": "array",
1248
1172
  "items": {
1249
1173
  "type": "string",
1250
- "enum": [
1251
- "config",
1252
- "env",
1253
- "interactive"
1254
- ]
1174
+ "enum": ["config", "env", "interactive"]
1255
1175
  },
1256
1176
  "description": "Auth source priority: config (config.toml), env (API key), interactive (prompt)"
1257
1177
  },
@@ -1271,11 +1191,7 @@
1271
1191
  "properties": {
1272
1192
  "type": {
1273
1193
  "type": "string",
1274
- "enum": [
1275
- "sequential",
1276
- "fanout",
1277
- "race"
1278
- ]
1194
+ "enum": ["sequential", "fanout", "race"]
1279
1195
  },
1280
1196
  "description": {
1281
1197
  "type": "string"
@@ -1429,11 +1345,7 @@
1429
1345
  "properties": {
1430
1346
  "strategy": {
1431
1347
  "type": "string",
1432
- "enum": [
1433
- "next-in-line",
1434
- "weighted-random",
1435
- "round-robin"
1436
- ]
1348
+ "enum": ["next-in-line", "weighted-random", "round-robin"]
1437
1349
  },
1438
1350
  "maxRetries": {
1439
1351
  "type": "number"
@@ -1602,22 +1514,13 @@
1602
1514
  },
1603
1515
  "profile": {
1604
1516
  "type": "string",
1605
- "enum": [
1606
- "strict",
1607
- "balanced",
1608
- "lightweight",
1609
- "none"
1610
- ]
1517
+ "enum": ["strict", "balanced", "lightweight", "none"]
1611
1518
  },
1612
1519
  "targets": {
1613
1520
  "type": "array",
1614
1521
  "items": {
1615
1522
  "type": "string",
1616
- "enum": [
1617
- "codex",
1618
- "claude",
1619
- "copilot"
1620
- ]
1523
+ "enum": ["codex", "claude", "copilot"]
1621
1524
  }
1622
1525
  },
1623
1526
  "overwriteExisting": {
@@ -1815,11 +1718,7 @@
1815
1718
  },
1816
1719
  "liveToolCompactionMode": {
1817
1720
  "type": "string",
1818
- "enum": [
1819
- "off",
1820
- "auto",
1821
- "aggressive"
1822
- ],
1721
+ "enum": ["off", "auto", "aggressive"],
1823
1722
  "default": "auto",
1824
1723
  "description": "off disables live compaction, auto compacts only when pressure or signal justify it, and aggressive favors stronger reduction for noisy command families."
1825
1724
  },
package/cli.mjs CHANGED
@@ -107,7 +107,7 @@ function showHelp() {
107
107
  ORCHESTRATOR
108
108
  --script <path> Path to the orchestrator script
109
109
  --args "<args>" Arguments passed to the script (default: "-MaxParallel 6")
110
- --restart-delay <ms> Delay before restart (default: 10000)
110
+ --restart-delay <ms> Delay before restart (default: 180000)
111
111
  --max-restarts <n> Max restarts, 0 = unlimited (default: 0)
112
112
 
113
113
  LOGGING
@@ -1391,6 +1391,39 @@ async function main() {
1391
1391
  process.exit(0);
1392
1392
  }
1393
1393
 
1394
+ if (args[0] === "apply-suggestions") {
1395
+ const { applyPrSuggestions } = await import("./tools/apply-pr-suggestions.mjs");
1396
+ const prNum = parseInt(args[1], 10);
1397
+ if (!prNum) {
1398
+ console.error("Usage: bosun apply-suggestions <pr-number> [--author <login>] [--dry-run]");
1399
+ process.exit(1);
1400
+ }
1401
+ const detected = (() => {
1402
+ try {
1403
+ const url = execSync("git config --get remote.origin.url", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
1404
+ const m = url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
1405
+ return m ? { owner: m[1], repo: m[2] } : { owner: "", repo: "" };
1406
+ } catch { return { owner: "", repo: "" }; }
1407
+ })();
1408
+ const authorIdx = args.indexOf("--author");
1409
+ const author = authorIdx >= 0 ? args[authorIdx + 1] : undefined;
1410
+ const dryRun = args.includes("--dry-run");
1411
+ try {
1412
+ const result = await applyPrSuggestions({
1413
+ owner: detected.owner, repo: detected.repo, prNumber: prNum, dryRun, author,
1414
+ });
1415
+ if (result.commitSha) {
1416
+ console.log(`✅ Applied ${result.applied} suggestion(s) → ${result.commitSha.slice(0, 8)}`);
1417
+ } else {
1418
+ console.log(`ℹ ${result.message || "No suggestions to apply."}`);
1419
+ }
1420
+ } catch (err) {
1421
+ console.error(`Error: ${err.message}`);
1422
+ process.exit(1);
1423
+ }
1424
+ process.exit(0);
1425
+ }
1426
+
1394
1427
  // Handle --help
1395
1428
  if (args.includes("--help") || args.includes("-h")) {
1396
1429
  showHelp();