@pellux/goodvibes-tui 1.18.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,165 @@ All notable changes to GoodVibes TUI.
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.19.0] — 2026-07-16
8
+
9
+ ### Changes
10
+ - 654eae83 deps: adopt published SDK 1.10.0 and regenerate operator contract artifact
11
+ - a7055269 docs: regenerate command reference + foundation artifacts for the new surfaces
12
+ - 17bcce8a voice setup: live per-component install progress
13
+ - cd1d1889 extract knowledge + voice-setup construction to hold services.ts under the 800-line cap
14
+ - 6eabbe16 compose the memory governor + managed voice provisioning in the daemon
15
+ - 4ea80514 voice status: render the real STT enums honestly
16
+ - c7c99a05 memory: doctor/status surface + pressure notice over ops.memory.get
17
+ - 49b5ac83 voice settings: size-labeled local-engine setup offer beside ElevenLabs
18
+ - f2bf0bb6 voice: /voice setup + /voice status one-act over the managed local-voice verbs
19
+ - f7bb30f6 changelog: macOS in-app fleet coverage, regeneration backups, provenance-gated replacement, kept promises, honest not-probed
20
+ - c26ad724 cli: not-probed is a tri-state on control-plane status and listener test — never a definite reachable:false
21
+ - 50e10f36 installer: the macOS in-app fleet is reachable — both LaunchAgent identities, structural plist provenance, zero silence on pinned plists
22
+ - ac27ebdd installer: replace-broken gate at every call site, backups before fingerprint regeneration, promises fulfilled on transfer refusal
23
+ - 576b3665 changelog: modern-systemd vocabulary, fielded pinned-unit repair, never-touch hand-written units, honest bind displays
24
+ - e63581be cli: every display surface routes endpoint bindings through one formatter seam
25
+ - 4c3c471e installer: hand-written units survive the corpse state untouched; launchd cannot-ask is never free-to-kill
26
+ - 1d3b42d8 installer: re-derive fielded pinned-endpoint units on upgrade (systemd + launchd, transfer + plain paths)
27
+ - 49fa896e tri-state honesty for modern systemd and flapping probes: rc-4 'no such unit' is ABSENT, a failed MainPID query is UNKNOWN
28
+ - 0019f2bf runtime: split the startup reconcile into legacy-daemon-reconcile.ts
29
+ - 3986860e changelog: config-derived units, fail-safe installer, serving-proof reconcile
30
+ - 9433bb11 installer: fail-safe on unknown service state, config-derived unit, endpoint-aware retirement, launchd run-state parity
31
+ - 5b66a3a1 daemon: endpoint-serving proof + never-stop-a-running-daemon on the reconcile; config-derived unit content; display parity flags
32
+ - eba26f90 changelog: describe the hardened migration, reconcile guards, and bind-honest banner
33
+ - b7e7a36e daemon: serving-proof + self-kill guards on the reconcile, timeout-bounded systemctl, bind-honest banner
34
+ - b10000df installer: supervised transfer for the legacy-active upgrade state, exit-status-checked retirement, quoting, launchd analog
35
+ - e55eb1e7 changelog: installer unit unification, honest daemon startup, legacy-unit reconcile
36
+ - 366560a0 daemon: honest startup identity and unattended legacy-unit reconcile
37
+ - 615d60aa installer: unify the daemon service on the canonical goodvibes.service unit
38
+
39
+ ## [Unreleased]
40
+
41
+ ### Fixed
42
+ - Installer now creates one daemon service unit that matches the app. The curl
43
+ installer used to write a `goodvibes-daemon.service` unit with a bare launch
44
+ command (no arguments), while the in-app service setup manages a
45
+ `goodvibes.service` unit launched with `--daemon-home`/`--hostname`/`--port`.
46
+ On upgrade a host could end up running both, and the extra bare unit booted a
47
+ second daemon that fought the real one for the same port. The installer now
48
+ writes only `goodvibes.service` with the same launch arguments the app uses,
49
+ and its create, restart, and uninstall paths all target that one name.
50
+ - Installer upgrade path migrates the old unit safely. When the daemon is
51
+ actively running under a leftover installer-created `goodvibes-daemon.service`
52
+ (the common upgrade state), the installer now performs a supervised transfer:
53
+ it writes the canonical unit, stops the old one, starts the new one, verifies
54
+ it is actually active, and only then disables and removes the old unit. If
55
+ the new unit fails to come up, everything rolls back and the old unit keeps
56
+ running. Every stop/disable checks its exit status — a failed disable (for
57
+ example, no user service bus) leaves the unit file in place and says so,
58
+ instead of removing it behind a false "disabled + removed" message. A
59
+ hand-written unit of that name (no installer marker) is never removed, an
60
+ unreadable one is reported as unreadable, and `GOODVIBES_RESTART_DAEMON=0`
61
+ now also keeps the migration from stopping a running unit. The installer's
62
+ process-restart fallback no longer kills a systemd-supervised daemon, and
63
+ paths with spaces are quoted in the generated unit. macOS gets the same
64
+ upgrade: an installer-managed LaunchAgent with the old bare launch command is
65
+ regenerated to the argument-driven form.
66
+ - Daemon startup prints an honest one-line identity. Launching the daemon binary
67
+ now prints its real version plus the home directory, host, and port it will
68
+ actually bind — the host/port come from the same resolution the bind path
69
+ uses (including the `hostMode` setting and port fallbacks), so the banner can
70
+ no longer claim a loopback bind while listening on every interface, or print
71
+ `port=0`. It points at the `install-service` command, replacing a startup
72
+ banner that could show a wrong `0.0.0` version. Version resolution is
73
+ hardened so a compiled binary can never pick up an unrelated `package.json`'s
74
+ placeholder version.
75
+ - Daemon self-heals the two-unit state at startup, carefully. If the daemon
76
+ finds a redundant installer-created `goodvibes-daemon.service` still enabled
77
+ beside its own unit, it disables and removes it and records what it did — but
78
+ only after verifying the canonical unit is genuinely serving (active with a
79
+ live main process), never from inside the old unit itself (it will not
80
+ disable the unit supervising its own process), never while the old unit has
81
+ a running daemon of its own (a running second daemon might be the one your
82
+ clients reach — retiring it needs the deliberate `migrate-service` command),
83
+ and only once the endpoint clients resolve from settings is confirmed to be
84
+ answering. The unit file is removed only after the disable actually
85
+ succeeded; a disable that times out is re-inspected and reported as exactly
86
+ what was confirmed, never a blanket claim. Refusals are logged with a reason,
87
+ the configured service name and the login home directory are used (custom
88
+ setups reconcile too), and every check runs with a per-call timeout plus one
89
+ overall time budget so even a slow service manager can never stall daemon
90
+ startup. A hand-written unit is only reported, never touched.
91
+ - Service units no longer pin the network endpoint. Both the installer and the
92
+ in-app service setup now write a unit that launches the daemon with only its
93
+ home directory; the daemon reads the configured interface mode, host, and
94
+ port from settings at startup. A host configured for network access or a
95
+ non-default port keeps that endpoint across upgrades — previously an upgrade
96
+ could silently pin the daemon back to loopback and the default port while
97
+ reporting success.
98
+ - Installer understands modern systemd's answers. Current systemd (verified on
99
+ systemd 260) reports "no such unit" with a distinct exit code that older
100
+ releases did not use; the installer now reads that as the affirmative "this
101
+ unit does not exist" — which permits writing the unit and migrating — instead
102
+ of refusing the whole upgrade with a false "service manager unreachable"
103
+ message. Transitional unit states (starting, stopping) are read as the unit
104
+ existing, and the same discipline applies to the daemon's startup check: a
105
+ service query that fails or times out is treated as unanswered, never as
106
+ "the old service is stopped".
107
+ - Existing installs with a pinned network endpoint get fixed on upgrade. Units
108
+ written by earlier releases baked the interface and port into the launch
109
+ command, silently overriding later settings changes on every boot. The
110
+ installer now regenerates recognizably product-managed units (and the macOS
111
+ LaunchAgent) to the settings-driven launch during upgrade; hand-written units
112
+ are never rewritten — they get a clear notice instead, and the migration
113
+ refuses to move a running daemon onto a hand-written unit with pinned flags.
114
+ - Hand-written service units are never modified, even broken ones. A
115
+ hand-written unit whose launch binary no longer exists is left exactly as it
116
+ is (no disable, no rename, no replacement unit written over it) with an
117
+ honest note about how to fix it.
118
+ - macOS installs made by the app itself now get every upgrade repair. The
119
+ in-app service setup registers the daemon under its own LaunchAgent name and
120
+ file, which the installer previously never looked at: pinned endpoints there
121
+ survived every upgrade silently, and the upgrade's restart path could kill
122
+ and orphan a daemon supervised under that name. The installer now handles
123
+ both LaunchAgent identities, restarts either in place, recognizes
124
+ product-installed launch files by their launch command when no marker is
125
+ present, and never stays silent about a launch file that pins the endpoint —
126
+ it is either regenerated (with a timestamped backup and a receipt) or called
127
+ out with instructions.
128
+ - Regenerating a recognized service unit always keeps a backup. A unit
129
+ identified as product-written by its description line may still carry user
130
+ customizations (proxy environment lines, a different binary path); the prior
131
+ file is saved as a timestamped backup next to the original, named in the
132
+ output, before any rewrite.
133
+ - No service unit is replaced unless it is provably platform-managed. The
134
+ broken-unit replacement path (for units whose launch binary vanished) now
135
+ checks provenance at every entry point — a hand-written daemon or agent unit
136
+ is never disabled, renamed, or replaced, even when broken; the installer
137
+ never writes agent units, so it never replaces one.
138
+ - The upgrade promise is always kept. When the installer defers a daemon
139
+ restart to the migration step and the migration then declines (for example, a
140
+ hand-written unit with pinned endpoint flags is in the way), the old unit is
141
+ restarted in place so the freshly installed binary actually starts serving,
142
+ with the reason explained.
143
+ - "Not probed" is reported as exactly that. Control-plane status and the
144
+ listener test no longer show "reachable: no" (or machine-readable false) for
145
+ an endpoint they deliberately did not probe; the output says it was not
146
+ probed and why.
147
+ - Status displays never invent a bind address. Every command that shows an
148
+ endpoint (status, doctor, control-plane status, web, listener test, service
149
+ posture, surfaces) now goes through one shared formatter: an unrecognized
150
+ interface mode is reported as exactly that — with a doctor finding naming the
151
+ fix — instead of being displayed as a definite loopback bind, and such
152
+ endpoints are never port-probed.
153
+ - Installer treats "cannot ask the service manager" as a hard stop. When
154
+ systemd cannot be reached (for example, a session without a user bus), the
155
+ installer no longer guesses: nothing is stopped, killed, or removed, and it
156
+ prints what to run once a normal session is available. The process-restart
157
+ fallback now checks per-process supervision by asking systemd which unit owns
158
+ the process — any unit name counts, and an unanswerable check counts as
159
+ supervised. macOS gets the same discipline: a loaded LaunchAgent is restarted
160
+ in place through launchd, an agent the user deliberately stopped is never
161
+ started by an upgrade, and rollbacks restore the exact pre-upgrade enablement
162
+ state.
163
+
164
+ ---
165
+
7
166
  ## [1.18.0] — 2026-07-14
8
167
 
9
168
  ### Changes
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/mgd34msu/goodvibes-tui/actions/workflows/ci.yml/badge.svg)](https://github.com/mgd34msu/goodvibes-tui/actions/workflows/ci.yml)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Version](https://img.shields.io/badge/version-1.18.0-blue.svg)](https://github.com/mgd34msu/goodvibes-tui)
5
+ [![Version](https://img.shields.io/badge/version-1.19.0-blue.svg)](https://github.com/mgd34msu/goodvibes-tui)
6
6
 
7
7
  A terminal-native AI coding, operations, automation, knowledge, and integration console with a typed runtime, omnichannel surfaces, structured memory/knowledge, and a raw ANSI renderer.
8
8