Latest Results
feat(cli): configure the send client through glion.config.ts
`glion send` set both client timeouts from `--timeout` and left the dial
policy at the client's default, so the flag was not the deadline the
help text promised: a refused target took the whole reconnect budget.
The flag is gone. `glion.config.ts` gains a `client` block, passed to
`MllpClientOptions` as given: `connectTimeoutMs`, `sendTimeoutMs`,
`maxBufferedBytes`, and `reconnect`. Each field is bounded to the range
the client itself asserts, so a value it would refuse is reported as a
config error naming the field; a schema test holds the two in step.
The config is now loaded on every send, for that block alone — the
target comes from the invocation, never from the config — and `--config`
is read whether it comes before or after the `send` token. A config that
fails to load and a `.glion/` directory that cannot be created are the
`invalid` outcome instead of an uncaught error; a project with no config
file sends on the client's defaults and has nothing written to it.
`--port` is bounded to 1–65535 at parse time and defaults to 2575, the
port MLLP standardizes on, so a target needs only `--host`.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> feat(cli): send over TLS
`client.tls` in `glion.config.ts` takes `true` or Node's TLS settings,
with file paths resolved against the config file and read before
dialing. `true` verifies the receiver against the runtime's trusted
CAs; an object names the authority that signed its certificate with
`ca` — or its own certificate, when it signed itself, as a development
server does — adds `cert` and `key` when the receiver asks for a client
certificate, and `servername` when the certificate names a host other
than the address dialed.
A TLS file that cannot be read is the `invalid` outcome, reported before
dialing with the target it was aimed at, and the `== connected` line
marks a TLS connection.
Tested against TLS servers on loopback with a CA issued per run: a
self-signed certificate trusted through `client.tls.ca`, an issued one,
untrusted, wrong name, and mutual TLS. One end-to-end case through the
built binary runs under Node and Bun.
Part of #657.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> fix(cli): report failures as facts, not as glion's internals
A failure told the user how glion thinks rather than what is wrong.
`--local` without a config said the flag "has no target to read"; a
missing target said "Specify a target with --host and --port"; an app
that imports a package it does not have said "Failed to load compiled
entry /…/.glion/glion.app.js: Cannot find package …", naming a file
glion wrote for itself and pasting Node's resolution error into the
sentence. Three different kinds of leak: our control flow, an
instruction standing in for a fact, and a foreign error spliced in.
`GlionError` already had four channels; they are now used for what
their names say. `message` is the fact, one sentence, about the file
the user wrote, the flag they passed, the port they asked for. `hint`
is what to do. `context` holds the values. `cause` holds the
underlying error, whole.
So the detail that used to ride inside the sentence has somewhere to
go: the `fatal` event gains `hint` and `cause`, the dev terminal
prints each on its own line under the message, and `glion send`'s
JSON line and diagnostic line carry both. The child now reports the
app file from the manifest instead of the compiled copy beside it,
which is the path an operator can act on. Supervisor warnings say
"the app" rather than "the child", and the runner's missing-manifest
guard is a plain bug report rather than a `config-not-found` nobody
can fix.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>cli-send/errors-state-facts fix(cli): report failures as facts, not as glion's internals
A failure told the user how glion thinks rather than what is wrong.
`--local` without a config said the flag "has no target to read"; a
missing target said "Specify a target with --host and --port"; an app
that imports a package it does not have said "Failed to load compiled
entry /…/.glion/glion.app.js: Cannot find package …", naming a file
glion wrote for itself and pasting Node's resolution error into the
sentence. Three different kinds of leak: our control flow, an
instruction standing in for a fact, and a foreign error spliced in.
`GlionError` already had four channels; they are now used for what
their names say. `message` is the fact, one sentence, about the file
the user wrote, the flag they passed, the port they asked for. `hint`
is what to do. `context` holds the values. `cause` holds the
underlying error, whole.
So the detail that used to ride inside the sentence has somewhere to
go: the `fatal` event gains `hint` and `cause`, the dev terminal
prints each on its own line under the message, and `glion send`'s
JSON line and diagnostic line carry both. The child now reports the
app file from the manifest instead of the compiled copy beside it,
which is the path an operator can act on. Supervisor warnings say
"the app" rather than "the child", and the runner's missing-manifest
guard is a plain bug report rather than a `config-not-found` nobody
can fix.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>cli-send/errors-state-facts Latest Branches
0%
0%
cli-send/connection-facts -15%
© 2026 CodSpeed Technology