Skip to content

Commit 716f40b

Browse files
authored
Merge branch 'dev' into feat/canceled-prompts-in-history
2 parents 0b06ff1 + 392a6d9 commit 716f40b

494 files changed

Lines changed: 96091 additions & 51215 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/VOUCHED.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
# - Denounce with minus prefix: -username or -platform:username.
99
# - Optional details after a space following the handle.
1010
adamdotdevin
11+
-agusbasari29 AI PR slop
1112
ariane-emory
13+
edemaine
1214
-florianleibert
1315
fwang
1416
iamdavidhill

.github/actions/setup-bun/action.yml

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
name: "Setup Bun"
22
description: "Setup Bun with caching and install dependencies"
3+
inputs:
4+
cross-compile:
5+
description: "Pre-cache canary cross-compile binaries for all targets"
6+
required: false
7+
default: "false"
38
runs:
49
using: "composite"
510
steps:
@@ -11,10 +16,72 @@ runs:
1116
restore-keys: |
1217
${{ runner.os }}-bun-
1318
19+
- name: Get baseline download URL
20+
id: bun-url
21+
shell: bash
22+
run: |
23+
if [ "$RUNNER_ARCH" = "X64" ]; then
24+
case "$RUNNER_OS" in
25+
macOS) OS=darwin ;;
26+
Linux) OS=linux ;;
27+
Windows) OS=windows ;;
28+
esac
29+
echo "url=https://github.com/oven-sh/bun/releases/download/canary/bun-${OS}-x64-baseline.zip" >> "$GITHUB_OUTPUT"
30+
fi
31+
1432
- name: Setup Bun
1533
uses: oven-sh/setup-bun@v2
1634
with:
17-
bun-version-file: package.json
35+
bun-version-file: ${{ !steps.bun-url.outputs.url && 'package.json' || '' }}
36+
bun-download-url: ${{ steps.bun-url.outputs.url }}
37+
38+
- name: Pre-cache canary cross-compile binaries
39+
if: inputs.cross-compile == 'true'
40+
shell: bash
41+
run: |
42+
BUN_VERSION=$(bun --revision)
43+
if echo "$BUN_VERSION" | grep -q "canary"; then
44+
SEMVER=$(echo "$BUN_VERSION" | sed 's/^\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/')
45+
echo "Bun version: $BUN_VERSION (semver: $SEMVER)"
46+
CACHE_DIR="$HOME/.bun/install/cache"
47+
mkdir -p "$CACHE_DIR"
48+
TMP_DIR=$(mktemp -d)
49+
for TARGET in linux-aarch64 linux-x64 linux-x64-baseline linux-aarch64-musl linux-x64-musl linux-x64-musl-baseline darwin-aarch64 darwin-x64 windows-x64 windows-x64-baseline; do
50+
DEST="$CACHE_DIR/bun-${TARGET}-v${SEMVER}"
51+
if [ -f "$DEST" ]; then
52+
echo "Already cached: $DEST"
53+
continue
54+
fi
55+
URL="https://github.com/oven-sh/bun/releases/download/canary/bun-${TARGET}.zip"
56+
echo "Downloading $TARGET from $URL"
57+
if curl -sfL -o "$TMP_DIR/bun.zip" "$URL"; then
58+
unzip -qo "$TMP_DIR/bun.zip" -d "$TMP_DIR"
59+
if echo "$TARGET" | grep -q "windows"; then
60+
BIN_NAME="bun.exe"
61+
else
62+
BIN_NAME="bun"
63+
fi
64+
mv "$TMP_DIR/bun-${TARGET}/$BIN_NAME" "$DEST"
65+
chmod +x "$DEST"
66+
rm -rf "$TMP_DIR/bun-${TARGET}" "$TMP_DIR/bun.zip"
67+
echo "Cached: $DEST"
68+
# baseline bun resolves "bun-darwin-x64" to the baseline cache key
69+
# so copy the modern binary there too
70+
if [ "$TARGET" = "darwin-x64" ]; then
71+
BASELINE_DEST="$CACHE_DIR/bun-darwin-x64-baseline-v${SEMVER}"
72+
if [ ! -f "$BASELINE_DEST" ]; then
73+
cp "$DEST" "$BASELINE_DEST"
74+
echo "Cached (baseline alias): $BASELINE_DEST"
75+
fi
76+
fi
77+
else
78+
echo "Skipped: $TARGET (not available)"
79+
fi
80+
done
81+
rm -rf "$TMP_DIR"
82+
else
83+
echo "Not a canary build ($BUN_VERSION), skipping pre-cache"
84+
fi
1885
1986
- name: Install dependencies
2087
run: bun install

.github/workflows/beta.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ jobs:
2727
opencode-app-id: ${{ vars.OPENCODE_APP_ID }}
2828
opencode-app-secret: ${{ secrets.OPENCODE_APP_SECRET }}
2929

30+
- name: Install OpenCode
31+
run: bun i -g opencode-ai
32+
3033
- name: Sync beta branch
3134
env:
3235
GH_TOKEN: ${{ steps.setup-git-committer.outputs.token }}
36+
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
3337
run: bun script/beta.ts

.github/workflows/compliance-close.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ jobs:
6565
body: closeMessage,
6666
});
6767
68+
try {
69+
await github.rest.issues.removeLabel({
70+
owner: context.repo.owner,
71+
repo: context.repo.repo,
72+
issue_number: item.number,
73+
name: 'needs:compliance',
74+
});
75+
} catch (e) {}
76+
6877
if (isPR) {
6978
await github.rest.pulls.update({
7079
owner: context.repo.owner,

.github/workflows/docs-locale-sync.yml

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ jobs:
1212
if: github.actor != 'opencode-agent[bot]'
1313
runs-on: blacksmith-4vcpu-ubuntu-2404
1414
permissions:
15-
id-token: write
1615
contents: write
1716
steps:
1817
- name: Checkout repository
1918
uses: actions/checkout@v4
2019
with:
20+
persist-credentials: false
2121
fetch-depth: 0
22+
ref: ${{ github.ref_name }}
2223

2324
- name: Setup Bun
2425
uses: ./.github/actions/setup-bun
@@ -51,9 +52,54 @@ jobs:
5152
uses: sst/opencode/github@latest
5253
env:
5354
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
55+
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
56+
OPENCODE_CONFIG_CONTENT: |
57+
{
58+
"permission": {
59+
"*": "deny",
60+
"read": {
61+
"*": "deny",
62+
"packages/web/src/content/docs": "allow",
63+
"packages/web/src/content/docs/*": "allow",
64+
"packages/web/src/content/docs/*.mdx": "allow",
65+
"packages/web/src/content/docs/*/*.mdx": "allow",
66+
".opencode": "allow",
67+
".opencode/agent": "allow",
68+
".opencode/glossary": "allow",
69+
".opencode/agent/translator.md": "allow",
70+
".opencode/glossary/*.md": "allow"
71+
},
72+
"edit": {
73+
"*": "deny",
74+
"packages/web/src/content/docs/*/*.mdx": "allow"
75+
},
76+
"glob": {
77+
"*": "deny",
78+
"packages/web/src/content/docs*": "allow",
79+
".opencode/glossary*": "allow"
80+
},
81+
"task": {
82+
"*": "deny",
83+
"translator": "allow"
84+
}
85+
},
86+
"agent": {
87+
"translator": {
88+
"permission": {
89+
"*": "deny",
90+
"read": {
91+
"*": "deny",
92+
".opencode/agent/translator.md": "allow",
93+
".opencode/glossary/*.md": "allow"
94+
}
95+
}
96+
}
97+
}
98+
}
5499
with:
55-
model: opencode/gpt-5.2
100+
model: opencode/gpt-5.3-codex
56101
agent: docs
102+
use_github_token: true
57103
prompt: |
58104
Update localized docs to match the latest English docs changes.
59105
@@ -67,10 +113,11 @@ jobs:
67113
2. You MUST use the Task tool for translation work and launch subagents with subagent_type `translator` (defined in .opencode/agent/translator.md).
68114
3. Do not translate directly in the primary agent. Use translator subagent output as the source for locale text updates.
69115
4. Run translator subagent Task calls in parallel whenever file/locale translation work is independent.
70-
5. Preserve frontmatter keys, internal links, code blocks, and existing locale-specific metadata unless the English change requires an update.
71-
6. Keep locale docs structure aligned with their corresponding English pages.
72-
7. Do not modify English source docs in packages/web/src/content/docs/*.mdx.
73-
8. If no locale updates are needed, make no changes.
116+
5. Use only the minimum tools needed for this task (read/glob, file edits, and translator Task). Do not use shell, web, search, or GitHub tools for translation work.
117+
6. Preserve frontmatter keys, internal links, code blocks, and existing locale-specific metadata unless the English change requires an update.
118+
7. Keep locale docs structure aligned with their corresponding English pages.
119+
8. Do not modify English source docs in packages/web/src/content/docs/*.mdx.
120+
9. If no locale updates are needed, make no changes.
74121
75122
- name: Commit and push locale docs updates
76123
if: steps.changes.outputs.has_changes == 'true'

.github/workflows/pr-standards.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@ jobs:
108108
109109
await removeLabel('needs:title');
110110
111-
// Step 2: Check for linked issue (skip for docs/refactor PRs)
112-
const skipIssueCheck = /^(docs|refactor)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
111+
// Step 2: Check for linked issue (skip for docs/refactor/feat PRs)
112+
const skipIssueCheck = /^(docs|refactor|feat)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
113113
if (skipIssueCheck) {
114114
await removeLabel('needs:issue');
115-
console.log('Skipping issue check for docs/refactor PR');
115+
console.log('Skipping issue check for docs/refactor/feat PR');
116116
return;
117117
}
118118
const query = `
@@ -189,7 +189,7 @@ jobs:
189189
190190
const body = pr.body || '';
191191
const title = pr.title;
192-
const isDocsOrRefactor = /^(docs|refactor)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
192+
const isDocsRefactorOrFeat = /^(docs|refactor|feat)\s*(\([a-zA-Z0-9-]+\))?\s*:/.test(title);
193193
194194
const issues = [];
195195
@@ -225,8 +225,8 @@ jobs:
225225
}
226226
}
227227
228-
// Check: issue reference (skip for docs/refactor)
229-
if (!isDocsOrRefactor && hasIssueSection) {
228+
// Check: issue reference (skip for docs/refactor/feat)
229+
if (!isDocsRefactorOrFeat && hasIssueSection) {
230230
const issueMatch = body.match(/### Issue for this PR\s*\n([\s\S]*?)(?=###|$)/);
231231
const issueContent = issueMatch ? issueMatch[1].trim() : '';
232232
const hasIssueRef = /(closes|fixes|resolves)\s+#\d+/i.test(issueContent) || /#\d+/.test(issueContent);

.github/workflows/publish.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ jobs:
7777
fetch-tags: true
7878

7979
- uses: ./.github/actions/setup-bun
80+
with:
81+
cross-compile: "true"
8082

8183
- name: Setup git committer
8284
id: committer
@@ -88,7 +90,7 @@ jobs:
8890
- name: Build
8991
id: build
9092
run: |
91-
./packages/opencode/script/build.ts
93+
./packages/opencode/script/build.ts --all
9294
env:
9395
OPENCODE_VERSION: ${{ needs.version.outputs.version }}
9496
OPENCODE_RELEASE: ${{ needs.version.outputs.release }}

.github/workflows/sign-cli.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ jobs:
2020
fetch-tags: true
2121

2222
- uses: ./.github/actions/setup-bun
23+
with:
24+
cross-compile: "true"
2325

2426
- name: Build
2527
run: |
26-
./packages/opencode/script/build.ts
28+
./packages/opencode/script/build.ts --all
2729
2830
- name: Upload unsigned Windows CLI
2931
id: upload_unsigned_windows_cli

.github/workflows/test.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,16 @@ on:
88
workflow_dispatch:
99
jobs:
1010
unit:
11-
name: unit (linux)
12-
runs-on: blacksmith-4vcpu-ubuntu-2404
11+
name: unit (${{ matrix.settings.name }})
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
settings:
16+
- name: linux
17+
host: blacksmith-4vcpu-ubuntu-2404
18+
- name: windows
19+
host: blacksmith-4vcpu-windows-2025
20+
runs-on: ${{ matrix.settings.host }}
1321
defaults:
1422
run:
1523
shell: bash

.github/workflows/vouch-check-issue.yml

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,17 @@ jobs:
4242
throw error;
4343
}
4444
45-
// Parse the .td file for denounced users
45+
// Parse the .td file for vouched and denounced users
46+
const vouched = new Set();
4647
const denounced = new Map();
4748
for (const line of content.split('\n')) {
4849
const trimmed = line.trim();
4950
if (!trimmed || trimmed.startsWith('#')) continue;
50-
if (!trimmed.startsWith('-')) continue;
5151
52-
const rest = trimmed.slice(1).trim();
52+
const isDenounced = trimmed.startsWith('-');
53+
const rest = isDenounced ? trimmed.slice(1).trim() : trimmed;
5354
if (!rest) continue;
55+
5456
const spaceIdx = rest.indexOf(' ');
5557
const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx);
5658
const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim();
@@ -65,32 +67,50 @@ jobs:
6567
const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1);
6668
if (!username) continue;
6769
68-
denounced.set(username.toLowerCase(), reason);
70+
if (isDenounced) {
71+
denounced.set(username.toLowerCase(), reason);
72+
continue;
73+
}
74+
75+
vouched.add(username.toLowerCase());
6976
}
7077
7178
// Check if the author is denounced
7279
const reason = denounced.get(author.toLowerCase());
73-
if (reason === undefined) {
74-
core.info(`User ${author} is not denounced. Allowing issue.`);
80+
if (reason !== undefined) {
81+
// Author is denounced — close the issue
82+
const body = 'This issue has been automatically closed.';
83+
84+
await github.rest.issues.createComment({
85+
owner: context.repo.owner,
86+
repo: context.repo.repo,
87+
issue_number: issueNumber,
88+
body,
89+
});
90+
91+
await github.rest.issues.update({
92+
owner: context.repo.owner,
93+
repo: context.repo.repo,
94+
issue_number: issueNumber,
95+
state: 'closed',
96+
state_reason: 'not_planned',
97+
});
98+
99+
core.info(`Closed issue #${issueNumber} from denounced user ${author}`);
75100
return;
76101
}
77102
78-
// Author is denounced — close the issue
79-
const body = 'This issue has been automatically closed.';
80-
81-
await github.rest.issues.createComment({
82-
owner: context.repo.owner,
83-
repo: context.repo.repo,
84-
issue_number: issueNumber,
85-
body,
86-
});
103+
// Author is positively vouched — add label
104+
if (!vouched.has(author.toLowerCase())) {
105+
core.info(`User ${author} is not denounced or vouched. Allowing issue.`);
106+
return;
107+
}
87108
88-
await github.rest.issues.update({
109+
await github.rest.issues.addLabels({
89110
owner: context.repo.owner,
90111
repo: context.repo.repo,
91112
issue_number: issueNumber,
92-
state: 'closed',
93-
state_reason: 'not_planned',
113+
labels: ['Vouched'],
94114
});
95115
96-
core.info(`Closed issue #${issueNumber} from denounced user ${author}`);
116+
core.info(`Added vouched label to issue #${issueNumber} from ${author}`);

0 commit comments

Comments
 (0)