bosun 0.31.8 → 0.33.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 (58) hide show
  1. package/.env.example +5 -5
  2. package/README.md +3 -0
  3. package/agent-prompts.mjs +127 -7
  4. package/anomaly-detector.mjs +54 -0
  5. package/bosun-skills.mjs +740 -0
  6. package/codex-config.mjs +104 -0
  7. package/github-app-auth.mjs +7 -7
  8. package/github-auth-manager.mjs +2 -2
  9. package/github-oauth-portal.mjs +7 -7
  10. package/monitor.mjs +3 -3
  11. package/package.json +14 -4
  12. package/postinstall.mjs +17 -0
  13. package/setup-web-server.mjs +616 -25
  14. package/task-executor.mjs +4 -4
  15. package/telegram-bot.mjs +61 -13
  16. package/ui/app.js +418 -38
  17. package/ui/app.monolith.js +4 -4
  18. package/ui/components/agent-selector.js +119 -11
  19. package/ui/components/chat-view.js +10 -9
  20. package/ui/components/diff-viewer.js +13 -12
  21. package/ui/components/forms.js +1 -1
  22. package/ui/components/kanban-board.js +172 -15
  23. package/ui/components/session-list.js +6 -5
  24. package/ui/components/workspace-switcher.js +5 -4
  25. package/ui/demo.html +1819 -310
  26. package/ui/index.html +40 -29
  27. package/ui/modules/icon-utils.js +183 -0
  28. package/ui/modules/icons.js +554 -0
  29. package/ui/modules/router.js +1 -0
  30. package/ui/modules/settings-schema.js +13 -13
  31. package/ui/modules/voice.js +294 -0
  32. package/ui/setup.html +465 -85
  33. package/ui/styles/base.css +4 -1
  34. package/ui/styles/components.css +1064 -65
  35. package/ui/styles/kanban.css +245 -0
  36. package/ui/styles/layout.css +330 -8
  37. package/ui/styles/sessions.css +243 -32
  38. package/ui/styles/variables.css +37 -0
  39. package/ui/styles/workspace-switcher.css +6 -0
  40. package/ui/styles.css +6 -0
  41. package/ui/tabs/agents.js +23 -22
  42. package/ui/tabs/chat.js +36 -13
  43. package/ui/tabs/control.js +5 -6
  44. package/ui/tabs/dashboard.js +19 -12
  45. package/ui/tabs/infra.js +11 -10
  46. package/ui/tabs/logs.js +11 -10
  47. package/ui/tabs/settings.js +17 -16
  48. package/ui/tabs/tasks.js +618 -48
  49. package/ui/tabs/workflows.js +1588 -0
  50. package/ui/vendor/es-module-shims.js +1063 -0
  51. package/ui/vendor/htm.js +1 -0
  52. package/ui/vendor/preact-compat.js +2 -0
  53. package/ui/vendor/preact-hooks.js +2 -0
  54. package/ui/vendor/preact-signals-core.js +1 -0
  55. package/ui/vendor/preact-signals.js +1 -0
  56. package/ui/vendor/preact.js +2 -0
  57. package/ui-server.mjs +420 -17
  58. package/vendor-sync.mjs +241 -0
package/.env.example CHANGED
@@ -332,9 +332,9 @@ TELEGRAM_MINIAPP_ENABLED=false
332
332
  # by the next agent working on that branch. Default: true
333
333
  # TASK_UPSTREAM_SYNC_MAIN=true
334
334
 
335
- # ─── GitHub App (Bosun[botswain] Identity + Auth) ────────────────────────────
336
- # App: https://github.com/apps/bosun-botswain (slug: bosun-botswain)
337
- # Bot identity: bosun-botswain[bot] (appears as contributor on every agent commit)
335
+ # ─── GitHub App (Bosun[VE] Identity + Auth) ────────────────────────────
336
+ # App: https://github.com/apps/bosun-ve (slug: bosun-ve)
337
+ # Bot identity: bosun-ve[bot] (appears as contributor on every agent commit)
338
338
  #
339
339
  # Numeric App ID (shown on the App settings page under "About"):
340
340
  # BOSUN_GITHUB_APP_ID=2911413
@@ -350,9 +350,9 @@ TELEGRAM_MINIAPP_ENABLED=false
350
350
  # BOSUN_GITHUB_WEBHOOK_SECRET=
351
351
  #
352
352
  # Path to the PEM private key downloaded from App settings → Generate a private key:
353
- # BOSUN_GITHUB_PRIVATE_KEY_PATH=/path/to/bosun-botswain.pem
353
+ # BOSUN_GITHUB_PRIVATE_KEY_PATH=/path/to/bosun-ve.pem
354
354
  #
355
- # ─── GitHub App Settings (enable all three in https://github.com/settings/apps/bosun-botswain) ────
355
+ # ─── GitHub App Settings (enable all three in https://github.com/settings/apps/bosun-ve) ────
356
356
  # ✅ Callback URL → http://127.0.0.1:54317/github/callback (set this FIRST, then Save)
357
357
  # ✅ "Request user authorization (OAuth) during installation" → ON
358
358
  # GitHub does OAuth at install time, redirecting to the Callback URL with
package/README.md CHANGED
@@ -36,6 +36,7 @@ bosun --setup
36
36
  ```
37
37
 
38
38
  Requires:
39
+
39
40
  - Node.js 18+
40
41
  - Git
41
42
  - Bash (for `.sh` wrappers) or PowerShell 7+ (for `.ps1` wrappers)
@@ -60,6 +61,7 @@ Requires:
60
61
  **Source docs (markdown):** `_docs/` is the source of truth for long-form documentation. The website should be generated from the same markdown content so docs stay in sync.
61
62
 
62
63
  Key references:
64
+
63
65
  - [GitHub adapter enhancements](_docs/KANBAN_GITHUB_ENHANCEMENT.md)
64
66
  - [GitHub Projects v2 index](_docs/GITHUB_PROJECTS_V2_INDEX.md)
65
67
  - [GitHub Projects v2 quickstart](_docs/GITHUB_PROJECTS_V2_QUICKSTART.md)
@@ -79,6 +81,7 @@ Bosun enforces a strict quality pipeline in both local hooks and CI:
79
81
 
80
82
  - **Pre-commit hooks** auto-format and lint staged files.
81
83
  - **Pre-push hooks** run targeted checks based on changed files (Go, portal, docs).
84
+ - **Demo load smoke test** runs in `npm test` and blocks push if `site/indexv2.html` or `site/ui/demo.html` fails to load required assets.
82
85
  - **Prepublish checks** validate package contents and release readiness.
83
86
 
84
87
  Local commands you can run any time:
package/agent-prompts.mjs CHANGED
@@ -119,6 +119,12 @@ const PROMPT_DEFS = [
119
119
  description:
120
120
  "Task management agent prompt with full CRUD access via CLI and REST API.",
121
121
  },
122
+ {
123
+ key: "frontendAgent",
124
+ filename: "frontend-agent.md",
125
+ description:
126
+ "Front-end specialist agent with screenshot-based validation and visual verification.",
127
+ },
122
128
  ];
123
129
 
124
130
  export const AGENT_PROMPT_DEFINITIONS = Object.freeze(
@@ -150,6 +156,19 @@ You are an autonomous task orchestrator agent. You receive implementation tasks
150
156
  - Existing functionality is preserved.
151
157
  - Relevant checks pass.
152
158
  - Branch is pushed and ready for PR/review flow.
159
+
160
+ ## Skills & Knowledge Base
161
+
162
+ Before starting any task, load relevant skills to avoid known pitfalls and
163
+ apply patterns discovered by previous agents:
164
+
165
+ 1. Check if \`.bosun/skills/index.json\` exists in the workspace or bosun home.
166
+ 2. Read the index to find skills whose tags match your task's module or domain.
167
+ 3. Load and apply any matching skill files from \`.bosun/skills/\`.
168
+
169
+ After completing a task, if you discovered a non-obvious pattern, workaround, or
170
+ domain-specific fact, write or update a skill file at \`.bosun/skills/<module>.md\`
171
+ so the next agent benefits from your investigation.
153
172
  `,
154
173
  planner: `# Codex-Task-Planner Agent
155
174
 
@@ -227,12 +246,23 @@ You are the always-on reliability guardian for bosun in devmode.
227
246
  - Branch: {{BRANCH}}
228
247
  - Repository: {{REPO_SLUG}}
229
248
 
249
+ ## Skills — Load Before Starting
250
+
251
+ Check for relevant skills before implementing:
252
+ 1. Look for \`.bosun/skills/index.json\` (in workspace root or BOSUN_HOME).
253
+ 2. Read the index; load skills whose tags match this task's module/domain.
254
+ 3. Apply the patterns — especially \`background-task-execution\`, \`error-recovery\`,
255
+ and \`pr-workflow\` which apply to almost every task.
256
+
230
257
  ## Instructions
231
- 1. Read task requirements carefully.
232
- 2. Implement required code changes.
233
- 3. Run relevant tests/lint/build checks.
234
- 4. Commit with conventional commit format.
235
- 5. Push branch updates.
258
+ 1. Load relevant skills as described above.
259
+ 2. Read task requirements carefully.
260
+ 3. Implement required code changes.
261
+ 4. Run relevant tests/lint/build checks.
262
+ 5. Commit with conventional commit format.
263
+ 6. Push branch updates.
264
+ 7. After completing: if you discovered non-obvious patterns, write a skill file
265
+ at \`.bosun/skills/<module>.md\` for future agents.
236
266
 
237
267
  ## Critical Rules
238
268
  - Do not ask for manual confirmation.
@@ -580,6 +610,75 @@ Types: feat, fix, docs, refactor, test, chore
580
610
  Statuses: draft → todo → inprogress → inreview → done
581
611
 
582
612
  See .bosun/agents/task-manager.md for full documentation.
613
+ `,
614
+ frontendAgent: `# Frontend Specialist Agent
615
+
616
+ You are a **front-end development specialist** agent managed by Bosun.
617
+
618
+ ## Core Responsibilities
619
+
620
+ 1. Implement HTML, CSS, and JavaScript/TypeScript UI changes
621
+ 2. Build responsive, accessible UI components
622
+ 3. Ensure visual accuracy matching specifications
623
+ 4. Validate changes through automated testing AND visual verification
624
+
625
+ ## Special Skills
626
+
627
+ - CSS Grid/Flexbox layout
628
+ - Component architecture (React, Preact, Vue, Svelte, vanilla)
629
+ - Responsive design (mobile-first)
630
+ - Accessibility (WCAG 2.1 AA)
631
+ - CSS animations and transitions
632
+ - Design system adherence
633
+
634
+ ## CRITICAL: Evidence-Based Validation
635
+
636
+ After completing implementation, you MUST collect visual evidence:
637
+
638
+ ### Screenshot Protocol
639
+ 1. Start the dev server if not already running
640
+ 2. Navigate to every page/component you modified
641
+ 3. Take screenshots at THREE viewport sizes:
642
+ - Desktop (1920×1080)
643
+ - Tablet (768×1024)
644
+ - Mobile (375×812)
645
+ 4. Save ALL screenshots to \`.bosun/evidence/\` directory
646
+ 5. Use descriptive filenames: \`<page>-<viewport>-<timestamp>.png\`
647
+ 6. Also screenshot any interactive states (modals, dropdowns, hover states)
648
+
649
+ ### Evidence Naming Convention
650
+ \`\`\`
651
+ .bosun/evidence/
652
+ homepage-desktop-1234567890.png
653
+ homepage-tablet-1234567890.png
654
+ homepage-mobile-1234567890.png
655
+ modal-open-desktop-1234567890.png
656
+ dark-mode-desktop-1234567890.png
657
+ \`\`\`
658
+
659
+ ## Workflow
660
+ 1. Read task requirements and any linked designs/specs
661
+ 2. Load relevant skills from \`.bosun/skills/\`
662
+ 3. Implement frontend changes
663
+ 4. Run build: \`npm run build\` (zero errors AND zero warnings)
664
+ 5. Run lint: \`npm run lint\`
665
+ 6. Run tests: \`npm test\`
666
+ 7. Start dev server and collect screenshots (see protocol above)
667
+ 8. Commit with conventional format: \`feat(ui): ...\` or \`fix(ui): ...\`
668
+ 9. Push branch
669
+
670
+ ## IMPORTANT: Do NOT mark the task complete
671
+ The Bosun workflow engine handles completion verification.
672
+ An independent model will review your screenshots against the task
673
+ requirements before the task is marked as done.
674
+
675
+ ## Task Context
676
+ - Task: {{TASK_TITLE}}
677
+ - Description: {{TASK_DESCRIPTION}}
678
+ - Branch: {{BRANCH}}
679
+ - Working Directory: {{WORKTREE_PATH}}
680
+
681
+ {{COAUTHOR_INSTRUCTION}}
583
682
  `,
584
683
  };
585
684
 
@@ -646,19 +745,40 @@ export function getDefaultPromptTemplate(key) {
646
745
  return DEFAULT_PROMPTS[key] || "";
647
746
  }
648
747
 
649
- export function renderPromptTemplate(template, values = {}) {
748
+ export function renderPromptTemplate(template, values = {}, rootDir) {
650
749
  if (typeof template !== "string") return "";
651
750
  const normalized = {};
652
751
  for (const [k, v] of Object.entries(values || {})) {
653
752
  normalized[String(k).trim().toUpperCase()] = normalizeTemplateValue(v);
654
753
  }
655
754
 
656
- return template.replace(/\{\{\s*([A-Za-z0-9_]+)\s*\}\}/g, (full, key) => {
755
+ // Resolve namespaced library refs: {{prompt:name}}, {{agent:name}}, {{skill:name}}
756
+ let result = template;
757
+ if (rootDir && _libraryResolver) {
758
+ try {
759
+ result = _libraryResolver(result, rootDir, {});
760
+ } catch {
761
+ // library resolver failed — skip namespaced refs
762
+ }
763
+ }
764
+
765
+ return result.replace(/\{\{\s*([A-Za-z0-9_]+)\s*\}\}/g, (full, key) => {
657
766
  const hit = normalized[String(key).toUpperCase()];
658
767
  return hit == null ? "" : hit;
659
768
  });
660
769
  }
661
770
 
771
+ /**
772
+ * Register the library reference resolver. Called by library-manager or at
773
+ * startup to enable {{prompt:name}}, {{agent:name}}, {{skill:name}} syntax.
774
+ *
775
+ * @param {(template: string, rootDir: string, vars: Object) => string} resolver
776
+ */
777
+ let _libraryResolver = null;
778
+ export function setLibraryResolver(resolver) {
779
+ _libraryResolver = typeof resolver === "function" ? resolver : null;
780
+ }
781
+
662
782
  export function resolvePromptTemplate(template, values, fallback) {
663
783
  const base = typeof fallback === "string" ? fallback : "";
664
784
  if (typeof template !== "string" || !template.trim()) return base;
@@ -1211,3 +1211,57 @@ export function createAnomalyDetector(options = {}) {
1211
1211
  */
1212
1212
 
1213
1213
  export default AnomalyDetector;
1214
+
1215
+ // ── Workflow Engine Integration ─────────────────────────────────────────────
1216
+
1217
+ /**
1218
+ * Registered workflow engine reference for anomaly → workflow triggers.
1219
+ * @type {import("./workflow-engine.mjs").WorkflowEngine | null}
1220
+ */
1221
+ let _workflowEngine = null;
1222
+
1223
+ /**
1224
+ * Register a workflow engine to receive anomaly trigger events.
1225
+ * When set, every anomaly emitted will also call engine.evaluateTriggers("anomaly", anomalyData).
1226
+ *
1227
+ * @param {import("./workflow-engine.mjs").WorkflowEngine} engine
1228
+ */
1229
+ export function setWorkflowEngine(engine) {
1230
+ _workflowEngine = engine;
1231
+ }
1232
+
1233
+ /** Get the currently registered workflow engine (or null) */
1234
+ export function getWorkflowEngine() {
1235
+ return _workflowEngine;
1236
+ }
1237
+
1238
+ /**
1239
+ * Create an onAnomaly callback that also fires workflow triggers.
1240
+ * Wraps the user's original callback and additionally invokes
1241
+ * evaluateTriggers on the registered workflow engine.
1242
+ *
1243
+ * @param {(anomaly: Anomaly) => void} [originalCallback]
1244
+ * @returns {(anomaly: Anomaly) => void}
1245
+ */
1246
+ export function wrapAnomalyCallback(originalCallback) {
1247
+ return (anomaly) => {
1248
+ // Always call the original callback
1249
+ if (originalCallback) originalCallback(anomaly);
1250
+
1251
+ // Fire workflow triggers if engine is registered
1252
+ if (_workflowEngine?.evaluateTriggers) {
1253
+ try {
1254
+ _workflowEngine.evaluateTriggers("anomaly", {
1255
+ anomalyType: anomaly.type,
1256
+ severity: anomaly.severity,
1257
+ agentId: anomaly.processId || anomaly.shortId,
1258
+ message: anomaly.message,
1259
+ action: anomaly.action,
1260
+ taskTitle: anomaly.taskTitle,
1261
+ data: anomaly.data,
1262
+ timestamp: Date.now(),
1263
+ });
1264
+ } catch { /* workflow trigger errors should not break anomaly detection */ }
1265
+ }
1266
+ };
1267
+ }