Skip to content

Commit 623d928

Browse files
committed
Merge remote-tracking branch 'upstream/main'
# Conflicts: # package.json
2 parents 7f03dfe + 4906701 commit 623d928

File tree

261 files changed

+13136
-1658
lines changed

Some content is hidden

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

261 files changed

+13136
-1658
lines changed

.github/actionlint.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ self-hosted-runner:
88
- blacksmith-8vcpu-windows-2025
99
- blacksmith-16vcpu-ubuntu-2404
1010
- blacksmith-16vcpu-windows-2025
11+
- blacksmith-32vcpu-windows-2025
1112
- blacksmith-16vcpu-ubuntu-2404-arm
1213

1314
# Ignore patterns for known issues

.github/actions/setup-node-env/action.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Setup Node environment
22
description: >
33
Initialize submodules with retry, install Node 22, pnpm, optionally Bun,
4-
and run pnpm install. Requires actions/checkout to run first.
4+
and optionally run pnpm install. Requires actions/checkout to run first.
55
inputs:
66
node-version:
77
description: Node.js version to install.
@@ -19,6 +19,10 @@ inputs:
1919
description: Use Blacksmith sticky disks for pnpm store caching.
2020
required: false
2121
default: "false"
22+
install-deps:
23+
description: Whether to run pnpm install after environment setup.
24+
required: false
25+
default: "true"
2226
frozen-lockfile:
2327
description: Whether to use --frozen-lockfile for install.
2428
required: false
@@ -44,7 +48,7 @@ runs:
4448
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
4549
with:
4650
node-version: ${{ inputs.node-version }}
47-
check-latest: true
51+
check-latest: false
4852

4953
- name: Setup pnpm + cache store
5054
uses: ./.github/actions/setup-pnpm-store-cache
@@ -68,10 +72,12 @@ runs:
6872
if command -v bun &>/dev/null; then bun -v; fi
6973
7074
- name: Capture node path
75+
if: inputs.install-deps == 'true'
7176
shell: bash
7277
run: echo "NODE_BIN=$(dirname "$(node -p "process.execPath")")" >> "$GITHUB_ENV"
7378

7479
- name: Install dependencies
80+
if: inputs.install-deps == 'true'
7581
shell: bash
7682
env:
7783
CI: "true"

.github/actions/setup-pnpm-store-cache/action.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ inputs:
1313
description: Use Blacksmith sticky disks instead of actions/cache for pnpm store.
1414
required: false
1515
default: "false"
16+
use-restore-keys:
17+
description: Whether to use restore-keys fallback for actions/cache.
18+
required: false
19+
default: "true"
20+
use-actions-cache:
21+
description: Whether to restore/save pnpm store with actions/cache.
22+
required: false
23+
default: "true"
1624
runs:
1725
using: composite
1826
steps:
@@ -49,8 +57,15 @@ runs:
4957
key: ${{ github.repository }}-pnpm-store-${{ runner.os }}-${{ inputs.cache-key-suffix }}
5058
path: ${{ steps.pnpm-store.outputs.path }}
5159

52-
- name: Restore pnpm store cache
53-
if: inputs.use-sticky-disk != 'true'
60+
- name: Restore pnpm store cache (exact key only)
61+
if: inputs.use-actions-cache == 'true' && inputs.use-sticky-disk != 'true' && inputs.use-restore-keys != 'true'
62+
uses: actions/cache@v4
63+
with:
64+
path: ${{ steps.pnpm-store.outputs.path }}
65+
key: ${{ runner.os }}-pnpm-store-${{ inputs.cache-key-suffix }}-${{ hashFiles('pnpm-lock.yaml') }}
66+
67+
- name: Restore pnpm store cache (with fallback keys)
68+
if: inputs.use-actions-cache == 'true' && inputs.use-sticky-disk != 'true' && inputs.use-restore-keys == 'true'
5469
uses: actions/cache@v4
5570
with:
5671
path: ${{ steps.pnpm-store.outputs.path }}

.github/workflows/ci.yml

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ jobs:
3232
# Push to main keeps broad coverage.
3333
changed-scope:
3434
needs: [docs-scope]
35-
if: needs.docs-scope.outputs.docs_only != 'true'
35+
if: github.event_name == 'pull_request' && needs.docs-scope.outputs.docs_only != 'true'
3636
runs-on: blacksmith-16vcpu-ubuntu-2404
3737
outputs:
3838
run_node: ${{ steps.scope.outputs.run_node }}
3939
run_macos: ${{ steps.scope.outputs.run_macos }}
4040
run_android: ${{ steps.scope.outputs.run_android }}
41+
run_windows: ${{ steps.scope.outputs.run_windows }}
4142
steps:
4243
- name: Checkout
4344
uses: actions/checkout@v4
@@ -61,7 +62,7 @@ jobs:
6162
6263
# Build dist once for Node-relevant changes and share it with downstream jobs.
6364
build-artifacts:
64-
needs: [docs-scope, changed-scope, check]
65+
needs: [docs-scope, changed-scope]
6566
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
6667
runs-on: blacksmith-16vcpu-ubuntu-2404
6768
steps:
@@ -113,7 +114,7 @@ jobs:
113114
run: pnpm release:check
114115

115116
checks:
116-
needs: [docs-scope, changed-scope, check]
117+
needs: [docs-scope, changed-scope]
117118
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
118119
runs-on: blacksmith-16vcpu-ubuntu-2404
119120
strategy:
@@ -284,7 +285,8 @@ jobs:
284285
uses: ./.github/actions/setup-node-env
285286
with:
286287
install-bun: "false"
287-
use-sticky-disk: "true"
288+
use-sticky-disk: "false"
289+
install-deps: "false"
288290

289291
- name: Setup Python
290292
uses: actions/setup-python@v5
@@ -328,13 +330,13 @@ jobs:
328330
run: pre-commit run --all-files pnpm-audit-prod
329331

330332
checks-windows:
331-
needs: [docs-scope, changed-scope, build-artifacts, check]
332-
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_node == 'true')
333-
runs-on: blacksmith-16vcpu-windows-2025
333+
needs: [docs-scope, changed-scope]
334+
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_windows == 'true')
335+
runs-on: blacksmith-32vcpu-windows-2025
334336
timeout-minutes: 45
335337
env:
336338
NODE_OPTIONS: --max-old-space-size=6144
337-
# Keep total concurrency predictable on the 16 vCPU runner.
339+
# Keep total concurrency predictable on the 32 vCPU runner.
338340
# Windows shard 2 has shown intermittent instability at 2 workers.
339341
OPENCLAW_TEST_WORKERS: 1
340342
defaults:
@@ -347,12 +349,32 @@ jobs:
347349
- runtime: node
348350
task: test
349351
shard_index: 1
350-
shard_count: 2
352+
shard_count: 6
351353
command: pnpm test
352354
- runtime: node
353355
task: test
354356
shard_index: 2
355-
shard_count: 2
357+
shard_count: 6
358+
command: pnpm test
359+
- runtime: node
360+
task: test
361+
shard_index: 3
362+
shard_count: 6
363+
command: pnpm test
364+
- runtime: node
365+
task: test
366+
shard_index: 4
367+
shard_count: 6
368+
command: pnpm test
369+
- runtime: node
370+
task: test
371+
shard_index: 5
372+
shard_count: 6
373+
command: pnpm test
374+
- runtime: node
375+
task: test
376+
shard_index: 6
377+
shard_count: 6
356378
command: pnpm test
357379
steps:
358380
- name: Checkout
@@ -383,13 +405,18 @@ jobs:
383405
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
384406
with:
385407
node-version: 22.x
386-
check-latest: true
408+
check-latest: false
387409

388410
- name: Setup pnpm + cache store
389411
uses: ./.github/actions/setup-pnpm-store-cache
390412
with:
391413
pnpm-version: "10.23.0"
392414
cache-key-suffix: "node22"
415+
# Sticky disk mount currently retries/fails on every shard and adds ~50s
416+
# before install while still yielding zero pnpm store reuse.
417+
use-sticky-disk: "false"
418+
use-restore-keys: "false"
419+
use-actions-cache: "false"
393420

394421
- name: Runtime versions
395422
run: |
@@ -408,7 +435,7 @@ jobs:
408435
which node
409436
node -v
410437
pnpm -v
411-
pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true || pnpm install --frozen-lockfile --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
438+
pnpm install --frozen-lockfile --prefer-offline --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true || pnpm install --frozen-lockfile --prefer-offline --ignore-scripts=false --config.engine-strict=false --config.enable-pre-post-scripts=true
412439
413440
- name: Configure test shard (Windows)
414441
if: matrix.task == 'test'
@@ -661,7 +688,7 @@ jobs:
661688
PY
662689
663690
android:
664-
needs: [docs-scope, changed-scope, check]
691+
needs: [docs-scope, changed-scope]
665692
if: needs.docs-scope.outputs.docs_only != 'true' && (github.event_name == 'push' || needs.changed-scope.outputs.run_android == 'true')
666693
runs-on: blacksmith-16vcpu-ubuntu-2404
667694
strategy:

.github/workflows/stale.yml

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
name: Stale
2+
3+
on:
4+
schedule:
5+
- cron: "17 3 * * *"
6+
workflow_dispatch:
7+
8+
permissions: {}
9+
10+
jobs:
11+
stale:
12+
permissions:
13+
issues: write
14+
pull-requests: write
15+
runs-on: blacksmith-16vcpu-ubuntu-2404
16+
steps:
17+
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
18+
id: app-token
19+
continue-on-error: true
20+
with:
21+
app-id: "2729701"
22+
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
23+
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
24+
id: app-token-fallback
25+
if: steps.app-token.outcome == 'failure'
26+
with:
27+
app-id: "2971289"
28+
private-key: ${{ secrets.GH_APP_PRIVATE_KEY_FALLBACK }}
29+
- name: Mark stale issues and pull requests
30+
uses: actions/stale@v9
31+
with:
32+
repo-token: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }}
33+
days-before-issue-stale: 7
34+
days-before-issue-close: 5
35+
days-before-pr-stale: 5
36+
days-before-pr-close: 3
37+
stale-issue-label: stale
38+
stale-pr-label: stale
39+
exempt-issue-labels: enhancement,maintainer,pinned,security,no-stale
40+
exempt-pr-labels: maintainer,no-stale
41+
operations-per-run: 10000
42+
exempt-all-assignees: true
43+
remove-stale-when-updated: true
44+
stale-issue-message: |
45+
This issue has been automatically marked as stale due to inactivity.
46+
Please add updates or it will be closed.
47+
stale-pr-message: |
48+
This pull request has been automatically marked as stale due to inactivity.
49+
Please add updates or it will be closed.
50+
close-issue-message: |
51+
Closing due to inactivity.
52+
If this is still an issue, please retry on the latest OpenClaw release and share updated details.
53+
If you are absolutely sure it still happens on the latest release, open a new issue with fresh repro steps.
54+
close-issue-reason: not_planned
55+
close-pr-message: |
56+
Closing due to inactivity.
57+
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
58+
That channel is the escape hatch for high-quality PRs that get auto-closed.
59+
60+
lock-closed-issues:
61+
permissions:
62+
issues: write
63+
runs-on: blacksmith-16vcpu-ubuntu-2404
64+
steps:
65+
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
66+
id: app-token
67+
with:
68+
app-id: "2729701"
69+
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
70+
- name: Lock closed issues after 48h of no comments
71+
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
72+
with:
73+
github-token: ${{ steps.app-token.outputs.token }}
74+
script: |
75+
const lockAfterHours = 48;
76+
const lockAfterMs = lockAfterHours * 60 * 60 * 1000;
77+
const perPage = 100;
78+
const cutoffMs = Date.now() - lockAfterMs;
79+
const { owner, repo } = context.repo;
80+
81+
let locked = 0;
82+
let inspected = 0;
83+
84+
let page = 1;
85+
while (true) {
86+
const { data: issues } = await github.rest.issues.listForRepo({
87+
owner,
88+
repo,
89+
state: "closed",
90+
sort: "updated",
91+
direction: "desc",
92+
per_page: perPage,
93+
page,
94+
});
95+
96+
if (issues.length === 0) {
97+
break;
98+
}
99+
100+
for (const issue of issues) {
101+
if (issue.pull_request) {
102+
continue;
103+
}
104+
if (issue.locked) {
105+
continue;
106+
}
107+
if (!issue.closed_at) {
108+
continue;
109+
}
110+
111+
inspected += 1;
112+
const closedAtMs = Date.parse(issue.closed_at);
113+
if (!Number.isFinite(closedAtMs)) {
114+
continue;
115+
}
116+
if (closedAtMs > cutoffMs) {
117+
continue;
118+
}
119+
120+
let lastCommentMs = 0;
121+
if (issue.comments > 0) {
122+
const { data: comments } = await github.rest.issues.listComments({
123+
owner,
124+
repo,
125+
issue_number: issue.number,
126+
per_page: 1,
127+
page: 1,
128+
sort: "created",
129+
direction: "desc",
130+
});
131+
132+
if (comments.length > 0) {
133+
lastCommentMs = Date.parse(comments[0].created_at);
134+
}
135+
}
136+
137+
const lastActivityMs = Math.max(closedAtMs, lastCommentMs || 0);
138+
if (lastActivityMs > cutoffMs) {
139+
continue;
140+
}
141+
142+
await github.rest.issues.lock({
143+
owner,
144+
repo,
145+
issue_number: issue.number,
146+
lock_reason: "resolved",
147+
});
148+
149+
locked += 1;
150+
}
151+
152+
page += 1;
153+
}
154+
155+
core.info(`Inspected ${inspected} closed issues; locked ${locked}.`);

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ mise.toml
2727
apps/android/.gradle/
2828
apps/android/app/build/
2929
apps/android/.cxx/
30+
apps/android/.kotlin/
3031

3132
# Bun build artifacts
3233
*.bun-build

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- GitHub issues/comments/PR comments: use literal multiline strings or `-F - <<'EOF'` (or $'...') for real newlines; never embed "\\n".
66
- GitHub comment footgun: never use `gh issue/pr comment -b "..."` when body contains backticks or shell chars. Always use single-quoted heredoc (`-F - <<'EOF'`) so no command substitution/escaping corruption.
77
- GitHub linking footgun: don’t wrap issue/PR refs like `#24643` in backticks when you want auto-linking. Use plain `#24643` (optionally add full URL).
8+
- GitHub searching footgun: don't limit yourself to the first 500 issues or PRs when wanting to search all. Unless you're supposed to look at the most recent, keep going until you've reached the last page in the search
89
- Security advisory analysis: before triage/severity decisions, read `SECURITY.md` to align with OpenClaw's trust model and design boundaries.
910

1011
## Project Structure & Module Organization

0 commit comments

Comments
 (0)