Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
9fe8d15
fix(runtime): use main project root for MCP preflight on task retry
kabaogluemre Jun 22, 2026
ae2558d
fix(workflow): pass output validation on resume-after-approval
kabaogluemre Jun 23, 2026
03748a3
fix(ci): use pull_request_target so fork PRs get Discord notification
OgnjenGligoric Jun 23, 2026
8582ab2
Enable Playwright retries in CI
OgnjenGligoric Jun 23, 2026
ac8815a
Separating DOTBOT_PROJECT_ROOT and DOTBOT_STATE_ROOT
kabaogluemre Jun 23, 2026
ae7bdae
fix(product-api): surface pending-review worktree artifacts on Produc…
IBondarenko-iwg Jun 23, 2026
69f65d5
fix: address pwsh-review
IBondarenko-iwg Jun 23, 2026
fa15cdc
fix(worktree): claim non-prompt tasks before worktree creation to pre…
IBondarenko-iwg Jun 25, 2026
fb1e8c0
fix(worktree): prevent zombie worktree and map leak on partial cleanu…
IBondarenko-iwg Jun 25, 2026
9f4f705
Merge pull request #527 from kabaogluemre/fix/515-mcp-preflight-proje…
carlospedreira Jun 25, 2026
f34d375
Merge pull request #532 from OgnjenGligoric/fix/487-notify-pr-fork-di…
carlospedreira Jun 25, 2026
496889e
Merge pull request #533 from OgnjenGligoric/fix/484-playwright-flaky-…
carlospedreira Jun 25, 2026
bedc896
fix(worktree): remove dead Get-NextWorkflowTask fetch from claim-guar…
IBondarenko-iwg Jun 25, 2026
667cfb4
test(ProductAPI): fix pending-worktree raw fallback test assertion
IBondarenko-iwg Jun 25, 2026
c60145f
test: fix SVG content mismatch in pending-worktree raw fallback test
IBondarenko-iwg Jun 25, 2026
484c818
Merge pull request #534 from IBondarenko-iwg/fix/519-pending-review-p…
carlospedreira Jun 26, 2026
24a05a5
Merge pull request #531 from kabaogluemre/fix/518-output-delta-resume…
carlospedreira Jun 26, 2026
b07b533
fix(task-input): own interview answers on task (#516)
kabaogluemre Jun 26, 2026
afe3131
Merge pull request #540 from IBondarenko-iwg/fix/536-non-atomic-task-…
carlospedreira Jun 26, 2026
6c93b58
fix(worktree): gate filesystem-delete fallback on junction teardown
IBondarenko-iwg Jun 26, 2026
4f99827
fix: address pwsh-review
IBondarenko-iwg Jun 26, 2026
03f5eab
Merge pull request #541 from IBondarenko-iwg/fix/537-orphan-worktree-…
carlospedreira Jun 26, 2026
9c757bf
fix(process): dep-gated conditions + barriers wait for spawned childr…
IBondarenko-iwg Jul 2, 2026
bd6c0aa
fix(ci): PR-based bump-release and repair v4 release pipeline (#567)
EnmaJim Jul 2, 2026
46bdc26
fix(worktree): classify orphan unrelated-history merge conflicts (#570)
IBondarenko-iwg Jul 2, 2026
623b965
chore(release): bump version to v4.0.1 (#577)
aselim31 Jul 3, 2026
79e1a4d
fix(runtime): verify-hook-blocked done escalates to needs-input (#571)
IBondarenko-iwg Jul 3, 2026
2702d2e
docs(worktree): note unrelated_history in conflict_files comment (cop…
IBondarenko-iwg Jul 3, 2026
ac57899
fix(runtime): type-guard breadcrumb write + truncate hook message (co…
IBondarenko-iwg Jul 3, 2026
ebf2c7e
docs: update README lifecycle docs for single-session task execution
aselim31 Jul 6, 2026
ea9c9ee
docs: add release notes for v4.0.1 (closes #580) (#583)
aselim31 Jul 6, 2026
716afc7
Merge pull request #573 from IBondarenko-iwg/fix/569-manifest-conditi…
carlospedreira Jul 6, 2026
9504137
fix(workflow): recipe resolver + output path normalize (#568)
IBondarenko-iwg Jul 6, 2026
ab11eb6
docs: update ROADMAP-RELEASES.md to reflect v4.0.1 deliverables
aselim31 Jul 6, 2026
3213ce9
feat(registry): registry remove command and auto-update
OgnjenGligoric Jul 7, 2026
43253e0
Merge pull request #578 from IBondarenko-iwg/fix/570-orphan-worktree-…
carlospedreira Jul 7, 2026
60b56ce
Merge pull request #579 from IBondarenko-iwg/fix/571-verify-hook-done…
carlospedreira Jul 7, 2026
5469202
fix(repo-clone): stop leaking ADO PAT + tolerant Jira-key parser (#566)
IBondarenko-iwg Jul 7, 2026
54db91a
docs: add dotbot v4 framework overview document
aselim31 Jul 7, 2026
11c03a6
fix(process): correct inverted priority sort in Get-NextWorkflowTask
IBondarenko-iwg Jul 8, 2026
754a374
Merge pull request #616 from IBondarenko-iwg/fix/613-get-next-workflo…
carlospedreira Jul 8, 2026
28047d1
feat(ci): auto-close linked issues on release-branch merge
IBondarenko-iwg Jul 8, 2026
16222cc
feat(ci): auto-close linked issues on release-branch merge
carlospedreira Jul 9, 2026
4978f75
chore(release): bump version to v4.0.2 (#626)
aselim31 Jul 10, 2026
43e7174
docs: add release notes for v4.0.2 (closes #627)
aselim31 Jul 10, 2026
573f992
Merge pull request #629 from andresharpe/docs/v4.0.2-release-notes
carlospedreira Jul 10, 2026
ae2e50e
fix(process): pin process-state writes to canonical BotRoot, not work…
emrahzunicaplab Jul 11, 2026
9542027
feat(ui): navigation shell CSS, review harness & shared-CSS serving (…
IBondarenko-iwg Jul 8, 2026
2718364
feat(events): add Publish-DotBotEvent with extensible event-type regi…
EnmaJim Jul 7, 2026
2b7f8dc
feat(events): surface task.* and workflow.* lifecycle as dotted bus e…
EnmaJim Jul 7, 2026
05a4689
feat(events): emit workflow.run terminal events on the bus
EnmaJim Jul 7, 2026
0fd029f
feat(events): add events settings section with sink flags and webhooks
EnmaJim Jul 7, 2026
79c32f8
feat(events): add Dotbot.Events module with folder-per-plugin sink di…
EnmaJim Jul 7, 2026
c33d724
feat(events): add non-aborting time-boxed sink dispatch
EnmaJim Jul 7, 2026
0c41290
feat(events): add background consumer with persisted byte cursor
EnmaJim Jul 8, 2026
b94652e
feat(events): host the event consumer in the runtime lifecycle
EnmaJim Jul 8, 2026
fbd2ccd
feat(events): add webhooks sink with HTTPS, HMAC and SSRF guard
EnmaJim Jul 8, 2026
08181c8
feat(events): add gated no-op mothership sink and thread full setting…
EnmaJim Jul 8, 2026
2835a87
feat(events): drive aether from task.* events, drop /api/state diffing
EnmaJim Jul 8, 2026
2e12d62
feat(ui): render v4 shell in Outpost control panel
IBondarenko-iwg Jul 9, 2026
2f3a1cd
feat(ui): retire Outpost header/tab-bar/footer chrome CSS
IBondarenko-iwg Jul 9, 2026
e64e1d9
feat(server): render dashboard inside v4 shell via _LayoutDashboard
IBondarenko-iwg Jul 9, 2026
739090e
test(e2e): target shell rail and wait for app-ready signal
IBondarenko-iwg Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 107 additions & 7 deletions .github/workflows/bump-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ on:

permissions:
contents: write
pull-requests: write

jobs:
bump:
name: Bump version and tag
name: Open version-bump PR
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Install PowerShell
Expand All @@ -29,8 +31,28 @@ jobs:
sudo apt-get update && sudo apt-get install -y powershell
fi

- name: Check for changes since last release
id: gate
shell: bash
run: |
LAST_TAG="$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 || true)"
if [ -z "$LAST_TAG" ]; then
echo "No prior version tag found — treating as releasable."
echo "release=true" >> "$GITHUB_OUTPUT"
exit 0
fi
COUNT="$(git rev-list "${LAST_TAG}..HEAD" --count)"
echo "Last tag: $LAST_TAG — $COUNT commit(s) since."
if [ "${{ github.event_name }}" = "schedule" ] && [ "$COUNT" -eq 0 ]; then
echo "Nothing merged since $LAST_TAG — nothing to release."
echo "release=false" >> "$GITHUB_OUTPUT"
else
echo "release=true" >> "$GITHUB_OUTPUT"
fi

- name: Bump version
id: bump
if: steps.gate.outputs.release == 'true'
shell: pwsh
run: |
$bump = "${{ github.event.inputs.bump || 'patch' }}"
Expand All @@ -43,16 +65,94 @@ jobs:
'patch' { $parts[2] = [int]$parts[2] + 1 }
}
$new = $parts -join '.'

$existingTag = git tag --list "v$new"
if ($existingTag) {
Write-Error "Tag v$new already exists — aborting to avoid a duplicate release."
exit 1
}
$existingBranch = git ls-remote --heads origin "release/v$new"
if ($existingBranch) {
Write-Error "Branch release/v$new already exists on origin — aborting."
exit 1
}

@{ version = $new } | ConvertTo-Json | Set-Content $versionFile
Write-Host "Bumped $current -> $new ($bump)"
"version=$new" >> $env:GITHUB_OUTPUT

- name: Commit and tag
- name: Promote CHANGELOG Unreleased block
id: changelog
if: steps.gate.outputs.release == 'true'
shell: pwsh
run: |
$version = "${{ steps.bump.outputs.version }}"
$date = (Get-Date).ToString('yyyy-MM-dd')
$path = "CHANGELOG.md"
$lines = Get-Content $path

$anchor = ($lines | Select-String -Pattern '^## \[Unreleased\]' -SimpleMatch:$false | Select-Object -First 1)
if (-not $anchor) {
Write-Error "No '## [Unreleased]' section found in $path"
exit 1
}
$idx = $anchor.LineNumber - 1
$bodyStart = $idx + 1
$next = $lines.Length
for ($i = $bodyStart; $i -lt $lines.Length; $i++) {
if ($lines[$i] -match '^## \[') { $next = $i; break }
}

$notes = ($lines[$bodyStart..($next - 1)] -join "`n").Trim()
$hasContent = $notes -split "`n" | Where-Object { $_ -notmatch '^\s*(#{2,6}\s|$)' }
if (-not $hasContent) {
$notes = "Maintenance release."
}
Set-Content -Path "release-notes.md" -Value $notes

$scaffold = @(
'## [Unreleased]',
'',
'### Added',
'',
'### Changed',
'',
'### Fixed',
'',
'### Removed',
'',
"## [$version] - $date"
)

$rebuilt = @()
$rebuilt += $lines[0..($idx - 1)]
$rebuilt += $scaffold
$rebuilt += $lines[$bodyStart..($lines.Length - 1)]
Set-Content -Path $path -Value $rebuilt
Write-Host "Promoted [Unreleased] -> [$version] - $date"

- name: Create branch, commit, open PR
if: steps.gate.outputs.release == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
set -euo pipefail
VERSION="${{ steps.bump.outputs.version }}"
BRANCH="release/v${VERSION}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add version.json
git commit -m "Bump version to v${VERSION}"
git tag "v${VERSION}"
git push origin main --tags
git checkout -b "$BRANCH"
git add version.json CHANGELOG.md
git commit -m "chore(release): bump version to v${VERSION}"
git push -u origin "$BRANCH"
{
cat release-notes.md
printf '\n\n---\n_Merging this PR cuts v%s — **Release & Publish** runs automatically on merge._\n' "$VERSION"
} > pr-body.md
gh pr create \
--base main \
--head "$BRANCH" \
--title "chore(release): v${VERSION}" \
--body-file pr-body.md \
--label no-issue
2 changes: 1 addition & 1 deletion .github/workflows/notify-pr.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: "Notify: PR activity → #pull-requests"

on:
pull_request:
pull_request_target:
types: [opened, ready_for_review, closed]

permissions:
Expand Down
62 changes: 62 additions & 0 deletions .github/workflows/release-autoclose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: "Auto-close linked issues (release branches)"

on:
# pull_request_target: token can close issues from fork PRs; no checkout.
pull_request_target:
types: [closed]
branches:
- 'releases/**'

permissions:
issues: write

jobs:
close-linked:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Close linked issues
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const base = pr.base.ref;
const body = pr.body || '';

// Same keywords as pr-link-check.yml; bare same-repo #N only.
const re = /(?:closes|fixes|resolves):?\s+#(\d+)/gi;
const numbers = [...new Set([...body.matchAll(re)].map(m => Number(m[1])))];

if (numbers.length === 0) {
core.info('No linked issues found in PR body.');
return;
}

for (const issue_number of numbers) {
try {
const { data: issue } = await github.rest.issues.get({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
});
if (issue.pull_request) { core.info(`#${issue_number} is a PR, skipping.`); continue; }
if (issue.state === 'closed') { core.info(`#${issue_number} already closed, skipping.`); continue; }

await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
body: `Closed via #${pr.number} (merged to \`${base}\`).`,
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number,
state: 'closed',
state_reason: 'completed',
});
core.info(`Closed #${issue_number}.`);
} catch (err) {
core.warning(`Failed to close #${issue_number}: ${err.message}`);
}
}
Loading
Loading