diff --git a/.github/workflows/oc.yml b/.github/workflows/oc.yml new file mode 100644 index 00000000..03f4bccb --- /dev/null +++ b/.github/workflows/oc.yml @@ -0,0 +1,74 @@ +# /oc builder, inline copy of haimcslab/oc-builder/.github/workflows/builder.yml. +# This repo is public, so it cannot call the private oc-builder workflow, and it +# runs on GitHub-hosted runners (free for public repos) instead of the dock runner. +# Keep in sync with oc-builder by hand. +name: oc builder + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + +concurrency: + group: oc-${{ github.event.issue.number || github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + opencode: + # Only owners/members/collaborators can start a run (each run spends model budget). + if: | + (contains(github.event.comment.body, '/oc') || contains(github.event.comment.body, '/opencode')) && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + issues: write + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Configure git identity + run: | + git config --global user.name "MCS Studio Builder" + git config --global user.email "builder@haimcslab.com" + + # Default config outside the workspace so it is never committed. + # A repo's own opencode.json takes precedence over it. + - name: Write default opencode config + run: | + cat > "$RUNNER_TEMP/opencode.json" <<'JSON' + { + "$schema": "https://opencode.ai/config.json", + "enabled_providers": ["haimcslab-gw"], + "model": "haimcslab-gw/workers-ai/@cf/moonshotai/kimi-k2.7-code", + "small_model": "haimcslab-gw/workers-ai/@cf/zai-org/glm-5.3-flash", + "provider": { + "haimcslab-gw": { + "npm": "@ai-sdk/openai-compatible", + "name": "haimcslab AI Gateway (builder)", + "options": { + "baseURL": "https://gateway.ai.cloudflare.com/v1/23d2119251af1e3d761921eadb8e7e0f/haimcslab/compat", + "apiKey": "{env:CF_WORKERS_AI_TOKEN}", + "headers": { "cf-aig-authorization": "Bearer {env:CF_WORKERS_AI_TOKEN}", "cf-aig-metadata": "{\"user_id\":\"github-builder\",\"repo\":\"${{ github.repository }}\"}" } + }, + "models": { + "workers-ai/@cf/moonshotai/kimi-k2.7-code": { "name": "Kimi K2.7 Code" }, + "workers-ai/@cf/zai-org/glm-5.3-flash": { "name": "GLM-5.3 Flash" } + } + } + } + } + JSON + echo "OPENCODE_CONFIG=$RUNNER_TEMP/opencode.json" >> "$GITHUB_ENV" + + - uses: anomalyco/opencode/github@2c14fc5586fe0b88e5c04732d2e846769cc35671 # tag "latest" on 2026-11-11; release tags (v2.2.x) do not contain github/ + env: + CF_WORKERS_AI_TOKEN: ${{ secrets.CF_WORKERS_AI_TOKEN }} + GITHUB_TOKEN: ${{ github.token }} + with: + model: haimcslab-gw/workers-ai/@cf/moonshotai/kimi-k2.7-code + use_github_token: true diff --git a/.github/workflows/upstream-sync.yml b/.github/workflows/upstream-sync.yml new file mode 100644 index 00000000..381c2423 --- /dev/null +++ b/.github/workflows/upstream-sync.yml @@ -0,0 +1,61 @@ +# Daily: merge OpenListTeam/OpenList-Worker main into a branch and open a PR. +# Merging the PR deploys (Workers Builds). Our wrangler.jsonc and README.md win on conflict. +# Needs secret SYNC_TOKEN: fine-grained PAT for this repo with Contents, Pull requests +# and Workflows read/write (upstream changes .github/workflows, which GITHUB_TOKEN can't push). +name: upstream sync + +on: + schedule: + - cron: "0 9 * * *" + workflow_dispatch: + +concurrency: + group: upstream-sync + cancel-in-progress: false + +jobs: + sync: + if: github.repository == 'haimcslab/OpenList-Worker' + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.SYNC_TOKEN }} + + - name: Merge upstream + id: merge + env: + GH_TOKEN: ${{ secrets.SYNC_TOKEN }} + run: | + git config user.name "upstream-sync" + git config user.email "builder@haimcslab.com" + git remote add upstream https://github.com/OpenListTeam/OpenList-Worker.git + git fetch upstream main + behind=$(git rev-list --count HEAD..upstream/main) + echo "behind=$behind" + if [ "$behind" = 0 ]; then echo "Up to date."; exit 0; fi + if gh pr list --state open --json headRefName --jq '.[].headRefName' | grep -q '^upstream-sync/'; then + echo "An upstream sync PR is already open."; exit 0 + fi + branch="upstream-sync/$(date -u +%Y%m%d)" + git checkout -b "$branch" + if ! git merge --no-edit upstream/main; then + for f in wrangler.jsonc README.md; do + if git diff --name-only --diff-filter=U | grep -qx "$f"; then git checkout --ours -- "$f"; git add "$f"; fi + done + left=$(git diff --name-only --diff-filter=U) + if [ -n "$left" ]; then + git merge --abort + body=$(printf 'Upstream has %s new commits but these files conflict:\n\n```\n%s\n```\n\nResolve with a manual merge PR (keep our wrangler.jsonc D1 config and README).' "$behind" "$left") + gh issue create --title "Upstream sync conflict ($(date -u +%F))" --body "$body" + exit 0 + fi + git commit --no-edit + fi + git push -u origin "$branch" + log=$(git log --oneline --no-merges HEAD^1..upstream/main | head -60) + gh pr create --base main --head "$branch" \ + --title "chore(sync): merge upstream main ($behind commits)" \ + --body "$(printf 'Automated merge of OpenListTeam/OpenList-Worker main. Our wrangler.jsonc and README.md are kept on conflict. Merging deploys.\n\n```\n%s\n```' "$log")" diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..22316e7c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,24 @@ +# Instructions for agents working in OpenList-Worker + +haimcslab's fork of OpenListTeam/OpenList-Worker (TypeScript, Hono + SolidJS), deployed as the Cloudflare Worker "openlist-worker" at openlist.haimcslab.com. Cloudflare Workers Builds deploys every merge to main, so a merged PR goes live. + +## How work happens +- Work arrives as a GitHub issue. Do only what the issue asks. +- Make changes on a branch and open a pull request. Never push to main. +- The PR description says what changed, why, how you tested it, and anything a person must do by hand. +- Extend existing folders instead of creating parallel ones. +- Keep each PR small. If the issue needs a decision you cannot make from the repo, ask in the issue instead of guessing. + +## Secrets +- Never print, echo, cat or commit secrets, tokens, keys, .env or config.json files. Refer to secrets by name only. +- List the secret names a person must set in the PR description. + +## .github/workflows/ +**Never create, edit or delete files here.** The builder's token cannot push workflow changes, so the push fails and the work is lost. Put proposed workflow YAML in the PR description and a person adds it. + +## Rules for this fork +- Keep our local config in wrangler.jsonc: worker name "openlist-worker", D1 binding DB (database openlist, id d905961f-18d5-4cd0-9245-1b8c1fb65b91), DB_DRIVER=d1, DB_FORMAT=sql. When merging upstream, keep ours on these lines. +- Keep our English-only README.md when merging upstream. +- Prefer upstream behavior. Put fork-only changes in as few files as possible so upstream merges stay easy. +- This repo is public. Never commit anything lab-internal (IPs, hostnames, tokens). +- Build check before a PR: `pnpm install && pnpm run build` if the change touches src/ or api/.