Replies: 4 comments
|
The two gates you identified are real and the code reads exactly as you describe. But there is a third one ahead of both, and I think it is the one your reproduction actually hits.
|
|
You are right about the third gate, and it splits my report into two cases I had collapsed into one. The minimal reproduction as I wrote it — a bare package directory with only the export faces — hits your missing-aggregate skip first and never reaches the two gates I named. But our real first encounter was one gate later: we had already learned the generator wants a On the empty-selections contract: agreed, and thank you for testing the naive fix before anyone ships it. A single-face workspace is legitimate and an analyzer-level throw would break it; I withdraw the implied "throw on empty" framing from my report. Your converse-of- Ranking your three suggestions from our seat as the consumer who hit this: the converse check first (it catches all three silent paths whenever the manifest states intent), the Offer: we maintain a deterministic out-of-tree regeneration harness for our package (staged generation against a pinned checkout, input/output hashes, CI drift gate). If a diagnostic patch materializes, I am happy to run it against all three silent shapes — no aggregate, aggregate without references, references without |
|
@nokkies found the third gate and you split the report correctly. I want to add a data point on your ask #2 (a supported single-package entry point), because I am another out-of-tree author who hit this wall and took the other exit — and the price of that exit is worth knowing when this gets prioritised. We gave up on the generated contract entirely. Same situation: an out-of-tree bundle whose browser half needs to talk to its own host service. Rather than the ~60 lines of staging you describe, we register our own route on
So: two out-of-tree authors, two different escapes, one cause. That is the argument for #2 in a nutshell — today the supported-looking path is not reachable from outside the workspace, so everyone either reconstructs the workspace or leaves. The cost of our exit, concretely, since it is the thing your staging hack buys you: no push channel. Our client half polls its own route — On your ask #1 (a diagnostic), which I would also put first: what makes this one bad is that it fails at build time and looks like success. A build that "generated" and shipped zero artifacts is worse than a build that failed, because the failure surfaces later, somewhere else, to someone else. And it is not the only silent gate on this path. The runtime half has its own: the host's client-modules scan resolves a package's manifest by subpath, so a package that declares So an out-of-tree browser half currently has at least two independent places where the honest answer is an empty result and the observable answer is silence — build-time typert discovery and runtime client-module discovery. If someone is fixing the diagnostic in one, the other is the same shape and probably the same afternoon. Interest disclosure: I maintain a third-party DSH plugin with a browser half, which is where both experiences come from. We do not modify the generator or the client loader and could not fix either; this is a second author's report, not a solution. |
|
I traced this against rc.2 (
The empty result itself cannot become a generic analyzer error: the upstream tests intentionally accept missing aggregates and aggregates with no references. A safer diagnostic is the converse at the generator/build layer: when an explicitly selected package or its manifest declares Typert intent but generation emits zero artifacts, fail with breadcrumbs for aggregate existence, parsed refs, canonical roots, containment, manifest name, and discovered faces. For current external plugins, a reproducible workaround is a disposable checkout pinned to the exact upstream commit: stage the package under I wrote the complete failure router, manifest contracts, provenance shape, and a possible Disclosure: I maintain this independent SandBase handbook; it is not an official DeepSeek AI project. |
Uh oh!
There was an error while loading. Please reload this page.
Versions: dsh
0.1.1-rc.2, commitb150a551b8d465e31e418e1b2eaf5e79bbb7d28e, Node v24.16.0, pnpm 11.7.0, macOS.What we were doing
Building an out-of-tree dsh bundle whose browser half calls its own host service. The documented path is a
TypertRemoteServicewith@Remotemethods, generatingtypert.host.jsandtypert.remote-client.js, which the client mounts viactx.remote.$mount().What happens
WorkspaceTypertGeneratordiscovers contributing packages throughloadRegistrations, which requires both:tsconfig.host.json;<workspace>/packages/(isWithin(..., join(root, 'packages'))).A package outside the workspace satisfies neither, and the generator does not report this:
discover()returns an empty list andgenerate()emits zero artifacts with no error. A build can appear to have generated successfully and ship nothing.The fallback — SRC weak parsing — is not usable here, because a browser client refuses SRC descriptors without strict codecs.
Reproduction
TypertRemoteServicewith@Remotemethods and the./typert/./remoteexport faces;WorkspaceTypertGenerator(<packageDir>).discover(['host']);The workaround we use
Stage the package into a clean checkout at the pinned commit (
packages/<org>/<pkg>), add a project reference totsconfig.host.json, generate with the real API, copy the artifacts out, restore the tree, and vendor the results with input/output hashes so CI fails on drift. This produces correct strict descriptors — the resulting bundle mounts and renders in a real browser session — but it is ~60 lines of staging every third-party author has to rediscover.What would help, in rough order of value
discover()returning empty is the whole problem — an error naming the missing project reference or thepackages/constraint would have saved most of the time this cost.generateForPackage(packageDir), that does not require the caller to be a workspace.All reactions