-
Notifications
You must be signed in to change notification settings - Fork 8
feat: inherit OpenCode prompts for Build+ and Plan+ agents #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| #!/bin/bash | ||
| # ============================================================================= | ||
| # Extract OpenCode Prompts from Binary | ||
| # ============================================================================= | ||
| # Extracts embedded prompts from the OpenCode binary for use by aidevops agents. | ||
| # This ensures our agents stay in sync with OpenCode updates. | ||
| # | ||
| # Usage: ./extract-opencode-prompts.sh | ||
| # Output: ~/.aidevops/cache/opencode-prompts/ | ||
| # ============================================================================= | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| # Colors | ||
| GREEN='\033[0;32m' | ||
| BLUE='\033[0;34m' | ||
| YELLOW='\033[1;33m' | ||
| # shellcheck disable=SC2034 # RED reserved for future error messages | ||
| RED='\033[0;31m' | ||
| NC='\033[0m' | ||
|
|
||
| CACHE_DIR="$HOME/.aidevops/cache/opencode-prompts" | ||
| OPENCODE_BIN="" | ||
|
|
||
| # Find OpenCode binary | ||
| find_opencode_binary() { | ||
| local locations=( | ||
| "$HOME/.bun/install/global/node_modules/opencode-darwin-arm64/bin/opencode" | ||
| "$HOME/.bun/install/global/node_modules/opencode-darwin-x64/bin/opencode" | ||
| "$HOME/.bun/install/global/node_modules/opencode-linux-x64/bin/opencode" | ||
| "$HOME/.bun/install/global/node_modules/opencode-linux-arm64/bin/opencode" | ||
| "/usr/local/bin/opencode" | ||
| "$HOME/.local/bin/opencode" | ||
| ) | ||
|
|
||
| for loc in "${locations[@]}"; do | ||
| if [[ -f "$loc" ]]; then | ||
| OPENCODE_BIN="$loc" | ||
| return 0 | ||
| fi | ||
| done | ||
|
|
||
| # Try which as fallback | ||
| if command -v opencode &>/dev/null; then | ||
| local bin_path | ||
| bin_path=$(which opencode) | ||
| # Follow symlinks to find actual binary | ||
| if [[ -L "$bin_path" ]]; then | ||
| bin_path=$(readlink -f "$bin_path" 2>/dev/null || readlink "$bin_path") | ||
| fi | ||
| if [[ -f "$bin_path" ]]; then | ||
| OPENCODE_BIN="$bin_path" | ||
| return 0 | ||
| fi | ||
| fi | ||
|
|
||
| return 1 | ||
| } | ||
|
Comment on lines
+26
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function Consider refactoring this function to print the found path to standard output. The calling function ( |
||
|
|
||
| # Extract a specific prompt by variable name | ||
| # Usage: extract_prompt "plan_default" "plan.txt" | ||
| extract_prompt() { | ||
| local var_name="$1" | ||
| local output_file="$2" | ||
| local start_marker="var ${var_name} = \`" | ||
|
|
||
| # Extract content between backticks | ||
| strings "$OPENCODE_BIN" | \ | ||
| grep -A 500 "^${start_marker}" | \ | ||
| head -n 100 | \ | ||
| sed "s/^${start_marker}//" | \ | ||
| sed '/^var init_/q' | \ | ||
| sed '/^var init_/d' | \ | ||
| sed 's/`$//' \ | ||
| > "$CACHE_DIR/$output_file" | ||
|
Comment on lines
+68
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This extraction logic is very brittle as it relies on parsing the string table of the compiled
The script's assumptions about variable names ( For long-term stability, a more robust solution would be for OpenCode to provide a command to export these prompts (e.g., |
||
|
|
||
| # Verify extraction worked | ||
| if [[ -s "$CACHE_DIR/$output_file" ]]; then | ||
| echo -e " ${GREEN}✓${NC} Extracted $output_file" | ||
| return 0 | ||
| else | ||
| echo -e " ${YELLOW}⚠${NC} Failed to extract $output_file" | ||
| return 1 | ||
| fi | ||
| } | ||
|
|
||
| # Get OpenCode version | ||
| get_opencode_version() { | ||
| if command -v opencode &>/dev/null; then | ||
| opencode --version 2>/dev/null || echo "unknown" | ||
| else | ||
| echo "unknown" | ||
| fi | ||
| } | ||
|
|
||
| main() { | ||
| echo -e "${BLUE}Extracting OpenCode prompts...${NC}" | ||
|
|
||
| # Find binary | ||
| if ! find_opencode_binary; then | ||
| echo -e "${YELLOW}Warning: OpenCode binary not found. Skipping prompt extraction.${NC}" | ||
| echo -e "${YELLOW}Install OpenCode with: bun install -g opencode-ai${NC}" | ||
| return 0 | ||
| fi | ||
|
|
||
| echo -e " Found binary: $OPENCODE_BIN" | ||
|
|
||
| # Create cache directory | ||
| mkdir -p "$CACHE_DIR" | ||
|
|
||
| # Get version for tracking | ||
| local version | ||
| version=$(get_opencode_version) | ||
| echo "$version" > "$CACHE_DIR/version.txt" | ||
| echo -e " OpenCode version: $version" | ||
|
|
||
| # Extract prompts | ||
| extract_prompt "plan_default" "plan-reminder.txt" || true | ||
| extract_prompt "build_switch_default" "build-switch.txt" || true | ||
| extract_prompt "max_steps_default" "max-steps.txt" || true | ||
|
|
||
| # Record extraction timestamp | ||
| date -u +"%Y-%m-%dT%H:%M:%SZ" > "$CACHE_DIR/extracted-at.txt" | ||
|
|
||
| echo -e "${GREEN}Done!${NC} Prompts cached in $CACHE_DIR" | ||
| } | ||
|
|
||
| main "$@" | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -907,6 +907,20 @@ deploy_ai_templates() { | |||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Extract OpenCode prompts from binary (for Plan+ system-reminder) | ||||||||||||||||||||||||||||||||||||||||||||||
| # Must run before deploy_aidevops_agents so the cache exists for injection | ||||||||||||||||||||||||||||||||||||||||||||||
| extract_opencode_prompts() { | ||||||||||||||||||||||||||||||||||||||||||||||
| local extract_script=".agent/scripts/extract-opencode-prompts.sh" | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -f "$extract_script" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| if bash "$extract_script"; then | ||||||||||||||||||||||||||||||||||||||||||||||
| print_success "OpenCode prompts extracted" | ||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||
| print_warning "OpenCode prompt extraction encountered issues (non-critical)" | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Deploy aidevops agents to user location | ||||||||||||||||||||||||||||||||||||||||||||||
| deploy_aidevops_agents() { | ||||||||||||||||||||||||||||||||||||||||||||||
| print_info "Deploying aidevops agents to ~/.aidevops/agents/..." | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -947,6 +961,25 @@ deploy_aidevops_agents() { | |||||||||||||||||||||||||||||||||||||||||||||
| script_count=$(find "$target_dir/scripts" -name "*.sh" -type f 2>/dev/null | wc -l | tr -d ' ') | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| print_info "Deployed $agent_count agent files and $script_count scripts" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Inject extracted OpenCode plan-reminder into Plan+ if available | ||||||||||||||||||||||||||||||||||||||||||||||
| local plan_reminder="$HOME/.aidevops/cache/opencode-prompts/plan-reminder.txt" | ||||||||||||||||||||||||||||||||||||||||||||||
| local plan_plus="$target_dir/plan-plus.md" | ||||||||||||||||||||||||||||||||||||||||||||||
| if [[ -f "$plan_reminder" && -f "$plan_plus" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||
| # Check if plan-plus.md has the placeholder marker | ||||||||||||||||||||||||||||||||||||||||||||||
| if grep -q "OPENCODE-PLAN-REMINDER-INJECT" "$plan_plus"; then | ||||||||||||||||||||||||||||||||||||||||||||||
| # Replace placeholder with extracted content | ||||||||||||||||||||||||||||||||||||||||||||||
| local reminder_content | ||||||||||||||||||||||||||||||||||||||||||||||
| reminder_content=$(cat "$plan_reminder") | ||||||||||||||||||||||||||||||||||||||||||||||
| # Use awk to replace the placeholder section | ||||||||||||||||||||||||||||||||||||||||||||||
| awk -v content="$reminder_content" ' | ||||||||||||||||||||||||||||||||||||||||||||||
| /<!-- OPENCODE-PLAN-REMINDER-INJECT-START -->/ { print; print content; skip=1; next } | ||||||||||||||||||||||||||||||||||||||||||||||
| /<!-- OPENCODE-PLAN-REMINDER-INJECT-END -->/ { skip=0 } | ||||||||||||||||||||||||||||||||||||||||||||||
| !skip { print } | ||||||||||||||||||||||||||||||||||||||||||||||
| ' "$plan_plus" > "$plan_plus.tmp" && mv "$plan_plus.tmp" "$plan_plus" | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+972
to
+979
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using A more robust method is to have
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||
| print_info "Injected OpenCode plan-reminder into Plan+" | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||
| print_error "Failed to deploy agents" | ||||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1807,6 +1840,7 @@ main() { | |||||||||||||||||||||||||||||||||||||||||||||
| deploy_ai_templates | ||||||||||||||||||||||||||||||||||||||||||||||
| migrate_old_backups | ||||||||||||||||||||||||||||||||||||||||||||||
| cleanup_deprecated_paths | ||||||||||||||||||||||||||||||||||||||||||||||
| extract_opencode_prompts | ||||||||||||||||||||||||||||||||||||||||||||||
| deploy_aidevops_agents | ||||||||||||||||||||||||||||||||||||||||||||||
| generate_agent_skills | ||||||||||||||||||||||||||||||||||||||||||||||
| inject_agents_reference | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of
readlink -fis not portable to macOS, where it's part ofcoreutilsand not installed by default. The fallbackreadlink "$bin_path"is not a full replacement, as it only resolves one level of symbolic links, whereas-fresolves them recursively. This could cause the script to fail in finding theopencodebinary if it's located behind multiple nested symlinks. For better portability, consider a loop to resolve symlinks until a real file is found.