# status maintenance via letta-backed agent # # two-phase workflow: # 1. workflow_dispatch: runs letta-backed script to archive, generate audio, open PR # 2. on PR merge: uploads audio to plyr.fm # # the letta agent maintains persistent memory across runs, remembering: # - previous status updates and their content # - architectural decisions and patterns # - recurring themes in development # # required secrets: # LETTA_API_KEY - letta cloud API key (for persistent memory) # ANTHROPIC_API_KEY - anthropic API key (for claude) # GOOGLE_API_KEY - gemini TTS (for audio generation) # PLYR_BOT_TOKEN - plyr.fm developer token (for audio upload) name: status maintenance on: # TODO: restore schedule after testing # schedule: # - cron: "0 9 * * 1" # every monday 9am UTC workflow_dispatch: inputs: skip_audio: description: "skip audio generation" type: boolean default: false dry_run: description: "dry run (no file changes)" type: boolean default: false pull_request: types: [closed] branches: [main] jobs: # phase 1: run letta-backed maintenance script + open PR maintain: if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: astral-sh/setup-uv@v4 - name: Run letta-backed status maintenance id: maintenance run: | ARGS="" if [ "${{ inputs.skip_audio }}" = "true" ]; then ARGS="$ARGS --skip-audio" fi if [ "${{ inputs.dry_run }}" = "true" ]; then ARGS="$ARGS --dry-run" fi uv run scripts/status_maintenance.py $ARGS # check if files were modified if [ -f .modified_files ]; then echo "files_modified=true" >> $GITHUB_OUTPUT else echo "files_modified=false" >> $GITHUB_OUTPUT fi env: LETTA_API_KEY: ${{ secrets.LETTA_API_KEY }} ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - name: Create PR if: steps.maintenance.outputs.files_modified == 'true' && inputs.dry_run != true run: | # generate unique branch name BRANCH="status-maintenance-$(date +%Y%m%d-%H%M%S)" # configure git git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" # create branch and commit git checkout -b "$BRANCH" git add .status_history/ STATUS.md update.wav 2>/dev/null || true git add -A # catch any other changes # check if there are changes to commit if git diff --cached --quiet; then echo "No changes to commit" exit 0 fi git commit -m "chore: status maintenance (letta-backed) 🤖 Generated with letta-backed status agent " git push -u origin "$BRANCH" # create PR gh pr create \ --title "chore: status maintenance - $(date +'%B %d, %Y')" \ --body "## automated status maintenance this PR was generated by the letta-backed status maintenance agent. ### what's included - STATUS.md updates (if any changes were detected) - archived content moved to .status_history/ (if needed) - update.wav podcast audio (if audio generation was enabled) ### letta memory the agent maintains persistent memory across runs, improving context and consistency over time. --- 🤖 generated by status-maintenance workflow" \ --label "ai-generated" || gh label create "ai-generated" --description "Generated by AI" && gh pr create \ --title "chore: status maintenance - $(date +'%B %d, %Y')" \ --body "automated status maintenance PR" \ --label "ai-generated" env: GH_TOKEN: ${{ github.token }} # phase 2: upload audio after PR merge upload-audio: if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'status-maintenance-') runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v4 - name: Upload audio to plyr.fm run: | if [ ! -f update.wav ]; then echo "No update.wav found, skipping upload" exit 0 fi # check existing tracks to determine episode number EXISTING=$(uv run --with plyrfm -- plyrfm my-tracks --limit 50 2>/dev/null || echo "") TODAY=$(date +'%B %d, %Y') YEAR=$(date +%Y) # count how many "plyr.fm update - {date}" tracks exist for today TODAY_COUNT=$(echo "$EXISTING" | grep -c "plyr.fm update - $TODAY" || echo "0") if [ "$TODAY_COUNT" -gt 0 ]; then # already have one today, add episode number EPISODE=$((TODAY_COUNT + 1)) TITLE="plyr.fm update - $TODAY (#$EPISODE)" else TITLE="plyr.fm update - $TODAY" fi echo "Uploading as: $TITLE" uv run --with plyrfm -- plyrfm upload update.wav "$TITLE" --album "$YEAR" -t '["ai"]' env: PLYR_TOKEN: ${{ secrets.PLYR_BOT_TOKEN }}