opencode-mad 0.3.10 → 0.3.11
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/agents/orchestrator.md +45 -1
- package/package.json +1 -1
- package/plugins/mad-plugin.ts +121 -1
- package/skills/mad-workflow/SKILL.md +14 -0
package/agents/orchestrator.md
CHANGED
|
@@ -579,6 +579,42 @@ Celebrate! The project is clean.
|
|
|
579
579
|
|
|
580
580
|
---
|
|
581
581
|
|
|
582
|
+
## Phase 6: Push & CI Watch
|
|
583
|
+
|
|
584
|
+
After all checks pass, push and watch CI:
|
|
585
|
+
|
|
586
|
+
```
|
|
587
|
+
mad_push_and_watch()
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
This will:
|
|
591
|
+
1. Push changes to the remote
|
|
592
|
+
2. Detect if GitHub Actions CI exists
|
|
593
|
+
3. Watch CI progress with `gh run watch`
|
|
594
|
+
4. Report success or failure
|
|
595
|
+
|
|
596
|
+
### If CI fails:
|
|
597
|
+
Create a fix worktree:
|
|
598
|
+
```
|
|
599
|
+
mad_worktree_create(
|
|
600
|
+
branch: "fix-ci",
|
|
601
|
+
task: "Fix CI failures:
|
|
602
|
+
[error details from mad_push_and_watch]
|
|
603
|
+
|
|
604
|
+
YOU OWN ALL FILES."
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
Task(
|
|
608
|
+
subagent_type: "mad-fixer",
|
|
609
|
+
description: "Fix CI",
|
|
610
|
+
prompt: "Fix the CI errors, commit, and call mad_done."
|
|
611
|
+
)
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Then merge, push again, and watch until CI passes.
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
582
618
|
## Available Tools
|
|
583
619
|
|
|
584
620
|
| Tool | Description |
|
|
@@ -594,6 +630,7 @@ Celebrate! The project is clean.
|
|
|
594
630
|
| `mad_read_task` | Read task description |
|
|
595
631
|
| `mad_log` | Log events for debugging |
|
|
596
632
|
| `mad_final_check` | Run global build/lint and categorize errors |
|
|
633
|
+
| `mad_push_and_watch` | Push to remote and watch CI |
|
|
597
634
|
|
|
598
635
|
## Subagents
|
|
599
636
|
|
|
@@ -731,6 +768,11 @@ Task(
|
|
|
731
768
|
║ → Run mad_cleanup() for ALL worktrees ║
|
|
732
769
|
║ → Verify with mad_status() that worktree list is empty ║
|
|
733
770
|
║ ║
|
|
771
|
+
║ □ 5. PUSHED AND CI PASSED? ║
|
|
772
|
+
║ → Run mad_push_and_watch() after cleanup ║
|
|
773
|
+
║ → If CI fails, create fix-ci worktree and fix ║
|
|
774
|
+
║ → Re-push until CI passes ║
|
|
775
|
+
║ ║
|
|
734
776
|
╚══════════════════════════════════════════════════════════════════════════════╝
|
|
735
777
|
```
|
|
736
778
|
|
|
@@ -759,7 +801,9 @@ Task(
|
|
|
759
801
|
5. mad_final_check() → Re-verify (repeat until clean)
|
|
760
802
|
6. mad_cleanup() x N → Remove all worktrees
|
|
761
803
|
7. mad_status() → Confirm worktree list is empty
|
|
762
|
-
8.
|
|
804
|
+
8. mad_push_and_watch() → Push to remote and watch CI
|
|
805
|
+
9. [If CI fails] Fix it → Create fix-ci worktree, fix, merge, re-push
|
|
806
|
+
10. Report to user → NOW you can say "DONE" 🎉
|
|
763
807
|
```
|
|
764
808
|
|
|
765
809
|
> **🚨 IF YOU DECLARE "DONE" WITHOUT COMPLETING THIS CHECKLIST, YOU HAVE FAILED! 🚨**
|
package/package.json
CHANGED
package/plugins/mad-plugin.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { execSync } from "child_process"
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// Current version of opencode-mad
|
|
16
|
-
const CURRENT_VERSION = "0.3.
|
|
16
|
+
const CURRENT_VERSION = "0.3.11"
|
|
17
17
|
|
|
18
18
|
// Update notification state (shown only once per session)
|
|
19
19
|
let updateNotificationShown = false
|
|
@@ -729,6 +729,126 @@ Latest version: ${updateInfo.latest}`
|
|
|
729
729
|
},
|
|
730
730
|
}),
|
|
731
731
|
|
|
732
|
+
/**
|
|
733
|
+
* Push and watch CI
|
|
734
|
+
*/
|
|
735
|
+
mad_push_and_watch: tool({
|
|
736
|
+
description: `Push changes to remote and watch CI if it exists.
|
|
737
|
+
After all merges and final checks, this pushes to the remote and monitors GitHub Actions.
|
|
738
|
+
Uses 'gh run watch' to follow CI progress in real-time.
|
|
739
|
+
If CI fails, returns error details for the orchestrator to spawn a fixer.`,
|
|
740
|
+
args: {
|
|
741
|
+
createFixWorktree: tool.schema.boolean().optional().describe("If true and CI fails, automatically suggest creating a fix-ci worktree"),
|
|
742
|
+
},
|
|
743
|
+
async execute(args, context) {
|
|
744
|
+
try {
|
|
745
|
+
const gitRoot = getGitRoot()
|
|
746
|
+
let report = getUpdateNotification() + "# Push & CI Watch\n\n"
|
|
747
|
+
|
|
748
|
+
// 1. Check if we have a remote
|
|
749
|
+
const remoteResult = runCommand("git remote get-url origin", gitRoot)
|
|
750
|
+
if (!remoteResult.success) {
|
|
751
|
+
return report + "⚠️ No remote 'origin' configured. Skipping push."
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// 2. Get current branch
|
|
755
|
+
const branch = getCurrentBranch()
|
|
756
|
+
report += `📍 Branch: \`${branch}\`\n\n`
|
|
757
|
+
|
|
758
|
+
// 3. Check if upstream exists, if not set it
|
|
759
|
+
const upstreamResult = runCommand(`git rev-parse --abbrev-ref ${branch}@{upstream}`, gitRoot)
|
|
760
|
+
|
|
761
|
+
// 4. Push
|
|
762
|
+
report += "## 🚀 Pushing to remote...\n"
|
|
763
|
+
const pushCmd = upstreamResult.success
|
|
764
|
+
? "git push"
|
|
765
|
+
: `git push -u origin ${branch}`
|
|
766
|
+
|
|
767
|
+
const pushResult = runCommand(pushCmd, gitRoot)
|
|
768
|
+
if (!pushResult.success) {
|
|
769
|
+
return report + `❌ Push failed:\n\`\`\`\n${pushResult.error}\n\`\`\`\n\nFix the issue and try again.`
|
|
770
|
+
}
|
|
771
|
+
report += "✅ Push successful!\n\n"
|
|
772
|
+
|
|
773
|
+
// 5. Check if gh CLI is available
|
|
774
|
+
const ghCheck = runCommand("gh --version", gitRoot)
|
|
775
|
+
if (!ghCheck.success) {
|
|
776
|
+
return report + "⚠️ GitHub CLI (gh) not installed. Cannot watch CI.\n\nInstall with: https://cli.github.com/"
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// 6. Check for running/pending workflow runs
|
|
780
|
+
report += "## 🔍 Checking for CI workflows...\n"
|
|
781
|
+
const runsResult = runCommand(
|
|
782
|
+
`gh run list --branch ${branch} --limit 1 --json databaseId,status,conclusion,name,event`,
|
|
783
|
+
gitRoot
|
|
784
|
+
)
|
|
785
|
+
|
|
786
|
+
if (!runsResult.success) {
|
|
787
|
+
return report + "⚠️ Could not check CI status. You may not be authenticated with `gh auth login`."
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
let runs: any[] = []
|
|
791
|
+
try {
|
|
792
|
+
runs = JSON.parse(runsResult.output)
|
|
793
|
+
} catch {
|
|
794
|
+
return report + "⚠️ No CI workflows found for this repository.\n\n✅ Push complete (no CI to watch)."
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
if (runs.length === 0) {
|
|
798
|
+
return report + "ℹ️ No CI workflows found for this branch.\n\n✅ Push complete!"
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
const latestRun = runs[0]
|
|
802
|
+
report += `Found workflow: **${latestRun.name}** (${latestRun.event})\n\n`
|
|
803
|
+
|
|
804
|
+
// 7. If already completed, just report status
|
|
805
|
+
if (latestRun.status === "completed") {
|
|
806
|
+
if (latestRun.conclusion === "success") {
|
|
807
|
+
return report + `✅ CI already passed! (${latestRun.name})\n\n🎉 All done!`
|
|
808
|
+
} else {
|
|
809
|
+
report += `❌ CI failed with conclusion: ${latestRun.conclusion}\n\n`
|
|
810
|
+
report += "Use `gh run view --log-failed` to see error details.\n"
|
|
811
|
+
if (args.createFixWorktree) {
|
|
812
|
+
report += "\n💡 **Suggestion:** Create a `fix-ci` worktree to fix the CI errors."
|
|
813
|
+
}
|
|
814
|
+
return report
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
// 8. Watch the CI run in real-time
|
|
819
|
+
report += "## ⏳ Watching CI...\n"
|
|
820
|
+
report += `Running: \`gh run watch ${latestRun.databaseId}\`\n\n`
|
|
821
|
+
|
|
822
|
+
// Use gh run watch (this blocks until complete)
|
|
823
|
+
const watchResult = runCommand(
|
|
824
|
+
`gh run watch ${latestRun.databaseId} --exit-status`,
|
|
825
|
+
gitRoot
|
|
826
|
+
)
|
|
827
|
+
|
|
828
|
+
if (watchResult.success) {
|
|
829
|
+
return report + `✅ CI passed!\n\n\`\`\`\n${watchResult.output.slice(-500)}\n\`\`\`\n\n🎉 All done!`
|
|
830
|
+
} else {
|
|
831
|
+
report += `❌ CI failed!\n\n\`\`\`\n${(watchResult.error || watchResult.output).slice(-1000)}\n\`\`\`\n\n`
|
|
832
|
+
|
|
833
|
+
// Get failed logs
|
|
834
|
+
const logsResult = runCommand(`gh run view ${latestRun.databaseId} --log-failed`, gitRoot)
|
|
835
|
+
if (logsResult.success && logsResult.output) {
|
|
836
|
+
report += `### Failed logs:\n\`\`\`\n${logsResult.output.slice(-2000)}\n\`\`\`\n\n`
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (args.createFixWorktree) {
|
|
840
|
+
report += "💡 **Recommendation:** Create a `fix-ci` worktree to fix these errors."
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
return report
|
|
844
|
+
}
|
|
845
|
+
} catch (e: any) {
|
|
846
|
+
logEvent("error", "mad_push_and_watch exception", { error: e.message })
|
|
847
|
+
return getUpdateNotification() + `❌ Error: ${e.message}`
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}),
|
|
851
|
+
|
|
732
852
|
/**
|
|
733
853
|
* Final check - run global build/lint and categorize errors
|
|
734
854
|
*/
|
|
@@ -112,6 +112,19 @@ mad_final_check()
|
|
|
112
112
|
```
|
|
113
113
|
This distinguishes session errors from pre-existing issues.
|
|
114
114
|
|
|
115
|
+
### 9. Push & CI Watch
|
|
116
|
+
Push to remote and monitor CI:
|
|
117
|
+
```
|
|
118
|
+
mad_push_and_watch()
|
|
119
|
+
```
|
|
120
|
+
This will:
|
|
121
|
+
- Push changes to the remote
|
|
122
|
+
- Detect if GitHub Actions CI exists
|
|
123
|
+
- Watch CI progress in real-time with `gh run watch`
|
|
124
|
+
- Report success or failure with logs
|
|
125
|
+
|
|
126
|
+
If CI fails, create a `fix-ci` worktree to fix the errors.
|
|
127
|
+
|
|
115
128
|
## Best Practices
|
|
116
129
|
|
|
117
130
|
1. **Keep subtasks focused** - Each should be completable in one session
|
|
@@ -134,6 +147,7 @@ This distinguishes session errors from pre-existing issues.
|
|
|
134
147
|
| `mad_blocked` | Mark task blocked |
|
|
135
148
|
| `mad_read_task` | Read task description |
|
|
136
149
|
| `mad_final_check` | Run global build/lint and categorize errors |
|
|
150
|
+
| `mad_push_and_watch` | Push to remote and watch CI |
|
|
137
151
|
|
|
138
152
|
## Example
|
|
139
153
|
|