Commit Graph
23512 Commits
Author SHA1 Message Date
Feiyu Xia 904a1caa2d Merge pull request #6664 from deepseek-harness/feat/mobile-input-viewport
fix(client): improve mobile input focus and caret scrolling
2026-10-22 15:58:15 +08:00
Yichen Jiang c1238b8792 Merge pull request #5263 from deepseek-harness/worktree/web-search-dynamic-tool-e26c2b
feat(web): withhold web_search and web_fetch from requests without credentials
2026-10-22 15:53:05 +08:00
Turtle 644eb3158e Merge pull request #6838 from deepseek-harness/turtle/market-install-allowbuilds-8b6f87a8284b
fix(plugin-manager): offer script approval for git-hosted packages
2026-10-22 15:52:14 +08:00
Yichen Jiang fb378dacf2 fix(web): offer DeepSeek web tools whenever a credential exists
The DeepSeek search and Search/Fetch API providers now report readiness
from credential presence alone, on any model route: the account token
first on the deepseek-account route, then a literal apiKey or a
configured apiKeyEnv reference. A conversation on another provider's
model keeps web_search and web_fetch while a DeepSeek key is configured,
as on master, so the route refusal WEB_PROVIDER_ROUTE_DISABLED and its
upgrade guide are removed.

The pi-ai-conversation-updates and deepseek-messages-system-prompt
snapshots replay their master recordings again, the headless keyless
smoke points its search key reference at an unset variable, and the
readiness Agent Note records the rejected route and endpoint rules.
2026-10-22 15:38:16 +08:00
Turtle b70735089d docs(plugin-manager): keep pendingBuilds JSDoc on one line 2026-10-22 15:38:14 +08:00
Turtle a8bf3e7600 fix(plugin-manager): harden git allowBuilds key parsing
Capture git keys that contain spaces, skip keys whose git URL carries a
credential, and isolate Git configuration for the real pnpm test.
2026-10-22 15:38:14 +08:00
Turtle 220301c614 fix(plugin-manager): offer script approval for git-hosted packages
pnpm 11 refuses to prepare a git-hosted dependency with
ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED instead of reporting ignored build
scripts. Classify that error as build-blocked and record the allowBuilds
key pnpm suggests, so the existing approval-and-retry flow applies.

Fixes #6837
2026-10-22 15:37:59 +08:00
Turtle 7df9a5a93b Merge pull request #6943 from deepseek-harness/turtle/git-https-source-auth-b46e6aff6136
fix(plugin-manager): install self-hosted Git plugins over SSH when only SSH can read them
2026-10-22 15:26:48 +08:00
Turtle f313e7911b Merge pull request #6564 from deepseek-harness/turtle/plugin-sticky-header-29bfdb179e18
feat(plugin-manager): pin the Plugins page title bar while scrolling
2026-10-22 15:15:12 +08:00
Yichen Jiang a19aabc8ba feat(web): let a key of search's own serve other model routes
A user who gives DeepSeek search a key of its own has chosen what that key
pays for, so the route check now applies only to the shared
DEEPSEEK_API_KEY. A literal apiKey, or an apiKeyEnv other than
DEEPSEEK_API_KEY, opens every model route for Messages search and for the
Search and Fetch APIs; a configured endpoint does not, since the search
still sends the shared key. The Web search settings page saves its key
under the section's apiKeyEnv, DEEPSEEK_API_KEY by default, so a key saved
there keeps serving only the DeepSeek routes.

The route refusal now names the settings that give search a key of its
own, and the READMEs, the readiness Agent Note, and the upgrade guide
describe the exception.
2026-10-22 15:00:39 +08:00
lsdsjy da910572c5 Merge pull request #6948 from deepseek-harness/fix/sidebar-noop-drag-caret
fix(sidebar): 隐藏不改变标签顺序的拖拽定位条
2026-10-22 14:58:05 +08:00
Turtle f837cdbfbf Merge remote-tracking branch 'origin/master' into turtle/plugin-sticky-header-29bfdb179e18
# Conflicts:
#	packages/client/ui-primitives/README.i18n.yaml
2026-10-22 14:50:11 +08:00
lsdsjy 3e2e051bf1 docs(sidebar): 明确无效拖拽落点的释放语义 2026-10-22 14:41:06 +08:00
Yichen Jiang a3c0265456 test(snapshots): share web-fetch's tool schemas with web-search-unconfigured
web-search-unconfigured declares exactly the tool catalog that web-fetch
already pins, so it names web-fetch as its toolSchemasSource instead of
committing a second copy.
2026-10-22 14:36:38 +08:00
Turtle c063b70b85 Merge pull request #6891 from deepseek-harness/turtle/sidebar-first-open-flash-c291a96690d1
fix(ui-sidebar-right): slide the panel in on its first open
2026-10-22 14:33:13 +08:00
Turtle f228c3ffa6 Merge pull request #6064 from deepseek-harness/turtle/async-notice-efficiency
feat(jobs): deliver job output in completion notices and drop repeated notice text
2026-10-22 14:30:55 +08:00
lsdsjy f9ff5d0979 fix(sidebar): 隐藏不改变标签顺序的拖拽定位条 2026-10-22 14:27:54 +08:00
turtle1999 6f4ce88207 Merge remote-tracking branch 'origin/master' into turtle/async-notice-efficiency
# Conflicts:
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
2026-10-22 14:12:42 +08:00
Turtle cce67394c9 docs(config-catalog): regenerate after merging master 2026-10-22 14:11:15 +08:00
Turtle 8255ebe3cc Merge remote-tracking branch 'origin/master' into turtle/git-https-source-auth-b46e6aff6136 2026-10-22 14:09:45 +08:00
Turtle 420a7797f6 fix(plugin-manager): harden Git transport probe prompts, fragments and attribution
Refs #6938
2026-10-22 14:07:10 +08:00
Turtle 1b7923db9d refactor(ui-sidebar-right): start the first-open slide with @starting-style
Replace the layout effect that forced a closed style with an opening marker derived during render. A @starting-style rule under the marker starts items mounted by the opening at the closed position. The marker clears when a transition ends, the panel closes, or the panel leaves the screen.
2026-10-22 14:07:05 +08:00
imccyu b04c1c3261 Merge pull request #6895 from deepseek-harness/turtle/icon-tokens/icons-plugin-tokens-e20dec90761c
feat(client): let themes replace product icons through an SVG sprite
2026-10-22 13:50:35 +08:00
Yichen Jiang 1922f322aa fix(web): gate the DeepSeek web providers on the model route alone
Review found two faults in the endpoint and configuration checks. The
providers took the official chat route's endpoint from the first active
dsh-llm-deepseek-api-key Loader row, so a composition that isolates several
instances answered for an unrelated one: a correct route lost search, or a
gateway's key reached DeepSeek. And a key saved on the Web search settings
page lands under the default DEEPSEEK_API_KEY reference, so the inference
that search had its own configuration never saw it.

Both DeepSeek web packages now serve only the deepseek-account and
deepseek-official routes, whatever key they are configured with, and no
longer compare the chat endpoint with their own. ready() checks the route
and then credential presence as before; the API-key resolver repeats the
route check and refuses with WEB_PROVIDER_ROUTE_DISABLED. The packages no
longer read Loader rows or depend on dsh-llm-deepseek-api-key, so the
lockfile, the module graph, and the keyless smoke expectations that the
endpoint check had changed return to master's.

An upgrade guide covers conversations on other providers' models, which
lose DeepSeek web search and, with the Search and Fetch APIs selected,
web_fetch.
2026-10-22 13:48:53 +08:00
Stevring 23a9cad68e Merge remote-tracking branch 'origin/master' into feat/mobile-input-viewport 2026-10-22 13:46:22 +08:00
Turtle f59f0dfc67 fix(plugin-manager): install self-hosted Git plugins over SSH when only SSH can read them
Refs #6938
2026-10-22 13:42:56 +08:00
imccyu 73931626be feat(webserver): add resource routes and in-process readResource (#6901)
* feat(webserver): add resource routes and in-process readResource

A webserver route or the fallback seat may now answer through a resource,
a function from a Fetch Request to a Response, besides the existing
node:http handler. register accepts either route form and registerFallback
accepts a handler or { resource }; existing handler callers are unchanged.
HTTP GET and HEAD requests reach a resource; webServer.readResource(request,
peer) follows the same match order and reaches only resources, so handler
routes stay unreachable to in-process readers.

client-modules registers /plugins as the fetchBundle resource, and
frontend-static claims the fallback seat with a resource that renders the
index for a supplied Peer, or runs Connection's existing authorizeIndex for
an HTTP request and renders for the browser Peer.

* fix(webserver): flush resource headers and keep one drain listener per response

Resource responses send their status and headers before the first body
chunk, register one drain/close listener pair per response so the gzip
middleware's zlib stream does not accumulate listeners across backpressure
waits, and readResource drops the body of a HEAD read as HTTP does. HTTP
requests and readResource share one responder lookup.

* chore(scripts): prune the retired client-modules unknown-cast baseline entry

* feat(frontend-static): let browsers revalidate dist files except the index

Every dist file other than the rendered index now carries
cache-control: no-cache and a weak ETag from a SHA-1 of its bytes; a
request whose If-None-Match equals that ETag receives an empty 304. The
index keeps sending no cache headers. In-process reads through
webServer.readResource revalidate the same way.

* fix(webserver): stop reading Host for resource URLs and copy no held body

A resource request's URL is the request target resolved against the same
placeholder origin the route match uses, so a missing or unparsable Host no
longer turns a dist or /plugins request into 400. The webserver ends a
resource response itself and treats any earlier close as an abort, which
also covers the Web Worker tunnel marking an aborted response ended first.
client-modules bundle bodies and frontend-static file bodies are the held
bytes themselves instead of copies, and frontend-static no longer exports
its internal serveStatic helper.

* docs(webserver): document resource route types and the handler-or-resource fallback

Paste WebResource and WebResourceRoute beside WebRoute on the web-server
subsystem page and link the catalog signatures to it, replace the remaining
'fallback handler' wording now that the seat takes a handler or a resource,
and note why the drain listener removal is a no-op under gzip.
2026-10-22 13:41:18 +08:00
Turtleandimccyu 140496c750 Credit review by @imccyu
Co-authored-by: imccyu <[email protected]>
2026-10-22 13:37:32 +08:00
Turtle 5f77d80555 Merge remote-tracking branch 'origin/master' into turtle/icon-tokens/icons-plugin-tokens-e20dec90761c
# Conflicts:
#	packages/client/ui-primitives/README.i18n.yaml
2026-10-22 13:24:28 +08:00
imccyu 9fb3a064ea Revert "fix(client): 将模型发布标记改为蓝色纯文字" (#6936) 2026-10-22 13:21:40 +08:00
Turtle 2e0ce8d448 Merge pull request #6924 from deepseek-harness/turtle/extract-bundle-lists-349637056285
refactor(boot): move official bundle lists out of app-boot
2026-10-22 13:16:20 +08:00
Yudong Han aeb1078126 Merge pull request #6875 from deepseek-harness/feat/document-zoom-controls
refactor(ui-primitives): 共享文档缩放控件
2026-10-22 13:01:22 +08:00
Yudong Han d2c2bc1d27 Merge pull request #6538 from deepseek-harness/fix/model-release-blue-text
fix(client): 将模型发布标记改为蓝色纯文字
2026-10-22 13:00:27 +08:00
Turtle bde671f984 test(web): ignore scroll-driven animations when waiting for settled layout
The model selector's clipped-text fade runs on a scroll timeline, which
never finishes, so document-wide waits never settled.
2026-10-22 12:48:28 +08:00
yudshj ca575ff573 refactor(client): fade clipped selector text with CSS only
Replace the FadeText measuring component with a self scroll timeline: it is
active only while a box overflows, so the end mask applies to clipped text
alone. Browsers without scroll-driven animations keep the ellipsis.
2026-10-22 12:48:28 +08:00
yudshj 652747423c fix(client): fade clipped model selector text instead of ellipsizing
Model and effort text in the composer trigger, root menu values, and option
rows now clips and fades over its last 24px while it overflows, following the
measured-clip mask used by dockkit tab titles and PathLabel.
2026-10-22 12:48:28 +08:00
yudshj a6aaac3ce6 fix(client): render model release as blue inline text 2026-10-22 12:48:28 +08:00
yudshj 3baadfb103 docs(client): record the zoom controls elevation follow-up
Mark the inherited literal shadow and neutral border with a TODO pointing at
the elevation token rules.
2026-10-22 12:46:06 +08:00
yudshj a740d8edc2 fix(client): let owner classes place zoom controls regardless of CSS order
Move the default bottom offset into a zero-specificity :where(.panel) rule and
correct the README description of which properties center and animate the
toolbar.
2026-10-22 12:46:06 +08:00
yudshj a2bfffad24 fix(client): drop stale shown zoom when the committed zoom changes
Reset the transient showZoom value during render on the first committed zoom
change, document the toolbar data attributes and the owner className scope,
and give the handle its own @param ref.
2026-10-22 12:46:06 +08:00
yudshj 0b5ff6ff02 refactor(client): address zoom controls review
Derive the displayed zoom during render instead of syncing the prop through
an effect, reference DOCUMENT_ZOOM directly in both packages, cover the
unfitted non-preset state, and list ZoomControls among localized primitives.
2026-10-22 12:46:05 +08:00
yudshj f70a511cca refactor(ui-primitives): share document zoom controls
Move the floating zoom controls from the document preview into
ui-primitives with the shared scale limits, so every document renderer
offers the same controls. Document preview renders them through its zoom
viewport with fit width as the optional fitting action.
2026-10-22 12:46:05 +08:00
Turtle f0ced1aa47 docs(boot): state which bundle lists app-boot applies 2026-10-22 12:44:00 +08:00
imccyu 4349b4e5f2 fix(ui-chat): clip horizontal overflow in the chat transcript (#6930) 2026-10-22 12:43:26 +08:00
imccyu 96f9a2f6c0 fix(ui-chat): clip horizontal overflow in the chat transcript 2026-10-22 12:21:11 +08:00
Yichen Jiang 103dac1b3c feat(web): gate web_fetch and the DeepSeek web APIs on readiness
The Web search switch selects the DeepSeek Search and Fetch APIs together,
and both reuse the DeepSeek chat key by default. Neither provider answered
readiness, so a step without a usable key was offered web_search and
web_fetch whose every call failed, and a conversation on another provider's
model or behind a gateway sent the chat key to DeepSeek.

dsh-web gives WebFetchProvider an optional ready(llmProvider) and adds
ctx.web.fetchReady(), which asks only the provider fetch() selects, as
searchReady() does for search. tool-web registers web_fetch with a step
activation condition on fetchReady(), so a step that cannot fetch leaves the
tool out of declarations, guidance, and PTC bindings and refuses a call to
it as UNKNOWN_TOOL; without web_fetch the search guidance uses its
search-only text. The shipped HTTP fetch provider has no ready() and stays
admitted.

web-deepseek-api applies the API-key rules of Messages search to both APIs:
without a literal apiKey, an apiKeyEnv other than DEEPSEEK_API_KEY, or a
baseURL other than the default, the chat key goes only to the DeepSeek
routes and only to an API base on the official chat route's origin. The
refusal sits in the key's only resolver, and both providers' ready()
answers presence in the order an operation resolves credentials. The
transport repeats these checks so the package still does not depend on
dsh-web-search-deepseek.
2026-10-22 12:10:21 +08:00
imccyu 1276a8e13a ci: split pull-request CI into Linux, Windows, and Python workflows (#6898)
* ci: run native Windows PR jobs in a separate workflow

GitHub re-runs failed jobs only after a whole run finishes, so slow Windows jobs blocked re-running failed Linux jobs. CI Windows now owns the native Windows jobs and the Windows x64 Python runtime target, with its own required 'windows checks passed' verdict.

Refs #6893

* ci: run Python PR jobs in a separate workflow

Python rarely fails while the Windows lanes run long, so the Python SDK suite and the Linux/Windows x64 runtime matrix move into CI Python. The three pull-request workflows can now be re-run without waiting for each other, and branch protection gains "python checks passed" beside the existing verdicts.

Refs #6893

* docs: record the three PR verdicts in the failover runbook

* test: pin the shared environment across the PR workflows

* test: read the python SDK lane from CI Python

* test(sdk): parse session JSONL frames in the keyless smoke

Node 24.19 returned only the first frame of a concatenated zstd log, so the single JSON.parse saw just the header; 24.22 returns every frame and the JSONL body broke the parse. Read frames explicitly and select the main session by its header so both versions agree.
2026-10-22 04:09:35 +00:00
Turtle f60cbc909b docs(boot): point remaining bundle-list references at official-bundles
Move the template value assertions into the official-bundles tests so a
template edit leaves app-boot tests untouched.
2026-10-22 12:05:04 +08:00
Saafo 6b25107abf ♻️ Defer global viewport styles from mobile input fixes 2026-10-22 12:04:03 +08:00
Saafo da54bbf3b0 🔀 Merge master into mobile input adaptation 2026-10-22 12:01:42 +08:00