Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
a86677c
Update README with image and enhanced description
dzianisv Dec 27, 2025
29ef10d
Update readme.md
dzianisv Dec 27, 2025
8e133a9
Update readme.md
dzianisv Dec 27, 2025
d992463
Update README.md
dzianisv Dec 27, 2025
a85130e
fix: improve feedback logging and ensure incomplete tasks receive gui…
dzianisv Dec 27, 2025
ee5c276
feat: always provide reflection feedback and send completion confirma…
dzianisv Dec 27, 2025
49a410a
feat: replace console.log with OpenCode toast notifications for clean…
dzianisv Dec 27, 2025
bb8517e
docs: add detailed OpenCode API usage and technical implementation to…
dzianisv Dec 27, 2025
c2eb1ba
docs: add comprehensive installation, restart, and update instructions
dzianisv Dec 27, 2025
834fe87
The reflection plugin code is updated correctly with:
dzianisv Dec 28, 2025
c7c5279
fix: add cooldown to prevent infinite reflection loops
dzianisv Dec 28, 2025
4809c93
fix: prevent infinite loop by not calling prompt() on complete tasks
dzianisv Dec 30, 2025
172c77d
fix: mark sessions completed BEFORE async ops to prevent race conditions
dzianisv Dec 30, 2025
cc14a12
fix: detect judge sessions by content to prevent cross-process loops
dzianisv Dec 30, 2025
5263472
refactor: simplify plugin, remove all console.log
dzianisv Dec 30, 2025
3250673
Fix: Deploy to ~/.config/opencode/plugin/, not npm global
dzianisv Dec 30, 2025
643422f
feat: add TTS plugin for macOS text-to-speech
dzianisv Jan 2, 2026
116035d
docs: update README with unified installation for all plugins
dzianisv Jan 2, 2026
be734e1
fix: skip reflection on user-cancelled sessions (Esc key)
dzianisv Jan 2, 2026
615a6ff
feat(tts): add /tts command to toggle voice on/off with persistent co…
dzianisv Jan 3, 2026
c1efce3
fix(tts): use shell script for /tts command toggle instead of broken …
dzianisv Jan 3, 2026
c7131bf
feat(tts): add Chatterbox neural TTS engine with CPU/GPU support
dzianisv Jan 3, 2026
b6d6a81
fix(tts): remove console.log, fix Chatterbox CPU mode caching issue
dzianisv Jan 3, 2026
6096a66
feat(tts): add OS voice config, server mode for faster Chatterbox inf…
dzianisv Jan 3, 2026
f24e12b
docs: update README with OS TTS default, server mode, speed comparison
dzianisv Jan 3, 2026
3d1ac3a
docs: add optional TTS config with MPS optimization for Apple Silicon
dzianisv Jan 8, 2026
d432d99
feat(tts): add server locking to share Chatterbox across sessions
dzianisv Jan 8, 2026
0edee4b
docs: update README and AGENTS.md with shared server architecture
dzianisv Jan 8, 2026
7107ebf
fix(tts): support MPS device in isChatterboxAvailable check
dzianisv Jan 8, 2026
e28be32
fix(tts): add MPS support to embedded Python scripts
dzianisv Jan 8, 2026
a63c244
test(tts): add E2E integration test for Chatterbox MPS
dzianisv Jan 9, 2026
d4073cd
What was changed:
dzianisv Jan 11, 2026
b3bc6ab
1. Bark model: Was incorrectly using speaker=args.bark_voice with a p…
dzianisv Jan 11, 2026
863805b
Testing Results …
dzianisv Jan 11, 2026
46745be
Add Jenny TTS model support and cross-process speech queue
dzianisv Jan 11, 2026
f16e1d2
Integrate speech queue into speak() function
dzianisv Jan 11, 2026
00eed45
Auto-delete judge sessions to prevent clutter in /session list
dzianisv Jan 11, 2026
cce9d0c
Summary
dzianisv Jan 13, 2026
d85d3b9
1. Fixed Session Tracking Issue (Original Bug)
dzianisv Jan 13, 2026
cb2289a
feat: Telegram two-way communication with voice message support (#2)
dzianisv Jan 24, 2026
54176cf
docs: Add plugin readiness playbook with health check instructions
dzianisv Jan 24, 2026
6786901
fix: test infrastructure and TypeScript configuration (#5)
dzianisv Jan 24, 2026
3c9e102
fix(docs): add --no-verify-jwt flag to telegram-webhook deployment
dzianisv Jan 25, 2026
e32654b
fix: add tool property to plugins for Plugin interface compliance (#7)
dzianisv Jan 25, 2026
c25ce26
feat: add worktree-status plugin for git state monitoring (#9)
dzianisv Jan 25, 2026
93050cc
feat: restructure skills to agentskills.io spec and fix Supabase RLS …
dzianisv Jan 25, 2026
d433dbe
feat: SEO optimization, CI/CD pipeline, and Telegram reply fixes
dzianisv Jan 25, 2026
c82ea9f
fix(ci): deploy only functions on push, fix db push command
dzianisv Jan 25, 2026
caef4a9
docs: add feature development workflow skill
dzianisv Jan 25, 2026
1cf910d
ci: add test workflow for unit tests and typecheck
dzianisv Jan 25, 2026
6a2685a
fix(types): align plugins with @opencode-ai/plugin types
dzianisv Jan 25, 2026
cb60885
docs: update README with worktree-status plugin and telegram.ts helpe…
dzianisv Jan 25, 2026
7b17d2f
docs: update repo URLs from opencode-reflection-plugin to opencode-pl…
dzianisv Jan 25, 2026
7e0400e
feat(reflection): nudge stuck agent after compression and reflection …
dzianisv Jan 26, 2026
2f32795
fix: increase reflection retries to 16 and fix compression nudge race…
dzianisv Jan 26, 2026
5f50eed
fix: include telegram.ts and worktree-status.ts in install:global script
dzianisv Jan 26, 2026
f810c80
fix: add type guard to telegram.ts and remove from plugin deployment
dzianisv Jan 26, 2026
f4e44b0
docs: add honest assessment of TTS/Telegram testing limitations
dzianisv Jan 26, 2026
f16f0d9
fix: add auth header to Telegram notifications and improve delegation…
dzianisv Jan 26, 2026
b15ece0
feat: add Telegram reaction updates for message delivery status
dzianisv Jan 26, 2026
482fcf8
I found two bugs causing the VibeProductPage session to get stuck aft…
dzianisv Jan 26, 2026
d04cde1
fix: use valid Telegram reaction emoji and skip subagent sessions
dzianisv Jan 26, 2026
9dae895
test: add automated tests for Telegram reply bug fixes
dzianisv Jan 26, 2026
f629cc6
test: replace flaky E2E test with reliable integration tests
dzianisv Jan 26, 2026
74e6a50
test: add real E2E test for Telegram reply flow
dzianisv Jan 26, 2026
145c5ab
refactor: remove useless pattern-matching tests, keep only real tests
dzianisv Jan 26, 2026
c3e3c31
test: add E2E test verifying Telegram replies are forwarded to OpenCo…
dzianisv Jan 26, 2026
6ef0635
test: add webhook simulation test for full Telegram reply flow
dzianisv Jan 26, 2026
a646a08
feat: TTS waits for reflection verdict, fix Esc abort race condition …
dzianisv Jan 27, 2026
3b75519
test: add comprehensive abort race condition tests and manual verific…
dzianisv Jan 27, 2026
5bf8fd5
fix: skip feedback when agent awaits user input, improve abort detection
dzianisv Jan 27, 2026
11d802d
feat(telegram): session-aware reply routing using native Reply featur…
dzianisv Jan 27, 2026
2984aac
fix(reflection): use original task for evaluation, not last message (…
dzianisv Jan 27, 2026
9f57a1a
fix(reflection): use ALL human messages for evaluation, not just firs…
dzianisv Jan 27, 2026
025b088
fix(telegram): text messages not sent due to markdown parsing errors …
dzianisv Jan 27, 2026
2889e3e
fix(telegram): auto-reconnect Realtime subscription and recover misse…
dzianisv Jan 28, 2026
0d31fbc
fix(reflection): detect and nudge stuck agent after tool call or comp…
dzianisv Jan 28, 2026
edff21d
feat(reflection): use GenAI for stuck detection instead of static heu…
dzianisv Jan 28, 2026
ada0bd8
feat(reflection): use GenAI for intelligent post-compression nudges (…
dzianisv Jan 28, 2026
243396b
fix(telegram): track failed reply deliveries when session no longer e…
dzianisv Jan 28, 2026
d5c15b1
feat: add promptfoo evaluation framework for GenAI functions (#39)
dzianisv Jan 28, 2026
2d9357f
feat(evals): add human-action-required test cases for task verificati…
dzianisv Jan 29, 2026
d653083
feat(eval): add E2E evaluation script with LLM-as-judge
dzianisv Jan 29, 2026
7513132
docs(agents): add task completion requirements based on 164 session a…
dzianisv Jan 29, 2026
f33359f
Update reflection plugin to be read-only
dzianisv Jan 29, 2026
d143e75
feat(tts): add /tts command for mute/toggle control
dzianisv Jan 29, 2026
74b1e50
feat(tts): add instant /tts command via command.execute.before hook
dzianisv Jan 29, 2026
8d3aa12
feat(evals): improve judge accuracy to 100% pass rate
dzianisv Jan 29, 2026
1d46420
fix(eval): make E2E test cases self-contained
dzianisv Jan 29, 2026
ae462c5
fix(telegram): add null guards and proper deployment structure
dzianisv Jan 30, 2026
056503e
test(telegram): add regression tests for config null guard and conver…
dzianisv Jan 30, 2026
50e622e
feat: worktree delegation and global tts stop
dzianisv Jan 30, 2026
33423bb
feat(telegram): add Whisper voice transcription with /transcribe-base…
dzianisv Jan 31, 2026
6297540
feat(reflection): add configurable prompts per-project and per-query
dzianisv Jan 31, 2026
8e02363
fix(telegram,tts): fix Whisper endpoint and switch to Coqui VCTK mode…
dzianisv Feb 7, 2026
e38d945
feat: add reflection-static plugin with simpler self-assessment approach
dzianisv Feb 7, 2026
412aa85
fix: prevent reflection spam on Esc abort, use real Azure eval
dzianisv Feb 7, 2026
618d227
fix: use override:true for dotenv to ensure correct Azure credentials
dzianisv Feb 7, 2026
87ec5da
fix: improve abort detection with cooldown-based tracking
dzianisv Feb 7, 2026
014c1d8
feat: add reflection-static plugin with simpler self-assessment appro…
dzianisv Feb 7, 2026
6744fcf
fix(telegram): deploy telegram.ts as plugin, fix isSessionComplete
dzianisv Feb 8, 2026
0b0a091
fix(telegram): non-blocking init, Whisper endpoint, consolidated tests
dzianisv Feb 8, 2026
ec5b71a
feat(github): add GitHub issue integration plugin
dzianisv Feb 8, 2026
f81d079
docs: add GitHub issue plugin documentation to AGENTS.md
dzianisv Feb 8, 2026
5c93411
Merge origin/main into feat/reflection-static-plugin
dzianisv Feb 8, 2026
d6580f3
Merge pull request #44 from dzianisv/feat/reflection-static-plugin
dzianisv Feb 8, 2026
5660c4a
Update README with new plugin descriptions
dzianisv Feb 8, 2026
475e528
feat(reflection-static): fix Plan Mode detection and add custom promp…
dzianisv Feb 9, 2026
514ca12
fix(test): add timeouts to flaky Telegram webhook tests
Feb 9, 2026
9c60a59
fix(telegram): remove _test_internal export that broke plugin loading
Feb 10, 2026
b18c50c
feat(worktree): use opencode attach for persistent multi-session deve…
Feb 10, 2026
d64ee4f
feat(worktree): auto-start opencode serve if not running
Feb 10, 2026
cab8a52
fix(reflection-static): prevent stale prompts when human types during…
Feb 10, 2026
36997a2
fix(reflection): prevent stale prompts when human types during judge …
Feb 10, 2026
76185a2
fix(tts,telegram,reflection-static): wait for reflection verdict befo…
Feb 10, 2026
eb6a6a8
feat(reflection-static): add judge model failover via reflection.yaml
Feb 10, 2026
e58b10b
fix(reflection): improve plan mode and route feedback
Feb 11, 2026
b0a454a
fix(reflection-static): rely on mode metadata
Feb 11, 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
4 changes: 4 additions & 0 deletions .eval-tmp/opencode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://opencode.ai/config.json",
"model": "github-copilot/gpt-4o"
}
55 changes: 55 additions & 0 deletions .github/workflows/deploy-supabase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Deploy Supabase

on:
push:
branches:
- main
- master
paths:
- 'supabase/**'
- '.github/workflows/deploy-supabase.yml'
workflow_dispatch:
inputs:
deploy_target:
description: 'What to deploy'
required: true
default: 'all'
type: choice
options:
- all
- functions
- migrations

jobs:
deploy:
name: Deploy to Supabase
runs-on: ubuntu-latest

env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_PROJECT_REF: ${{ secrets.SUPABASE_PROJECT_REF || 'slqxwymujuoipyiqscrl' }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DB_PASSWORD }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Supabase CLI
uses: supabase/setup-cli@v1
with:
version: latest

- name: Verify Supabase CLI
run: supabase --version

- name: Deploy (push event)
if: github.event_name == 'push'
run: ./scripts/deploy-supabase.sh functions

- name: Deploy (manual trigger)
if: github.event_name == 'workflow_dispatch'
run: ./scripts/deploy-supabase.sh ${{ inputs.deploy_target }}

- name: List deployed functions
run: |
supabase functions list --project-ref "$SUPABASE_PROJECT_REF"
155 changes: 155 additions & 0 deletions .github/workflows/evals.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: Prompt Evaluations

on:
# Run on PRs to validate prompt quality
pull_request:
branches:
- main
- master
paths:
- 'reflection.ts'
- 'evals/**'
# Manual trigger for full evaluation
workflow_dispatch:
inputs:
eval_type:
description: 'Which evaluation to run'
required: true
default: 'all'
type: choice
options:
- all
- judge
- stuck
- compression

permissions:
contents: read
pull-requests: write

jobs:
evaluate:
name: Run Prompt Evaluations
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Create results directory
run: mkdir -p evals/results

- name: Run Judge Evaluation
if: ${{ github.event.inputs.eval_type == 'all' || github.event.inputs.eval_type == 'judge' || github.event_name == 'pull_request' }}
env:
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
run: npm run eval:judge -- --no-progress-bar -o evals/results/judge-results.json
continue-on-error: true

- name: Run Stuck Detection Evaluation
if: ${{ github.event.inputs.eval_type == 'all' || github.event.inputs.eval_type == 'stuck' }}
env:
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
run: npm run eval:stuck -- --no-progress-bar -o evals/results/stuck-results.json
continue-on-error: true

- name: Run Post-Compression Evaluation
if: ${{ github.event.inputs.eval_type == 'all' || github.event.inputs.eval_type == 'compression' }}
env:
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
run: npm run eval:compression -- --no-progress-bar -o evals/results/compression-results.json
continue-on-error: true

- name: Upload Evaluation Results
uses: actions/upload-artifact@v4
with:
name: eval-results
path: evals/results/*.json
retention-days: 30

- name: Generate Summary
run: |
echo "## Prompt Evaluation Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

for file in evals/results/*.json; do
if [ -f "$file" ]; then
name=$(basename "$file" .json)
echo "### $name" >> $GITHUB_STEP_SUMMARY

# Extract pass/fail counts using node
node -e "
const fs = require('fs');
const data = JSON.parse(fs.readFileSync('$file', 'utf-8'));
const results = data.results || [];
const passed = results.filter(r => r.success).length;
const failed = results.filter(r => !r.success).length;
const total = results.length;
const passRate = total > 0 ? ((passed / total) * 100).toFixed(1) : 0;
console.log('- Total tests: ' + total);
console.log('- Passed: ' + passed);
console.log('- Failed: ' + failed);
console.log('- Pass rate: ' + passRate + '%');
" >> $GITHUB_STEP_SUMMARY 2>/dev/null || echo "- Could not parse results" >> $GITHUB_STEP_SUMMARY

echo "" >> $GITHUB_STEP_SUMMARY
fi
done

- name: Comment on PR
if: github.event_name == 'pull_request'
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');

const resultsDir = 'evals/results';
if (!fs.existsSync(resultsDir)) {
console.log('No results directory found, skipping comment');
return;
}

const files = fs.readdirSync(resultsDir).filter(f => f.endsWith('.json'));
if (files.length === 0) {
console.log('No result files found, skipping comment');
return;
}

let summary = '## Prompt Evaluation Results\n\n';

for (const file of files) {
try {
const data = JSON.parse(fs.readFileSync(path.join(resultsDir, file), 'utf-8'));
const results = data.results || [];
const passed = results.filter(r => r.success).length;
const total = results.length;
const passRate = total > 0 ? ((passed / total) * 100).toFixed(1) : 0;
const icon = passRate >= 80 ? '✅' : passRate >= 50 ? '⚠️' : '❌';

summary += `### ${icon} ${file.replace('.json', '')}\n`;
summary += `- Pass rate: **${passRate}%** (${passed}/${total})\n\n`;
} catch (e) {
summary += `### ❓ ${file}\n- Could not parse results\n\n`;
}
}

await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: summary
});
35 changes: 35 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Tests

on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master

jobs:
test:
name: Run Tests
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run type check
run: npm run typecheck

- name: Run unit tests
run: npm test
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
.tts
.reflection
.opencode/
node_modules/
__pycache__/
*.log
.DS_Store
.env

# Build artifacts
*.js
!jest.config.js
*.js.map
*.d.ts

# Test artifacts
fixtures/
test/mocks/

# Promptfoo eval results
evals/results/
evals/evals/
Loading