Root cause of the persistent 401s found: Gitea's own per-job GITEA_TOKEN
cannot publish to any package registry at all — a known, still-
unimplemented limitation (go-gitea/gitea#23642), not a settings.xml
auth-format issue as first assumed. Confirmed by testing: GITEA_TOKEN
authenticated fine against the plain API but every registry write
endpoint rejected it regardless of scope or header style.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Basic auth didn't fix it either — same 401 as the httpHeaders form.
Before guessing again: confirm GITEA_TOKEN actually reaches this step
non-empty, and check whether it authenticates against the plain API at
all (both header styles), independent of Maven/wagon-http.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Still 401 after granting packages:write — the httpHeaders form from
Gitea's docs is honored by Maven's resolver (dependency reads) but
apparently not reliably by the wagon-http provider maven-deploy-plugin
uploads through, which deployed unauthenticated. Basic auth is
wagon-http's oldest, always-supported path.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Deploy failed with 401 Unauthorized: this repo's default Actions token
permission mode is Restricted (read-only on packages, not Permissive),
so the auto-provided GITEA_TOKEN couldn't push to the Maven registry
without explicitly requesting write access.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
actions/checkout@v4 is a Node-based action; the maven:3.9-eclipse-temurin-21
container it was running in has no Node, so it failed with "node: executable
file not found in \$PATH". A shell git clone needs neither Node nor any
action runtime, just git (installed here via apt).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "org" runner label is scoped to the Pixel-Services organization —
Flash5 lives under the separate Relism account, which can only reach
the global runner (labels ubuntu-latest/ubuntu-24.04/ubuntu-22.04).
This job just runs Maven inside a container, no Docker access needed,
so ubuntu-latest is a fine fit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The org's Gitea Actions runner is registered under the label "org" —
"docker" doesn't match anything online, so the publish job never got
picked up.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets Pathway (and other consumers) resolve dev.relism:flash from Gitea's
Maven registry instead of requiring a local `mvn install`. Every push
stamps all modules with a commit-scoped version (2.1.0-<short-sha>) before
deploying, since Gitea's registry won't let a build overwrite an existing
name+version.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Data/RepositoryFactory/HibernateData give applications one cached,
stateless entry point for repositories per entity type instead of
per-request instantiation, with write()/afterCommit() replacing manual
transaction+reload choreography.
McpConfig.rolesClaimPath is removed - MCP now derives the claim path
from OidcMiddleware.rolesClaimPath() so applications never duplicate
the roles-claim config between OIDC and MCP. McpPackageScanner is
rebuilt on the shared PackageScanner.discover(packageName) primitive,
doing only McpTool/McpResource/McpPrompt classification itself.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Streamable HTTP transport (JSON-RPC 2.0 over POST), one-class-per-tool/resource/prompt
API mirroring RequestHandler, boot-time-precompiled schema/list payloads for a zero-alloc
hot path, and optional OAuth2 protection built on flash-ext-oidc (lazy-loaded, RFC 8707
audience binding, RFC 9728 Protected Resource Metadata). Registers the module in the
root and flash-extensions POMs and adds the ext-mcp commit scope to AGENTS.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Introduces AssetDirectoryScanner, StaticFrontendStrategy, and WebBundlerBuild for
build-time asset discovery, plus config/docs updates for frontend-type resolution.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds the QUERY method (RFC 10008) — safe and idempotent like GET,
but carries a request body like POST, useful for complex filters
that don't fit in a URL query string.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- TlsConfig.applicationProtocols(String...) sets the listener's negotiable
ALPN protocol list via SSLParameters, inherited by every accepted socket
like clientAuth — works on both keystore() and ofContext(), untouched
unless called. Enables TLS-ALPN-01 (RFC 8737) style on-demand cert
issuance: a custom KeyManager can read the already-resolved protocol via
engine/socket getHandshakeApplicationProtocol() inside
chooseEngineServerAlias/chooseServerAlias, since ALPN is resolved during
ClientHello/ServerHello, always before Certificate production.
- Request gains isSecure()/sslSession(), threaded through RequestParser from
the accepted SSLSocket exactly like remoteAddress() — reference-only,
zero per-request allocation. sslSession() defers to SSLSocket#getSession()
lazily, so it's a cached-field read (handshake already completed by the
time a handler can call it), never a forced handshake.
- WebSocketSession.isSecure()/sslSession() delegate to the upgrading
Request rather than tracking the socket a second time.
- Documents TLS end-to-end in README.md (listeners, TlsConfig, SNI, ALPN,
mTLS, Request/WebSocketSession accessors).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Flash can now serve HTTPS and WSS, on one or many listeners per app:
- FlashConfiguration gains an optional `tls` field for the single default
listener, and a `listeners` list for apps that bind multiple ports (each
independently plain or TLS).
- New dev.relism.flash.tls package: TlsConfig.keystore(path, password) builds
an SSLContext from a PKCS12/JKS keystore, with SNI-based certificate
selection for free when the keystore holds more than one alias (matched by
SAN/CN, pure JDK APIs). TlsConfig.ofContext(sslContext) is a full escape
hatch — Flash never calls setSSLParameters on that path, so caller-set
protocols/cipher suites/ALPN survive untouched. TlsConfig.clientAuth(...)
adds optional/required mTLS on either path.
- HttpServer moves from a single ServerSocket to a list of bound listeners;
the per-request hot path (RequestParser, routing, response writing) is
untouched — TLS only changes which bytes come out of accept(), so WSS needs
no separate code path from WS.
- process()'s catch is widened to log non-IOException failures (e.g. a
misbehaving custom KeyManager/TrustManager on the ofContext path) instead
of swallowing them silently; the failure was already isolated to the one
connection via the existing try-with-resources/executor-submission
boundary — this only fixes the missing log line.
- Fixes a pre-existing gap where FlashConfiguration#host was accepted but
never used to bind (listeners always bound to the wildcard address).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- WebSocketSession supports client-mode outgoing frame masking (RFC 6455) via
in-place XOR, reusing the unmask routine already used for inbound frames.
- HeaderMap gains an allocation-free forEach(HeaderConsumer) for callers that
must handle an open-ended set of header names (e.g. proxying).
- HttpServer relays streaming/chunked response bodies through a shared
per-connection ThreadLocal buffer instead of relying on InputStream#transferTo
(which allocates internally) or a fresh byte[8192] per chunked write.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Move JteStaticServing to dev.relism.flash package
- Fix imports in HttpStatus and test files
- Add fluent config methods to JteExtension (templateRoot, serveStatics, staticPrefix, etc.)
- Implement routes() for static asset serving with HEAD support
- Include Main.java entry point