Skip to content

Commit 8ee493c

Browse files
committed
chore: resolve merge conflicts between daemon_mode_b_main and main
Resolve all conflicts from merging origin/main into daemon_mode_b_main using 84f4080 as the virtual merge base (last sync point from #4469). Key resolution decisions: - httpAcpBridge.ts: keep daemon's 102-line re-export shim (code lifted to @qwen-code/acp-bridge per F1) - httpAcpBridge.test.ts: removed (tests moved to acp-bridge/bridge.test.ts) - TelemetryRuntimeConfig: added isInteractive() and getOutboundCorrelationPropagateTraceContext() from main - btwCommand.ts: keep daemon's clean buildBtwCacheSafeParams delegation - sessionRecap.ts: main's getHistoryShallow() API + daemon's debug logging - session-tracing.ts: daemon's ROOT_CONTEXT parent for bounded traces - Session.ts: daemon's runInToolSpanContext + main's skipClassifierReason rename
1 parent 03b3968 commit 8ee493c

522 files changed

Lines changed: 66275 additions & 6545 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/pull_request_template.md

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,66 @@
11
<!--
2-
Help reviewers verify this PR quickly.
2+
Maintainers prioritize PRs with a clear reviewer test plan — without it, review may be delayed.
33
4-
Maintainers prioritize PRs that include clear proof of work.
5-
If a PR does not include enough validation detail to reproduce and verify the change efficiently, review may be delayed.
4+
Don't hard-wrap paragraphs: GitHub renders single newlines as <br>, so wrapped text shows as a narrow column. Write each paragraph or list item as one long line.
65
-->
76

8-
## Summary
7+
## What this PR does
98

10-
- What changed:
11-
- Why it changed:
12-
- Reviewer focus:
9+
<!-- What this PR does. Describe the change in prose, not by file or function names. -->
1310

14-
## Validation
11+
## Why it's needed
1512

16-
<!--
17-
Be concrete. Do not write only "tested locally".
18-
Include the exact commands, prompts, outputs, logs, screenshots, or videos that prove the change was actually run and observed.
13+
<!-- Why it's needed: the motivation, the problem being solved, or the user-facing benefit. -->
14+
15+
## Reviewer Test Plan
1916

20-
For user-visible changes, bug fixes, CLI / TUI behavior changes, or interaction changes, include key screenshots or a short video.
21-
When possible, show before/after behavior.
17+
<!--
18+
How a reviewer can confirm this PR: reproduction steps, expected vs observed behavior, and evidence. CI runs on macOS, Windows, and Linux — Tested on is what you verified locally.
2219
23-
If helpful, use the `e2e-testing` skill to gather stronger end-to-end validation evidence.
20+
User-visible / TUI: Before/After with tmux-real-user-testing skill, screenshots, or a short recording.
21+
Non–user-visible (refactor, types, docs): commands and output below; write N/A under Before/After.
2422
-->
2523

26-
- Commands run:
27-
```bash
28-
# paste commands here
29-
```
30-
- Prompts / inputs used:
31-
- Expected result:
32-
- Observed result:
33-
- Quickest reviewer verification path:
34-
- Evidence (output, logs, screenshots, video, JSON, before/after, etc.):
24+
### How to verify
3525

36-
## Scope / Risk
26+
<!-- How you reproduced it and what a reviewer should confirm — steps if needed, expected vs observed behavior. Focus on outcomes; paste logs or test output when helpful. -->
3727

38-
- Main risk or tradeoff:
39-
- Not covered / not validated:
40-
- Breaking changes / migration notes:
28+
### Evidence (Before & After)
4129

42-
## Testing Matrix
30+
<!-- User-visible / TUI changes: paste before-and-after screenshots, tmux logs, or video side by side. Non-UI changes (docs, refactor, types): N/A -->
4331

44-
<!--
45-
Use:
46-
- ✅ tested
47-
- ⚠️ not tested
48-
- N/A
49-
If anything is ⚠️, explain why briefly below.
50-
-->
32+
### Tested on
33+
34+
| OS | Status |
35+
| :--------: | :----: |
36+
| 🍏 macOS | |
37+
| 🪟 Windows | |
38+
| 🐧 Linux | |
5139

52-
| | 🍏 | 🪟 | 🐧 |
53-
| -------- | --- | --- | --- |
54-
| npm run | ⚠️ | ⚠️ | ⚠️ |
55-
| npx | ⚠️ | ⚠️ | ⚠️ |
56-
| Docker | ⚠️ | ⚠️ | ⚠️ |
57-
| Podman | ⚠️ | N/A | N/A |
58-
| Seatbelt | ⚠️ | N/A | N/A |
40+
<!-- ✅ tested · ⚠️ not tested · N/A -->
5941

60-
Testing matrix notes:
42+
### Environment (optional)
6143

62-
-
44+
<!-- Local runtime: e.g. npm run dev, Docker/Podman sandbox, seatbelt. N/A if only unit tests. -->
6345

64-
## Linked Issues / Bugs
46+
## Risk & Scope
47+
48+
- Main risk or tradeoff:
49+
- Not validated / out of scope:
50+
- Breaking changes / migration notes:
51+
52+
## Linked Issues
6553

6654
<!--
67-
If this PR fully resolves an issue, use one of:
68-
- Closes #<issue_number>
69-
- Fixes #<issue_number>
70-
- Resolves #<issue_number>
55+
Closes #N / Fixes #N / Resolves #N to auto-close.
56+
Otherwise reference without a closing keyword.
57+
-->
58+
59+
<details>
60+
<summary>中文说明</summary>
7161

72-
Otherwise reference related issues without a closing keyword.
62+
<!--
63+
完整翻译上面的英文正文,逐段对应,不要省略或缩写。PR 标题保持英文。
7364
-->
65+
66+
</details>

.github/workflows/release.yml

Lines changed: 8 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -386,63 +386,6 @@ jobs:
386386
RELEASE_VERSION: '${{ needs.prepare.outputs.release_version }}'
387387
run: 'npm run package:standalone:release -- --version "${RELEASE_VERSION}" --out-dir dist/standalone'
388388

389-
- name: 'Verify Installation Release Assets'
390-
run: 'npm run verify:installation-release -- --dir dist/standalone'
391-
392-
- name: 'Package Hosted Installation Assets'
393-
env:
394-
RELEASE_VERSION: '${{ needs.prepare.outputs.release_version }}'
395-
run: 'npm run package:hosted-installation -- --out-dir dist/installation --version "${RELEASE_VERSION}"'
396-
397-
- name: 'Install ossutil'
398-
if: |-
399-
${{ needs.prepare.outputs.is_dry_run == 'false' }}
400-
env:
401-
OSSUTIL_URL: "${{ vars.OSSUTIL_URL || 'https://gosspublic.alicdn.com/ossutil/1.7.19/ossutil-v1.7.19-linux-amd64.zip' }}"
402-
OSSUTIL_SHA256: "${{ vars.OSSUTIL_SHA256 || 'dcc512e4a893e16bbee63bc769339d8e56b21744fd83c8212a9d8baf28767343' }}"
403-
run: |-
404-
set -euo pipefail
405-
406-
tmp_dir="$(mktemp -d)"
407-
curl -fsSL --connect-timeout 15 --max-time 300 "${OSSUTIL_URL}" -o "${tmp_dir}/ossutil.zip"
408-
echo "${OSSUTIL_SHA256} ${tmp_dir}/ossutil.zip" | sha256sum -c -
409-
unzip -q "${tmp_dir}/ossutil.zip" -d "${tmp_dir}"
410-
411-
ossutil_path="$(find "${tmp_dir}" -type f \( -name 'ossutil' -o -name 'ossutil64' \) -print -quit)"
412-
if [[ -z "${ossutil_path}" ]]; then
413-
echo "::error::ossutil binary not found in downloaded archive"
414-
exit 1
415-
fi
416-
417-
chmod +x "${ossutil_path}"
418-
mkdir -p "${HOME}/.local/bin"
419-
install -m 0755 "${ossutil_path}" "${HOME}/.local/bin/ossutil"
420-
echo "${HOME}/.local/bin" >> "${GITHUB_PATH}"
421-
rm -rf "${tmp_dir}"
422-
"${HOME}/.local/bin/ossutil" >/dev/null
423-
424-
- name: 'Configure Aliyun OSS Credentials'
425-
if: |-
426-
${{ needs.prepare.outputs.is_dry_run == 'false' }}
427-
env:
428-
ALIYUN_OSS_ACCESS_KEY_ID: '${{ secrets.ALIYUN_OSS_ACCESS_KEY_ID }}'
429-
ALIYUN_OSS_ACCESS_KEY_SECRET: '${{ secrets.ALIYUN_OSS_ACCESS_KEY_SECRET }}'
430-
ALIYUN_OSS_ENDPOINT: "${{ vars.ALIYUN_OSS_ENDPOINT || 'https://oss-cn-hangzhou.aliyuncs.com' }}"
431-
run: |-
432-
set -euo pipefail
433-
434-
if [[ -z "${ALIYUN_OSS_ACCESS_KEY_ID}" || -z "${ALIYUN_OSS_ACCESS_KEY_SECRET}" ]]; then
435-
echo "::error::Missing Aliyun OSS credentials. Set ALIYUN_OSS_ACCESS_KEY_ID and ALIYUN_OSS_ACCESS_KEY_SECRET in the production-release environment secrets."
436-
exit 1
437-
fi
438-
439-
ossutil config \
440-
-e "${ALIYUN_OSS_ENDPOINT}" \
441-
-i "${ALIYUN_OSS_ACCESS_KEY_ID}" \
442-
-k "${ALIYUN_OSS_ACCESS_KEY_SECRET}" \
443-
-L EN \
444-
-c "${RUNNER_TEMP}/.ossutilconfig"
445-
446389
- name: 'Publish @qwen-code/qwen-code'
447390
working-directory: 'dist'
448391
run: |-
@@ -457,150 +400,37 @@ jobs:
457400
env:
458401
NODE_AUTH_TOKEN: '${{ secrets.NPM_TOKEN }}'
459402

403+
- name: 'Verify Standalone Archives'
404+
run: |-
405+
npm run verify:installation-release -- --dir dist/standalone
406+
460407
- name: 'Create GitHub Release and Tag'
461408
if: |-
462409
${{ needs.prepare.outputs.is_dry_run == 'false' }}
463410
env:
464-
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
411+
# CI_BOT_PAT required: GITHUB_TOKEN events cannot trigger downstream workflows (sync-release-to-oss.yml).
412+
GITHUB_TOKEN: '${{ secrets.CI_BOT_PAT }}'
465413
RELEASE_BRANCH: '${{ steps.release_branch.outputs.BRANCH_NAME }}'
466414
RELEASE_TAG: '${{ needs.prepare.outputs.release_tag }}'
467415
PREVIOUS_RELEASE_TAG: '${{ needs.prepare.outputs.previous_release_tag }}'
468416
IS_NIGHTLY: '${{ needs.prepare.outputs.is_nightly }}'
469417
IS_PREVIEW: '${{ needs.prepare.outputs.is_preview }}'
470418
run: |-
471-
set -euo pipefail
472-
473419
PRERELEASE_FLAG=""
474420
if [[ "${IS_NIGHTLY}" == "true" || "${IS_PREVIEW}" == "true" ]]; then
475421
PRERELEASE_FLAG="--prerelease"
476422
fi
477423
478-
mapfile -t release_assets < <(node scripts/verify-installation-release.js --dir dist/standalone --list-release-asset-paths)
479-
480424
gh release create "${RELEASE_TAG}" \
481425
dist/cli.js \
482-
"${release_assets[@]}" \
426+
dist/standalone/qwen-code-* \
427+
dist/standalone/SHA256SUMS \
483428
--target "${RELEASE_BRANCH}" \
484429
--title "Release ${RELEASE_TAG}" \
485430
--notes-start-tag "${PREVIOUS_RELEASE_TAG}" \
486431
--generate-notes \
487432
${PRERELEASE_FLAG}
488433
489-
- name: 'Sync Release Assets to Aliyun OSS'
490-
if: |-
491-
${{ needs.prepare.outputs.is_dry_run == 'false' }}
492-
env:
493-
ALIYUN_OSS_BUCKET: "${{ vars.ALIYUN_OSS_BUCKET || 'qwen-code-assets' }}"
494-
RELEASE_TAG: '${{ needs.prepare.outputs.release_tag }}'
495-
run: |-
496-
set -euo pipefail
497-
498-
mapfile -t release_assets < <(node scripts/verify-installation-release.js --dir dist/standalone --list-release-asset-paths)
499-
node scripts/upload-aliyun-oss-assets.js \
500-
--bucket "${ALIYUN_OSS_BUCKET}" \
501-
--config "${RUNNER_TEMP}/.ossutilconfig" \
502-
--prefix "releases/qwen-code/${RELEASE_TAG}" \
503-
"${release_assets[@]}"
504-
505-
- name: 'Verify Aliyun OSS Release Assets'
506-
if: |-
507-
${{ needs.prepare.outputs.is_dry_run == 'false' }}
508-
env:
509-
ALIYUN_OSS_PUBLIC_BASE_URL: "${{ vars.ALIYUN_OSS_PUBLIC_BASE_URL || 'https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com' }}"
510-
RELEASE_TAG: '${{ needs.prepare.outputs.release_tag }}'
511-
run: |-
512-
set -euo pipefail
513-
514-
npm run verify:installation-release -- --base-url "${ALIYUN_OSS_PUBLIC_BASE_URL}/releases/qwen-code/${RELEASE_TAG}"
515-
516-
- name: 'Sync Hosted Installation Assets to Aliyun OSS'
517-
if: |-
518-
${{ needs.prepare.outputs.is_dry_run == 'false' && needs.prepare.outputs.is_nightly == 'false' && needs.prepare.outputs.is_preview == 'false' }}
519-
env:
520-
ALIYUN_OSS_BUCKET: "${{ vars.ALIYUN_OSS_BUCKET || 'qwen-code-assets' }}"
521-
RELEASE_TAG: '${{ needs.prepare.outputs.release_tag }}'
522-
run: |-
523-
set -euo pipefail
524-
525-
hosted_assets=(
526-
dist/installation/install-qwen-standalone.sh
527-
dist/installation/install-qwen-standalone.ps1
528-
dist/installation/install-qwen-standalone.bat
529-
dist/installation/uninstall-qwen-standalone.sh
530-
dist/installation/uninstall-qwen-standalone.ps1
531-
dist/installation/SHA256SUMS
532-
)
533-
node scripts/upload-aliyun-oss-assets.js \
534-
--bucket "${ALIYUN_OSS_BUCKET}" \
535-
--config "${RUNNER_TEMP}/.ossutilconfig" \
536-
--prefix "installation/${RELEASE_TAG}" \
537-
"${hosted_assets[@]}"
538-
node scripts/upload-aliyun-oss-assets.js \
539-
--bucket "${ALIYUN_OSS_BUCKET}" \
540-
--config "${RUNNER_TEMP}/.ossutilconfig" \
541-
--prefix "installation" \
542-
"${hosted_assets[@]}"
543-
544-
- name: 'Verify Aliyun OSS Hosted Installation Assets'
545-
if: |-
546-
${{ needs.prepare.outputs.is_dry_run == 'false' && needs.prepare.outputs.is_nightly == 'false' && needs.prepare.outputs.is_preview == 'false' }}
547-
env:
548-
ALIYUN_OSS_PUBLIC_BASE_URL: "${{ vars.ALIYUN_OSS_PUBLIC_BASE_URL || 'https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com' }}"
549-
RELEASE_TAG: '${{ needs.prepare.outputs.release_tag }}'
550-
run: |-
551-
set -euo pipefail
552-
553-
hosted_tmp_dir="$(mktemp -d)"
554-
trap 'rm -rf "${hosted_tmp_dir}"' EXIT
555-
mkdir -p "${hosted_tmp_dir}/versioned" "${hosted_tmp_dir}/global"
556-
for asset in install-qwen-standalone.sh install-qwen-standalone.ps1 install-qwen-standalone.bat uninstall-qwen-standalone.sh uninstall-qwen-standalone.ps1 SHA256SUMS; do
557-
url="${ALIYUN_OSS_PUBLIC_BASE_URL}/installation/${RELEASE_TAG}/${asset}"
558-
global_url="${ALIYUN_OSS_PUBLIC_BASE_URL}/installation/${asset}"
559-
curl -fsSL --connect-timeout 15 --max-time 300 "${url}" -o "${hosted_tmp_dir}/versioned/${asset}"
560-
curl -fsSL --connect-timeout 15 --max-time 300 "${global_url}" -o "${hosted_tmp_dir}/global/${asset}"
561-
done
562-
cmp -s "dist/installation/SHA256SUMS" "${hosted_tmp_dir}/versioned/SHA256SUMS" || {
563-
echo "::error::Hosted installation SHA256SUMS does not match local dist/installation/SHA256SUMS"
564-
diff -u "dist/installation/SHA256SUMS" "${hosted_tmp_dir}/versioned/SHA256SUMS" || true
565-
exit 1
566-
}
567-
cmp -s "dist/installation/SHA256SUMS" "${hosted_tmp_dir}/global/SHA256SUMS" || {
568-
echo "::error::Global hosted installation SHA256SUMS does not match local dist/installation/SHA256SUMS"
569-
diff -u "dist/installation/SHA256SUMS" "${hosted_tmp_dir}/global/SHA256SUMS" || true
570-
exit 1
571-
}
572-
(cd "${hosted_tmp_dir}/versioned" && sha256sum -c SHA256SUMS)
573-
(cd "${hosted_tmp_dir}/global" && sha256sum -c SHA256SUMS)
574-
575-
- name: 'Publish Aliyun OSS Latest VERSION'
576-
# Run last so the `latest/VERSION` pointer only flips after every
577-
# release asset and hosted installer object has been uploaded and
578-
# verified. If any earlier step fails, the pointer keeps referring
579-
# to the previously-good release.
580-
if: |-
581-
${{ needs.prepare.outputs.is_dry_run == 'false' && needs.prepare.outputs.is_nightly == 'false' && needs.prepare.outputs.is_preview == 'false' }}
582-
env:
583-
ALIYUN_OSS_BUCKET: "${{ vars.ALIYUN_OSS_BUCKET || 'qwen-code-assets' }}"
584-
ALIYUN_OSS_PUBLIC_BASE_URL: "${{ vars.ALIYUN_OSS_PUBLIC_BASE_URL || 'https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com' }}"
585-
RELEASE_TAG: '${{ needs.prepare.outputs.release_tag }}'
586-
run: |-
587-
set -euo pipefail
588-
589-
printf '%s\n' "${RELEASE_TAG}" > "${RUNNER_TEMP}/qwen-code-latest-version"
590-
ossutil cp "${RUNNER_TEMP}/qwen-code-latest-version" "oss://${ALIYUN_OSS_BUCKET}/releases/qwen-code/latest/VERSION" -c "${RUNNER_TEMP}/.ossutilconfig" -f --acl public-read
591-
592-
latest_version="$(curl -fsSL --connect-timeout 15 --max-time 300 "${ALIYUN_OSS_PUBLIC_BASE_URL}/releases/qwen-code/latest/VERSION" | tr -d '[:space:]')"
593-
if [[ "${latest_version}" != "${RELEASE_TAG}" ]]; then
594-
echo "::error::Aliyun latest VERSION points to ${latest_version}, expected ${RELEASE_TAG}"
595-
exit 1
596-
fi
597-
598-
- name: 'Cleanup Aliyun OSS Credentials'
599-
if: |-
600-
${{ always() && needs.prepare.outputs.is_dry_run == 'false' }}
601-
run: |-
602-
rm -f "${RUNNER_TEMP}/.ossutilconfig"
603-
604434
- name: 'Create PR to merge release branch into main'
605435
if: |-
606436
${{ needs.prepare.outputs.is_dry_run == 'false' && needs.prepare.outputs.is_nightly == 'false' && needs.prepare.outputs.is_preview == 'false' }}

0 commit comments

Comments
 (0)