Quellcode durchsuchen

Merge remote-tracking branch 'origin/master' into worktree/issue-3929-v41-request-image

creatixchu vor 1 Woche
Ursprung
Commit
db6dff8f67

+ 2 - 3
.github/workflows/ci-master.yml

@@ -249,10 +249,9 @@ jobs:
       - name: Configure persistent pnpm store
         shell: pwsh
         # The store must share the ReFS workspace volume for the clone
-        # import method below; LOCALAPPDATA (C:) would cross volumes and
-        # break block clone. See 2026-08-30-windows-refs-store-block-clone-install.
+        # import method below. Runner workspaces can reside on different drives.
         run: |
-          $storeRoot = "F:\.pnpm-store"
+          $storeRoot = Join-Path ([IO.Path]::GetPathRoot($env:GITHUB_WORKSPACE)) '.pnpm-store'
           echo "PNPM_CONFIG_STORE_DIR=$storeRoot" >> $env:GITHUB_ENV
 
       - name: Install (immutable)

+ 1 - 1
apps/web/tests/built-boot.expected.e2e.ts

@@ -101,7 +101,7 @@ it('boots the built plugin graph and renders a fixture session end to end', asyn
   // Skip the resident fixture's three questions, then resolve its approval so
   // the ordinary composer bar (which owns ContextMeter) resumes.
   for (let index = 0; index < 3; index += 1) {
-    fireEvent.click(await screen.findByRole('button', { name: 'Skip this question' }))
+    fireEvent.click(await screen.findByRole('button', { name: 'Skip' }))
   }
   fireEvent.click(await screen.findByRole('button', { name: 'Allow once' }))
 

+ 1 - 1
apps/web/tests/question-composer.e2e.ts

@@ -345,7 +345,7 @@ describe('web e2e: resident question composer round trip', () => {
     expect(await capMetrics(field)).toEqual({ textLines: CAP_LINES, scrolls: true })
 
     // Settle the wait so teardown is not racing a pending question.
-    await composer.getByRole('button', { name: 'Skip this question' }).click()
+    await composer.getByRole('button', { name: 'Skip' }).click()
     expect(await asked).toEqual({ answers: [{ id: 'free', selected: [] }] })
     await expect.poll(() => page.locator('[data-question-key]').count(), { timeout: 10_000 }).toBe(0)
   }, 60_000)

+ 2 - 2
packages/client/ui-user-questions/README.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write packages/client/ui-user-questions/README.md
-README.md: 9e5997eb2ebe69b4b2d49b57a61b0bd36ec41053
-README.zh.md: 44a73607f95e7859b344034b5abaa2c386619083
+README.md: 5a31c688d7f7ea9a9ad10877628a333d797ac06d
+README.zh.md: 4db6cfa9fdead65c8e1c567981d0c16d92e9cb1e

+ 1 - 1
packages/client/ui-user-questions/README.md

@@ -29,7 +29,7 @@ When the agent asks a question, the composer becomes the question surface: answe
 
 ### Answering
 
-A multi-select draft keeps its selected labels while the user opens or edits the custom answer, so its submitted item may carry both `selected` and `custom`; a single-select custom answer remains exclusive. Question detail reuses the assistant-output `MarkdownText` primitive, including its GFM rendering and untrusted-content policy. The capped card keeps its title, navigation, and submission actions fixed while long detail and choices share an internal scroll region. "Skip this question" retains other drafts and emits the existing blank `{ selected: [] }` result for that item, while close rejects the whole wait as `ASK_CANCELLED`.
+A multi-select draft keeps its selected labels while the user opens or edits the custom answer, so its submitted item may carry both `selected` and `custom`; a single-select custom answer remains exclusive. Question detail reuses the assistant-output `MarkdownText` primitive, including its GFM rendering and untrusted-content policy. The capped card keeps its title, navigation, and submission actions fixed while long detail and choices share an internal scroll region. "Skip" retains other drafts and emits the existing blank `{ selected: [] }` result for that item, while close rejects the whole wait as `ASK_CANCELLED`.
 
 ### The plan-review card
 

+ 1 - 1
packages/client/ui-user-questions/README.zh.md

@@ -29,7 +29,7 @@ kind: "package-reference"
 
 ### 作答
 
-用户打开或编辑自定义答案时,多选题草稿会保留已选中的标签,因此提交项可以同时携带 `selected` 与 `custom`;单选题的自定义答案仍保持互斥。问题详情复用助手输出的 `MarkdownText` 原语,包括其 GFM 渲染与不受信任内容策略。限高卡片保持标题、导航与提交动作固定,超长的详情与选项共享内部滚动区。「跳过此问题」会保留其他草稿,并为该项发出既有的空 `{ selected: [] }` 结果;关闭则以 `ASK_CANCELLED` 拒绝整个等待。
+用户打开或编辑自定义答案时,多选题草稿会保留已选中的标签,因此提交项可以同时携带 `selected` 与 `custom`;单选题的自定义答案仍保持互斥。问题详情复用助手输出的 `MarkdownText` 原语,包括其 GFM 渲染与不受信任内容策略。限高卡片保持标题、导航与提交动作固定,超长的详情与选项共享内部滚动区。「跳过」会保留其他草稿,并为该项发出既有的空 `{ selected: [] }` 结果;关闭则以 `ASK_CANCELLED` 拒绝整个等待。
 
 ### plan-review 卡片
 

+ 2 - 2
packages/client/ui-user-questions/src/client/locales.ts

@@ -11,7 +11,7 @@ export const zh = {
   'nav.cancel': '放弃整组问题',
   'option.recommended': '推荐',
   'custom.placeholder': '输入你的答案',
-  'action.skip': '跳过本题',
+  'action.skip': '跳过',
   'action.next': '下一题',
   'plan.header': '计划待审',
   'plan.approve': '确认执行',
@@ -33,7 +33,7 @@ export const en = {
   'nav.cancel': 'Dismiss all questions',
   'option.recommended': 'Recommended',
   'custom.placeholder': 'Type your answer',
-  'action.skip': 'Skip this question',
+  'action.skip': 'Skip',
   'action.next': 'Next',
   'plan.header': 'Plan review',
   'plan.approve': 'Approve',

+ 4 - 4
packages/client/ui-user-questions/tests/user-questions-composer.client.spec.tsx

@@ -247,9 +247,9 @@ describe('QuestionComposer', () => {
     expect((screen.getByText('下一题').closest('button') as HTMLButtonElement).disabled).toBe(true)
     fireEvent.click(screen.getByRole('radio', { name: '研究潜力型' }))
     expect(screen.getByText('2 / 3')).toBeTruthy()
-    fireEvent.click(screen.getByRole('button', { name: '跳过本题' }))
+    fireEvent.click(screen.getByRole('button', { name: '跳过' }))
     expect(screen.getByText('3 / 3')).toBeTruthy()
-    fireEvent.click(screen.getByRole('button', { name: '跳过本题' }))
+    fireEvent.click(screen.getByRole('button', { name: '跳过' }))
 
     expect(answer).toHaveBeenCalledWith(answerBatch([
       { id: 'profile', selected: ['研究潜力型'] },
@@ -346,7 +346,7 @@ describe('QuestionComposer', () => {
 
     fireEvent.click(screen.getByRole('button', { name: '放弃整组问题' }))
     expect(await screen.findByText('第一次取消失败')).toBeTruthy()
-    expect(screen.getByRole<HTMLButtonElement>('button', { name: '跳过本题' }).disabled).toBe(false)
+    expect(screen.getByRole<HTMLButtonElement>('button', { name: '跳过' }).disabled).toBe(false)
 
     fireEvent.click(screen.getByRole('button', { name: '放弃整组问题' }))
     expect(await screen.findByText('第二次取消失败')).toBeTruthy()
@@ -387,7 +387,7 @@ describe('QuestionComposer', () => {
     const { carrier } = wait([{ id: 'detail', question: '补充你的要求' }])
     render(<QuestionComposer matched={carrier} {...kit} t={seatOver(en, commonEn)} />)
     expect(screen.getByLabelText('Dismiss all questions')).toBeTruthy()
-    expect(screen.getByRole('button', { name: 'Skip this question' })).toBeTruthy()
+    expect(screen.getByRole('button', { name: 'Skip' })).toBeTruthy()
     expect(screen.getByPlaceholderText('Type your answer')).toBeTruthy()
   })
 

+ 2 - 1
scripts/ci-workflow.spec.ts

@@ -258,7 +258,8 @@ describe('CI workflow', () => {
       isRecord(step) && step.name === 'Configure persistent pnpm store' && typeof step.run === 'string'
     ))
     expect(serialStore).toBeDefined()
-    expect(serialStore!.run).toContain('F:\\.pnpm-store')
+    expect(serialStore!.run).toContain('[IO.Path]::GetPathRoot($env:GITHUB_WORKSPACE)')
+    expect(serialStore!.run).toContain("'.pnpm-store'")
     const serialInstall = serialSteps.find((step): step is Record<string, unknown> & { run: string } => (
       isRecord(step) && step.name === 'Install (immutable)' && typeof step.run === 'string'
     ))

+ 1 - 1
snapshots/web/question-composer/composed.expected.md

@@ -15,5 +15,5 @@
   - button "Next question" [disabled]:
     - img
   - status
-  - button "Skip this question"
+  - button "Skip"
   - button "Submit"

+ 1 - 1
snapshots/web/question-composer/ui.expected.md

@@ -15,5 +15,5 @@
   - button "Next question" [disabled]:
     - img
   - status
-  - button "Skip this question"
+  - button "Skip"
   - button "Submit" [disabled]

+ 1 - 1
snapshots/web/steering/mid-steer.expected.md

@@ -47,5 +47,5 @@
   - button "Next question" [disabled]:
     - img
   - status
-  - button "Skip this question"
+  - button "Skip"
   - button "Submit" [disabled]