From a105f1a95f63fd040d8dc4f411a4d5696943117f Mon Sep 17 00:00:00 2001 From: Owen Qwen Date: Fri, 27 Mar 2026 18:26:37 -0500 Subject: [PATCH 1/3] chore: updating the system prompt to remove uneeded lines and be more direct --- src/llm/system-prompt.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/llm/system-prompt.ts b/src/llm/system-prompt.ts index d8b78dc..e378f0e 100644 --- a/src/llm/system-prompt.ts +++ b/src/llm/system-prompt.ts @@ -23,18 +23,18 @@ export function buildSystemPrompt(config: BuddyConfig, channel: PromptChannel = } return [ - `You are ${botName}, a local terminal-first AI assistant that helps the user inside a CLI application called buddy.`, + `You are ${botName}, a AI assistant that helps the user.`, userName ? `The user's name is ${userName}.` : "The user's name has not been configured.", "", "Your role:", - "- Help the user think, plan, write, edit, and operate files from a local assistant interface.", + "- Help the user think, plan, write, edit, and operate the users computer in some ways.", "- Be practical, accurate, and clear.", "- Prefer useful action and direct answers over vague commentary.", "", "Your environment:", - "- You are operating in a local assistant environment, not a web chat.", + "- You are operating in a assistant environment, not a web chat.", "- The user may expect help with files, code, configuration, and terminal-oriented tasks.", - "- You should act like a capable local assistant that can inspect and modify files through tools when those tools are available.", + "- You should act like a capable assistant that can inspect and modify files through tools when those tools are available.", `- Your default workspace is ${workspacePath}. Unless the user asks otherwise, you should treat that as the main place to read, create, edit, and organize files.`, "- When a file path is relative, treat it as relative to the workspace by default.", "- If the user says 'desktop', assume they mean this assistant's own desktop/local environment by default, not the OS Desktop folder.", @@ -51,11 +51,11 @@ export function buildSystemPrompt(config: BuddyConfig, channel: PromptChannel = : undefined, "- Do not claim you changed a file unless you actually used a file-writing tool successfully.", "- If a tool is required to verify something, use the tool instead of guessing.", - "- Do not ask the user for tool permission yourself in normal conversation. Attempt the tool call directly when it is appropriate.", + "- Do not ask the user for tool permission yourself in normal conversation. Attempt the tool call directly. If it requires permission, the user will be prompted automatically.", "- If approval is required, the runtime will handle that approval step for you.", - "- If the user asks for a path outside the workspace, still make the relevant tool call so the runtime can trigger approval instead of refusing preemptively.", + "- If the users task path is outside the workspace, still make the relevant tool call so the runtime can trigger approval instead of refusing preemptively.", "- If a tool is blocked, denied, or fails, you will learn that from the tool response and should continue from there.", - "- If you cannot complete an action, explain exactly what is blocked.", + "- If you cannot complete an action, explain exactly what is blocked. Make sure to try everything before giving up.", "", "Guardrails and restrictions:", `- Access level is currently set to ${config.restrictions.accessLevel}.`, @@ -69,9 +69,6 @@ export function buildSystemPrompt(config: BuddyConfig, channel: PromptChannel = "How to respond:", "- Be concise by default, but include enough detail to be useful.", "- Use clear, direct language and avoid filler.", - "- If the user asks for an explanation, give a structured explanation.", - "- If the user asks for help writing or editing something, provide concrete output rather than abstract advice.", - "- If there is uncertainty, say what is certain and what is uncertain.", channel === "discord" ? "- You are replying inside Discord, so avoid tables and other non-Discord markdown." : undefined, channel === "discord" ? "- Prefer short paragraphs, simple bullets, inline code, and fenced code blocks. Do not use markdown tables, footnotes, HTML, or other formatting that may render poorly in Discord." From 18fb0c1a97c2f57f77801b4090759caea2459612 Mon Sep 17 00:00:00 2001 From: Owen Qwen Date: Fri, 27 Mar 2026 18:51:17 -0500 Subject: [PATCH 2/3] chore: automate development and production releases --- .github/workflows/create-release.yml | 132 +++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/create-release.yml diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..8b9500e --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,132 @@ +name: Create Release + +on: + push: + branches: + - development + - production + +permissions: + contents: write + +jobs: + create-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Determine release metadata + id: release + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + + branch="${GITHUB_REF_NAME}" + before="${{ github.event.before }}" + head="${GITHUB_SHA}" + current_version="$(node -p "require('./package.json').version")" + + previous_version="" + if [[ "$before" != "0000000000000000000000000000000000000000" ]]; then + if git cat-file -e "${before}:package.json" 2>/dev/null; then + previous_version="$( + git show "${before}:package.json" \ + | node -p "JSON.parse(require('node:fs').readFileSync(0, 'utf8')).version" + )" + fi + fi + + if [[ "$current_version" == "$previous_version" ]]; then + echo "should_release=false" >> "$GITHUB_OUTPUT" + echo "Package version is unchanged; skipping release." + exit 0 + fi + + if [[ "$branch" == "development" ]]; then + tag="v${current_version}-dev" + previous_tag="$( + git tag --list 'v*-dev' --sort=-creatordate \ + | grep -Fxv "$tag" \ + | head -n 1 || true + )" + elif [[ "$branch" == "production" ]]; then + tag="v${current_version}" + previous_tag="$( + git tag --list 'v*' --sort=-creatordate \ + | grep -Ev -- '-dev$' \ + | grep -Fxv "$tag" \ + | head -n 1 || true + )" + else + echo "should_release=false" >> "$GITHUB_OUTPUT" + echo "Branch ${branch} is not configured for releases." + exit 0 + fi + + if gh release view "$tag" >/dev/null 2>&1; then + echo "should_release=false" >> "$GITHUB_OUTPUT" + echo "Release ${tag} already exists; skipping." + exit 0 + fi + + echo "should_release=true" >> "$GITHUB_OUTPUT" + echo "tag=${tag}" >> "$GITHUB_OUTPUT" + echo "previous_tag=${previous_tag}" >> "$GITHUB_OUTPUT" + echo "version=${current_version}" >> "$GITHUB_OUTPUT" + echo "Release ${tag} will be created." + + - name: Generate release notes + if: steps.release.outputs.should_release == 'true' + shell: bash + run: | + set -euo pipefail + + tag="${{ steps.release.outputs.tag }}" + previous_tag="${{ steps.release.outputs.previous_tag }}" + + { + echo "## Changes" + echo + + if [[ -n "$previous_tag" ]]; then + echo "Commits since ${previous_tag}:" + echo + git log "${previous_tag}..${GITHUB_SHA}" --pretty=format:'- %s (%h)' + else + echo "Commits included in this release:" + echo + git log "${GITHUB_SHA}" --pretty=format:'- %s (%h)' + fi + } > release-notes.md + + if [[ ! -s release-notes.md ]]; then + printf '## Changes\n\n- No commits found.\n' > release-notes.md + fi + + echo "Prepared release notes for ${tag}:" + cat release-notes.md + + - name: Create GitHub release + if: steps.release.outputs.should_release == 'true' + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + + tag="${{ steps.release.outputs.tag }}" + gh release create "$tag" \ + --target "${GITHUB_SHA}" \ + --title "$tag" \ + --notes-file release-notes.md diff --git a/package.json b/package.json index e5e822c..1340f53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@teichai/buddy", - "version": "0.0.2", + "version": "0.0.3", "description": "Terminal-first AI assistant with onboarding, chat UI, and local or remote server support.", "license": "MIT", "type": "module", From 6092e75faefb04dfd0988d2dfce8b4bff37f806b Mon Sep 17 00:00:00 2001 From: Owen Qwen Date: Fri, 27 Mar 2026 18:58:39 -0500 Subject: [PATCH 3/3] Update release workflow to refresh notes and assets --- .github/workflows/create-release.yml | 113 +++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 14 deletions(-) diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 8b9500e..b71440d 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -23,6 +23,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: 22 + cache: npm - name: Determine release metadata id: release @@ -34,7 +35,6 @@ jobs: branch="${GITHUB_REF_NAME}" before="${{ github.event.before }}" - head="${GITHUB_SHA}" current_version="$(node -p "require('./package.json').version")" previous_version="" @@ -47,10 +47,9 @@ jobs: fi fi - if [[ "$current_version" == "$previous_version" ]]; then - echo "should_release=false" >> "$GITHUB_OUTPUT" - echo "Package version is unchanged; skipping release." - exit 0 + version_changed=false + if [[ "$current_version" != "$previous_version" ]]; then + version_changed=true fi if [[ "$branch" == "development" ]]; then @@ -69,25 +68,33 @@ jobs: | head -n 1 || true )" else - echo "should_release=false" >> "$GITHUB_OUTPUT" + echo "release_action=skip" >> "$GITHUB_OUTPUT" echo "Branch ${branch} is not configured for releases." exit 0 fi if gh release view "$tag" >/dev/null 2>&1; then - echo "should_release=false" >> "$GITHUB_OUTPUT" - echo "Release ${tag} already exists; skipping." - exit 0 + release_action="update" + else + release_action="create" + fi + + if [[ "$release_action" == "create" && "$version_changed" == "true" ]]; then + echo "Package version changed; creating ${tag}." + elif [[ "$release_action" == "create" ]]; then + echo "No release exists for ${tag}; creating it." + else + echo "Release ${tag} exists; updating its notes." fi - echo "should_release=true" >> "$GITHUB_OUTPUT" + echo "release_action=${release_action}" >> "$GITHUB_OUTPUT" echo "tag=${tag}" >> "$GITHUB_OUTPUT" echo "previous_tag=${previous_tag}" >> "$GITHUB_OUTPUT" echo "version=${current_version}" >> "$GITHUB_OUTPUT" - echo "Release ${tag} will be created." + echo "version_changed=${version_changed}" >> "$GITHUB_OUTPUT" - name: Generate release notes - if: steps.release.outputs.should_release == 'true' + if: steps.release.outputs.release_action != 'skip' shell: bash run: | set -euo pipefail @@ -117,8 +124,57 @@ jobs: echo "Prepared release notes for ${tag}:" cat release-notes.md + - name: Install dependencies + if: steps.release.outputs.release_action != 'skip' + run: npm ci + + - name: Build release assets + if: steps.release.outputs.release_action != 'skip' + shell: bash + run: | + set -euo pipefail + + tag="${{ steps.release.outputs.tag }}" + asset_base="buddy-${tag}" + + rm -rf release-assets + mkdir -p release-assets + + pack_json="$(npm pack --json --pack-destination release-assets)" + pack_file="$( + node -e 'const data = JSON.parse(process.argv[1]); process.stdout.write(data[0].filename);' \ + "$pack_json" + )" + + mv "release-assets/${pack_file}" "release-assets/${asset_base}.tgz" + + temp_dir="$(mktemp -d)" + trap 'rm -rf "$temp_dir"' EXIT + + tar -xzf "release-assets/${asset_base}.tgz" -C "$temp_dir" + ( + cd "$temp_dir/package" + zip -rq "$GITHUB_WORKSPACE/release-assets/${asset_base}.zip" . + ) + + ls -lh release-assets + + - name: Update release tag + if: steps.release.outputs.release_action != 'skip' + shell: bash + run: | + set -euo pipefail + + tag="${{ steps.release.outputs.tag }}" + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git tag -f "$tag" "${GITHUB_SHA}" + git push --force origin "refs/tags/${tag}" + - name: Create GitHub release - if: steps.release.outputs.should_release == 'true' + if: steps.release.outputs.release_action == 'create' env: GH_TOKEN: ${{ github.token }} shell: bash @@ -127,6 +183,35 @@ jobs: tag="${{ steps.release.outputs.tag }}" gh release create "$tag" \ - --target "${GITHUB_SHA}" \ --title "$tag" \ + --verify-tag \ --notes-file release-notes.md + + - name: Update GitHub release notes + if: steps.release.outputs.release_action == 'update' + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + + tag="${{ steps.release.outputs.tag }}" + gh release edit "$tag" \ + --title "$tag" \ + --notes-file release-notes.md + + - name: Upload release assets + if: steps.release.outputs.release_action != 'skip' + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + set -euo pipefail + + tag="${{ steps.release.outputs.tag }}" + asset_base="buddy-${tag}" + + gh release upload "$tag" \ + "release-assets/${asset_base}.tgz" \ + "release-assets/${asset_base}.zip" \ + --clobber