Skip to content

feat: OpenCode server docs, privacy filter, and self-improving agents (t115, t116, t117)#302

Merged
marcusquinn merged 3 commits intomainfrom
feature/opencode-server-docs
Feb 4, 2026
Merged

feat: OpenCode server docs, privacy filter, and self-improving agents (t115, t116, t117)#302
marcusquinn merged 3 commits intomainfrom
feature/opencode-server-docs

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 4, 2026

Summary

This PR implements three related tasks from the self-improving agent system plan:

  • t115: OpenCode server subagent documentation
  • t117: Privacy filter for public PR contributions
  • t116: Self-improving agent system

Changes

OpenCode Server Documentation (t115)

  • Created tools/ai-assistants/opencode-server.md with comprehensive API docs
  • Covers server setup, SDK usage, session management, async prompts, SSE events
  • Includes aidevops integration patterns: parallel agents, voice dispatch, testing
  • TypeScript SDK examples and direct HTTP API reference

Privacy Filter (t117)

  • Created privacy-filter-helper.sh with scan/filter/apply/patterns commands
  • Detects 30+ privacy patterns (credentials, PII, internal URLs, paths)
  • Integrates with secretlint for comprehensive credential detection
  • Supports global and project-specific custom patterns
  • Created tools/security/privacy-filter.md documentation

Self-Improving Agent System (t116)

  • Created self-improve-helper.sh with analyze/refine/test/pr commands
  • Analyze phase: Query memory for failure patterns, identify gaps
  • Refine phase: Generate improvements via OpenCode session
  • Test phase: Validate proposals in isolated OpenCode sessions
  • PR phase: Create privacy-filtered PRs with evidence
  • Created aidevops/self-improving-agents.md documentation

Files Changed

.agent/tools/ai-assistants/opencode-server.md  (new)
.agent/tools/ai-assistants/overview.md         (updated)
.agent/tools/security/privacy-filter.md        (new)
.agent/scripts/privacy-filter-helper.sh        (new)
.agent/aidevops/self-improving-agents.md       (new)
.agent/scripts/self-improve-helper.sh          (new)
.agent/subagent-index.toon                     (updated)
TODO.md                                        (updated)

Testing

  • All markdown files pass markdownlint
  • Shell scripts pass shellcheck (minor warnings only)
  • Privacy filter tested with scan command
  • Self-improve helper tested with status command

Related

Summary by CodeRabbit

Release Notes

  • New Features

    • Self-improving agent system with four-phase workflow (analyze, refine, test, pr)
    • Privacy filter helper for scanning and redacting sensitive information from contributions
    • OpenCode server mode enabling programmatic API access and session management
  • Documentation

    • Comprehensive guides for self-improving agent configuration, privacy filtering patterns, and server integration

- Create tools/ai-assistants/opencode-server.md with comprehensive API docs
- Cover server setup, SDK usage, session management, async prompts, SSE events
- Include aidevops integration patterns: parallel agents, voice dispatch, testing
- Add TypeScript SDK examples and direct HTTP API reference
- Update subagent-index.toon with new opencode-server entry
- Update overview.md to reference server mode documentation
- Mark t115 as started in TODO.md

Closes #t115
- Create privacy-filter-helper.sh with scan/filter/apply/patterns commands
- Detect 30+ privacy patterns (credentials, PII, internal URLs, paths)
- Integrate with secretlint for comprehensive credential detection
- Support global (~/.aidevops/config/) and project (.aidevops/) patterns
- Create tools/security/privacy-filter.md documentation
- Update subagent-index.toon with new security folder and script
- Mark t117 as complete in TODO.md

This filter is mandatory before creating PRs to public repositories.
Used by the self-improving agent system (t116) in the PR phase.

Closes #t117
- Create self-improve-helper.sh with analyze/refine/test/pr commands
- Analyze phase: Query memory for failure patterns, identify gaps
- Refine phase: Generate improvements via OpenCode session
- Test phase: Validate proposals in isolated OpenCode sessions
- PR phase: Create privacy-filtered PRs with evidence
- Create aidevops/self-improving-agents.md documentation
- Update subagent-index.toon with new script and docs
- Mark t116 and all subtasks as complete in TODO.md

The self-improvement cycle enables aidevops to learn from failures,
generate improvements, test them in isolation, and contribute back
with privacy-safe PRs.

Closes #t116
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

Walkthrough

Introduces a comprehensive self-improving agent system with four-phase workflow (analyze, refine, test, PR), privacy-filtering helper for credential redaction, OpenCode server documentation, and supporting utilities. Includes new scripts, documentation, and configuration updates enabling autonomous code improvement with privacy safeguards.

Changes

Cohort / File(s) Summary
Agent Workflow Scripts
\.agent/scripts/self-improve-helper.sh, \.agent/scripts/privacy-filter-helper.sh
Two new Bash helper scripts: self-improve-helper.sh orchestrates the four-phase agent cycle (analyze, refine, test, pr) with OpenCode server integration, memory-driven analysis, and workspace management; privacy-filter-helper.sh provides scanning, preview, and redaction of sensitive data using Secretlint and regex patterns with support for custom pattern management.
Self-Improving Agent Documentation
\.agent/aidevops/self-improving-agents.md
New comprehensive guide detailing the ANALYZE → REFINE → TEST → PR architectural cycle, prerequisites, workspace layout, JSON-based artifact flow (analysis.json, proposals.json, test-results.json), environment configuration, usage examples, safety guardrails, and troubleshooting.
Privacy Filter Documentation & Configuration
\.agent/tools/security/privacy-filter.md
New documentation describing privacy filtering system for redacting credentials, personal data, internal URLs, and private keys. Covers pattern management, Secretlint integration, and troubleshooting for the privacy-filter-helper.sh utility.
OpenCode Server Documentation
\.agent/tools/ai-assistants/opencode-server.md, \.agent/tools/ai-assistants/overview.md
New OpenCode server mode documentation detailing HTTP API, TypeScript SDK, session lifecycle, SSE events, and TUI integration. Overview.md updated with reference to server mode capabilities.
Configuration & Task Tracking
\.agent/subagent-index.toon, TODO.md
Subagent index expanded to 36 entries with self-improving-agents capability and extended tooling ecosystem (pdf/, performance/, ui/, code-review/, context/, conversion/, video/, and new services). Scripts index updated to 29 with new privacy and self-improve helpers. TODO.md updated to mark t115–t117 tasks as completed with implementation details.

Sequence Diagram

sequenceDiagram
    participant Agent as Self-Improving Agent
    participant Mem as Memory System
    participant OC as OpenCode Server
    participant PF as Privacy Filter
    participant GH as GitHub/PR

    Agent->>Mem: ANALYZE: Query failure patterns<br/>& missing solutions
    Mem-->>Agent: Return analysis.json
    
    Agent->>OC: REFINE: Create session<br/>+ send proposals prompt
    OC-->>Agent: Generate proposals.json
    OC->>Agent: Close session
    
    Agent->>OC: TEST: Create session<br/>+ validate proposals
    OC-->>Agent: Return test-results.json
    OC->>Agent: Close session
    
    Agent->>PF: PR: Scan for sensitive data<br/>in evidence/code
    PF-->>Agent: Preview redactions
    
    Agent->>PF: Apply privacy filter
    PF-->>Agent: Redacted content
    
    Agent->>GH: Create privacy-filtered PR<br/>with attestation
    GH-->>Agent: PR created (privacy-safe)
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Poem

🚀 Self-improving loops now run free,
Privacy guards what none shall see,
From analyze to PR creation bright,
The agent learns and does right,
A cycle of growth—secure and fleet!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and comprehensively summarizes the three main features implemented: OpenCode server documentation, privacy filter functionality, and self-improving agents system, with explicit task references (t115, t116, t117).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/opencode-server-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the AI DevOps framework by introducing a self-improving agent system, ensuring privacy-safe contributions to public repositories, and providing detailed documentation for programmatic interaction with the OpenCode server. These additions aim to automate the continuous improvement cycle of agents, safeguard sensitive information during public contributions, and facilitate advanced AI orchestration and testing scenarios.

Highlights

  • OpenCode Server Documentation: Comprehensive documentation for the OpenCode server mode has been added, detailing its HTTP API, TypeScript SDK, session management, asynchronous prompts, SSE events, and various aidevops use cases like parallel agent orchestration and automated testing.
  • Privacy Filter for Public PRs: A new privacy filter system has been implemented, including a shell script and documentation. It detects and optionally redacts privacy-sensitive content such as credentials, PII, internal URLs, and private keys, integrating with Secretlint for enhanced detection.
  • Self-Improving Agent System: A self-improving agent system has been introduced, designed to learn from failures, generate improvements, test them in isolation using OpenCode sessions, and create privacy-filtered pull requests. This system operates through analyze, refine, test, and PR phases.
Changelog
  • .agent/aidevops/self-improving-agents.md
    • Added new documentation detailing the architecture, phases (analyze, refine, test, PR), prerequisites, configuration, usage examples, safety guardrails, memory integration, and scheduling for the self-improving agent system.
  • .agent/scripts/privacy-filter-helper.sh
    • Introduced a new shell script to scan for, preview, and apply redactions of privacy-sensitive content, supporting global and project-specific custom patterns and integrating with secretlint and ripgrep.
  • .agent/scripts/self-improve-helper.sh
    • Added a new shell script to orchestrate the self-improving agent system, providing commands for analyzing memory patterns, refining improvement proposals using OpenCode, testing changes in isolated sessions, and creating privacy-filtered pull requests.
  • .agent/subagent-index.toon
    • Updated the subagent index to register the new self-improving-agents documentation under aidevops/ and opencode-server under tools/ai-assistants/.
    • Added privacy-filter under tools/security/.
    • Registered the new privacy-filter-helper.sh and self-improve-helper.sh scripts.
  • .agent/tools/ai-assistants/opencode-server.md
    • Added new documentation for the OpenCode server mode, covering its HTTP API, TypeScript SDK, session management, asynchronous prompts, SSE events, and various aidevops use cases like parallel orchestration and automated testing.
  • .agent/tools/ai-assistants/overview.md
    • Updated to include a reference to the new opencode-server.md for programmatic API access to the OpenCode server.
  • .agent/tools/security/privacy-filter.md
    • Provided detailed documentation for the privacy filter, explaining its purpose, usage, detected patterns (credentials, PII, internal URLs, private keys), custom pattern management, and integration with self-improving agents and Git hooks.
  • TODO.md
    • Marked tasks t115 (OpenCode server docs), t116 (Self-improving agent system), and t117 (Privacy filter) as completed, including their sub-tasks.
    • Added actual time spent and completion timestamps for the completed tasks.
Activity
  • The OpenCode server subagent documentation (t115) was started and completed.
  • The Self-improving agent system (t116) was started and completed, including its analyze, refine, test, and PR phases.
  • The Privacy filter for public PRs (t117) was started and completed.
  • All three major features (t115, t116, t117) are now fully implemented and documented.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 4, 2026

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 409 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Feb 4 02:18:44 UTC 2026: Code review monitoring started
Wed Feb 4 02:18:45 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 409
Wed Feb 4 02:18:45 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Wed Feb 4 02:18:47 UTC 2026: Codacy analysis completed with auto-fixes
Wed Feb 4 02:18:48 UTC 2026: Applied 2 automatic fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 409
  • VULNERABILITIES: 0

Generated on: Wed Feb 4 02:20:11 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces impressive new capabilities with the self-improving agent system and a privacy filter, accompanied by comprehensive documentation. The shell scripts are well-structured and follow good practices. However, I've identified a critical issue in the privacy filter's pattern definitions that would cause it to fail silently for several important patterns. I've also noted a few other medium to high severity issues, including a discrepancy between documentation and implementation in the privacy filter, and fragile parsing logic in the self-improvement script. Addressing these points will significantly improve the robustness and reliability of these new features.

Comment on lines +233 to +234
# Exclude test fixtures
!test/fixtures/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The documentation suggests that paths can be excluded from scans by prefixing them with ! in .aidevops/privacy-patterns.txt. However, the privacy-filter-helper.sh script does not implement this exclusion logic; the load_custom_patterns function reads all non-comment lines as patterns to be detected. This discrepancy is misleading and could cause confusion when users try to handle false positives.

Comment on lines +237 to +239
else
mapfile -t files < <(find "$target" -type f -not -path '*/\.*' -not -path '*/node_modules/*' 2>/dev/null)
fi

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The comment on line 232 states that the file search respects .gitignore. While ripgrep (rg) does this, the fallback find command does not. It uses some -not -path arguments, but this is not as reliable as respecting .gitignore properly. This can lead to scanning files that should be ignored (e.g., build artifacts, logs), causing false positives and slower scans. Consider using git ls-files --cached --others --exclude-standard as a more reliable fallback for git repositories.


# Extract proposals from response
local proposals
proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null | grep -o '\[.*\]' | head -1 || echo "[]")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The method used to extract JSON proposals from the AI's response is fragile. It uses grep -o '\[.*\]' | head -1, which assumes the entire JSON array is on a single line and is not enclosed in a markdown code block (e.g., json ... ). If the LLM formats the JSON with newlines or wraps it in a code block, this parsing will likely fail or produce an incomplete result. A more robust parsing method that handles multi-line JSON and markdown code blocks should be used to improve reliability.

@marcusquinn marcusquinn merged commit 9f0e017 into main Feb 4, 2026
12 of 14 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Fix all issues with AI agents
In @.agent/aidevops/self-improving-agents.md:
- Around line 33-385: This doc embeds large step-by-step workflows and sample
outputs that should be replaced with high-level pointers to the authoritative
implementations; remove the long inline bash examples, outputs and
troubleshooting blocks and instead summarize the phase (Analyze, Refine, Test,
PR) and link to the actual scripts and artifacts (self-improve-helper.sh,
privacy-filter-helper.sh, memory-helper.sh, opencode serve, and workspace files
like analysis.json/proposals.json/test-results.json) and add file:line
references in the summary to the authoritative implementations so readers follow
the real code for details; keep only minimal examples that are authoritative and
move all commands, sample outputs and troubleshooting into the referenced
scripts/docs.

In @.agent/scripts/privacy-filter-helper.sh:
- Around line 175-206: run_secretlint currently treats any non-zero result from
the npx branch as "secretlint not available" and returns success; change the npx
fallback to first verify npx exists (e.g., command -v npx) and if absent
print_warning and return 0, but if npx is present run npx --yes secretlint
"$target" and treat a non-zero exit as a real failure (print_error "Secretlint:
Potential secrets found!" and return 1) instead of masking it as skipped; update
the npx branch in run_secretlint to explicitly distinguish "npx missing" vs
"scan failed" behaviors.
- Around line 326-399: apply_redactions currently uses sed per-pattern (breaking
on / delimiters and \b, and recreates backups per pattern); change it to use
ripgrep's replace to perform safe, delimiter-free replacements and create a
single backup per file: in apply_redactions (and the matches loop) detect if
command -v rg; for each file create its "${file}.privacy-backup" only once
(before any replacements) and then for replacement run a pipeline applying all
patterns via rg --passthru --replace (iteratively feed the file through rg
--passthru --replace -e "$pattern" --replace '[REDACTED]' into a temp file, or
construct a single stream of replacements) and atomically move the temp into
place; if rg is not available, fallback to perl -pe using s{pattern}[REDACTED}g
with proper escaping so / and \b work; ensure patterns from get_all_patterns are
quoted/handled safely and remove the per-pattern cp "$file"
"${file}.privacy-backup" so backup is only created once per file.

In @.agent/scripts/self-improve-helper.sh:
- Around line 39-46: The CYAN color constant (readonly CYAN='\033[0;36m') is
defined but unused; remove that line from the color definitions in
.agent/scripts/self-improve-helper.sh (the block containing GREEN, BLUE, YELLOW,
RED, PURPLE, CYAN, NC) so static analysis no longer flags an unused variable, or
alternatively use CYAN in any output helper function (e.g., the script's
logging/echo calls) if you prefer to keep it.
- Around line 281-334: The proposals extraction fails for multi-line JSON
because proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text")
| .text' 2>/dev/null | grep -o '\[.*\]' | head -1 || echo "[]") uses a
single-line grep and a greedy regex; change the extraction to parse the full
response with jq and validate with jq --exit-status to ensure JSON-only output:
call send_prompt as before, capture response, then use jq to locate and parse
the JSON array (e.g., filter .parts[][].text or assemble candidate strings) and
run jq . to validate; if validation fails, log the raw response and return
error; update the variable proposals and the error branch that checks proposals
(the log_warn block) to handle empty/invalid JSON returned by jq and to avoid
silent failures from grep.

In @.agent/tools/ai-assistants/opencode-server.md:
- Around line 90-473: The "TypeScript SDK" and subsequent long example sections
(e.g., headings "Creating a Client", "Session Management", "Sending Prompts",
"Direct HTTP API", and all numbered use-case examples) are too large for this
agent doc; replace the embedded TS/Bash/YAML blocks with short overview text and
explicit pointers to the authoritative examples and implementation (e.g., link
or repo reference to the SDK README and the server/example scripts), and move
the full code samples out to those canonical files; keep only a one-line minimal
snippet or CLI example where necessary and add "See: [authoritative doc or
file:line]" references for "createOpencode/createOpencodeClient", session
methods (session.create, session.prompt/promptAsync), event.subscribe, and the
CI YAML so readers are directed to the real source.

In @.agent/tools/security/privacy-filter.md:
- Around line 44-221: Collapse the long CLI walkthrough in
.agent/tools/security/privacy-filter.md (section starting at the Usage header
with many command examples) into a concise overview that points readers to the
actual implementation script .agent/scripts/privacy-filter-helper.sh with
file:line references for the relevant functions/flags (e.g., the scan, filter,
apply, patterns, and patterns add-project handlers inside
privacy-filter-helper.sh); remove the inline multi-line command blocks and
retain only one brief example for authoritative usage, plus explicit file:line
pointers to the helper script where the full commands and behavior live, and
ensure the "Integration with Self-Improving Agents" and "Git Hooks" sections
reference the specific functions/lines in privacy-filter-helper.sh instead of
embedding full scripts.
- Around line 229-235: The documentation shows a negation pattern
(!test/fixtures/) that privacy-filter-helper.sh does not support; update
.aidevops/privacy-patterns.txt examples and the privacy-filter.md instructions
to remove the negation example and instead show a supported workaround (e.g.,
narrow the regex or move fixtures to ignored paths like .gitignore) and add an
explicit note that privacy-filter-helper.sh treats every line as a positive
regex and does not support leading "!" negation; reference the helper script
name privacy-filter-helper.sh and the patterns file
.aidevops/privacy-patterns.txt so reviewers can locate and edit the offending
example.
🧹 Nitpick comments (4)
TODO.md (1)

232-244: Align t115 status with completed work and sync TOON blocks.

t115 is still unchecked even though the PR objectives say it’s implemented. Please mark it completed (with a completed date) and ensure the TOON backlog entries for t115–t117 are updated to match the human-readable status.

🧾 Suggested update
- - [ ] t115 OpenCode server subagent documentation `#docs` `#tools` `#ai-assistants` ~2h (ai:1.5h test:20m read:10m) logged:2026-02-04 started:2026-02-04T12:00Z
+ - [x] t115 OpenCode server subagent documentation `#docs` `#tools` `#ai-assistants` ~2h actual:?? (ai:1.5h test:20m read:10m) logged:2026-02-04 started:2026-02-04T12:00Z completed:2026-02-04
.agent/aidevops/self-improving-agents.md (1)

147-390: Add architecture + self‑assessment protocol pointers to prerequisites/guardrails.
This doc should point readers to .agent/aidevops/architecture.md and the self‑assessment protocol (complete task first, cite evidence, check duplicates via rg "pattern" .agent/, propose fixes for observable failures) in the prerequisites or safety guardrails.

Based on learnings: Before extending aidevops framework, read .agent/aidevops/architecture.md to understand agent design patterns (progressive disclosure, context offloading, Ralph loop), extension guidelines, and framework conventions; Apply self-assessment protocol when developing agents: complete task first, cite evidence, check for duplicates using rg "pattern" .agent/ before adding instructions, and propose fixes when observable failures or contradictions are detected.

.agent/scripts/self-improve-helper.sh (2)

61-99: Add curl timeouts/--fail to avoid hangs in OpenCode calls.
Without timeouts, a stalled server can block the whole loop. Use --connect-timeout/--max-time and --fail for fast, reliable error handling.

🔧 Proposed fix
-    if curl -s "${OPENCODE_URL}/global/health" > /dev/null 2>&1; then
+    if curl -fsS --connect-timeout 2 --max-time 5 "${OPENCODE_URL}/global/health" > /dev/null 2>&1; then
         return 0
     else
         return 1
     fi
@@
-    response=$(curl -s -X POST "${OPENCODE_URL}/session" \
+    response=$(curl -fsS --connect-timeout 2 --max-time 30 -X POST "${OPENCODE_URL}/session" \
         -H "Content-Type: application/json" \
         -d "{\"title\": \"$title\"}")
@@
-    response=$(curl -s -X POST "${OPENCODE_URL}/session/${session_id}/message" \
+    response=$(curl -fsS --connect-timeout 2 --max-time 60 -X POST "${OPENCODE_URL}/session/${session_id}/message" \
         -H "Content-Type: application/json" \
         -d "{\"parts\": [{\"type\": \"text\", \"text\": $(echo "$prompt" | jq -Rs .)}]}")
@@
-    curl -s -X DELETE "${OPENCODE_URL}/session/${session_id}" > /dev/null
+    curl -fsS --connect-timeout 2 --max-time 10 -X DELETE "${OPENCODE_URL}/session/${session_id}" > /dev/null
As per coding guidelines: .agent/scripts/*.sh: Automation scripts - focus on: Reliability and robustness; Proper exit codes; Error recovery mechanisms.

286-307: Embed the self‑assessment protocol in the refine prompt.
Add a short protocol reminder (complete task first, cite evidence, check duplicates via rg "pattern" .agent/, propose fixes when failures/contradictions are observed) so generated proposals comply.

Based on learnings: Apply self-assessment protocol when developing agents: complete task first, cite evidence, check for duplicates using rg "pattern" .agent/ before adding instructions, and propose fixes when observable failures or contradictions are detected.

Comment on lines +33 to +385
```text
┌─────────────────────────────────────────────────────────────┐
│ Self-Improvement Cycle │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ ANALYZE │───▶│ REFINE │───▶│ TEST │───▶│ PR │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ Memory │ │ OpenCode │ │ OpenCode │ │ GitHub │ │
│ │ Patterns │ │ Session │ │ Session │ │ PR │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```

## Phases

### 1. Analyze Phase

Query memory for failure patterns and identify improvement opportunities.

```bash
self-improve-helper.sh analyze
```

**What it does:**
- Queries memory for FAILED_APPROACH entries
- Queries memory for ERROR_FIX entries
- Identifies gaps (failures without corresponding solutions)
- Saves analysis to `analysis.json`

**Output:**

```text
Memory Summary:
- Failed approaches: 15
- Error fixes: 8
- Working solutions: 42
- Codebase patterns: 12

Gaps identified: 7 (failures without solutions)
```

### 2. Refine Phase

Generate specific improvement proposals using OpenCode.

```bash
self-improve-helper.sh refine [--dry-run]
```

**What it does:**
- Creates OpenCode session for improvement generation
- Sends analysis data with structured prompt
- Receives proposals as JSON array
- Saves proposals to `proposals.json`

**Proposal format:**

```json
{
"file": ".agent/workflows/git-workflow.md",
"change_type": "edit",
"description": "Add guidance for handling merge conflicts",
"diff": "...",
"impact": "Reduces merge conflict failures by 30%",
"test_prompt": "Simulate a merge conflict scenario..."
}
```

### 3. Test Phase

Validate improvements in isolated OpenCode sessions.

```bash
self-improve-helper.sh test [session-id]
```

**What it does:**
- Loads proposals from previous phase
- Runs each proposal's test_prompt in OpenCode
- Checks responses for error indicators
- Saves results to `test-results.json`

**Test criteria:**
- Response doesn't contain error keywords
- Task completes without exceptions
- Output matches expected patterns

### 4. PR Phase

Create privacy-filtered PR with evidence.

```bash
self-improve-helper.sh pr [--dry-run]
```

**What it does:**
- Runs mandatory privacy filter scan
- Builds PR body with evidence:
- Memory analysis summary
- Test results attestation
- Privacy filter confirmation
- Creates PR via gh CLI

**PR includes:**
- Summary of improvements
- Evidence from memory analysis
- Test results for each change
- Privacy attestation

## Prerequisites

### OpenCode Server

Start the server before running improvement cycles:

```bash
opencode serve --port 4096
```

Or with authentication:

```bash
OPENCODE_SERVER_PASSWORD=secret opencode serve --port 4096
```

### Memory System

The analyze phase requires populated memory:

```bash
# Check memory stats
memory-helper.sh stats

# Ensure there are failure entries
memory-helper.sh recall --type FAILED_APPROACH --limit 5
```

### Privacy Filter

The PR phase requires the privacy filter:

```bash
# Verify installation
privacy-filter-helper.sh status

# Test scan
privacy-filter-helper.sh scan .
```

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OPENCODE_HOST` | `localhost` | OpenCode server hostname |
| `OPENCODE_PORT` | `4096` | OpenCode server port |

### Workspace Files

```text
~/.aidevops/.agent-workspace/self-improve/
├── analysis.json # Memory analysis results
├── proposals.json # Generated improvement proposals
└── test-results.json # Test validation results
```

## Usage Examples

### Full Improvement Cycle

```bash
# 1. Start OpenCode server
opencode serve --port 4096 &

# 2. Run improvement cycle
self-improve-helper.sh analyze
self-improve-helper.sh refine
self-improve-helper.sh test
self-improve-helper.sh pr

# 3. Review and merge PR
gh pr view
```

### Dry Run Preview

```bash
# Preview what would be generated
self-improve-helper.sh refine --dry-run

# Preview PR without creating
self-improve-helper.sh pr --dry-run
```

### Check Status

```bash
self-improve-helper.sh status
```

Output:

```text
Self-Improvement Status

✅ Analysis: 2026-02-04T12:00:00Z (7 gaps)
✅ Proposals: 2026-02-04T12:15:00Z (5 proposals)
✅ Tests: 2026-02-04T12:30:00Z (5 passed, 0 failed)
✅ OpenCode server: Running at http://localhost:4096
```

## Safety Guardrails

### Privacy Filter (Mandatory)

The PR phase will not proceed without passing the privacy filter:

- Secretlint scan for credentials
- Pattern-based detection for PII
- Project-specific patterns from `.aidevops/privacy-patterns.txt`

### Worktree Isolation

All changes must be made in a worktree, not on main:

```bash
# Create worktree for improvements
wt switch -c feature/self-improve-$(date +%Y%m%d)

# Run improvement cycle
self-improve-helper.sh analyze
# ...
```

### Human Approval

The PR phase requires:
1. All tests to pass
2. Privacy filter to pass
3. Human review before merge

### Dry Run Mode

Always preview with `--dry-run` first:

```bash
self-improve-helper.sh refine --dry-run
self-improve-helper.sh pr --dry-run
```

## Integration with Memory

### Storing Learnings

After successful improvements, store the pattern:

```bash
memory-helper.sh store \
--content "Self-improvement: Added merge conflict guidance to git-workflow.md" \
--type WORKING_SOLUTION \
--tags "self-improve,git,merge-conflict"
```

### Querying Patterns

The analyze phase queries these memory types:

| Type | Purpose |
|------|---------|
| `FAILED_APPROACH` | What didn't work |
| `ERROR_FIX` | Errors and their fixes |
| `WORKING_SOLUTION` | Successful approaches |
| `CODEBASE_PATTERN` | Code conventions |

## Scheduling

### Manual Trigger

Run the improvement cycle manually when needed:

```bash
self-improve-helper.sh analyze && \
self-improve-helper.sh refine && \
self-improve-helper.sh test && \
self-improve-helper.sh pr --dry-run
```

### Cron Integration (Future)

The cron agent (t110) will enable scheduled improvement cycles:

```bash
# Weekly improvement analysis (future)
cron-agent add "self-improve-weekly" \
--schedule "0 2 * * 0" \
--command "self-improve-helper.sh analyze"
```

## Troubleshooting

### OpenCode Server Not Running

```bash
# Check if running
curl http://localhost:4096/global/health

# Start server
opencode serve --port 4096
```

### No Memory Entries

```bash
# Check memory stats
memory-helper.sh stats

# Store some test entries
memory-helper.sh store \
--content "Test failure: X didn't work because Y" \
--type FAILED_APPROACH
```

### Privacy Filter Fails

```bash
# See what's detected
privacy-filter-helper.sh scan .

# Add exceptions if needed
privacy-filter-helper.sh patterns add-project 'test\.example\.com'
```

### Tests Fail

Review the test results:

```bash
cat ~/.aidevops/.agent-workspace/self-improve/test-results.json | jq '.'
```

Refine proposals and re-test:

```bash
self-improve-helper.sh refine
self-improve-helper.sh test
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace large inline workflows with pointers to authoritative sources.
Lines 33‑385 embed step‑by‑step commands, sample outputs, and troubleshooting. For .agent docs, keep this as a high‑level overview and link to authoritative implementations (e.g., .agent/scripts/self-improve-helper.sh with file:line references) so details don’t drift.

As per coding guidelines: .agent/**/*.md: Apply progressive disclosure pattern by using pointers to subagents rather than including inline content in agent documentation; Include code examples only when authoritative; use file:line references to point to actual implementation instead of inline code snippets.

🤖 Prompt for AI Agents
In @.agent/aidevops/self-improving-agents.md around lines 33 - 385, This doc
embeds large step-by-step workflows and sample outputs that should be replaced
with high-level pointers to the authoritative implementations; remove the long
inline bash examples, outputs and troubleshooting blocks and instead summarize
the phase (Analyze, Refine, Test, PR) and link to the actual scripts and
artifacts (self-improve-helper.sh, privacy-filter-helper.sh, memory-helper.sh,
opencode serve, and workspace files like
analysis.json/proposals.json/test-results.json) and add file:line references in
the summary to the authoritative implementations so readers follow the real code
for details; keep only minimal examples that are authoritative and move all
commands, sample outputs and troubleshooting into the referenced scripts/docs.

Comment on lines +175 to +206
# Run secretlint scan first
run_secretlint() {
local target="${1:-.}"

print_header "Running Secretlint scan..."

if command -v secretlint &> /dev/null; then
if secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found!"
return 1
fi
elif [[ -f "node_modules/.bin/secretlint" ]]; then
if ./node_modules/.bin/secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found!"
return 1
fi
else
# Try npx
if npx --yes secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_warning "Secretlint not available, skipping credential scan"
return 0
fi
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, confirm the file exists and examine the run_secretlint function
cat -n .agent/scripts/privacy-filter-helper.sh | sed -n '175,206p'

Repository: marcusquinn/aidevops

Length of output: 1317


🏁 Script executed:

# Also check if there are any tests or callers of this function
rg "run_secretlint" .agent/scripts/ -A 2 -B 2

Repository: marcusquinn/aidevops

Length of output: 660


🏁 Script executed:

# Check the overall structure of the file
wc -l .agent/scripts/privacy-filter-helper.sh

Repository: marcusquinn/aidevops

Length of output: 107


npx secretlint fallback fails open on findings.
In the npx fallback branch (lines 198-205), any non-zero exit—whether from missing npx, failed execution, or detected secrets—is treated as "not available" and returns success. This masks secrets that secretlint detects. Since the caller checks return codes to track findings, this silent pass introduces security risk.

Add an explicit check for npx availability before attempting the scan, then return error status if the scan fails:

🔧 Proposed fix
-    else
-        # Try npx
-        if npx --yes secretlint "$target" 2>/dev/null; then
-            print_success "Secretlint: No secrets detected"
-            return 0
-        else
-            print_warning "Secretlint not available, skipping credential scan"
-            return 0
-        fi
-    fi
+    elif command -v npx &> /dev/null; then
+        if npx --yes secretlint "$target" 2>/dev/null; then
+            print_success "Secretlint: No secrets detected"
+            return 0
+        else
+            print_error "Secretlint: Potential secrets found or scan failed"
+            return 1
+        fi
+    else
+        print_warning "Secretlint not available, skipping credential scan"
+        return 0
+    fi

Per .agent/scripts/*.sh guidelines: maintain reliability, robust exit codes, and proper error recovery.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Run secretlint scan first
run_secretlint() {
local target="${1:-.}"
print_header "Running Secretlint scan..."
if command -v secretlint &> /dev/null; then
if secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found!"
return 1
fi
elif [[ -f "node_modules/.bin/secretlint" ]]; then
if ./node_modules/.bin/secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found!"
return 1
fi
else
# Try npx
if npx --yes secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_warning "Secretlint not available, skipping credential scan"
return 0
fi
fi
# Run secretlint scan first
run_secretlint() {
local target="${1:-.}"
print_header "Running Secretlint scan..."
if command -v secretlint &> /dev/null; then
if secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found!"
return 1
fi
elif [[ -f "node_modules/.bin/secretlint" ]]; then
if ./node_modules/.bin/secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found!"
return 1
fi
elif command -v npx &> /dev/null; then
if npx --yes secretlint "$target" 2>/dev/null; then
print_success "Secretlint: No secrets detected"
return 0
else
print_error "Secretlint: Potential secrets found or scan failed"
return 1
fi
else
print_warning "Secretlint not available, skipping credential scan"
return 0
fi
}
🤖 Prompt for AI Agents
In @.agent/scripts/privacy-filter-helper.sh around lines 175 - 206,
run_secretlint currently treats any non-zero result from the npx branch as
"secretlint not available" and returns success; change the npx fallback to first
verify npx exists (e.g., command -v npx) and if absent print_warning and return
0, but if npx is present run npx --yes secretlint "$target" and treat a non-zero
exit as a real failure (print_error "Secretlint: Potential secrets found!" and
return 1) instead of masking it as skipped; update the npx branch in
run_secretlint to explicitly distinguish "npx missing" vs "scan failed"
behaviors.

Comment on lines +326 to +399
# Show before/after for each match
if command -v rg &> /dev/null; then
rg -n -e "$pattern" "$file" 2>/dev/null | while IFS= read -r match; do
local line content redacted
line=$(echo "$match" | cut -d: -f1)
content=$(echo "$match" | cut -d: -f2-)
redacted=$(echo "$content" | sed -E "s/$pattern/[REDACTED]/g")
echo -e " Line $line:"
echo -e " ${RED}Before:${NC} ${content:0:80}"
echo -e " ${GREEN}After:${NC} ${redacted:0:80}"
done
fi
echo ""
done <<< "$matches"
fi
done

print_info "Run 'privacy-filter-helper.sh apply' to apply redactions"
return 0
}

# Apply redactions to files
apply_redactions() {
local target="${1:-.}"
local -a patterns
local changes=0

print_header "Applying Privacy Redactions"
print_warning "This will modify files in place!"
echo ""

read -p "Continue? [y/N] " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "Aborted"
return 1
fi

# Load all patterns
mapfile -t patterns < <(get_all_patterns)

# Apply redactions
for pattern in "${patterns[@]}"; do
local matches
if command -v rg &> /dev/null; then
matches=$(rg -l -e "$pattern" "$target" 2>/dev/null || true)
else
matches=$(grep -rl -E "$pattern" "$target" 2>/dev/null || true)
fi

if [[ -n "$matches" ]]; then
while IFS= read -r file; do
# Create backup
cp "$file" "${file}.privacy-backup"

# Apply redaction
if [[ "$(uname)" == "Darwin" ]]; then
sed -i '' -E "s/$pattern/[REDACTED]/g" "$file"
else
sed -i -E "s/$pattern/[REDACTED]/g" "$file"
fi

print_success "Redacted: $file"
changes=$((changes + 1))
done <<< "$matches"
fi
done

echo ""
if [[ $changes -eq 0 ]]; then
print_info "No changes made"
else
print_success "Applied redactions to $changes files"
print_info "Backup files created with .privacy-backup extension"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate and read the file to understand full context
fd "privacy-filter-helper.sh" -t f

Repository: marcusquinn/aidevops

Length of output: 103


🏁 Script executed:

# Read the file to see the complete apply_redactions function
head -n 410 .agent/scripts/privacy-filter-helper.sh | tail -n 100

Repository: marcusquinn/aidevops

Length of output: 3180


🏁 Script executed:

# Get a better view of the entire apply_redactions function
sed -n '350,410p' .agent/scripts/privacy-filter-helper.sh

Repository: marcusquinn/aidevops

Length of output: 1765


🏁 Script executed:

# Check if rg supports --passthru by examining rg documentation
rg --help | grep -A 2 "passthru\|replace"

Repository: marcusquinn/aidevops

Length of output: 2104


🏁 Script executed:

# Also check the sed behavior with different regex features
# Create a test to see if sed -E handles \b like rg does
cat > /tmp/test_regex.sh << 'EOF'
#!/bin/bash

# Test 1: Check if sed -E and rg handle \b differently
echo "Testing word boundary \\b"
echo "test word testing" > /tmp/test.txt

# rg output (if available)
if command -v rg &> /dev/null; then
    echo "rg -E '\\bword\\b' matches:"
    rg -E '\bword\b' /tmp/test.txt 2>/dev/null || echo "No match or error"
fi

# sed output
echo "sed -E 's/\\bword\\b/[REDACTED]/g' result:"
sed -E 's/\bword\b/[REDACTED]/g' /tmp/test.txt

echo ""
echo "Testing forward slash in pattern:"
# Test 2: Forward slash in pattern breaking sed
echo "path/to/file.txt" > /tmp/test2.txt
pattern="path/to"
echo "Pattern: $pattern"
echo "Using sed with default delimiter:"
sed -E "s/$pattern/[REDACTED]/g" /tmp/test2.txt 2>&1 || echo "ERROR with default delimiter"
echo "Using sed with pipe delimiter:"
sed -E "s|$pattern|[REDACTED]|g" /tmp/test2.txt 2>&1 && echo "SUCCESS with pipe delimiter"
EOF

bash /tmp/test_regex.sh

Repository: marcusquinn/aidevops

Length of output: 445


🏁 Script executed:

# Check if there's any pattern definition in the config that uses special characters
grep -n "patterns\|PASSWORD\|SECRET\|regex" .agent/scripts/privacy-filter-helper.sh | head -20

Repository: marcusquinn/aidevops

Length of output: 956


🏁 Script executed:

# Look for how patterns are defined or loaded
sed -n '1,100p' .agent/scripts/privacy-filter-helper.sh | grep -A 10 "get_all_patterns\|PRIVACY_PATTERNS"

Repository: marcusquinn/aidevops

Length of output: 46


🏁 Script executed:

# Get the DEFAULT_PATTERNS array to see actual pattern content
sed -n '38,135p' .agent/scripts/privacy-filter-helper.sh

Repository: marcusquinn/aidevops

Length of output: 2501


🏁 Script executed:

# Also check for any extended regex features that might differ between sed and rg
grep -E "\\\\[bBdDsSwW]|\\\\[1-9]" .agent/scripts/privacy-filter-helper.sh

Repository: marcusquinn/aidevops

Length of output: 467


🏁 Script executed:

# Test if the actual patterns from the script would fail with current sed implementation
cat > /tmp/test_actual_patterns.sh << 'EOF'
#!/bin/bash

# Test patterns from the DEFAULT_PATTERNS array that contain problematic characters
test_file="/tmp/test_patterns.txt"
cat > "$test_file" << 'CONTENT'
Connect to mongodb://user:pass@localhost:27017/dbname
API key: sk-1234567890abcdefghij
Bearer token: Bearer abc.def.ghi
CONTENT

# Test 1: Forward slash patterns (will fail)
echo "=== Testing forward slash pattern (mongodb) ==="
pattern='mongodb(\+srv)?://[^\s]+'
echo "Pattern: $pattern"
echo "Testing sed with default delimiter:"
sed -i -E "s/$pattern/[REDACTED]/g" "$test_file" 2>&1 && echo "SUCCESS" || echo "FAILED (as expected)"

# Restore file
cat > "$test_file" << 'CONTENT'
Connect to mongodb://user:pass@localhost:27017/dbname
API key: sk-1234567890abcdefghij
Bearer token: Bearer abc.def.ghi
CONTENT

# Test 2: Word boundary pattern
echo ""
echo "=== Testing word boundary pattern ==="
pattern='Bearer [a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+'
echo "Pattern: $pattern"
echo "Original line:"
grep "Bearer" "$test_file"
echo "After sed -E (no escaping of slashes):"
sed -E "s/$pattern/[REDACTED]/g" "$test_file" | grep "Bearer" || echo "Pattern processed"

# Test 3: Using pipe delimiter (safer)
echo ""
echo "=== Testing with pipe delimiter ==="
pattern='mongodb(\+srv)?://[^\s]+'
echo "Pattern: $pattern"
sed -E "s|$pattern|[REDACTED]|g" "$test_file" 2>&1 && echo "SUCCESS with pipe delimiter"
grep "mongodb" "$test_file"
EOF

bash /tmp/test_actual_patterns.sh

Repository: marcusquinn/aidevops

Length of output: 742


🏁 Script executed:

# Verify rg --passthru --replace functionality
echo "Testing rg --passthru --replace:"
test_file="/tmp/test_rg.txt"
cat > "$test_file" << 'EOF'
API key: sk-1234567890abcdefghij
Password: secret123
Normal line
EOF

if command -v rg &> /dev/null; then
    echo "File before:"
    cat "$test_file"
    echo ""
    echo "Using rg --passthru --replace:"
    rg --passthru -e 'sk-[a-zA-Z0-9]{20,}' --replace '[REDACTED]' "$test_file"
fi

Repository: marcusquinn/aidevops

Length of output: 258


🏁 Script executed:

# Verify the backup overwrite issue more explicitly
cat > /tmp/test_backup_logic.sh << 'EOF'
#!/bin/bash

# Simulate the current backup logic
test_dir="/tmp/backup_test"
mkdir -p "$test_dir"
test_file="$test_dir/test.txt"

# Create initial file
echo "Original content" > "$test_file"
echo "Backup creation simulation:"
echo "Initial file:"
cat "$test_file"

# Simulate pattern loop (3 patterns)
for i in 1 2 3; do
    cp "$test_file" "${test_file}.privacy-backup"
    echo "Pattern $i: Backup created/overwritten"
    # Modify file
    echo "Modified by pattern $i" >> "$test_file"
done

echo ""
echo "Final backup content (should be from first pattern, but might be overwritten):"
cat "${test_file}.privacy-backup"

echo ""
echo "Final file content:"
cat "$test_file"
EOF

bash /tmp/test_backup_logic.sh

Repository: marcusquinn/aidevops

Length of output: 481


🏁 Script executed:

# Check if word boundary \b actually appears in patterns used
grep -o "\\\\b" .agent/scripts/privacy-filter-helper.sh | wc -l

Repository: marcusquinn/aidevops

Length of output: 65


🏁 Script executed:

# Test if sed -E actually handles \b correctly (spoiler: it doesn't match as word boundary)
cat > /tmp/test_word_boundary.sh << 'EOF'
#!/bin/bash

# Test word boundary with actual IP pattern from script
ip_pattern='\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'

echo "Testing IPv4 pattern with word boundaries"
echo "Pattern: $ip_pattern"

test_content="IP: 192.168.1.1 and text192.168.1.1text"
echo "Test content: $test_content"

echo ""
echo "Using rg (should match both, respecting word boundaries):"
if command -v rg &> /dev/null; then
    echo "$test_content" | rg -o '\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b' 2>&1 || echo "Pattern match result above"
fi

echo ""
echo "Using sed -E (will NOT respect \\b as word boundary):"
echo "$test_content" | sed -E 's/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/[REDACTED]/g' 2>&1 || echo "Error (expected - sed doesn't support PCRE)"
EOF

bash /tmp/test_word_boundary.sh

Repository: marcusquinn/aidevops

Length of output: 501


Critical regex incompatibility and backup data loss risks.

The current implementation has multiple failure modes:

  1. Forward slashes break sed: Patterns like mongodb://, postgres://, redis:// fail with "unknown option to s'" error because sed interprets the /` as a delimiter. The script dies silently on these patterns.

  2. Word boundaries unsupported in sed: Patterns using \b (e.g., IPv4 address detection) fail with "Invalid preceding regular expression" because sed's extended regex doesn't support PCRE word boundaries, while rg does. This causes silent pattern misses in the scan phase but catastrophic errors in apply phase.

  3. Backups overwritten per pattern: When multiple patterns match the same file, the backup is created fresh for each pattern iteration. If pattern 1 modifies the file, then pattern 2 overwrites the backup—losing the original content before pattern 1.

Use rg --passthru --replace for consistent redaction and create backups once per file, not once per pattern:

Suggested fix
-                # Create backup
-                cp "$file" "${file}.privacy-backup"
-                
-                # Apply redaction
-                if [[ "$(uname)" == "Darwin" ]]; then
-                    sed -i '' -E "s/$pattern/[REDACTED]/g" "$file"
-                else
-                    sed -i -E "s/$pattern/[REDACTED]/g" "$file"
-                fi
+                # Create backup once per file
+                if [[ ! -f "${file}.privacy-backup" ]]; then
+                    cp "$file" "${file}.privacy-backup"
+                fi
+
+                # Apply redaction using the same regex engine as scan
+                if command -v rg &> /dev/null; then
+                    rg --passthru -e "$pattern" --replace '[REDACTED]' "$file" > "${file}.privacy-tmp"
+                    mv "${file}.privacy-tmp" "$file"
+                else
+                    # Fallback: use pipe delimiter to handle forward slashes
+                    safe_pattern="${pattern//|/\\|}"
+                    if [[ "$(uname)" == "Darwin" ]]; then
+                        sed -i '' -E "s|$safe_pattern|[REDACTED]|g" "$file"
+                    else
+                        sed -i -E "s|$safe_pattern|[REDACTED]|g" "$file"
+                    fi
+                fi

Per coding guidelines: automation scripts must prioritize reliability and robustness. This implementation fails on existing default patterns and loses original backups.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Show before/after for each match
if command -v rg &> /dev/null; then
rg -n -e "$pattern" "$file" 2>/dev/null | while IFS= read -r match; do
local line content redacted
line=$(echo "$match" | cut -d: -f1)
content=$(echo "$match" | cut -d: -f2-)
redacted=$(echo "$content" | sed -E "s/$pattern/[REDACTED]/g")
echo -e " Line $line:"
echo -e " ${RED}Before:${NC} ${content:0:80}"
echo -e " ${GREEN}After:${NC} ${redacted:0:80}"
done
fi
echo ""
done <<< "$matches"
fi
done
print_info "Run 'privacy-filter-helper.sh apply' to apply redactions"
return 0
}
# Apply redactions to files
apply_redactions() {
local target="${1:-.}"
local -a patterns
local changes=0
print_header "Applying Privacy Redactions"
print_warning "This will modify files in place!"
echo ""
read -p "Continue? [y/N] " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "Aborted"
return 1
fi
# Load all patterns
mapfile -t patterns < <(get_all_patterns)
# Apply redactions
for pattern in "${patterns[@]}"; do
local matches
if command -v rg &> /dev/null; then
matches=$(rg -l -e "$pattern" "$target" 2>/dev/null || true)
else
matches=$(grep -rl -E "$pattern" "$target" 2>/dev/null || true)
fi
if [[ -n "$matches" ]]; then
while IFS= read -r file; do
# Create backup
cp "$file" "${file}.privacy-backup"
# Apply redaction
if [[ "$(uname)" == "Darwin" ]]; then
sed -i '' -E "s/$pattern/[REDACTED]/g" "$file"
else
sed -i -E "s/$pattern/[REDACTED]/g" "$file"
fi
print_success "Redacted: $file"
changes=$((changes + 1))
done <<< "$matches"
fi
done
echo ""
if [[ $changes -eq 0 ]]; then
print_info "No changes made"
else
print_success "Applied redactions to $changes files"
print_info "Backup files created with .privacy-backup extension"
# Create backup once per file
if [[ ! -f "${file}.privacy-backup" ]]; then
cp "$file" "${file}.privacy-backup"
fi
# Apply redaction using the same regex engine as scan
if command -v rg &> /dev/null; then
rg --passthru -e "$pattern" --replace '[REDACTED]' "$file" > "${file}.privacy-tmp"
mv "${file}.privacy-tmp" "$file"
else
# Fallback: use pipe delimiter to handle forward slashes
safe_pattern="${pattern//|/\\|}"
if [[ "$(uname)" == "Darwin" ]]; then
sed -i '' -E "s|$safe_pattern|[REDACTED]|g" "$file"
else
sed -i -E "s|$safe_pattern|[REDACTED]|g" "$file"
fi
fi
print_success "Redacted: $file"
changes=$((changes + 1))
🤖 Prompt for AI Agents
In @.agent/scripts/privacy-filter-helper.sh around lines 326 - 399,
apply_redactions currently uses sed per-pattern (breaking on / delimiters and
\b, and recreates backups per pattern); change it to use ripgrep's replace to
perform safe, delimiter-free replacements and create a single backup per file:
in apply_redactions (and the matches loop) detect if command -v rg; for each
file create its "${file}.privacy-backup" only once (before any replacements) and
then for replacement run a pipeline applying all patterns via rg --passthru
--replace (iteratively feed the file through rg --passthru --replace -e
"$pattern" --replace '[REDACTED]' into a temp file, or construct a single stream
of replacements) and atomically move the temp into place; if rg is not
available, fallback to perl -pe using s{pattern}[REDACTED}g with proper escaping
so / and \b work; ensure patterns from get_all_patterns are quoted/handled
safely and remove the per-pattern cp "$file" "${file}.privacy-backup" so backup
is only created once per file.

Comment on lines +39 to +46
# Colors for output
readonly GREEN='\033[0;32m'
readonly BLUE='\033[0;34m'
readonly YELLOW='\033[1;33m'
readonly RED='\033[0;31m'
readonly PURPLE='\033[0;35m'
readonly CYAN='\033[0;36m'
readonly NC='\033[0m' # No Color
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused CYAN to keep static checks clean.
Static analysis flags CYAN as unused. Remove it or use it in output.

🧹 Proposed fix
-readonly CYAN='\033[0;36m'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Colors for output
readonly GREEN='\033[0;32m'
readonly BLUE='\033[0;34m'
readonly YELLOW='\033[1;33m'
readonly RED='\033[0;31m'
readonly PURPLE='\033[0;35m'
readonly CYAN='\033[0;36m'
readonly NC='\033[0m' # No Color
# Colors for output
readonly GREEN='\033[0;32m'
readonly BLUE='\033[0;34m'
readonly YELLOW='\033[1;33m'
readonly RED='\033[0;31m'
readonly PURPLE='\033[0;35m'
readonly NC='\033[0m' # No Color
🧰 Tools
🪛 GitHub Check: Codacy Static Code Analysis

[warning] 45-45: .agent/scripts/self-improve-helper.sh#L45
CYAN appears unused. Verify use (or export if used externally).

🤖 Prompt for AI Agents
In @.agent/scripts/self-improve-helper.sh around lines 39 - 46, The CYAN color
constant (readonly CYAN='\033[0;36m') is defined but unused; remove that line
from the color definitions in .agent/scripts/self-improve-helper.sh (the block
containing GREEN, BLUE, YELLOW, RED, PURPLE, CYAN, NC) so static analysis no
longer flags an unused variable, or alternatively use CYAN in any output helper
function (e.g., the script's logging/echo calls) if you prefer to keep it.

Comment on lines +281 to +334
prompt="You are analyzing failure patterns to generate agent improvements.

## Analysis Data
$(echo "$analysis" | jq -c '.')

## Task
Based on the failures without solutions, propose specific improvements to:
1. Agent instructions (AGENTS.md or subagents)
2. Helper scripts
3. Workflows

For each proposal, provide:
- File to modify
- Specific change (as a diff or description)
- Expected impact
- Test prompt to validate

Output as JSON array:
[
{
\"file\": \"path/to/file\",
\"change_type\": \"edit|add|delete\",
\"description\": \"What to change\",
\"diff\": \"Optional diff content\",
\"impact\": \"Expected improvement\",
\"test_prompt\": \"Prompt to validate this works\"
}
]"

if [[ "$dry_run" == true ]]; then
log_info "[DRY RUN] Would send prompt to OpenCode session"
echo ""
echo "Prompt preview:"
echo "$prompt" | head -30
echo "..."
delete_session "$session_id"
return 0
fi

log_info "Generating improvement proposals..."

local response
response=$(send_prompt "$session_id" "$prompt")

# Extract proposals from response
local proposals
proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null | grep -o '\[.*\]' | head -1 || echo "[]")

if [[ "$proposals" == "[]" || -z "$proposals" ]]; then
log_warn "No proposals generated. Response may need manual review."
echo "$response" | jq '.' 2>/dev/null || echo "$response"
delete_session "$session_id"
return 1
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the file structure and the specific lines in question
wc -l .agent/scripts/self-improve-helper.sh

Repository: marcusquinn/aidevops

Length of output: 105


🏁 Script executed:

# Read the section around lines 281-334
sed -n '270,345p' .agent/scripts/self-improve-helper.sh | cat -n

Repository: marcusquinn/aidevops

Length of output: 2826


🏁 Script executed:

# Let's also check the broader context to understand how proposals are used
grep -n "proposals=" .agent/scripts/self-improve-helper.sh | head -10

Repository: marcusquinn/aidevops

Length of output: 281


🏁 Script executed:

# Test the grep pattern with multi-line JSON
cat > /tmp/test_extract.sh << 'EOF'
#!/bin/bash

# Simulate a response with multi-line JSON
response_multiline='Some text before
[
  {
    "file": "path/to/file",
    "change_type": "edit"
  }
]
More text after'

echo "=== Test 1: Multi-line JSON ==="
echo "Input:"
echo "$response_multiline"
echo ""
echo "Using grep -o '\[.*\]':"
echo "$response_multiline" | grep -o '\[.*\]' || echo "NO MATCH"
echo ""

# Test with single-line JSON
response_singleline='Some text [{"file":"path","change_type":"edit"}] more text'
echo "=== Test 2: Single-line JSON ==="
echo "Input:"
echo "$response_singleline"
echo ""
echo "Using grep -o '\[.*\]':"
echo "$response_singleline" | grep -o '\[.*\]' || echo "NO MATCH"
echo ""

# Test with greedy capture issue
response_greedy='text [{"a":1}] middle [{"b":2}] end'
echo "=== Test 3: Multiple JSON arrays (greedy issue) ==="
echo "Input:"
echo "$response_greedy"
echo ""
echo "Using grep -o '\[.*\]':"
echo "$response_greedy" | grep -o '\[.*\]' || echo "NO MATCH"
echo ""

# Test the proposed fix
echo "=== Test 4: Proposed fix with multi-line ==="
echo "$response_multiline" | printf '%s\n' "$(cat)" | jq -c '.' 2>/dev/null || echo "Failed - invalid JSON"
EOF

bash /tmp/test_extract.sh

Repository: marcusquinn/aidevops

Length of output: 615


🏁 Script executed:

# Test the improved extraction approach
cat > /tmp/test_improved.sh << 'EOF'
#!/bin/bash

# Simulate actual response structure as per OpenCode API
response='{"parts":[{"type":"text","text":"Here are the proposals:\n\n[\n  {\"file\":\"AGENTS.md\",\"change_type\":\"edit\",\"description\":\"Update instructions\",\"diff\":\"test\",\"impact\":\"Better performance\",\"test_prompt\":\"test this\"}\n]\n\nThese are good proposals."}]}'

echo "=== Original approach (grep greedy) ==="
proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null | grep -o '\[.*\]' | head -1 || echo "[]")
echo "Result: $proposals"
echo ""
echo "Validation with jq:"
echo "$proposals" | jq '.' 2>&1 | head -5
echo ""

echo "=== Improved approach (split + jq validate) ==="
proposals_text=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null)
proposals=$(echo "$proposals_text" | jq -c '.' 2>/dev/null || echo "[]")
echo "Result: $proposals"
echo ""
EOF

bash /tmp/test_improved.sh

Repository: marcusquinn/aidevops

Length of output: 194


🏁 Script executed:

# Check if there are any other JSON extraction patterns in the file
grep -n "grep.*\[.*\]" .agent/scripts/self-improve-helper.sh

Repository: marcusquinn/aidevops

Length of output: 208


🏁 Script executed:

# Check what happens when proposals is used downstream - line 70
sed -n '68,80p' .agent/scripts/self-improve-helper.sh | cat -n

Repository: marcusquinn/aidevops

Length of output: 455


Fix JSON extraction to handle multi-line responses and validate with jq.

The current grep -o '\[.*\]' pattern fails silently for multi-line JSON (grep's . doesn't match newlines), causing proposals to return empty and the function to incorrectly report "No proposals generated". This breaks reliability when the LLM returns properly formatted multi-line JSON per the prompt instructions. Additionally, the greedy regex creates corruption risk if multiple JSON structures are present.

Fix: Enforce JSON-only output in the prompt, then extract directly with jq validation:

🔧 Recommended fix
-Output as JSON array:
+Return ONLY the JSON array with no additional prose:
@@
-    proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null | grep -o '\[.*\]' | head -1 || echo "[]")
+    proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null | jq -s 'if . == [""] then "[]" else (if .[0] | startswith("[") then .[0] else "[]" end) end | fromjson' 2>/dev/null || echo "[]")

Or simpler—if enforcing JSON-only output works:

+    proposals=$(echo "$response" | jq -r '.parts[] | select(.type == "text") | .text' 2>/dev/null | jq -c '.' 2>/dev/null || echo "[]")

Per coding guidelines (Reliability, robustness, proper error recovery): Silent failures on multi-line responses violate these requirements.

🤖 Prompt for AI Agents
In @.agent/scripts/self-improve-helper.sh around lines 281 - 334, The proposals
extraction fails for multi-line JSON because proposals=$(echo "$response" | jq
-r '.parts[] | select(.type == "text") | .text' 2>/dev/null | grep -o '\[.*\]' |
head -1 || echo "[]") uses a single-line grep and a greedy regex; change the
extraction to parse the full response with jq and validate with jq --exit-status
to ensure JSON-only output: call send_prompt as before, capture response, then
use jq to locate and parse the JSON array (e.g., filter .parts[][].text or
assemble candidate strings) and run jq . to validate; if validation fails, log
the raw response and return error; update the variable proposals and the error
branch that checks proposals (the log_warn block) to handle empty/invalid JSON
returned by jq and to avoid silent failures from grep.

Comment on lines +90 to +473
## TypeScript SDK

### Installation

```bash
npm install @opencode-ai/sdk
```

### Creating a Client

```typescript
import { createOpencode, createOpencodeClient } from "@opencode-ai/sdk"

// Option 1: Start server + client together
const { client, server } = await createOpencode({
port: 4096,
hostname: "127.0.0.1",
config: {
model: "anthropic/claude-sonnet-4-20250514",
},
})

// Option 2: Connect to existing server
const client = createOpencodeClient({
baseUrl: "http://localhost:4096",
})
```

### Session Management

```typescript
// Create a new session
const session = await client.session.create({
body: { title: "My automated task" },
})

// List all sessions
const sessions = await client.session.list()

// Get session details
const details = await client.session.get({
path: { id: session.data.id },
})

// Delete a session
await client.session.delete({
path: { id: session.data.id },
})
```

### Sending Prompts

```typescript
// Synchronous prompt (waits for full response)
const result = await client.session.prompt({
path: { id: session.data.id },
body: {
model: {
providerID: "anthropic",
modelID: "claude-sonnet-4-20250514",
},
parts: [{ type: "text", text: "Explain this codebase structure" }],
},
})

console.log(result.data.parts) // AI response parts

// Asynchronous prompt (fire and forget)
await client.session.promptAsync({
path: { id: session.data.id },
body: {
parts: [{ type: "text", text: "Run the test suite" }],
},
})
// Returns 204 No Content immediately
// Monitor via SSE events
```

### Context Injection (No Reply)

```typescript
// Inject context without triggering AI response
await client.session.prompt({
path: { id: session.data.id },
body: {
noReply: true,
parts: [
{
type: "text",
text: "Context: This project uses TypeScript and Bun runtime.",
},
],
},
})
```

### Real-Time Events (SSE)

```typescript
// Subscribe to server events
const events = await client.event.subscribe()

for await (const event of events.stream) {
switch (event.type) {
case "session.message":
console.log("New message:", event.properties)
break
case "session.status":
console.log("Status change:", event.properties)
break
case "tool.call":
console.log("Tool invoked:", event.properties)
break
}
}
```

## Direct HTTP API

### Create Session

```bash
curl -X POST http://localhost:4096/session \
-H "Content-Type: application/json" \
-d '{"title": "API Test Session"}'
```

### Send Prompt (Sync)

```bash
curl -X POST http://localhost:4096/session/{session_id}/message \
-H "Content-Type: application/json" \
-d '{
"model": {
"providerID": "anthropic",
"modelID": "claude-sonnet-4-20250514"
},
"parts": [{"type": "text", "text": "Hello!"}]
}'
```

### Send Prompt (Async)

```bash
curl -X POST http://localhost:4096/session/{session_id}/prompt_async \
-H "Content-Type: application/json" \
-d '{
"parts": [{"type": "text", "text": "Run tests in background"}]
}'
# Returns 204 immediately
```

### Subscribe to Events

```bash
curl -N http://localhost:4096/event
# SSE stream - first event is server.connected
```

### Execute Slash Command

```bash
curl -X POST http://localhost:4096/session/{session_id}/command \
-H "Content-Type: application/json" \
-d '{
"command": "remember",
"arguments": "This pattern worked for async processing"
}'
```

### Run Shell Command

```bash
curl -X POST http://localhost:4096/session/{session_id}/shell \
-H "Content-Type: application/json" \
-d '{
"agent": "default",
"command": "npm test"
}'
```

## Use Cases for aidevops

### 1. Parallel Agent Orchestration

Run multiple AI sessions concurrently for different tasks:

```typescript
import { createOpencodeClient } from "@opencode-ai/sdk"

const client = createOpencodeClient({ baseUrl: "http://localhost:4096" })

// Create parallel sessions for different tasks
const [codeReview, docGen, testGen] = await Promise.all([
client.session.create({ body: { title: "Code Review" } }),
client.session.create({ body: { title: "Documentation" } }),
client.session.create({ body: { title: "Test Generation" } }),
])

// Dispatch tasks in parallel
await Promise.all([
client.session.promptAsync({
path: { id: codeReview.data.id },
body: { parts: [{ type: "text", text: "Review src/auth.ts for security issues" }] },
}),
client.session.promptAsync({
path: { id: docGen.data.id },
body: { parts: [{ type: "text", text: "Generate API documentation for src/api/" }] },
}),
client.session.promptAsync({
path: { id: testGen.data.id },
body: { parts: [{ type: "text", text: "Generate unit tests for src/utils/" }] },
}),
])
```

### 2. Voice Dispatch (VoiceInk/iOS Shortcut)

Send voice transcriptions to OpenCode:

```bash
#!/bin/bash
# voice-dispatch.sh - Called by VoiceInk or iOS Shortcut

TRANSCRIPTION="$1"
SESSION_ID="${OPENCODE_SESSION_ID:-default}"
SERVER="http://localhost:4096"

curl -X POST "$SERVER/session/$SESSION_ID/prompt_async" \
-H "Content-Type: application/json" \
-d "{\"parts\": [{\"type\": \"text\", \"text\": \"$TRANSCRIPTION\"}]}"
```

### 3. Automated Agent Testing

Test agent changes in isolated sessions:

```typescript
async function testAgentChange(testPrompt: string, expectedPattern: RegExp) {
const client = createOpencodeClient({ baseUrl: "http://localhost:4096" })

// Create isolated test session
const session = await client.session.create({
body: { title: `Test: ${Date.now()}` },
})

try {
// Send test prompt
const result = await client.session.prompt({
path: { id: session.data.id },
body: {
parts: [{ type: "text", text: testPrompt }],
},
})

// Extract text from response
const responseText = result.data.parts
.filter((p) => p.type === "text")
.map((p) => p.text)
.join("\n")

// Validate response
const passed = expectedPattern.test(responseText)
return { passed, response: responseText }
} finally {
// Cleanup
await client.session.delete({ path: { id: session.data.id } })
}
}
```

### 4. Self-Improving Agent Loop

Query memory, generate improvements, test in isolated session:

```typescript
async function selfImproveLoop() {
const client = createOpencodeClient({ baseUrl: "http://localhost:4096" })

// 1. Review phase - analyze memory for patterns
const reviewSession = await client.session.create({
body: { title: "Self-Improve: Review" },
})

const analysis = await client.session.prompt({
path: { id: reviewSession.data.id },
body: {
parts: [
{
type: "text",
text: `Analyze recent memory entries for failure patterns:

/recall --type FAILURE --recent 20

Identify gaps where we failed but don't have solutions.
Output as JSON: { gaps: [{ pattern, frequency, suggestion }] }`,
},
],
},
})

// 2. Refine phase - generate improvements
const refineSession = await client.session.create({
body: { title: "Self-Improve: Refine" },
})

const improvements = await client.session.prompt({
path: { id: refineSession.data.id },
body: {
parts: [
{
type: "text",
text: `Based on these gaps, propose agent improvements:
${JSON.stringify(analysis.data)}

Generate specific edits to agent files. Use worktree isolation.`,
},
],
},
})

// 3. Test phase - validate in isolated session
const testSession = await client.session.create({
body: { title: "Self-Improve: Test" },
})

// Run test prompts against improved agents...

// 4. PR phase - create PR if tests pass (with privacy filter)
}
```

### 5. CI/CD Integration

Trigger AI analysis from GitHub Actions:

```yaml
# .github/workflows/ai-review.yml
name: AI Code Review

on:
pull_request:
types: [opened, synchronize]

jobs:
ai-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Start OpenCode Server
run: |
opencode serve --port 4096 &
sleep 5

- name: Run AI Review
run: |
SESSION=$(curl -s -X POST http://localhost:4096/session \
-H "Content-Type: application/json" \
-d '{"title": "PR Review"}' | jq -r '.id')

curl -X POST "http://localhost:4096/session/$SESSION/message" \
-H "Content-Type: application/json" \
-d '{
"parts": [{
"type": "text",
"text": "Review the changes in this PR for security issues and code quality. Output as markdown."
}]
}' | jq -r '.parts[0].text' > review.md

- name: Post Review Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs')
const review = fs.readFileSync('review.md', 'utf8')
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: review
})
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Move deep API/SDK examples to authoritative sources.
Lines 90‑473 embed extensive TS/Bash/YAML examples. Keep this doc as an overview and point to authoritative sources (official docs or repo scripts with file:line references) rather than inline blocks.

As per coding guidelines: .agent/**/*.md: Apply progressive disclosure pattern by using pointers to subagents rather than including inline content in agent documentation; Include code examples only when authoritative; use file:line references to point to actual implementation instead of inline code snippets.

🤖 Prompt for AI Agents
In @.agent/tools/ai-assistants/opencode-server.md around lines 90 - 473, The
"TypeScript SDK" and subsequent long example sections (e.g., headings "Creating
a Client", "Session Management", "Sending Prompts", "Direct HTTP API", and all
numbered use-case examples) are too large for this agent doc; replace the
embedded TS/Bash/YAML blocks with short overview text and explicit pointers to
the authoritative examples and implementation (e.g., link or repo reference to
the SDK README and the server/example scripts), and move the full code samples
out to those canonical files; keep only a one-line minimal snippet or CLI
example where necessary and add "See: [authoritative doc or file:line]"
references for "createOpencode/createOpencodeClient", session methods
(session.create, session.prompt/promptAsync), event.subscribe, and the CI YAML
so readers are directed to the real source.

Comment on lines +44 to +221
## Usage

### Scan for Issues

```bash
# Scan current directory
privacy-filter-helper.sh scan

# Scan specific path
privacy-filter-helper.sh scan ./src

# Scan staged changes only
git diff --cached --name-only | xargs privacy-filter-helper.sh scan
```

### Preview Redactions

```bash
# See what would be redacted (dry-run)
privacy-filter-helper.sh filter

# Preview specific files
privacy-filter-helper.sh filter ./config
```

### Apply Redactions

```bash
# Apply redactions (creates .privacy-backup files)
privacy-filter-helper.sh apply

# Review and commit
git diff
git add -p
```

## Detected Patterns

### Credentials

| Pattern | Example |
|---------|---------|
| API keys | `sk-abc123...`, `pk-xyz789...` |
| AWS keys | `AKIAIOSFODNN7EXAMPLE` |
| GitHub tokens | `ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
| Stripe keys | `sk_live_...`, `pk_test_...` |
| Slack tokens | `xoxb-...` |
| JWT tokens | `eyJhbGciOiJIUzI1NiIs...` |
| Bearer tokens | `Bearer eyJ...` |

### Personal Information

| Pattern | Example |
|---------|---------|
| Email addresses | `user@example.com` |
| Home paths | `/Users/john/`, `/home/jane/` |
| Windows paths | `C:\Users\admin\` |

### Internal URLs

| Pattern | Example |
|---------|---------|
| Localhost | `localhost:3000`, `127.0.0.1:8080` |
| Database URLs | `mongodb://user:pass@host/db` |
| Internal domains | Custom patterns via config |

### Private Keys

| Pattern | Example |
|---------|---------|
| RSA keys | `-----BEGIN RSA PRIVATE KEY-----` |
| EC keys | `-----BEGIN EC PRIVATE KEY-----` |
| OpenSSH keys | `-----BEGIN OPENSSH PRIVATE KEY-----` |

## Custom Patterns

### Global Patterns

Add patterns that apply to all projects:

```bash
# Add a pattern
privacy-filter-helper.sh patterns add 'mycompany\.internal'

# Edit patterns file
privacy-filter-helper.sh patterns edit
```

Location: `~/.aidevops/config/privacy-patterns.txt`

### Project Patterns

Add patterns specific to a project:

```bash
# Add project pattern
privacy-filter-helper.sh patterns add-project 'staging\.example\.com'

# Edit project patterns
privacy-filter-helper.sh patterns edit-project
```

Location: `.aidevops/privacy-patterns.txt`

### Pattern Format

Patterns use POSIX extended regular expressions:

```text
# Comments start with #
# Each line is a regex pattern

# Internal domains
staging\.mycompany\.com
dev\.mycompany\.com

# Project-specific secrets
MY_PROJECT_[A-Z]+_KEY

# Custom usernames
(john|jane|admin)@mycompany\.com
```

## Integration with Self-Improving Agents

The privacy filter is mandatory in the PR phase (t116.4) of the self-improving agent system:

```bash
# In self-improve-helper.sh pr command:

# 1. Run privacy filter
if ! privacy-filter-helper.sh scan "$worktree_path"; then
echo "Privacy issues detected. Review and fix before PR."
exit 1
fi

# 2. Show redacted diff for approval
privacy-filter-helper.sh filter "$worktree_path"
read -p "Approve PR creation? [y/N] " approval

# 3. Create PR only if approved
if [[ "$approval" == "y" ]]; then
gh pr create ...
fi
```

## Integration with Git Hooks

Add to pre-commit hook for automatic scanning:

```bash
# .git/hooks/pre-commit
#!/bin/bash

# Run privacy filter on staged files
staged_files=$(git diff --cached --name-only)
if [[ -n "$staged_files" ]]; then
echo "$staged_files" | xargs ~/.aidevops/agents/scripts/privacy-filter-helper.sh scan
if [[ $? -ne 0 ]]; then
echo "Privacy issues detected. Fix before committing."
exit 1
fi
fi
```

## Secretlint Integration

The privacy filter uses Secretlint for credential detection:

```bash
# Install secretlint
npm install -g secretlint @secretlint/secretlint-rule-preset-recommend

# Or use npx (automatic)
# The filter falls back to npx if secretlint isn't installed
```

Secretlint provides more comprehensive credential detection than regex patterns alone.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Collapse detailed CLI walkthroughs into pointers to the helper script.
Lines 44‑221 include extensive command sequences. Please reference .agent/scripts/privacy-filter-helper.sh with file:line pointers and keep this doc as a concise overview.

As per coding guidelines: .agent/**/*.md: Apply progressive disclosure pattern by using pointers to subagents rather than including inline content in agent documentation; Include code examples only when authoritative; use file:line references to point to actual implementation instead of inline code snippets.

🤖 Prompt for AI Agents
In @.agent/tools/security/privacy-filter.md around lines 44 - 221, Collapse the
long CLI walkthrough in .agent/tools/security/privacy-filter.md (section
starting at the Usage header with many command examples) into a concise overview
that points readers to the actual implementation script
.agent/scripts/privacy-filter-helper.sh with file:line references for the
relevant functions/flags (e.g., the scan, filter, apply, patterns, and patterns
add-project handlers inside privacy-filter-helper.sh); remove the inline
multi-line command blocks and retain only one brief example for authoritative
usage, plus explicit file:line pointers to the helper script where the full
commands and behavior live, and ensure the "Integration with Self-Improving
Agents" and "Git Hooks" sections reference the specific functions/lines in
privacy-filter-helper.sh instead of embedding full scripts.

Comment on lines +229 to +235
1. Review the pattern causing the match
2. Add an exception to `.aidevops/privacy-patterns.txt`:

```text
# Exclude test fixtures
!test/fixtures/
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The “!pattern” exclusion example isn’t supported by the helper.
Line 229‑235 suggests negation (!test/fixtures/), but privacy-filter-helper.sh treats every line as a positive regex, so this won’t exclude anything. Either implement negation support or update the doc to a supported workaround.

✍️ Suggested doc tweak
-2. Add an exception to `.aidevops/privacy-patterns.txt`:
-
-```text
-# Exclude test fixtures
-!test/fixtures/
-```
+2. Narrow the matching regex or move fixtures under ignored paths (e.g., `.gitignore`).
+   Note: negation patterns (`!`) are not currently supported by privacy-filter-helper.sh.
🤖 Prompt for AI Agents
In @.agent/tools/security/privacy-filter.md around lines 229 - 235, The
documentation shows a negation pattern (!test/fixtures/) that
privacy-filter-helper.sh does not support; update .aidevops/privacy-patterns.txt
examples and the privacy-filter.md instructions to remove the negation example
and instead show a supported workaround (e.g., narrow the regex or move fixtures
to ignored paths like .gitignore) and add an explicit note that
privacy-filter-helper.sh treats every line as a positive regex and does not
support leading "!" negation; reference the helper script name
privacy-filter-helper.sh and the patterns file .aidevops/privacy-patterns.txt so
reviewers can locate and edit the offending example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant