100 Commits
Author SHA1 Message Date
imccyu fcc0ad4621 Merge pull request #7873 from deepseek-harness/merge/release-dsh-0.2.2-rc.1-to-master
Merge release/dsh-0.2.2 (0.2.2-rc.1) into master
2026-11-04 16:40:00 +08:00
imccyu 66491b05e3 Merge pull request #7870 from deepseek-harness/worktree/release-dsh-0.2.2-rc.1
release: dsh@0.2.2-rc.1
2026-11-04 15:54:45 +08:00
imccyu 54cb44c006 Merge pull request #7792 from deepseek-harness/fix-goal-disarmed-zh-label
fix(ui-goal): tell an inactive goal from a paused one in Chinese
2026-11-03 20:30:41 +08:00
imccyu 36626c7dfa Merge pull request #7700 from deepseek-harness/refactor/css-anchored-panels
refactor(client): position floating panels with CSS anchors
2026-11-03 15:43:31 +08:00
imccyu 8bd073392e Merge pull request #7798 from deepseek-harness/worktree-sync-dsh-0.2.2-to-master-1103b
release(dsh): sync 0.2.2-alpha.3 back to master
2026-11-03 15:27:29 +08:00
imccyu 24db102f15 release(dsh): align master packages with 0.2.2-alpha.3 2026-11-03 15:13:20 +08:00
imccyu f590c13c92 Merge master into worktree-sync-dsh-0.2.2-to-master-1103b 2026-11-03 15:10:23 +08:00
imccyu 41ef8c47a3 Merge pull request #7790 from deepseek-harness/worktree-release-vendor-0.2.2-alpha.3
release(vendor): prepare alpha.2 packages for DSH 0.2.2-alpha.3
2026-11-03 14:27:17 +08:00
imccyu 85c775322f fix(ui-goal): tell an inactive goal from a paused one in Chinese
The Chinese GoalBar used 已暂停的目标 both for a durably paused goal and for an
active goal whose automatic continuation is disarmed, the state every active
goal has after a restart. Users could not tell whether a goal had been paused.
The disarmed label now reads 待继续的目标; paused goals keep 已暂停的目标.

Refs #7757
2026-11-03 14:20:39 +08:00
imccyu 05b1cae8db release(vendor): cordis 4.0.6-alpha.2, cosmokit 1.8.7-alpha.2, group 1.0.6-alpha.2, hmr 1.0.21-alpha.2, include 1.0.11-alpha.2, loader 1.0.7-alpha.2, logger-console 1.0.6-alpha.2, schemastery 3.18.6-alpha.2, timer 1.1.8-alpha.2 2026-11-03 14:19:06 +08:00
imccyu c18851aa30 Merge pull request #7780 from deepseek-harness/worktree-sync-dsh-0.2.2-to-master-1103
release(dsh): sync release/dsh-0.2.2 back to master (#7704)
2026-11-03 14:07:24 +08:00
imccyu b3f1904e86 Merge pull request #7724 from deepseek-harness/worktree-release-dsh-0.2.2-alpha.3
release(dsh): 0.2.2-alpha.3
2026-11-03 13:55:35 +08:00
imccyu f26f308e5e Merge pull request #7768 from deepseek-harness/fix/goal-shutdown-pause
fix(goal-round-driver): keep a running goal active when its agent is disposed
2026-11-03 05:52:48 +00:00
imccyu 1c78d475bf release(dsh): 0.2.2-alpha.3 2026-11-03 13:37:26 +08:00
imccyu c08621b991 Merge master into worktree-sync-dsh-0.2.2-to-master-1103 2026-11-03 13:32:45 +08:00
imccyu 70d9b57f5c Merge pull request #7565 from deepseek-harness/feat/web-search-fetch-settings
feat(web): 网页搜索与获取设置页分开选择 Search 与 Fetch,Search 默认改为 DeepSeek Search API
2026-11-03 13:31:41 +08:00
imccyu b3f301e573 Revert "fix(settings): show saved API keys and preserve environment detection…" (#7775)
This reverts commit 9bb49604b63bb5d50e879bcf63c9f5cb2afbd737.
2026-11-03 12:35:13 +08:00
imccyu 06bf7ce024 Revert "fix(settings): show saved API keys and preserve environment detection…"
This reverts commit 9bb49604b63bb5d50e879bcf63c9f5cb2afbd737.
2026-11-03 12:33:44 +08:00
imccyu e4ac64c9c7 Merge pull request #7734 from deepseek-harness/worktree-sync-dsh-0.2.2-to-master
release(dsh): sync release/dsh-0.2.2 back to master
2026-11-03 12:28:59 +08:00
imccyu a3f6f94c1e test(snapshot): refresh fixtures for the 10-query web_search default 2026-11-03 12:13:05 +08:00
imccyu aa4774e685 Merge master into worktree-sync-dsh-0.2.2-to-master 2026-11-03 12:05:47 +08:00
imccyu ef5f28d0fb Merge master into worktree-sync-dsh-0.2.2-to-master 2026-11-03 11:47:40 +08:00
imccyu eb1713f856 fix(session-projection): keep released units in checkpoints (#7754)
* fix(session-projection): keep released units in checkpoints

Since the Cordis rc.11 teardown order unloads the Web layer before the
base layer, Session Controller and harness-dev-context release their
projection units before their live Sessions detach. The projection
cache is still alive at that point and wrote a checkpoint holding only
the units that were still registered, replacing the complete record.
A blank Session then lost sessionListMetadata and listed as an untitled
conversation after every graceful restart.

A released unit now stays in the registry as a predecessor: it leaves
event drives, snapshots, restores, and change notifications, while
checkpoint() keeps each Session's last cell of it without advancing it.
Registering the same key again replaces the predecessor and refolds
the log. The projection cache keeps replacing whole records.

* test(session-projection): assert frozen released units across unload tests

Update the remaining unload tests that still expected a released unit
to vanish from checkpoint(): user-approval, agent-loop inbox and scope
lifecycle, time-context, and the agent registry now assert that the
same Session keeps its pre-unload row, that a later event does not
advance it, and that a Session created after the unload has no row.
The token-meter and goal unload tests also append an event after the
unload.

Document that a retained handle read still advances a released cell
that checkpoint() serves, and that restore() folds only live units, so
its refreshed rows omit released units.

* docs(session-projection): sync the ProjectionHandle type-equiv block

* docs(session-projection): record frozen released units and their upgrade

Add the upgrade guide for checkpoint() keeping a released unit's last
row, update the registration-handles Agent Note with the frozen-cell
decision and the retained predecessor, list both consequences under the
registry README's known limitations, note in the projection cache README
that a stored row can be frozen at its unit's release, and say that
restoreFloor() ignores released predecessors.

Update the agent-loop resource-lifecycle unload test, which read
checkpoints through an alias, to the frozen-row semantics.

* docs(upgrade-guide): mark the released-checkpoint snippet ignore-check

* docs(session-projection): state the retained-handle path and narrow a rejected alternative

* docs(upgrade-guide): re-record the released-checkpoint guide pairing
2026-11-03 11:07:09 +08:00
imccyu 6e77ea0131 feat(web): boot past failed optional client plugins (#7733)
* feat(web): boot past failed optional client plugins

The Web client boot audit now follows Host startup strictness. An
inactive entry on the global required list (module system, Session
transport, renderer, application frame, Session view, and sidebar)
still rejects startup and the report marks the required entries.
Other inactive entries produce one console warning and the
application mounts without them. The boot page no longer draws a
failed entry before the audit decides.

* fix(web): audit boot entries whose creation rejects and name activation errors

ClientEntries.start() now logs a row whose Loader creation rejects, such
as a module that exports no plugin, and leaves it inactive for the boot
audit, as the Host Loader group does. The audit awaits only failed
fibers to report their recorded activation error. Notes, READMEs, and
the Web client subsystem page describe the browser boot audit; tests
cover invalid exports, carrier presentation of optional failures, and
required names absent from the boot graph.

* test(web): fail test carriers and e2e on inactive client entries

The product boot only warns about inactive entries outside its required
list, but tests must still surface every plugin that fails. TestClient
and createClientTest now require every roster entry to activate unless
a case passes allowInactiveEntries. The watchConsole tripwire, the
real-host smoke, and the assembled jsdom boot treat a web boot warning
as a failure with no opt-out.

Docs: the Web README names Session control, notes that an entry without
a fiber is reported as an import failure like the Host audit's "failed
to import", and the startup strictness note lists the browser tests.
2026-11-02 16:20:50 +00:00
imccyuandimccyu bedcb559ac test(snapshot): refresh the ptc-script-imports system prompt (#7738)
* test(snapshot): refresh the ptc-script-imports system prompt

The pinned prompt kept the fs-observation wording from before the apply_patch guidance
landed, so the scenario failed on the prompt after the session records matched.

* test(snapshot): carry the current tool declarations into the ptc-script-imports prompt

The pinned prompt still listed the tools from before `apply_patch` and `wait_agent`
landed and before the subagent tool docs changed; the tool block now matches the
current declarations, the same 51 added and 12 removed lines CI reported.

---------

Co-authored-by: imccyu <imccyu@users.noreply.github.com>
2026-11-02 20:55:02 +08:00
imccyuandimccyu 07f2b259e7 ci: run the merge checks on release branches, and fix the ptc-script-imports fixture (#7732)
* ci: run the merge checks on release branches too

All three `Policy` workflows filtered on `master`, so a pull request into `release/dsh-*`
got no `Master Change` and no `Pre-Merge Check`, and its review check only refreshed when
somebody submitted a review. The checks already take their base branch from the event, so
the filters now name the release branches as well.

* ci: limit the release branch filter to x.y.z

`release/dsh-*` also matched prerelease branches such as `release/dsh-0.1.2-alpha.4`;
the filter now spells the version digits, so only `release/dsh-x.y.z` counts.

* test(snapshot): carry the subagent identity section into the ptc-script-imports scenario

The runtime context gained a `subagent:identity` section and every session fixture but
this one was regenerated, so replay failed with a mismatch on the added section.

(cherry picked from commit c7a4119965cb26c69fd8fccbfd703c7d73351742)

---------

Co-authored-by: imccyu <imccyu@users.noreply.github.com>
2026-11-02 20:12:14 +08:00
imccyu d3f7b8abe7 Merge pull request #7701 from deepseek-harness/fix/empty-session-sidebar-0.2.2
[0.2.2] fix(session-projection): compute exactly the requested projections for hot session summaries
2026-11-02 17:05:09 +08:00
imccyu a25eebc146 Merge pull request #7698 from deepseek-harness/fix/temporarily-disable-apply-patch
fix(fs): set apply_patch to false
2026-11-02 16:53:15 +08:00
imccyu cd5f5c80ba Merge pull request #7707 from deepseek-harness/fix/7688-locked-runtime-deploy-0.2.2
[0.2.2] fix(python): deploy the runtime from the workspace lockfile
2026-11-02 16:35:17 +08:00
imccyu e428c74d51 Merge pull request #7207 from deepseek-harness/feat/sidebar-plugin-pin-preview
feat(ui): 优化侧栏插件固定与 More 交互
2026-11-01 01:05:56 +08:00
imccyu 24ac78d283 fix(ui): show unpinned sidebar panels while More is absent 2026-10-31 22:47:22 +08:00
Yudong Han 02578b3cce Merge pull request #7629 from deepseek-harness/fix/revert-4484-display-dollar
revert(ui-primitives): 撤回 #4484 的多行美元公式解析
2026-10-30 17:43:58 +08:00
imccyu 93e28b1418 Merge pull request #7581 from deepseek-harness/fix/merge-approve-jobs
ci: decide the review verdict in one Approve Check job
2026-10-30 16:15:02 +08:00
imccyu ea9912523d Merge pull request #7619 from deepseek-harness/worktree/forge-local-changes-independent
fix(web): keep local changes visible alongside pull requests
2026-10-30 15:49:46 +08:00
imccyu 945006c984 perf(session): send one projection frame per committed event (#7587)
* perf(session): send one projection frame per committed event

* fix(session): deliver keys changed before a drive failure; address review

* perf(session): carry projection frame changes as key and val entries
2026-10-30 14:14:03 +08:00
imccyu 76bb45e2be Merge pull request #7609 from deepseek-harness/revert-7423-feat/composer-prefill-api
Revert "feat(client): expose stable composer prefill API"
2026-10-30 14:00:08 +08:00
imccyu 5c2826eae5 Revert "feat(client): expose stable composer prefill API" 2026-10-30 13:59:08 +08:00
imccyu 8c2f5d85b2 fix(ui-conversation): keep the docked composer seat stable (#7591)
* fix(ui-conversation): keep the docked composer seat stable

The active composer seat now keeps one stacking rank (z-index 9) in every
state, a direct compositing reason (will-change: transform), the scroll
floor without relying on a View to fill the column (margin-top: auto), and
no scroll-anchoring role. Composer tooltips portal to the body because the
seat is the containing block for fixed descendants. The width handle keeps
z-index 0 while dragging.

The docked statistics row reserves one reading's height before its
projections arrive, and the header without a Session keeps the blank
Session's 40px row on every platform so both Hero states center the input
card at the same height.

Fixes #7590

* docs(ui-conversation): state the composer fixed-overlay contract

Composer-hosted slots now document that fixed overlays must portal to the
document body, because the docked composer is their containing block; the
client slot catalog is regenerated from that JSDoc. The README also records
that gutter tables cover a captured width-handle drag and that the
composer's backdrop blur is verified only in Chromium. Local comments note
the grayscale text antialiasing of the permanent composer layer, why the
statistics row uses a minimum height, why the sessionless header keeps an
empty title row, and that the Hero offset test assumes the default plugins.

Refs #7590

* docs(ui-conversation): state the back-to-bottom offset as geometry

The composer and back-to-bottom stacking comments now state the resting
16px gap instead of claiming the control never overlaps the input card.

Refs #7590
2026-10-30 12:36:21 +08:00
imccyu 95e37ce6a9 docs(ui-conversation): state the back-to-bottom offset as geometry
The composer and back-to-bottom stacking comments now state the resting
16px gap instead of claiming the control never overlaps the input card.

Refs #7590
2026-10-30 12:22:22 +08:00
imccyu 12e47f5974 docs(ui-conversation): state the composer fixed-overlay contract
Composer-hosted slots now document that fixed overlays must portal to the
document body, because the docked composer is their containing block; the
client slot catalog is regenerated from that JSDoc. The README also records
that gutter tables cover a captured width-handle drag and that the
composer's backdrop blur is verified only in Chromium. Local comments note
the grayscale text antialiasing of the permanent composer layer, why the
statistics row uses a minimum height, why the sessionless header keeps an
empty title row, and that the Hero offset test assumes the default plugins.

Refs #7590
2026-10-30 12:13:03 +08:00
imccyu af4bddbc59 fix(ui-conversation): keep the docked composer seat stable
The active composer seat now keeps one stacking rank (z-index 9) in every
state, a direct compositing reason (will-change: transform), the scroll
floor without relying on a View to fill the column (margin-top: auto), and
no scroll-anchoring role. Composer tooltips portal to the body because the
seat is the containing block for fixed descendants. The width handle keeps
z-index 0 while dragging.

The docked statistics row reserves one reading's height before its
projections arrive, and the header without a Session keeps the blank
Session's 40px row on every platform so both Hero states center the input
card at the same height.

Fixes #7590
2026-10-30 02:23:24 +08:00
imccyu ce7073d512 Merge pull request #7552 from deepseek-harness/fix/webworker-live-import-bindings
fix(webworker): read named and default imports at each reference
2026-10-30 00:13:15 +08:00
imccyu 6397b4e59c Merge pull request #7556 from deepseek-harness/fix/mobile-sidebar-title
fix(web): 稳定手机端右侧栏切换时的会话标题布局
2026-10-29 23:54:15 +08:00
imccyu c536530456 Merge pull request #7578 from deepseek-harness/worktree/sync-dsh-0.2.1-rc.5-to-master
release(dsh): sync 0.2.1-rc.5 back to master
2026-10-29 23:41:20 +08:00
imccyu 4d5945cb72 Merge pull request #7523 from deepseek-harness/07akioni/show-devtools-menu
fix(desktop): 在应用菜单显示 DevTools 开关
2026-10-29 14:51:22 +08:00
Shigma 3b3f93ac66 Merge pull request #6210 from deepseek-harness/chore/cordis-core-rc11
chore(cordis): upgrade Core to 4.0.0-rc.11
2026-10-28 21:34:50 +08:00
imccyu b9fafb54c8 Merge pull request #6951 from deepseek-harness/feat/extensible-context-menus
feat(client): 统一可扩展右键菜单与原始文件操作
2026-10-28 21:13:34 +08:00
imccyu 1e4ceb5ea0 Merge pull request #7468 from deepseek-harness/docs/gif-attach-only
docs(gif): require gh attach and split oversized GIFs
2026-10-28 15:40:42 +08:00
imccyu 68132b9a6a perf(values): reduce temporary JSON traversal allocations (#7451)
* perf(values): traverse JSON with active container cursors

* fix(values): preserve fractional Proxy index schedules
2026-10-28 12:58:29 +08:00
imccyu 79231619e4 🔀 Sync master and resolve sidebar column comment 2026-10-28 11:31:29 +08:00
imccyu 18bd83bf88 fix(ci): repair Wine heap budget and release workflow tests (#7438)
* fix(ci): budget Wine client heap and align release assertions

* fix(release): restore hosted publication runners

* fix(ci): split Wine client checks and strengthen dispatch tests

* docs: remove Wine diagnostic instruction from AGENTS
2026-10-28 11:22:35 +08:00
imccyu f3803c9697 release(dsh): 0.2.2-alpha.2 (#7437) 2026-10-28 02:17:58 +08:00
imccyu 00d541438b release(dsh): 0.2.2-alpha.2 2026-10-28 02:03:15 +08:00
imccyu 7509c174d9 fix(build): serialize release builds and give Client checks 8 GiB (#7435)
* fix(build): serialize publication and raise client aggregate heap

* docs: refresh development guide translation pairing

* fix(release): align pack runner and allow explicit tag-check bypass
2026-10-28 01:58:28 +08:00
imccyu 5106da3bb7 Merge pull request #7434 from deepseek-harness/worktree/release-dsh-0.2.2-alpha.1
release: dsh@0.2.2-alpha.1
2026-10-28 00:17:25 +08:00
imccyu 69c389ae11 release(dsh): 0.2.2-alpha.1 2026-10-28 00:00:58 +08:00
imccyu a4c9c208cd Merge pull request #7431 from deepseek-harness/release/vendor-alpha-for-0.2.2-alpha.1
release(vendor): prepare alpha.1 family for 0.2.2-alpha.1
2026-10-27 23:51:40 +08:00
imccyu 656c740669 release(vendor): cordis 4.0.6-alpha.1, cosmokit 1.8.7-alpha.1, group 1.0.6-alpha.1, hmr 1.0.21-alpha.1, include 1.0.11-alpha.1, loader 1.0.7-alpha.1, logger-console 1.0.6-alpha.1, schemastery 3.18.6-alpha.1, timer 1.1.8-alpha.1 2026-10-27 23:39:36 +08:00
imccyu c232e618fd Merge pull request #7430 from deepseek-harness/revert-7413-perf/web-startup-assets
Revert "perf(web): 压缩动态插件资源以加快冷启动"
2026-10-27 23:27:45 +08:00
imccyu 3ddab34194 Revert "perf(web): 压缩动态插件资源以加快冷启动" 2026-10-27 23:25:57 +08:00
imccyu 873c68c15b feat(models): show model selector badges from the /models listing (#7027)
* refactor(llm-deepseek): share the /models listing machinery

Move the account route's `/models` request and decoding, its
credential-scoped listing cache, and listed-catalog resolution with the
version gate into the shared DeepSeek Messages library, so a second
route can follow the same listing. Names drop the account prefix, the
cache takes each access's endpoint settings with the call, and it gains
`invalidate()` for a forced reload. `isBuiltInCatalog()` recognizes the
catalog an uncustomized `models` setting resolves to.

The account route keeps its behavior; only its imports and the
override diagnostic wording ("model listing") change.

* feat(llm-deepseek-api-key): follow the official /models listing

While `models` equals the built-in catalog and the Messages origin is
https://api.deepseek.com, `deepseek-official` serves the official
`GET /models` listing, authenticated with the API key in `x-api-key`.
Loading, refresh, fallback, merging, and the client-version gate match
the account route: the first access waits up to `modelsTimeoutMs`, a
listing older than `modelsMaxAgeMs` refreshes in the background on the
next access, a failure keeps the last good listing or the built-in
catalog, and listed models this build cannot serve are refused before
network I/O.

A customized `models` list replaces the catalog and requests nothing.
Switching between a customized catalog and the listing discards the
cached listing, so Restore defaults reloads it on the next access.

Suites that boot the route on the official endpoint now answer the
listing themselves instead of reaching the network.

* docs: describe the official route model listing

Document when `deepseek-official` follows the official `/models`
listing, its timing fields, customization precedence, and the forced
reload after Restore defaults in the API-key README, the shared
transport README, and the provider guide. Record the decision in a new
Agent Note, keep the account note's statement of where the shared
listing code lives current, and regenerate the configuration catalog.

* test(llm-deepseek-api-key): pin the once-per-listing hidden-entry diagnostic

* docs: regenerate module and event graphs for the shared listing

* fix(llm-deepseek-api-key): report credential failures on the model request

On the official endpoint, `connect` waited for the listing view, whose
credential lookup rethrew a malformed key or a credential-store failure
before the agent loop recorded the prompt. A failed lookup now resolves
the connection from the current listing view, so `resolveAuth` reports
the failure on the model request and the turn keeps the prompt and the
failed attempt. A caller abort still rejects.

* docs(llm-deepseek-api-key): name which hidden listing entries are logged

* test: keep unit suites off the official model listing

Suites that boot the DeepSeek routes with a dummy or inherited key now
request `GET https://api.deepseek.com/models` on the official endpoint.
A unit-lane setup file rejects that request at once, so such a suite
serves the built-in catalog instead of reaching production or waiting
out the listing deadline on a network that never answers; suites that
exercise the listing answer `fetch` themselves. Other requests pass
through unchanged.

* feat(llm-deepseek): read tool_update from the model listing

Both DeepSeek routes now take a listed model's Messages tool update mode
from `api_capabilities.anthropic_messages.tool_update`, alongside the
system prompt mode. `in-history` and `addition-only` replace the
bundled mode; any other value reads as `leading-only` and removes it.
An absent or `null` mode keeps the bundled one, so a listing that does
not declare the field leaves `deepseek-flash` on `addition-only`.

`system_prompt_update: null` likewise keeps the bundled mode now; it
previously read as `leading-only`, which a serializer writing empty
values as null would have turned into a cache-unfriendly downgrade.

* fix(llm-deepseek): sync the built-in context window with the official listing

The official `/models` listing declares a 1,048,576-token context window
for `deepseek-flash` and `deepseek-v4-pro`; the built-in catalog said
1,000,000, a decimal-versus-binary mismatch. Both built-in entries now
carry the listed value, so offline starts and listing failures size the
context the same way the listing does. The Models page shows the exact
count for these rows, since 1,048,576 has no decimal K/M spelling.

`defaultContextWindow`, the fallback for model ids the catalog does not
describe, stays 1,000,000.

* test(llm-deepseek-api-key): reject the stubbed listing request with an Error

* test(cli): keep the built SDK smoke off the official model listing

The SDK profile's initialize now resolves the deepseek-official catalog,
which requests GET https://api.deepseek.com/models on the official
endpoint. With the smoke's fixture key that request answers 401 and the
route warns on stderr, so the test's empty-stderr assertion failed in the
e2e and snapshots lanes. Point the run at a loopback mock and assert it
received no model call.

* feat(llm): carry /models badges into the model catalog

The shared DeepSeek listing decoder reads an optional per-entry
`badge: { text, tone }`. Text is one literal or translations keyed by
lowercase language id with a required English entry, each trimmed to 1
to 12 characters on one line; tone is neutral, info, success, or
warning, and an absent or unrecognized tone reads as neutral. An absent
or null badge declares none; an unreadable one is dropped with a listing
problem and never hides its model.

resolveListedCatalog keeps the badges of offered models, both DeepSeek
routes attach them through catalogModelInfo, LlmRuntime.listModels
detaches them, and the Host model catalog forwards them as
ModelCatalogModel.badge. resolveModelInfo omits the badge, so no model
request, Session event, or model-facing tool carries it.

* feat(client): render catalog badges in the model selector

The composer model seat shows a catalog model's badge after its name in
the trigger, the root-menu value, and each option: a Tag in the badge's
tone whose text is resolved for the active locale through
ctx.locale.resolveText. A conversation.input.model.label contribution
replaces the name and badge together and receives the badge in its
owner props.

Remove ui-deepseek-model-label-1017, which hard-coded `1017` beside
DeepSeek-V4.1-Flash for two providers, and its Web bundle row. The badge
now comes only from the model listing, so the build ships none of its
own; the upgrade guide covers profile patches that still target the
removed row. The Web e2e replaces the fixed-badge case with replay
catalogs that declare literal and translated badges, and the replay
adapter validates and advertises a configured badge.

* feat(llm-deepseek): read model badges from client_metadata

Each /models entry now declares its selector badge under
client_metadata["deepseek-harness"].badge, keyed by the User-Agent product
token like client_requirements, so the public model fields stay unchanged
and later DeepSeek Harness fields join the same object. Every field under
client_metadata is ignorable: null at any level shows no badge, and a level
that is not an object drops only the badge with a diagnostic naming it.

* docs: record why the listing badge container is client_metadata

* fix(models): refresh listed badges in open selectors

* refactor(models): share listing cache lifecycle wiring

* docs(models): refresh listing event producer catalog

* fix(models): retain badges when listing refresh fails

* fix(models): validate badge text and preserve tags beside long names

* test(models): cover account listing automatic badge removal
2026-10-27 23:18:07 +08:00
imccyu 6a6e88754d Merge pull request #7429 from deepseek-harness/fix/ci-premerge-depth-window
fix(ci): deepen the pre-merge fetch when the time window strands the merge base
2026-10-27 23:09:35 +08:00
imccyu 18a559e7dd fix(ci): deepen the pre-merge fetch when the time window strands the merge base 2026-10-27 23:01:19 +08:00
imccyu 2de3029cc6 Merge pull request #7427 from deepseek-harness/fix/chat-landing
fix(chat): keep the transcript steady at Turn end and when steering lands
2026-10-27 22:16:47 +08:00
imccyu a1659120a3 fix(session-controller): retire a queued echo when its Inbox row is canceled
A queued echo now records its Inbox position like transcript and steering
echoes. Later splices move that position, so a canceled splice that removes
the row retires the echo even when no Inbox projection ever showed it, for
example when the Turn is stopped right after queueing. A claimed row still
waits for its admitted message, and the queue dock still hands the echo over
to the Host row it renders.

The fold-room e2e no longer samples the running status slide or the
`data-chat-tail-pinned` mark that this branch removed. It asserts that fold
room below a short answer takes the new Turn's growth without scrolling
through Turn end, that the room never grows back, and that the running
status only moves down.
2026-10-27 21:36:10 +08:00
imccyu ae07093132 fix(chat): keep the transcript steady at Turn end and when steering lands
Measured against 0.2.1-rc.4 and master with the frame-sampled motion matrix,
the transcript moved back and forth at Turn end and around input landing.
This keeps rc.4's landing behavior, master's steering layout, and fixes the
reversals that remain.

- Completion-time folding keeps the first visible surviving row still when
  work rows close at once, filling the gap with bottom space capped at half
  the scrollport, instead of letting the browser clamp the position.
- After the Session stops running, the running status keeps its tail slot
  hidden and silent until the Turn's actions row replaces it, so the tail
  does not shrink and grow back.
- A Turn's duration control takes its gap in one frame instead of sliding.
- A fold batch that takes over following for a content change absorbs
  growth outside the batch before its first frame.
- Steering lands at once under either fold timing: the running Turn keeps
  streaming above its echo, which a native animation would push down.
- The running status no longer slides below a Step's first output, and the
  column no longer carries `data-chat-tail-pinned`; the steering entrance
  keeps its animation.
- A queued prompt is accepted by its Inbox row as well as by its receipt,
  so the composer clears the draft in the frame the queue dock shows it.
- A queued echo waits for the Inbox projection instead of retiring on the
  durable splice, so the queue dock does not empty for a frame.
2026-10-27 20:44:52 +08:00
Yifffan d4470e59dc Merge pull request #7089 from deepseek-harness/sidebar-spacing-pr1
fix(client): 统一侧边栏对齐原则,扩大操作热区,沉淀对齐方式 skills
2026-10-27 12:16:17 +08:00
imccyu 3bb9682210 Merge pull request #7260 from deepseek-harness/worktree/sync-dsh-0.2.1-rc.4-to-master
release(dsh): sync 0.2.1-rc.4 to master
2026-10-27 11:00:01 +08:00
imccyu d534e65692 release(dsh): align master packages with 0.2.1-rc.4 2026-10-27 02:23:17 +08:00
imccyu 543219b909 Merge remote-tracking branch 'origin/master' into worktree/sync-dsh-0.2.1-rc.4-to-master 2026-10-27 02:21:20 +08:00
imccyu 9c69007eca Merge pull request #7384 from deepseek-harness/feat/pre-merge-check
feat(ci): run one script for the merged tree in the pre-merge check
2026-10-27 01:44:02 +08:00
imccyu 5d0b96b5bd docs: state the pre-merge order the check runs, without a stray blank line 2026-10-26 23:52:18 +08:00
imccyu 3ddacfd725 fix(ci): narrow the version scan and keep a crashing check inside its mode
The scan now reads exactly the manifests the release tooling rewrites, names
every directory and file it cannot read, and refuses an empty corpus; the
command takes the root it checks so the exit code is tested, and the workflow
reports a crashed check as a warning in report mode.
2026-10-26 23:51:18 +08:00
imccyu 2b485ea1db fix(ci): run the version check as the first step of the pre-merge check
It reads the manifests without an install, so it opens the step list and a
mistyped release stops the check before anything is built.
2026-10-26 23:27:39 +08:00
imccyu 1e433706f4 refactor(ci): run the pre-merge steps as one ordered list
Each step is a spawn whose stdio reaches the job log, the first failure stops
the list, and the script decides from CHECK_MODE whether to annotate as an
error or a warning, so the workflow only calls it.
2026-10-26 23:24:20 +08:00
imccyu a518d10c95 fix(ci): keep the pre-merge check's failures honest
The missing-script branch now fails in block mode instead of passing, the shell
block parses, the version walk refuses a directory it cannot read or one that
holds no manifest, the install is watched before anything else can throw, and a
spec runs `bash -n` over every Policy shell block.
2026-10-26 23:12:29 +08:00
imccyu c3998dde7c feat(ci): run one script for the merged tree in the pre-merge check
`Policy / Pre-Merge Check` now runs `scripts/pre-merge-check.ts` under plain
Node and knows nothing else about the merged tree. That script installs the
dependencies, checks that every released manifest carries the root version
while the install runs, and builds the Host and Client contracts, reporting
which step failed.
2026-10-26 22:54:02 +08:00
imccyu 1ba07e14ec Merge pull request #7368 from deepseek-harness/revert-7362-turtle/files-pane-scroll-72ef67cde97a
Revert "fix(client): keep files tree view across session switches"
2026-10-26 19:41:22 +08:00
imccyu 6ff50a4890 Revert "fix(client): keep files tree view across session switches" 2026-10-26 19:40:44 +08:00
imccyu 083bdcf625 Merge pull request #7255 from deepseek-harness/worktree/release-dsh-0.2.1-rc.4
release: next version dsh@0.2.1-rc.4
2026-10-26 18:39:43 +08:00
imccyu ce31187885 release(dsh): align master packages with 0.2.1-rc.4 2026-10-26 16:32:02 +08:00
imccyu 31693e2151 fix(ui-conversation): drop the unused more views label from the remaining locales 2026-10-26 16:31:53 +08:00
imccyu 8c9c51d86d Merge worktree/release-dsh-0.2.1-rc.4 into the 0.2.1-rc.4 synchronization branch 2026-10-26 16:21:42 +08:00
imccyu 6a19d120c9 Merge master into DSH 0.2.1-rc.4 synchronization branch 2026-10-26 16:18:13 +08:00
imccyu 504a01a957 release(dsh): 0.2.1-rc.4 2026-10-26 16:15:51 +08:00
imccyu 199ffe37ba fix(ui): keep the more views tooltip fixed (#7342) 2026-10-26 16:12:05 +08:00
imccyuandimccyu df469ea6ff fix(ci): keep the pre-merge check green in report mode (#7311)
* fix(ci): keep the pre-merge check off the report-mode failures

* fix(ci): fail the pre-merge check in block mode without a base commit

* fix(ci): report every pre-merge failure the way its mode asks

The merge step now separates a base commit it cannot fetch from a merge it
cannot do, both failures print an annotation, and a spec pins the mode
wiring of the three Policy workflows.

* test(ci): type the Policy workflow assertions

---------

Co-authored-by: imccyu <imccyu@users.noreply.github.com>
2026-10-26 13:39:57 +08:00
imccyu a3c3f107ef feat(storage): support compatible whole-unit versions (#6957)
* feat(storage): support compatible whole-unit versions

* fix(storage): contain failed writes

* test(storage): cover lock rejection and per-record version isolation

* docs(storage): align version rules with review findings

* fix(storage): unify versioned batch writes and deletion recovery
2026-10-26 13:22:25 +08:00
imccyu 762418208a Merge pull request #7097 from deepseek-harness/worktree-ciapprove
feat(ci): run the merge checks from deepseek-harness-check
2026-10-26 12:16:11 +08:00
imccyu 09b2bc7acf Merge pull request #6830 from deepseek-harness/design/floating-window-snap-back
feat(ui-dockkit): spring floating panels back inside the viewport
2026-10-26 11:34:38 +08:00
imccyu 6d4faf5423 release(dsh): align master packages with 0.2.1-rc.4 2026-10-26 01:31:00 +08:00
imccyu 3014b0af0f Merge master into DSH 0.2.1-rc.4 synchronization branch 2026-10-26 01:29:12 +08:00
imccyu 341beb33c0 release(dsh): 0.2.1-rc.4 2026-10-26 00:57:37 +08:00
imccyu ca4c00de46 Merge pull request #7154 from deepseek-harness/session-stream-snapshot
refactor(session): separate history, state and Web follow implementations
2026-10-25 20:08:12 +08:00
imccyu 8b8d1a4942 test(session): call the renamed events read 2026-10-25 19:55:32 +08:00
imccyu e032fdc2a8 refactor(session): rename the history controller read to events 2026-10-25 19:54:41 +08:00
imccyu 8cddf8b14c chore(docs): refresh event producer graph 2026-10-25 19:49:03 +08:00
imccyu 12a8c3adf7 docs(session): correct the events page and activation wording 2026-10-25 19:36:04 +08:00
imccyu 7c7b021766 docs(session): document events, deprecated page and activation order
Sync the Session README, implementation notes and follow upgrade guide,
then regenerate the API, subsystem, persistence and event-graph catalogs.
2026-10-25 18:14:32 +08:00
imccyu 99a6c14527 test(session): cover the split controllers and passive follow
Move the facade, listener, state, wait and history tests onto the new
controllers, and cover passive activation, omitted cursors and the
event subscription frames.
2026-10-25 18:14:28 +08:00