Skip to content

refactor(workbench): Hub projects 端口抽取 + 契约切片(#1546 #1528) - #1608

Merged
DeliciousBuding merged 3 commits into
masterfrom
refactor/workbench-hubclient-port
Aug 4, 2026
Merged

refactor(workbench): Hub projects 端口抽取 + 契约切片(#1546 #1528)#1608
DeliciousBuding merged 3 commits into
masterfrom
refactor/workbench-hubclient-port

Conversation

@DeliciousBuding

@DeliciousBuding DeliciousBuding commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #1546 and completes the #1528 projects slice. The shared Workbench no longer depends on the concrete HubClient — neither as a value import nor as a type.

  • Port layer ([P1] 移除 shared Workbench 对具体 HubClient 的隐藏数据层依赖 #1546): new narrow domain port WorkbenchProjectsPort (app/shared/src/workbench/workbenchProjectsPort.ts); Desktop/Web composition roots implement it (desktopWorkbenchProjectsPort.ts / webWorkbenchProjectsPort.ts) and inject projectsPort. useWorkbenchProjectsRoute is now port-driven only — single ownership (parent-managed XOR port, no runtime projects ?? hubClient ?? mock guessing).
  • Pagination failures are now visible & retryable: loadMoreError surfaces in ProjectNav with an explicit retry button (zh/en i18n), hasMore stops the scroll sentinel, in-flight guard prevents duplicate pages, unmount-safe state writes.
  • Contract slice ([P2] Workbench 合同切片:用领域 assembler 收口项目/Agent/市场 prop-bag #1528): shared layer consumes only the typed port contract; hubDataMapping (shared by both adapters) gets a contract test; pure-types contract file joins the narrow coverage exclusion set (same precedent as types.ts/index.ts).
  • Verifier hardened: verify-shared-ui-hubclient.ps1 now forbids both value AND type references to concrete HubClient in shared presentation layers.

Verification

  • shared tests: 197 files / 1752 tests, 0 failed, 0 skipped
  • desktop tests: 62 files / 595 tests, 0 failed
  • web tests: 27 files / 226 tests, 0 failed
  • desktop lint (--max-warnings 0): 0 errors / 0 warnings; web lint: 0 errors (20 pre-existing warnings, identical to master)
  • desktop + web typecheck (TS 5.8.3, CI-pinned): clean
  • verify-shared-ui-hubclient.ps1 / verify-shared-boundary.ps1 / verify-shared-barrel.ps1 / verify-coverage-baseline.ps1: all pass (coverage above baseline: shared 76.99 / web 64.85 / desktop 49.54 lines)
  • git diff --check: clean

Notes

  • Local pnpm typecheck resolves the app-root hoisted TypeScript 6.0.3 (which fails on the deprecated baseUrl option); CI uses the lockfile-pinned 5.8.x. Verified locally with the pinned 5.8.3 binary.
  • Shared tsc --noEmit has 53 pre-existing errors on master (test-file/storybook debt, not run by CI); this change adds zero new errors.

Summary by CodeRabbit

  • New Features
    • Added project listing, creation, and editing across desktop and web workbenches.
    • Added paginated project loading with retryable errors when loading more projects fails.
    • Added localized English and Chinese messages for pagination errors and retries.
  • Refactor
    • Improved separation between workbench UI and platform-specific project services.
  • Tests
    • Expanded coverage for project operations, pagination, mapping, error handling, and retries.

Copilot AI lite review requested due to automatic review settings August 4, 2026 07:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@DeliciousBuding, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 5 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 33a7ae99-9d19-4215-b1fb-173776b9721f

📥 Commits

Reviewing files that changed from the base of the PR and between f8fa164 and 3e64888.

📒 Files selected for processing (29)
  • app/desktop/src/App.tsx
  • app/desktop/src/platform/desktopWorkbenchProjectsPort.test.ts
  • app/desktop/src/platform/desktopWorkbenchProjectsPort.ts
  • app/shared/src/i18n/workbench.ts
  • app/shared/src/workbench/AgentHubWorkbenchHelpers.test.ts
  • app/shared/src/workbench/AgentHubWorkbenchHelpers.ts
  • app/shared/src/workbench/AgentHubWorkbenchTypes.ts
  • app/shared/src/workbench/WorkbenchFrame.tsx
  • app/shared/src/workbench/WorkbenchFrameParts.test.tsx
  • app/shared/src/workbench/WorkbenchRoutes.tsx
  • app/shared/src/workbench/hubDataMapping.test.ts
  • app/shared/src/workbench/index.ts
  • app/shared/src/workbench/pages/ProjectsPage.tsx
  • app/shared/src/workbench/pages/projects/ProjectNav.tsx
  • app/shared/src/workbench/pages/projects/types.ts
  • app/shared/src/workbench/useWorkbenchProjectsRoute.test.ts
  • app/shared/src/workbench/useWorkbenchProjectsRoute.ts
  • app/shared/src/workbench/workbenchFramePartsHelpers.test.ts
  • app/shared/src/workbench/workbenchFramePartsHelpers.ts
  • app/shared/src/workbench/workbenchFrameTypes.ts
  • app/shared/src/workbench/workbenchProjectsPort.ts
  • app/shared/src/workbench/workbenchRoutesHelpers.ts
  • app/shared/src/workbench/workbenchRoutesTypes.ts
  • app/shared/vitest.config.ts
  • app/web/src/App.tsx
  • app/web/src/platform/webWorkbenchProjectsPort.test.ts
  • app/web/src/platform/webWorkbenchProjectsPort.ts
  • docs/progress/MASTER.md
  • scripts/verify/verify-shared-ui-hubclient.ps1
📝 Walkthrough

Walkthrough

Changes

Workbench projects integration

Layer / File(s) Summary
Projects port contract and wiring
app/shared/src/workbench/workbenchProjectsPort.ts, app/shared/src/workbench/*Types.ts, app/shared/src/workbench/WorkbenchFrame.tsx, app/shared/src/workbench/WorkbenchRoutes.tsx, app/shared/src/workbench/*Helpers*
Shared Workbench props now use WorkbenchProjectsPort instead of hubClient. The port and paginated page types are publicly exported.
Port-backed loading and retry behavior
app/shared/src/workbench/useWorkbenchProjectsRoute.ts, app/shared/src/workbench/useWorkbenchProjectsRoute.test.ts, app/shared/src/workbench/pages/*, app/shared/src/workbench/workbenchRoutesHelpers.ts, app/shared/src/i18n/workbench.ts
Project loading, pagination, creation, and updates use the injected port. Pagination failures expose localized errors and an explicit retry action. Tests cover loading, retries, errors, stale updates, and duplicate requests.
Web and Desktop project adapters
app/web/src/platform/webWorkbenchProjectsPort.ts, app/web/src/platform/webWorkbenchProjectsPort.test.ts, app/desktop/src/platform/desktopWorkbenchProjectsPort.ts, app/desktop/src/platform/desktopWorkbenchProjectsPort.test.ts, app/web/src/App.tsx, app/desktop/src/App.tsx, app/shared/src/workbench/hubDataMapping.test.ts
Web and Desktop factories adapt HubClient project APIs to the shared port. Both adapters map pagination and project data and normalize write fields.
Boundary verification and tracking
scripts/verify/verify-shared-ui-hubclient.ps1, app/shared/vitest.config.ts, docs/progress/MASTER.md
Shared UI verification now rejects concrete hubClient imports and HubClient references. The new port file is excluded from coverage, and the progress tracker records the completed slice.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant AgentHubWorkbench
  participant WorkbenchRoutes
  participant useWorkbenchProjectsRoute
  participant WorkbenchProjectsPort
  participant HubClient
  participant ProjectNav

  App->>AgentHubWorkbench: provide authenticated projectsPort
  AgentHubWorkbench->>WorkbenchRoutes: forward projectsPort
  WorkbenchRoutes->>useWorkbenchProjectsRoute: initialize route
  useWorkbenchProjectsRoute->>WorkbenchProjectsPort: listProjects
  WorkbenchProjectsPort->>HubClient: request workspace projects
  HubClient-->>WorkbenchProjectsPort: paginated project response
  WorkbenchProjectsPort-->>useWorkbenchProjectsRoute: WorkbenchProjectsPage
  useWorkbenchProjectsRoute-->>ProjectNav: projects and pagination state
  ProjectNav->>useWorkbenchProjectsRoute: retry loadMore after failure
Loading
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The port boundary, adapter wiring, retry handling, stale-update guards, and mapping tests meet the goals, but telemetry and one shared adapter suite are not evidenced. Add explicit pagination-failure telemetry and run one shared contract suite against both Web and Desktop adapters.
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the Workbench Hub projects port extraction and contract refactor.
Out of Scope Changes check ✅ Passed The listed changes support #1546 and #1528 through adapters, shared routing, retry UI, tests, verifier enforcement, and progress documentation.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/workbench-hubclient-port

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/shared/src/workbench/WorkbenchRoutes.tsx (1)

277-285: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Enforce exclusive project ownership or require parent mutation callbacks.

useWorkbenchProjectsRoute disables port-backed project reads when projects is supplied, but it still calls projectsPort for create/update when onProjectCreate or onProjectUpdate are absent. That allows port-managed project mutations while the parent-managed projects source can remain stale.

Make the route input an exclusive ownership type, or require both parent mutation callbacks whenever projects is provided.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/src/workbench/WorkbenchRoutes.tsx` around lines 277 - 285, The
WorkbenchProjectsRouteGate input currently allows parent-managed projects with
missing mutation callbacks, while useWorkbenchProjectsRoute still sends
create/update operations through projectsPort. Enforce an exclusive ownership
contract in the route props, or require both onProjectCreate and onProjectUpdate
whenever projects is provided, so parent-managed project state cannot coexist
with port-backed mutations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/shared/src/workbench/pages/projects/ProjectNav.tsx`:
- Around line 149-167: Update the loadMoreError rendering in ProjectNav to put
role="alert" on StatusNotice, pass the retry button through its action prop, and
remove the outer div’s role="alert" so the error and retry action use one alert
region.
- Around line 150-161: Update the retry block in ProjectNav’s statusStack to
apply `?? ''` to each new CSS module lookup, and replace the direct
`onClick={onLoadMore}` binding with a synchronous callback that invokes
`onLoadMore` using `void` to discard its async result.

In `@app/shared/src/workbench/useWorkbenchProjectsRoute.ts`:
- Around line 104-124: Update the project-loading flows centered on loadProjects
and the related load-more and mutation handlers to invalidate requests when
projectsPort changes and guard every post-await state update with both the
mounted check and current request generation or cancellation token. Apply the
guards in success, catch, and finally paths, including setLoadingMore(false),
and prevent mutation-triggered loadProjects refreshes after unmount. Add
coverage for port replacement, load-more unmount, and mutation unmount.
- Line 81: Update the ownership selection around portProjectsEnabled and the
list/create/update paths to resolve one project owner for the entire hook: use
the port for reads and mutations when projectsPort is provided, otherwise use
the configured mutation callbacks consistently. Add or refine a discriminated
options type so configurations combining projectsPort with mutation callbacks,
or supplying only one callback, are rejected; ensure the affected list and
mutation operations all route through the selected owner.

In `@app/shared/src/workbench/WorkbenchFrameParts.test.tsx`:
- Line 487: Remove the explicit projectsPort={undefined} assignment from the
fixture in WorkbenchFrameParts tests, leaving the optional prop omitted while
preserving all other fixture fields.

In `@scripts/verify/verify-shared-ui-hubclient.ps1`:
- Around line 64-67: Update Strip-Comments and the verification flow to scan
comment-free TypeScript rather than the original lines: preserve block-comment
state across lines, ignore comment markers inside string literals, and apply the
stripped result to every import and forbidden type-name check covering the logic
around Strip-Comments and lines 74-107.

---

Outside diff comments:
In `@app/shared/src/workbench/WorkbenchRoutes.tsx`:
- Around line 277-285: The WorkbenchProjectsRouteGate input currently allows
parent-managed projects with missing mutation callbacks, while
useWorkbenchProjectsRoute still sends create/update operations through
projectsPort. Enforce an exclusive ownership contract in the route props, or
require both onProjectCreate and onProjectUpdate whenever projects is provided,
so parent-managed project state cannot coexist with port-backed mutations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 784bf850-1d2b-446f-8aed-d572c6576f5c

📥 Commits

Reviewing files that changed from the base of the PR and between 0343056 and dff72c2.

📒 Files selected for processing (29)
  • app/desktop/src/App.tsx
  • app/desktop/src/platform/desktopWorkbenchProjectsPort.test.ts
  • app/desktop/src/platform/desktopWorkbenchProjectsPort.ts
  • app/shared/src/i18n/workbench.ts
  • app/shared/src/workbench/AgentHubWorkbenchHelpers.test.ts
  • app/shared/src/workbench/AgentHubWorkbenchHelpers.ts
  • app/shared/src/workbench/AgentHubWorkbenchTypes.ts
  • app/shared/src/workbench/WorkbenchFrame.tsx
  • app/shared/src/workbench/WorkbenchFrameParts.test.tsx
  • app/shared/src/workbench/WorkbenchRoutes.tsx
  • app/shared/src/workbench/hubDataMapping.test.ts
  • app/shared/src/workbench/index.ts
  • app/shared/src/workbench/pages/ProjectsPage.tsx
  • app/shared/src/workbench/pages/projects/ProjectNav.tsx
  • app/shared/src/workbench/pages/projects/types.ts
  • app/shared/src/workbench/useWorkbenchProjectsRoute.test.ts
  • app/shared/src/workbench/useWorkbenchProjectsRoute.ts
  • app/shared/src/workbench/workbenchFramePartsHelpers.test.ts
  • app/shared/src/workbench/workbenchFramePartsHelpers.ts
  • app/shared/src/workbench/workbenchFrameTypes.ts
  • app/shared/src/workbench/workbenchProjectsPort.ts
  • app/shared/src/workbench/workbenchRoutesHelpers.ts
  • app/shared/src/workbench/workbenchRoutesTypes.ts
  • app/shared/vitest.config.ts
  • app/web/src/App.tsx
  • app/web/src/platform/webWorkbenchProjectsPort.test.ts
  • app/web/src/platform/webWorkbenchProjectsPort.ts
  • docs/progress/MASTER.md
  • scripts/verify/verify-shared-ui-hubclient.ps1

Comment on lines +149 to +167
{loadMoreError ? (
<div className={styles.statusStack} role="alert">
<StatusNotice
{...(styles.statusNotice ? { className: styles.statusNotice } : {})}
icon={<DesignNavIcon name="error404" size={14} />}
>
{t('projects.loadMoreError', { message: loadMoreError })}
</StatusNotice>
{onLoadMore ? (
<button
type="button"
className={`${styles.newProjectBtn} ${styles.navNewProjectBtn} outline-action`}
onClick={onLoadMore}
>
{t('projects.retryLoadMore')}
</button>
) : null}
</div>
) : null}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use one alert region for the error and retry action.

The outer role="alert" contains a StatusNotice that defaults to role="status". Assistive technology can announce the same error through both live regions.

Set role="alert" on StatusNotice. Pass the retry button through its action prop. Remove the outer alert role.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/src/workbench/pages/projects/ProjectNav.tsx` around lines 149 -
167, Update the loadMoreError rendering in ProjectNav to put role="alert" on
StatusNotice, pass the retry button through its action prop, and remove the
outer div’s role="alert" so the error and retry action use one alert region.

Comment on lines +150 to +161
<div className={styles.statusStack} role="alert">
<StatusNotice
{...(styles.statusNotice ? { className: styles.statusNotice } : {})}
icon={<DesignNavIcon name="error404" size={14} />}
>
{t('projects.loadMoreError', { message: loadMoreError })}
</StatusNotice>
{onLoadMore ? (
<button
type="button"
className={`${styles.newProjectBtn} ${styles.navNewProjectBtn} outline-action`}
onClick={onLoadMore}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Apply the TypeScript UI boundary rules to the retry block.

Add ?? '' to the new CSS module lookups. Wrap the retry call in a synchronous handler that discards the async result with void.

Proposed fix
-        <div className={styles.statusStack} role="alert">
+        <div className={styles.statusStack ?? ''} role="alert">
...
-              className={`${styles.newProjectBtn} ${styles.navNewProjectBtn} outline-action`}
-              onClick={onLoadMore}
+              className={`${styles.newProjectBtn ?? ''} ${styles.navNewProjectBtn ?? ''} outline-action`}
+              onClick={() => {
+                void onLoadMore();
+              }}

As per coding guidelines, CSS module indexing must use ?? '', and async handlers passed to () => void must use void fn().

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className={styles.statusStack} role="alert">
<StatusNotice
{...(styles.statusNotice ? { className: styles.statusNotice } : {})}
icon={<DesignNavIcon name="error404" size={14} />}
>
{t('projects.loadMoreError', { message: loadMoreError })}
</StatusNotice>
{onLoadMore ? (
<button
type="button"
className={`${styles.newProjectBtn} ${styles.navNewProjectBtn} outline-action`}
onClick={onLoadMore}
<div className={styles.statusStack ?? ''} role="alert">
<StatusNotice
{...(styles.statusNotice ? { className: styles.statusNotice } : {})}
icon={<DesignNavIcon name="error404" size={14} />}
>
{t('projects.loadMoreError', { message: loadMoreError })}
</StatusNotice>
{onLoadMore ? (
<button
type="button"
className={`${styles.newProjectBtn ?? ''} ${styles.navNewProjectBtn ?? ''} outline-action`}
onClick={() => {
void onLoadMore();
}}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/src/workbench/pages/projects/ProjectNav.tsx` around lines 150 -
161, Update the retry block in ProjectNav’s statusStack to apply `?? ''` to each
new CSS module lookup, and replace the direct `onClick={onLoadMore}` binding
with a synchronous callback that invokes `onLoadMore` using `void` to discard
its async result.

Source: Coding guidelines

Comment thread app/shared/src/workbench/useWorkbenchProjectsRoute.ts
Comment thread app/shared/src/workbench/useWorkbenchProjectsRoute.ts
activeProjectId={undefined}
projectsStatus={undefined}
hubClient={undefined}
projectsPort={undefined}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Omit projectsPort from this fixture.

Line 487 explicitly assigns undefined to an optional prop. Remove the prop to test the omitted state and preserve exact optional-property semantics.

Proposed fix
-          projectsPort={undefined}

As per coding guidelines: “仅在值已定义时赋值”.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
projectsPort={undefined}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/shared/src/workbench/WorkbenchFrameParts.test.tsx` at line 487, Remove
the explicit projectsPort={undefined} assignment from the fixture in
WorkbenchFrameParts tests, leaving the optional prop omitted while preserving
all other fixture fields.

Source: Coding guidelines

Comment on lines +64 to +67
function Strip-Comments([string]$Line) {
$code = [regex]::Replace($Line, '/\*.*?\*/', ' ', 'Singleline')
$code = [regex]::Replace($code, '//.*$', ' ')
return $code

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Strip comments before every forbidden-reference scan.

The import scans use the original $line. A line such as // import type { HubClient } from './hubClient' therefore fails the gate.

Strip-Comments also handles only block comments that start and end on one line. An interior HubClient line in a multi-line documentation comment also fails.

Tokenize the TypeScript source, or use a stateful scanner that tracks block comments and string literals. Run all import and type-name checks against the resulting code.

Also applies to: 74-107

🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)

[warning] Missing BOM encoding for non-ASCII encoded file 'verify-shared-ui-hubclient.ps1'

(PSUseBOMForUnicodeEncodedFile)


[warning] 64-64: The cmdlet 'Strip-Comments' uses an unapproved verb.

(PSUseApprovedVerbs)


[warning] 64-64: The cmdlet 'Strip-Comments' uses a plural noun. A singular noun should be used instead.

Suggested fix: Singularized correction of 'Strip-Comments'

(PSUseSingularNouns)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/verify/verify-shared-ui-hubclient.ps1` around lines 64 - 67, Update
Strip-Comments and the verification flow to scan comment-free TypeScript rather
than the original lines: preserve block-comment state across lines, ignore
comment markers inside string literals, and apply the stripped result to every
import and forbidden type-name check covering the logic around Strip-Comments
and lines 74-107.

@DeliciousBuding
DeliciousBuding force-pushed the refactor/workbench-hubclient-port branch from f8fa164 to a947242 Compare August 4, 2026 13:28
Codex (Delicious233) added 3 commits August 4, 2026 21:45
shared Workbench 不再以 type/value 形式引用 concrete HubClient:
- 新增窄领域端口 WorkbenchProjectsPort(shared/workbench/workbenchProjectsPort.ts),
  Desktop/Web composition root 各实现 adapter(desktop/webWorkbenchProjectsPort.ts)
  注入 projectsPort,transport DTO 映射与默认名称归一化移到 app 层;
- useWorkbenchProjectsRoute 的 internal-fetch 路径改为纯端口驱动(单一 ownership:
  parent-managed 或 port,不再运行时猜测 hubClient);
- 分页失败不再静默:loadMoreError 可见、hasMore 停哨兵、重试按钮(ProjectNav + zh/en i18n);
- 同 contract 双端 adapter 测试(desktop 5 / web 6 例)+ shared route 端口测试 11 例;
- verify-shared-ui-hubclient.ps1 升级为同时禁止 value/type 引用 concrete HubClient。
#1546 的 projects slice 收尾,shared 层只依赖领域契约:
- hubDataMapping.test.ts:为双端 ports 共用的 DTO→ProjectInfo 映射补契约测试,
  该文件重新进入 shared coverage(uncovered 回落至基线 38);
- shared vitest.config.ts:将纯类型契约 workbenchProjectsPort.ts 列入窄排除
  (与 types.ts/index.ts 同先例,零运行时语句);
- docs/progress/MASTER.md:登记本切片完成状态(agents/catalog 收口留待后续切片)。
@DeliciousBuding
DeliciousBuding force-pushed the refactor/workbench-hubclient-port branch from a947242 to 3e64888 Compare August 4, 2026 13:45
@DeliciousBuding
DeliciousBuding merged commit ced7072 into master Aug 4, 2026
22 checks passed
@DeliciousBuding
DeliciousBuding deleted the refactor/workbench-hubclient-port branch August 4, 2026 14:08
DeliciousBuding added a commit that referenced this pull request Aug 11, 2026
* refactor(workbench): Hub projects 依赖端口化为 WorkbenchProjectsPort(#1546)

shared Workbench 不再以 type/value 形式引用 concrete HubClient:
- 新增窄领域端口 WorkbenchProjectsPort(shared/workbench/workbenchProjectsPort.ts),
  Desktop/Web composition root 各实现 adapter(desktop/webWorkbenchProjectsPort.ts)
  注入 projectsPort,transport DTO 映射与默认名称归一化移到 app 层;
- useWorkbenchProjectsRoute 的 internal-fetch 路径改为纯端口驱动(单一 ownership:
  parent-managed 或 port,不再运行时猜测 hubClient);
- 分页失败不再静默:loadMoreError 可见、hasMore 停哨兵、重试按钮(ProjectNav + zh/en i18n);
- 同 contract 双端 adapter 测试(desktop 5 / web 6 例)+ shared route 端口测试 11 例;
- verify-shared-ui-hubclient.ps1 升级为同时禁止 value/type 引用 concrete HubClient。

* refactor(workbench): projects 契约切片收口映射合同与纯类型端口(#1528#1546 的 projects slice 收尾,shared 层只依赖领域契约:
- hubDataMapping.test.ts:为双端 ports 共用的 DTO→ProjectInfo 映射补契约测试,
  该文件重新进入 shared coverage(uncovered 回落至基线 38);
- shared vitest.config.ts:将纯类型契约 workbenchProjectsPort.ts 列入窄排除
  (与 types.ts/index.ts 同先例,零运行时语句);
- docs/progress/MASTER.md:登记本切片完成状态(agents/catalog 收口留待后续切片)。

* fix(web): webWorkbenchProjectsPort 测试补 beforeEach 导入 (#1546)

---------

Co-authored-by: Codex <codex@vectorcontrol.tech>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P1] 移除 shared Workbench 对具体 HubClient 的隐藏数据层依赖

2 participants