memex-cli 0.2.0

A CLI tool for organizing AI-assisted development into a versioned, navigable DAG of conversation nodes.
name: memex PR context

on:
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  memex-pr-context:
    name: Surface memex node context for changed files
    runs-on: ubuntu-latest
    if: "!contains(github.event.pull_request.title, '[skip memex]')"
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Cache cargo build
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-pr-context-${{ hashFiles('Cargo.lock') }}

      - name: Build memex
        run: cargo build --release --locked

      - name: Compute changed files and render PR context
        id: render
        run: |
          BASE=origin/${{ github.base_ref }}
          mapfile -t FILES < <(git diff --name-only "$BASE"...HEAD)
          if [ ${#FILES[@]} -eq 0 ]; then
            echo "No changed files; skipping comment."
            echo "skip=true" >> "$GITHUB_OUTPUT"
            exit 0
          fi
          ARGS=()
          for f in "${FILES[@]}"; do
            ARGS+=(--file "$f")
          done
          ./target/release/memex pr-context "${ARGS[@]}" > pr-context.md
          echo "skip=false" >> "$GITHUB_OUTPUT"

      - name: Upsert PR comment
        if: steps.render.outputs.skip != 'true'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const body = fs.readFileSync('pr-context.md', 'utf8');
            const marker = '<!-- memex-pr-context -->';

            const { data: comments } = await github.rest.issues.listComments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.pull_request.number,
            });

            const existing = comments.find((c) => c.body && c.body.startsWith(marker));
            if (existing) {
              await github.rest.issues.updateComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                comment_id: existing.id,
                body,
              });
              core.info(`Updated existing comment #${existing.id}.`);
            } else {
              const { data: created } = await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.payload.pull_request.number,
                body,
              });
              core.info(`Created comment #${created.id}.`);
            }