Beside every TypeScript entrypoint the builder writes an executable launcher; the runtime is told it (hq ADR 0193)

The runtime knows no language: the build makes each served entrypoint executable. For a TypeScript
bundle that is <entry>.serve.mjs, which imports the entrypoint and serves what it registered over
MCP on stdio through the bundle's own SDK. The build records its launchers on the bundle, and the
composer names the launcher where a build wrote one and the entrypoint where it did not, so bundles
built before this keep serving until they are rebuilt.
This commit is contained in:
jochen
2026-10-03 21:07:07 +02:00
parent f966693583
commit 17dba2a34c
6 changed files with 136 additions and 2 deletions
+4 -1
View File
@@ -28,6 +28,9 @@ type Built struct {
Reference string
// Digest is "sha256:<hex>", for an archive. An image reference already ends in one.
Digest string
// Launchers are, for a bundle in an interpreted language, the executable the build wrote beside
// each entrypoint, by entrypoint (novox/hq ADR 0193): what the node's runtime starts to serve it.
Launchers map[string]string
}
// Resolve fills a manifest's resources in from what was built.
@@ -92,7 +95,7 @@ func (m Manifest) Resolve(built []Built) (Manifest, error) {
out.Bundles = append(out.Bundles, Bundle{
Name: a.Name, Source: Recorded(made.Reference), Digest: made.Digest,
Language: a.Language, Entrypoints: append([]string(nil), a.Entrypoints...),
Loads: loads, Env: copyWords(a.Env),
Loads: loads, Env: copyWords(a.Env), Launchers: copyWords(made.Launchers),
})
}
sort.Slice(out.Bundles, func(i, j int) bool { return out.Bundles[i].Name < out.Bundles[j].Name })