Commit Graph
77 Commits
Author SHA1 Message Date
liukx0205 8b1e5e7d88 fix(client-modules): contain flush enumeration failures 2026-10-29 15:37:23 +08:00
liukx0205 657d6a8129 perf(client-modules): index Loader entries once per flush 2026-10-29 12:58:03 +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
imccyu 4fb0054448 fix(client): rewrite image-set urls and keep the route fixture valid on Windows 2026-10-20 04:00:23 +08:00
imccyu 7f3dd4ade0 fix(client): tolerate minified stylesheet placeholders and document the asset reference encoding 2026-10-20 03:40:00 +08:00
imccyu 991b2635ad fix(client): keep package-asset references valid in CSS and pin preview placeholders 2026-10-20 03:07:59 +08:00
imccyu c1d9f141b9 feat(client): resolve package assets through require.asset so the WebWorker preview can map them 2026-10-20 02:14:33 +08:00
imccyu 1ab28c1cb6 fix(client): keep watch-built assets, end cancelled asset streams quietly, and stat before reading bundles 2026-10-20 02:14:31 +08:00
imccyu 0ecc1dec41 fix(client-modules): reread package manifests when Loader entries restart 2026-10-20 02:13:37 +08:00
imccyu ce84953e46 feat(client): serve plugin package assets by URL instead of data URLs 2026-10-20 02:13:37 +08:00
imccyu 5026df8fd1 Merge pull request #6250 from deepseek-harness/worktree-optbundles
feat(webworker): offer optional bundles in the preview and fetch lazy chunks on demand
2026-10-15 12:17:34 +08:00
imccyu 18a22f73b2 Merge pull request #6228 from deepseek-harness/worktree-versionmismatch
feat(client-modules): prompt to reload when the host release changes
2026-10-15 11:31:54 +08:00
imccyu 93d2ad2d25 feat(webworker): boot the preview from the shipped profile and fetch lazy chunks on demand
The packer images the web template bundles, every optional bundle, and an installation manifest instead of a dumped composition, and the Worker boots that profile through app-boot like dsh web. Package-local lazy client chunks move into content-addressed archives that the VFS fetches on first asynchronous read; client-modules reads chunks asynchronously.

The Worker replaces node-addon-require-builtin with Node v24.18.0 internal-module interfaces and reports Node 24, so plugin metadata, the Cordis Loader, and HMR reach one cascaded loader backed by the Worker loader. Resolution failures carry Node error codes, the empty load cache lets HMR apply profile changes, and every optional bundle switches on and off live. Platform stubs throw ERR_FEATURE_UNAVAILABLE_ON_PLATFORM.
2026-10-15 11:30:45 +08:00
imccyu a7a40f93d9 fix(client-modules): compare host releases before parsing the graph 2026-10-15 01:35:28 +08:00
imccyu f52abc04fa feat(client-modules): apply no plugin update from another host release 2026-10-15 00:51:20 +08:00
imccyu 7c9e54b3ef feat(client-modules): prompt to reload when the host release changes 2026-10-14 19:11:22 +08:00
imccyu e137ebaaa1 Build shared Client bundles independently for Node and browser 2026-10-14 14:43:59 +08:00
Turtle 015349e4ad fix(client-modules): remove untagged styles of a failed factory 2026-09-30 15:14:59 +08:00
Turtle aa5334f1e0 fix(client-modules): claim only styles a factory injects
Materialization tagged every untagged <style> in the document for the
materializing plugin, so styles inserted later by other owners (Cordis
dynamic plugins, runtime-injecting libraries) were removed when an
unrelated plugin was toggled.
2026-09-30 15:01:51 +08:00
winewill c22b226b18 fix: address review threads on the fatal-diagnostics PR
- Agent Notes: cross-link the new decision with the native fatal recovery
  and fail-loud release notes both ways, rewrite the older note's
  console-retention and dialog-detail facts in place, and state the report's
  actual bounds.
- crash-report: cut the rendered error section at 256 KiB and prune only
  files matching the generated crash-<time>-<source>.log syntax.
- main: backendReady follows the backend state except during shutdown, so a
  failure while tearing down a ready backend still reads as running.
- subprocess-local: the temporary-file-cleaner hint is appended only for
  ENOENT; other codes rely on the appended error.
- client-modules: describeError is module-private; BootModuleRow.url's
  JSDoc names its fallback role.
2026-09-22 18:20:12 +08:00
winewill cafb9b93b4 fix: address adversarial review of the fatal-diagnostics branch
client-modules: a batch that already executed is never requested again,
even when its first importer was a row it did register — every executed
batch URL is remembered and a still-missing row goes straight to its
one-resource URL. The in-process module system test in test-support is
updated to the aggregated arrival message. describeError replaces three
inline non-Error ternaries and is covered.

subprocess-local: the spill path is published only after the exclusive
open succeeds, so a failed open (EEXIST on a planted entry included) can no
longer unlink a path this process did not create; a reporter that throws is
contained and written to stderr; logSpillFailure builds the owner reporter
for both the runtime and the SSH helper so the logging path is exercised
once instead of duplicated. Tests cover the runtime logger, the bare-caller
stderr default, EEXIST, and a throwing reporter.

desktop: a fatal failure during shutdown still writes its report; the
report phase follows the backend state so a failure during a restart is
'startup' again; writeReport is a required recovery operation and the
dialog tests await the write; the shell pid is labelled; the withheld
response-header list states why set-cookie is dropped.

app-boot, READMEs, Agent Note: "never resumes" is restated as control never
returning to the failed operation while the loop runs until release
settles; inspect output is bounded; incident inferences (who removed the
spill directory, which batch failure occurred) are written as inferences.
2026-09-22 14:41:10 +08:00
winewill afde35880f feat(client-modules): recover from a failed batch script and record import errors
One application batch is a single classic script that registers every
package in sequence, requested exactly once during boot. A transient
failure of that one <script> request failed every row in the batch and,
through arriveGraphRow's dependency wait, every row that injects or
requests them; the boot audit then listed each as "import failed (see
console for the import error)" with the real error only in the renderer
console.

Arrival now distinguishes the two failure kinds. A transport failure
(script error event, nothing executed) is retried once on the same URL and
the retry is shared by every row waiting on that batch. A script that
loaded without registering a row is never re-executed, because register()
rejects duplicates and a replay would stop at the first package the
original run did register. Either way each still-missing row then loads its
own one-resource combo URL, which the Host serves for every package. A batch
URL that failed is remembered so later rows skip straight to their
fallback; a one-resource URL is not, so it stays retryable on the next
import as before. Dependency failures are wrapped with the consumer and
dependency names so a cascade reads as a chain.

The module system records the last import() or prefetch() failure per
graph row at the outer operation, so factory execution errors are captured
as well as arrival errors, and clears it on success or invalidation.
assertEntriesActive takes the module system and reports that text per
fiberless entry.
2026-09-22 13:00:13 +08:00
imccyu d49f2b1bf8 test(client): make rebuild generations independent of clock precision 2026-09-22 00:18:59 +08:00
imccyu 2d236df56f test(client): wait for filesystem ctime before revision checks 2026-09-21 23:49:42 +08:00
imccyu b1921cf56d fix(client): keep artifact revisions stable across server restarts 2026-09-21 21:47:52 +08:00
Tianyi Cui 580bdc7258 refactor: remove redundant unknown casts 2026-09-19 20:13:58 +08:00
Yichen Yan eeb9b03465 feat(web): serve the shell, API and plugin resources from the document directory 2026-09-17 16:00:15 +08:00
imccyu 7fb4cb4c8e fix(client): version lazy chunks by build generation 2026-09-15 20:45:49 +08:00
imccyu 45c74c5483 fix(client): satisfy chunk loader test lint 2026-09-15 20:45:49 +08:00
imccyu b98d5c8003 test(client): cover lazy chunk loader branches 2026-09-15 20:45:49 +08:00
imccyu b1471fd73c perf(client): load split bundles on demand 2026-09-15 20:45:49 +08:00
imccyu 7f5385bf01 revert(client): remove eager chunk scanning 2026-09-15 20:45:49 +08:00
imccyu d28807e05c fix(client): preserve lazy chunk runtime semantics 2026-09-15 20:45:49 +08:00
imccyu a5c224f9b1 feat(client): lazy-load PDF and terminal runtimes 2026-09-15 20:45:49 +08:00
Yichen Jiang c28fcc6cdb Merge remote-tracking branch 'origin/master' into worktree/client-modules-live
# Conflicts:
#	docs/subsystems/client-modules.i18n.yaml
#	docs/subsystems/client-modules.md
#	docs/subsystems/client-modules.zh.md
#	packages/client/hmr/package.json
#	packages/client/modules/README.i18n.yaml
#	packages/client/modules/README.md
#	packages/client/modules/README.zh.md
2026-09-15 15:31:14 +08:00
Yichen Jiang 2c9375e509 fix(web): reconcile pending plugin revisions and preserve bootstrap 2026-09-15 14:15:23 +08:00
Yichen Jiang 1fec9adb61 docs(web): clarify client plugin reload failures 2026-09-15 13:29:58 +08:00
imccyu 42286726c8 perf(web): defer client combo assembly 2026-09-15 11:00:34 +08:00
Yichen Jiang b49f57ca12 fix(web): share pending loads across matching graph notifications 2026-09-14 21:59:58 +08:00
Yichen Jiang fb0fb48033 feat(web): apply client plugin changes without reloading 2026-09-14 21:47:38 +08:00
imccyu c1504a2aa6 fix(client-modules): resolve the owning Loader instance 2026-09-13 21:27:54 +08:00
imccyu a475a65bed fix(client-test-runtime): isolate client instances 2026-09-13 21:27:53 +08:00
turtle1999 eb9da8930e test(boot): cover Web failure recovery and inject module routes 2026-09-11 14:34:17 +08:00
07akioni 2ef85b1e17 fix: windows build 2026-08-31 11:54:28 +08:00
imccyu b46953f3cc test(client-modules): type loader resolver stubs 2026-08-27 20:16:51 +08:00
imccyu 827acd07b1 docs(client-modules): align resolver contract 2026-08-27 20:10:20 +08:00
imccyu dc1be1334f fix(inspector): address bootstrap review findings 2026-08-27 20:03:17 +08:00
imccyu ac13b16c0c fix(inspector): stabilize client bootstrap identity 2026-08-27 19:35:34 +08:00
imccyu 1429737a52 perf(hmr): poll client bundles only 2026-08-26 15:09:48 +08:00
imccyu 075a46cdec fix(client): preserve combo source identities 2026-08-25 06:43:25 +08:00