Repository navigation
fix(process-graph): consumer-facing surface found by the Switchboard integration - #53
Merged
Merged
Conversation
Pinning every peer dependency to one exact version forced each consumer onto exactly those versions. A stable peer is now a caret range whose floor is the version the workspace tests run against; the oRPC betas, drizzle-orm's release candidate and the SQLite wasm build stay exact, since a prerelease has no compatible-range semantics. The published-manifest check validates peers against the catalog by satisfies rather than equality, requires the caret form for a stable peer and an exact version for a prerelease one, and keeps dependencies and devDependencies exact. The smoke consumer installs each peer at the floor its specifier declares.
…ta path prepareDataFile, which creates a store's directory 0700 and its database 0600 before SQLite opens it and narrows an owned store others can read, moves from the command line into sqlite-node, so process-graph/store/node exports it with its modes and options for any host that opens a store itself. nodePorts takes a dataPath: a data file the host owns, used as the default data path and given the same private treatment as the command line's own XDG data file, so a host embedding the command line keeps its store private.
A token port that threw anything but a GraphSourceError escaped the adapter as a plain error, which the router turned into an internal server error, so the command line exited with a general failure and the port's own error sat two causes deep. The adapter now wraps it in an unauthorised GraphSourceError naming the token port and the owner, with the port's error as its cause, and passes a GraphSourceError the port throws, or an abort, through unchanged.
The library sync operation ended its error with command-line wording
("resume with: sync ..."), which a host calling it as a library could only
parse. It now throws SyncInterruptedError, a CliError carrying the source's
failure as its message, the request that resumes the failing source, the
scopes not reached and whether pages were saved; the command line renders
those as the commands it prints. The error's cause is the error underneath
the source failure, so a token port's own error is one level deep, and such
a failure exits with the source-failure status.
…stant A consumer had no way to read the package's version. The exports map now carries ./package.json, and process-graph/cli exports version, which tsdown writes into the bundle through define from the manifest when the package is built, so reading it touches no file at run time. Vitest applies the same define, and the bin's --version uses the constant too. The smoke test imports both from the packed tarball.
The umask probe opened the command line's default store through nodePorts, loading the whole command line to test a guarantee that belongs to prepareDataFile. It now lives in sqlite-node and prepares and opens a store directly, with no per-test clock bound, since a spawned process's duration is the machine's scheduling; the command line keeps an in-process check that it hands its XDG data file to prepareDataFile as one it owns.
The test starts the built bin as a process three times, so how long it takes is the machine's scheduling rather than a property of the code, and the default per-test bound failed it on a loaded host. It now runs unbounded, as the projection package's work-counting cases do, leaving a hang to the CI job's own timeout.
A consumer with an install age gate exempted process-graph but still could not install it, because trilean and its dependency trilean-regex are ExaDev packages released alongside it and often younger than the gate. The root README gains an install section saying so, and the package README points to it.
The theme contract vars was only exported beside the components, so a Vanilla Extract stylesheet that themed them loaded the whole component library and React. The ./theme entry carries vars, the light and dark theme classes and their values on their own; the library build emits it as a separate file sharing one chunk with the components' entry.
process-graph/ui/theme exports the theme contract, the theme classes and their values without the components, for a .css.ts file that themes process-graph/ui. The smoke test imports it in the consumer project that has none of the optional peers, where React does not resolve, and checks it carries the same contract and values as process-graph/ui.
A consumer that embedded modelSchema in a schema of its own and emitted
declarations had the whole model schema written out inline, trilean's JSON
value included, which could exceed the length TypeScript will serialise
(TS7056) and forced an annotation. modelSchema is now declared as the
exported interface ModelSchema, whose unwrap still returns the strict
object schema, so such a declaration refers to the name. A test compiles a
consumer-style z.object({ model: modelSchema }) under declaration: true and
checks it emits without diagnostics and names ModelSchema.
Mearman
marked this pull request as ready for review
October 11, 2026 17:11
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
The test builds a TypeScript program over the schema package and zod's declarations, which under coverage instrumentation on a CI runner took past the default per-test bound. Its duration is the compiler's work on the machine at hand, so it runs unbounded, leaving a hang to the job's timeout.
Member
Author
|
@codex security review |
1 similar comment
Member
Author
|
@codex security review |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the problems the Switchboard integration (ExaCapLtd/switchboard#345) found in the published surface of
process-graph.Stable peer dependencies are now caret ranges whose floor is the version the workspace tests run against; the oRPC betas, drizzle-orm's release candidate and the SQLite wasm build stay exact, because a prerelease has no compatible-range semantics.
scripts/check-published-manifests.tsvalidates peers against the catalog by satisfies instead of equality, requires the caret form for a stable peer and an exact version for a prerelease, and keepsdependenciesanddevDependenciesexact. The smoke consumer installs each peer at its declared floor.prepareDataFile(0700 directory, 0600 database before SQLite opens it, narrowing an owned store others can read) moves into sqlite-node and is exported fromprocess-graph/store/node, andnodePorts({ dataPath })gives a host-owned data file the same private treatment as the command line's own XDG file.The exports map carries
./package.json, andprocess-graph/cliexportsversion, written into the bundle by tsdown'sdefinefrom the manifest at build time; the smoke test imports both from the packed tarball.The library
syncnow throwsSyncInterruptedError, carrying the resume request, the scopes not reached and whether pages were saved as data; only the command line renders theresume with:andthen:hints. A token port that fails is reported by the GitHub adapter asunauthorised, naming the token port and owner, so the command line exits with the source-failure status, and the interrupted sync's cause is the port's own error, one level deep.process-graph/ui/themeexports the theme contractvars, the light and dark theme classes and their values without the components, built as a separate entry of graph-ui; the smoke test imports it in the consumer that has none of the optional peers, where React does not resolve.modelSchemais declared as the exported interfaceModelSchema(itsunwrap()still returns the strict object schema), so a consumer'sz.object({ model: modelSchema })underdeclaration: trueemits a reference toModelSchemainstead of the whole schema with trilean'sJsonValueinline (TS7056). A test compiles that consumer module with the TypeScript API and checks the emit has no diagnostics and names the interface.The root README gains an install section saying a project with an install age gate must exempt
trileanandtrilean-regexbesideprocess-graph.Two tests that start Node processes (the umask probe, now beside
prepareDataFilein sqlite-node, and the CLI's bin smoke test) run without a per-test clock bound, following the projection package's precedent, since their duration is the machine's scheduling.