mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-10-26 05:30:18 +00:00
e9f824266b
* feat: open a published port at its configured service URL
Store the address as the compose label sencho.service.url so a port click follows that host, and keep the generated link when the label is absent.
* fix: reject an escaping compose path before reading it
The compose filename scan checks the path stays inside the compose directory before it stats the file, so a rejected path is not treated as a missing file.
* fix: keep inherited labels and unsaved edits when a service URL is saved
A URL edit copies inherited labels onto that service, a changed compose filename keeps the draft unless the operator reloads, and a missing URL list still opens the generated link.
* fix: keep a service URL edit on the service that was opened
A shared label or service anchor is copied before the edit, clearing a merged URL does not restore the inherited address, and a running container opens only its own saved URL.
* fix: keep empty labels and dynamic ports on a service URL
A URL edit dropped empty labels and failed when a nested anchor was still used. A Docker-assigned port now opens that service's own URL, and the pencil stays unavailable when the service is not in the open compose file.
* fix: keep a service URL on the service that was edited
A shared URL value no longer changes another service. Open App does not follow a different service's dynamic address, a named port on its own bind address stays clickable, and a repeated list label takes the new address.
* fix: keep a service URL dialog on the stack it was opened for
The dialog now records the node and stack it was opened on, closes when that selection changes, and refuses the save before it can write a different stack. Clearing or replacing a list alias updates only the edited service. A URL supplied by another compose file stays on that file, and reloading the compose source refreshes the cached addresses.
* fix: edit a service URL without rewriting the rest of the compose file
A save splices the label into the original text, so octal modes, line endings, and unrelated keys stay as written. A node with no host keeps the plain port, a refresh keeps the last URL, and Open App opens its tab before the lookup.
* fix: keep service URL edits and compose saves inside the edited stack
- Refuse a compose file, or a stack directory, that resolves outside
<compose root>/<stack>, so a read or save of one stack cannot reach a
sibling stack's compose file. Covers saveStackContent too.
- Edit flow-style labels and services in place, copy anchored flow
nodes without their defining key, keep source tokens such as 0440 and
022 when labels are copied, append after the last real label (before
trailing comments, and at an end of file with no newline), and keep
the separator when an empty URL value is set or cleared.
- Check every patch before it can be saved: the file is read with YAML
types and as untyped text, and anything that changes outside the URL
label, drops a comment inside brackets, or touches a file with a
custom YAML tag is refused with a clear message.
- Return the cached service URLs only for the node and stack they were
read for, so a port never links to the previous selection.
- Log stacks the networking summary skips instead of dropping them
silently.
* test: assert the networking summary skips a sibling-linked stack
A stack whose compose file resolves outside its own directory is skipped
with a warning. Assert the linked stack stays out of every bucket, the
healthy stack is still summarized, and the skip is announced.
* fix: keep service URL edits effective and prototype-safe
The effective-anatomy response now reports, per service, whether the open
main compose file controls the sencho.service.url label (serviceUrlEdit).
That is established from the authored chain: the label key presence is read
in the files merged after the open one (deploy spec order, or the resolved
main file plus the auto-discovered override). A later file that sets the key
blocks the edit whatever its value (invalid, interpolated, or equal); a later
file that uses include, extends, a custom YAML tag, or COMPOSE_FILE, or that
cannot be read, refuses the edit as unverifiable. The pencil lock, the save
guard, and a fresh re-read immediately before the write consume this
metadata, so the editor no longer infers ownership from the label value or
its absence. Post-save verification stays.
Service-keyed maps are built on null prototypes and read through own-property
lookups across the backend extractor, the response parser and resolvers, and
the local anatomy facts. Services named constructor, toString, hasOwnProperty,
or __proto__ now resolve the generated link when they have no label and keep
an own override when they do.
* fix: refuse a service URL edit the compose chain would shadow or reveal
A later bare `sencho.service.url` list item (`- sencho.service.url`) sets
the key to an empty value and shadows the open file, so the source
authority now counts it as a key contribution like the `key=value` form.
Clearing is not the mirror of setting: removing the open file's direct
label can surface an earlier chain file, the open file's own include, a
service's extends target, or its label_file. The anatomy response now
carries a per-service clear authority alongside the set authority, the
editor refuses an empty save the chain would keep winning or reveal, and
the patch helper refuses the same layouts before writing. Setting a URL
is unaffected.
The patch helper also treats a bare list item as the key when setting or
clearing, so a set no longer leaves a trailing empty entry that renders
as an empty value.
Operator docs describe the set and clear limits accurately.
* fix: refuse interpolated label keys and honor explicit dynamic ports
Compose interpolates a list label's key, so `- "${URL_LABEL}=https://app"`
sets `sencho.service.url` even though the authored source never names it.
A later file using that shape reported the open file as editable and the
write did not take effect; an earlier or later one failed to block a clear.
Such a key now marks the service unverifiable, so both guards refuse before
the save. A literal key with an interpolated value stays a known set.
`published: 0` (from `"0:80"` or `{ target: 80, published: 0 }`) asks
Docker to assign the host port, but the dynamic-owner predicate treated it
as a fixed host, so a container-port click and Open App fell back to the
generated node address. It now counts as automatic allocation, leaving UDP
binding, named-service isolation, and ambiguity refusal unchanged.
* fix: keep a saved service URL effective and a port link on its owner
- Read the open compose file's own source in the service URL set
authority: a labels list whose key is interpolated (`- "${NAME}=..."`)
makes that service unverifiable instead of editable, including when the
file's other facts cannot be traced (a top-level `include` or a custom
tag) and when the file cannot be read at all.
- Refuse a set and a clear in the editor buffer when the target service's
label list carries an interpolated key, so an unsaved draft is caught
before any write.
- Open a named container's own automatic binding URL on its card when
Docker assigned it the host port, even when another service's saved
file declares the same number, and refuse a saved-only single fixed
declaration when another service's automatic binding could hold it.
- Carry the runtime main-port owner (`com.docker.compose.service`) from
the bulk stack status through to Open App so it opens the address of
the running service that owns the port.
* fix: keep a runtime container card on its own service URL
- Treat a named runtime container as direct ownership evidence: when a
card carries both the compose service and the running container's own
port, that service's configured URL applies even after the saved port
declarations changed or were removed without a redeploy.
- Keep saved-model inference and its ambiguity refusals for callers
without runtime port data, such as the anatomy footer.
- Cover the changed-port, removed-binding, hostless-remote, and rendered
anchor cases in resolver and component tests.
- State in the stack management docs that the configured label applies
first and the generated address is the fallback.
* fix: keep merged label text and a runtime card's generated link
Clearing a service URL from a labels map that also merges a YAML anchor
materialized the whole map from parsed values, which deleted operator
comments inside the map and respelled unrelated scalar tokens. The clear
now copies inherited entries from their own source text, leaves direct
entries untouched, and refuses layouts whose text cannot be kept.
A running container whose compose service has no URL override fell
through to saved-model inference and could turn ambiguous when other
saved services claimed the same host port. Runtime ownership now answers
with the service's own URL or the ordinary generated host and port.
Regression tests cover the preserved comments and tokens (block, flow,
CRLF, merge lists, nested merges, shared anchors) and the generated
anchor plus copy target for a runtime owner without an override.
* fix: wait for the first service URL lookup before opening a port
A first effective-anatomy lookup was read as "no override", so a
published-port link and Open App could open the generated host and port
while a configured service URL was still being fetched. The in-flight
entry now stays pending: the port renders as plain text until the outcome
is known, and Open App opens the tab in the click and navigates once the
lookup resolves. Completed outcomes (no label, a failed load, an older
node) keep the generated fallback, and a refresh that still holds the
prior model keeps rendering it.
* fix: keep a long service URL on the card and a refused path honest
A long host now truncates so the copy button and pencil stay clickable, and every port link keeps its open arrow. Clearing the only service URL removes the labels key, including when the address has a fragment. Opening a stack the server refuses shows that reason. Effective anatomy refuses a compose file or discovered override that links outside the stack. The editor shows a new URL only after the save is accepted.
* fix: keep the port link visible and drop a sole URL list
The port mapping stays on the card when the host is long, and on a phone the identity line wraps above the action buttons. Clearing a labels list that only holds the service URL removes the labels key, while a comment still keeps an empty value.
* fix: keep a cleared service URL renderable and the port controls reachable
A clear that left the labels map with no entries wrote `labels:` with no
value, which Compose rejects ("must be a mapping"), so the stack stopped
rendering and every pencil in it disappeared. The key now goes with its
last label, and a comment the removal would drop keeps the entries as an
empty map or list under the key instead. That covers a clear through a `<<`
merge, a sole label with a trailing comment, a comment line closing the
block, and a shared anchor whose other consumer keeps its address. A comment
between the removed entries is still refused before any write.
The container list now clamps to its pane, so a long host truncates and the
port link's copy button and pencil stay reachable at 1440px and below
instead of sitting past the pane edge. The copy button also gets the 44px
phone target the pencil already had.
A refused compose path answers with the condition instead of "path is not
allowed", and the parser no longer warns about the custom tags those edits
refuse.
Every layout the clear can produce renders under `docker compose config`.
* fix: keep the port line readable in a narrow container pane
The pane clamp left the action icons at full size, so the name and port link collapsed. The card now wraps those icons once the name column would drop below 12rem. A refused URL edit stays in the dialog until the address or the compose buffer changes.
* fix: keep the service URL editable after a failed list load
A failed first load keeps the generated link, explains that the list is unavailable, and offers Retry. A later failed refresh keeps the last address and the pencil. The pencil tooltip matches the copy control.
163 KiB
163 KiB