feat(functions-compiler): carry the invocation-logs response channel - #628
Merged
Merged
Conversation
Ports apper #22656 into the extracted engine. The per-app router buffers an invocation's console lines on the request store when the server-injected X-B44-Capture-Logs header is set, and returns them on the response — the 404 / init-500 / 503 early returns and the crash path included. Without this the package compiles a worker that silently drops the feature, so apper's bundler service cannot adopt it. src/invocation-logs.ts is apper's file verbatim except for two constants that lost `export` (used only inside the module; knip rejects the rest). test/ is byte-identical to apper's copy, as the extraction requires. Version 0.1.1, since 0.1.0 is already published. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/cli@0.1.15-pr.628.ddce31bPrefer not to change any import paths? Install using npm alias so your code still imports npm i "base44@npm:@base44-preview/cli@0.1.15-pr.628.ddce31b"Or add it to your {
"dependencies": {
"base44": "npm:@base44-preview/cli@0.1.15-pr.628.ddce31b"
}
}
Preview published to npm registry — try new features instantly! |
netanelgilad
approved these changes
Sep 17, 2026
yurynix
added a commit
that referenced
this pull request
Sep 17, 2026
main has been red since #623 landed: it added src/version.ts pinned to 0.1.0 and the test that guards it, having branched before #628 bumped package.json to 0.1.1. Setting the literal to 0.1.1 is the whole of that fix. The publish workflow would have reintroduced the drift on every release. `npm version` rewrites package.json alone, and the literal cannot be read from package.json at run time — a host that bundles this module ships none beside it (that is what src/version.ts documents). So a release would have published a banner naming the previous version and left main red again. scripts/sync-version.ts rewrites the literal from package.json and throws if it matches nothing, because a silent no-op sed is precisely the failure being prevented. The workflow runs it between the bump and the build, and the release commit now carries both files. Bumping by hand runs the same script. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
yurynix
added a commit
that referenced
this pull request
Sep 17, 2026
* ci(functions-compiler): add a manual npm publish workflow The CLI's manual-publish.yml cannot be reused for @base44/functions-compiler. Most of it is CLI-specific — standalone binaries, the Homebrew tap, PostHog sourcemaps, the skills-repo dispatch, the GitHub Release that carries the tarballs — and every one of those steps would need an `if:` guard on a package input, in the one job that must not break. The two trains also tag differently: `v<version>` is the CLI's series, so this one tags `functions-compiler-v<version>`. Sharing the file would buy nothing anyway. npm trusted publishing keys a publisher on the repo *and* the workflow filename, so @base44/functions-compiler needs its own registry entry either way; a separate file makes that entry narrower — it can publish this package and nothing else. Two differences from the CLI workflow worth naming: - Nothing is stripped from package.json before publish. The CLI deletes devDependencies because everything is bundled; here esbuild, @deno/loader and zod are real runtime dependencies consumers install. - The job only builds and publishes. The packaging proof that hits the registry (scripts/verify-package.ts) stays in functions-compiler.yml, behind the Wix gateway, where it runs on every push to main — so this job still resolves nothing, which is what its gateway exemption rests on. Before the first run, a trusted publisher for @base44/functions-compiler must be registered on npmjs.com against this repo and this filename. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * ci(functions-compiler): declare the repository for trusted publishing npm's trusted-publisher validation requires package.json's repository URL to match the GitHub repository the OIDC token comes from. packages/cli already declares it; this package did not, so the first publish would have failed the check with nothing in the workflow to explain why. `directory` points at the package inside the monorepo, which is also what makes the npm page link to the right subtree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(functions-compiler): keep COMPILER_VERSION in step with package.json main has been red since #623 landed: it added src/version.ts pinned to 0.1.0 and the test that guards it, having branched before #628 bumped package.json to 0.1.1. Setting the literal to 0.1.1 is the whole of that fix. The publish workflow would have reintroduced the drift on every release. `npm version` rewrites package.json alone, and the literal cannot be read from package.json at run time — a host that bundles this module ships none beside it (that is what src/version.ts documents). So a release would have published a banner naming the previous version and left main red again. scripts/sync-version.ts rewrites the literal from package.json and throws if it matches nothing, because a silent no-op sed is precisely the failure being prevented. The workflow runs it between the bump and the build, and the release commit now carries both files. Bumping by hand runs the same script. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Note
Description
Ports the invocation-logs response channel into
@base44/functions-compiler. It was added to apper on 14 September 2026 by base44-dev/apper#22656 — feat(builder): test_backend_function returns its own invocation's logs, flagTEST_FUNCTION_RESPONSE_LOGS, commit9d315265b06— closing the last behavioural gap between this package and the compiler engine apper runs in production. When the server setsX-B44-Capture-Logs: 1, the per-app router buffers that invocation's ownconsole.*lines on the request store and returns them on theX-B44-Invocation-Logsresponse header — covering the normal reply, the 404 / init-500 / 503 early returns, and the crash path. Without it, adopting 0.1.0 as-is would compile user workers that silently drop the feature, so this unblocks the apper swap.Related Issue
None (ports base44-dev/apper#22656; enables retiring apper's in-tree
base44-userapp-bundlerengine)Type of Change
Changes Made
src/invocation-logs.ts— the injected runtime snippets:CAPTURE_PATCH(per-line buffering with budgets),INVOCATION_LOGS_PATCH(_b44CaptureStore/_b44AttachInvocationLogs/_b44CrashResponse), andASCII_ESCAPE, plus the header names and caps (40 lines, 6 KB of captured payload, 7 KB response-header budget).src/worker-entry.ts) —_b44Wrapnow formats once and captures the line via_b44Capturebefore forwarding it to the original sink, so captured and shipped logs cannot diverge.buildAppEntrySourceinjectsINVOCATION_LOGS_PATCH, seeds the request store with..._b44CaptureStore(request), and routes every reply through_b44AttachInvocationLogs(telemetry stays the inner wrap so its header survives); a thrown error answers through_b44CrashResponse, which mirrors the dispatcher'suser-exception500 body but rethrows CPU-limit / subrequest-quota errors so the dispatcher's own classification stands.\\uXXXX-escaped (workerd'sheaders.setthrows above0xff), overflow is reported as adroppedcount rather than hidden, and when the function's own headers leave no room the payload degrades to drop-count-only and then to no header at all, never breaking a response that works with capture off. A silent invocation still gets an empty-list header, so "no header" stays the unambiguous "app has not rebundled" signal.test/invocation-logs.test.ts(12 tests running the real patches in workerd via Miniflare: levels, line cap, byte budget under adversarial escaping, header squeeze, non-ASCII, passthrough of status/body/headers, crash body, quota rethrow) and 3 added assertions intest/worker-entry.test.tson the generated entry.package.json— version 0.1.0 → 0.1.1, since 0.1.0 is already published.What is verbatim from apper, and what is new
All of it is a port of apper's files at
9d315265b06(the tip of base44-dev/apper#22656), with four deliberate deltas and nothing else. Every row below is reproducible with a plaindiffagainst that commit.test/invocation-logs.test.tstest/worker-entry.test.tssrc/invocation-logs.tsMAX_CAPTURED_BYTESandRESPONSE_HEADER_BUDGETlost theirexport. They are used only inside the module andknipfails the build on unused exports — the same treatment #621 gave four internal typessrc/worker-entry.tsfrom "./invocation-logs.js"; apper's has no extension. This repo resolves NodeNext-stylepackage.jsonNo formatting or restructuring rode along. The diff on
src/worker-entry.tsis 8 hunks and every one of them is the feature. The file still differs from apper's copy in.jsimport extensions, import ordering and Biome line wrapping — all of that is pre-existing from #621 and untouched here.To repeat the check: pull every line in either copy of
worker-entry.tsmentioningASCII_ESCAPE,CAPTURE_PATCH,INVOCATION_LOGS_PATCH,_b44Wrap,_b44CaptureStore,_b44AttachInvocationLogsor_b44CrashResponse— 20 lines on each side — and diff them. The only difference is the.jsextension above.Nothing was renamed, re-commented or otherwise improved on the way over. The behaviour is apper's; a divergence would be a bug that only surfaces once apper compiles through this package.
Testing
Checklist
How the gap opened
b27ce1f6)9d315265b06)Eighteen minutes after the extraction landed, and four days after the commit it was snapshotted from. The extraction was verbatim against a commit that predated the feature, and the feature landed in apper while the extraction was in review — which is exactly why apper cannot adopt 0.1.0: the package's
worker-entry.tsis the older one.While both copies exist, the check before any swap is a directory diff of the two
src/trees, not a read of either changelog.Additional Notes
🤖 Generated by Claude | 2026-09-16 17:14 UTC | ddce31b