@hraness/message-like-me 0.8.20 → 0.8.22

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
@@ -1,23 +1,47 @@
1
1
  # Changelog
2
2
 
3
- ## 0.8.20 (2026-09-24)
3
+ Each version's section is copied onto its GitHub Release page: a summary
4
+ paragraph, then one bullet per change. Write the section in the version bump
5
+ pull request.
6
+
7
+ ## 0.8.22 - 2026-09-28
8
+
9
+ The Textbutler menu companion is rebuilt around one status line and ten top-level rows, the terminal gains a guided macOS access step, and the `messagelikeme` history CLI drops its banner and names the app in access errors.
10
+
11
+ - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.22` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
12
+ - Rebuild the menu companion around a status line and ten top-level rows: failed actions surface as a ⚠︎ row that clears, Quit actually ends the menu process, and the menu can launch through the locally built TextButler.app (behind `HRANESS_LOCAL_APP`).
13
+ - Add a guided "Give Textbutler access" step to the terminal walkthrough and detect existing Ghostget and Bun installs in the connect step, using the shared desktop-foundation 0.8 permission copy, audience detection, and symbols.
14
+ - Add owner-set contact labels: `textbutler contacts label <contact> <name>` renames a chat for commands instead of a raw number; labels are display metadata only and never touch routing, grants, or reply settings.
15
+ - Adopt support-foundation 0.6.0: agent support verbs move to `textbutler help advanced` and every root help keeps one support line.
16
+ - Reply loop: the acknowledgement now overlaps composition, polls yield to sends, due runs start at debounce expiry, drain replays deduplicate, and self-chat acks correlate by relatedMessageId; Ghostget pins 0.18.43 for the native iMessage setup.
17
+ - `messagelikeme` CLI: root help no longer prints the banner, and Messages/Contacts permission failures name the app and deep-link the Full Disk Access pane.
18
+ - Refresh the Textbutler site: quiet landing with real terminal proof, design-kit v0.23.0, and copy checked against source.
19
+
20
+ ## 0.8.21 - 2026-09-24
21
+
22
+ A LaunchAgent service installed by 0.8.19 now verifies and uninstalls under this release. In 0.8.20 it failed verification, because 0.8.19 had changed the service template without changing the receipt schema.
23
+
24
+ - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.21` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
25
+ - Complete the LaunchAgent contract fix: receipts written before schema 4 recorded an artifact now verify the installed service definition against every exact render a shipped template produced (the template changed `ProcessType` within the same receipt schema), so a service installed by the previous release verifies and uninstalls under this binary. When advancing an absent service's older receipt, the rewritten plist lands before the receipt so an interruption still verifies against the older contract's historical renders.
26
+
27
+ ## 0.8.20 - 2026-09-24
4
28
 
5
29
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.20` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
6
30
  - Make the LaunchAgent receipt record the exact rendered plist it installed (schema version 4): installation verification now compares the on-disk service definition with the recorded artifact instead of re-rendering it under the current binary, so a launch-template change can no longer make a newer `textbutler` unable to verify or uninstall a service an older binary installed. Older receipts keep verifying against their historical template bytes, `daemon install` refuses to mutate an owned service on an earlier contract until it is removed and reinstalled, and an absent service's older receipt advances to the recorded-artifact contract in place.
7
31
 
8
- ## 0.8.19 (2026-09-23)
32
+ ## 0.8.19 - 2026-09-23
9
33
 
10
34
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.19` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
11
35
  - Run the Textbutler daemon at standard launchd priority instead of `Background`: on a loaded host the previous setting starved the messaging child's spawn-synchronous startup, so automation initialization could outlast its request deadline and cycle through recovery without ever answering inbound messages.
12
36
  - Make the automation child's initialize watchdog progress-aware: it re-arms only while the recorded process group proves CPU progress, so a slowly starting child is adopted instead of orphaned while a genuinely frozen child still dies on the original deadline under the same hard cap.
13
37
  - Escalate failed-child cleanup to the recorded process group whenever that group may be alive rather than only while the direct child process entry is absent, so same-group helpers left behind by a closed child meet SIGKILL instead of surviving as orphans.
14
38
 
15
- ## 0.8.18 (2026-09-23)
39
+ ## 0.8.18 - 2026-09-23
16
40
 
17
41
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.18` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
18
42
  - Let the local TextButler app build against a persistent owner signing identity with `--signing-identity`, so macOS permission grants such as Full Disk Access and Apple Events bind to a stable certificate instead of each ad-hoc rebuild's changing code hash. The managed app receipt records the signing class explicitly (`ad-hoc` or `certificate`), treats a signing-class change as a new permission target that requires reinstall, and rejects unreviewed signing classes at startup. Ad-hoc signing remains the default for development builds.
19
43
 
20
- ## 0.8.17 (2026-09-23)
44
+ ## 0.8.17 - 2026-09-23
21
45
 
22
46
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.17` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
23
47
  - Add isolated per-contact habitats: each enrolled contact gets a private workspace whose bounded evolution loop proposes, evaluates and promotes reply-guidance updates through the admitted subscription driver, with journaled budgets and reservations.
@@ -26,28 +50,28 @@
26
50
  - Keep the automatic loop honest under load: inbound events drain in batches, a degraded transport keeps pending work and only reports attention after repeated failures, reactions and echoes can no longer erase or trigger pending replies, and a continuous inbound stream is answered within a bounded debounce instead of starving.
27
51
  - Accept bare-object driver output, map silent suggestions to an explicit outcome, supervise the messaging transport child with custody-verified recovery, keep injected contact-workspace guidance out of trusted policy, and reseal the reviewed XCB composition receipt over the current sources.
28
52
 
29
- ## 0.8.16 (2026-09-22)
53
+ ## 0.8.16 - 2026-09-22
30
54
 
31
55
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.16` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
32
56
  - Treat an owner text naming the butler in an enrolled contact conversation as a deliberate invocation: it now queues a disclosed reply through the same grant, rate-limit, capability, and freshness checks instead of marking the thread answered. Only a strictly newer owner message suppresses it as a takeover, and invocations no longer count as owner presence, so they cannot cool the butler down or swallow the next inbound. `inbox` and `replies suggest` report the same owner run the loop sees.
33
57
 
34
- ## 0.8.15 (2026-09-21)
58
+ ## 0.8.15 - 2026-09-21
35
59
 
36
60
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.15` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
37
61
  - Keep an admitted automatic reply alive while it is drafted: the post-composition recheck measures event age from admission instead of the live clock, so a slow provider call can no longer cancel a live reply as stale, while owner activity, superseded events, sync, and settings still cancel it.
38
62
  - Treat the butler's own echoed messages as loop traffic only: they no longer cancel an in-flight reply or clear a newer pending inbound, and echo-only traffic cannot supersede a live reply.
39
63
 
40
- ## 0.8.14 (2026-09-21)
64
+ ## 0.8.14 - 2026-09-21
41
65
 
42
66
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.14` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
43
67
  - Let the owner mark a conversation as their own address with `contacts self CONTACT on|off`. iMessage self chats deliver each owner text as an inbound copy plus an outgoing echo; the echo is no longer mistaken for the owner's answer, and the butler's own wrapped sends echoing back inbound cannot trigger another reply. Marking requires a visible butler wrap so the echo signal cannot be cleared away, and stored contacts default off.
44
68
 
45
- ## 0.8.13 (2026-09-21)
69
+ ## 0.8.13 - 2026-09-21
46
70
 
47
71
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.13` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
48
72
  - Accept the renamed XCB account identity fields (`name` plus optional `email`, with `label` retained as an alias) in subscription capability discovery, so a verified Textbutler bundle works against both pre- and post-rename XCB runtimes.
49
73
 
50
- ## 0.8.12 (2026-09-21)
74
+ ## 0.8.12 - 2026-09-21
51
75
 
52
76
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.12` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
53
77
  - Add the native TextButler desktop app with scoped guided setup, a menu bar companion, and per-contact review-first controls. New installations start paused and automatic replies stay off per contact.
@@ -56,13 +80,13 @@
56
80
  - Restore native iMessage discovery and history through the reviewed Ghostget connector, including literal modern coordinates, and provision the pinned private transport during setup so a reviewed connector upgrade cannot leave a stale helper.
57
81
  - Refresh the informational site's identity and keep it informational only; it receives no messages or contact data.
58
82
 
59
- ## 0.8.11 (2026-09-16)
83
+ ## 0.8.11 - 2026-09-16
60
84
 
61
85
  - Bind legacy installation to the exact public `@hraness/message-like-me@0.8.11` npm package, with the same reviewed bytes mirrored in the immutable GitHub Release. This does not install the Textbutler menu companion or enable automatic replies.
62
86
  - Add optional development support to CLI discovery, the Message Like Me skill, the Textbutler menu, and the public website. Task output and private message boundaries stay unchanged.
63
87
  - Bundle the shared local support protocol separately from all public SDK graphs. Paid support remains a human choice; no newsletter is offered for this product.
64
88
 
65
- ## 0.8.10 (2026-09-13)
89
+ ## 0.8.10 - 2026-09-13
66
90
 
67
91
  - Show a compact ASCII robot before interactive root help. Piped output,
68
92
  machine-readable commands, version output, and command help stay unchanged.
@@ -70,20 +94,20 @@
70
94
  Textbutler app remains in development; this package does not enable replies.
71
95
  - Route legacy installation to the exact public `@hraness/message-like-me@0.8.10` npm package after release admission, with the same reviewed bytes mirrored in the immutable GitHub Release.
72
96
 
73
- ## 0.8.9 (2026-09-10)
97
+ ## 0.8.9 - 2026-09-10
74
98
 
75
99
  - Use the shared Paper theme on the informational website, with warm neutral surfaces, compact Nebula Sans headings, and a blue action color in light and dark appearances.
76
100
  - Verify the theme snapshot's immutable source and file digests independently of the existing component package versions.
77
101
  - Route installation to the exact public `@hraness/message-like-me@0.8.9` npm package after release admission, with the same reviewed bytes mirrored in the immutable GitHub Release. CLI behavior and private data boundaries remain unchanged.
78
102
 
79
- ## 0.8.8 (2026-09-09)
103
+ ## 0.8.8 - 2026-09-09
80
104
 
81
105
  - Route installation to the exact public `@hraness/message-like-me@0.8.8` npm package after release admission, with the same reviewed bytes in the immutable GitHub Release.
82
106
  - Use Ghostget in current CLI options, SDK names, source guidance, and the public site. Keep the original Wrench options and exports as compatibility aliases.
83
107
  - Accept `ghostgetContext` when preparing a handoff while preserving the existing serialized handoff, receipt, contract hashes, and local history. Reject simultaneous context aliases.
84
108
  - Point Ghostget setup to its exact canonical GitHub Release archive.
85
109
 
86
- ## 0.8.7 (2026-09-09)
110
+ ## 0.8.7 - 2026-09-09
87
111
 
88
112
  - Make the exact public `@hraness/message-like-me@0.8.7` npm package the
89
113
  supported default install, with the same reviewed bytes mirrored in the
@@ -97,7 +121,7 @@
97
121
  - Strengthen the development Effect architecture checker. Public protocols,
98
122
  the source readers, and command behavior are unchanged.
99
123
 
100
- ## 0.8.6 (2026-09-07)
124
+ ## 0.8.6 - 2026-09-07
101
125
 
102
126
  - Make the exact public `@hraness/message-like-me@0.8.6` npm package the
103
127
  supported default install, with the same reviewed bytes mirrored in the
@@ -113,7 +137,7 @@
113
137
  - Strengthen the development Effect checker with generator alias and wrapper
114
138
  regressions. Public protocol graphs and local-only behavior remain unchanged.
115
139
 
116
- ## 0.8.5 (2026-09-06)
140
+ ## 0.8.5 - 2026-09-06
117
141
 
118
142
  - Make the exact public `@hraness/message-like-me@0.8.5` npm package the
119
143
  supported default install, with the same reviewed bytes mirrored in the
@@ -130,7 +154,7 @@
130
154
  - Bound private JSON read allocation to the admitted file size, including
131
155
  short reads and files that grow during inspection.
132
156
 
133
- ## 0.8.4 (2026-09-06)
157
+ ## 0.8.4 - 2026-09-06
134
158
 
135
159
  - Make the exact public `@hraness/message-like-me@0.8.4` npm package the
136
160
  supported default install, with the same reviewed bytes mirrored in the
@@ -145,7 +169,7 @@
145
169
  skip-aware condition, and a terminal admission fails unless verification and
146
170
  provider admission both succeeded.
147
171
 
148
- ## 0.8.3 (2026-09-06)
172
+ ## 0.8.3 - 2026-09-06
149
173
 
150
174
  - Let Beeper users bring a finished private Wrench bundle into the same local
151
175
  evidence corpus as Apple Messages and the other supported sources. The exact
package/README.md CHANGED
@@ -2,31 +2,38 @@
2
2
 
3
3
  [![skills.sh](https://skills.sh/b/hraness/message-like-me)](https://skills.sh/hraness/message-like-me)
4
4
 
5
- Textbutler is a local message assistant for macOS. Its guided terminal and menu
6
- bar help you connect selected iMessage, WhatsApp and Beeper conversations, see
7
- what needs an answer, and review replies before sending them.
8
-
9
- **Current status: source pilot.** Messaging setup, conversation selection,
10
- private contact memory, inbox review and replies you write yourself are
11
- implemented. AI replies require a verified Textbutler bundle with reviewed
12
- composition admission and connect to a separately installed
13
- [xcb](https://github.com/hraness/xcb) native runtime with an explicit subscription
14
- account and model. Textbutler is an MIT-licensed reference application for xcb's
15
- zero-tool generation API; xcb keeps provider credentials and custody. Account
16
- setup, current runtime admission and live verification on your chosen messaging
17
- account and recipient are required before relying on automatic replies. See the
18
- [subscription guide](docs/textbutler/native-subscription.md).
5
+ Textbutler is an AI butler for the iMessage, WhatsApp, and Beeper chats you
6
+ choose on your Mac. Turn it on for one person, and it replies as a clearly
7
+ marked assistant that knows your history with them.
8
+
9
+ **Status:** In development. Textbutler runs from source on a Mac; there is no
10
+ app to download and no published Textbutler package. Without an AI account you
11
+ can connect iMessage, WhatsApp, and Beeper through Ghostget, check your inbox,
12
+ and send replies you write yourself. AI replies also need a local build of
13
+ Textbutler and a Claude Code, Codex, or Devin subscription connected through
14
+ [xcb](https://github.com/hraness/xcb). Automatic replies have worked end to end
15
+ over iMessage in our testing. Try them on your own account,
16
+ especially over WhatsApp or Beeper, before you rely on them.
19
17
 
20
18
  Start with the [guided setup](docs/textbutler/getting-started.md) and
21
19
  [messaging app support](docs/textbutler/messaging-apps.md). Beeper can connect
22
- apps such as Signal, Telegram and Instagram through Ghostget's current text
23
- automation adapter. Its linked apps and account permissions determine what is
24
- available. The [architecture](docs/textbutler/architecture.md) records the
25
- runtime boundaries and remaining qualification work.
26
-
27
- Agents can use the [JSON CLI](docs/textbutler/agent-cli.md) to read and summarize
28
- one conversation, prepare text or media drafts, and send an explicitly
29
- authorized message. Each connection reports its available actions.
20
+ apps such as Signal, Telegram, and Instagram through Ghostget, for text only;
21
+ its linked apps and account permissions decide what is available. The
22
+ [subscription guide](docs/textbutler/native-subscription.md) covers AI replies,
23
+ and the [architecture](docs/textbutler/architecture.md) describes how the parts
24
+ fit together and what still needs live testing.
25
+
26
+ Agents can use the [JSON CLI](docs/textbutler/agent-cli.md) to list
27
+ conversations, read and summarize history, prepare text or media drafts, and
28
+ send an explicitly authorized message, using the same staged actions the butler
29
+ uses on its own. Each connection reports its available actions.
30
+
31
+ Textbutler keeps each contact's context in files you can read and edit, marks
32
+ its own replies by default, and answers only after you turn a contact on and
33
+ resume the butler: the design every Hraness project shares. [The thread through
34
+ hraness](https://hraness.com/writing/the-thread-through-hraness) follows that
35
+ design across the projects, and the [ALGAL
36
+ vision](https://algal.computer/docs/vision/) states the bet behind it.
30
37
 
31
38
  ## Open the guided terminal
32
39
 
@@ -45,12 +52,16 @@ contacts have automatic replies off. Setup and conversation selection never
45
52
  send a message.
46
53
 
47
54
  For AI replies, build and install with `bun run textbutler:install`, then run
48
- `~/.local/bin/textbutler`. The builder requires the reviewed composition receipt
49
- to match current source bytes and both contact capability profiles. A source
50
- daemon has no embedded composition admission and cannot enable subscription
51
- inference. Source commands remain useful for setup and manual reply controls.
52
-
53
- Textbutler's source is MIT licensed and its new packages remain unpublished.
55
+ `~/.local/bin/textbutler`. The installer refuses to build unless the source
56
+ files it checks and both contact permission profiles match the reviewed record
57
+ in `qualification/`. Running from source never writes AI replies; source
58
+ commands handle setup and the replies you write yourself. xcb keeps your AI
59
+ sign-in, and the model gets no tools of its own. Before you rely on automatic
60
+ replies, finish account setup and test with a recipient you trust on the
61
+ messaging account you'll use.
62
+
63
+ Textbutler's source is MIT licensed, and it also serves as an example app for
64
+ developers building on xcb's generation API. Its new packages are unpublished.
54
65
  The published Message Like Me package documented below installs the legacy
55
66
  history tools, not Textbutler. The website at
56
67
  [textbutler.app](https://textbutler.app) is informational and receives no private
@@ -58,9 +69,9 @@ messages or contact folders.
58
69
 
59
70
  ## Run the Textbutler menu companion
60
71
 
61
- The native companion downloads and verifies a pinned prebuilt
62
- desktop-foundation runner on first start. No local Rust build is needed. Start
63
- it from the terminal's **Menu bar companion** action or run:
72
+ On first start, the menu bar companion downloads a prebuilt desktop-foundation
73
+ runner and checks it against a pinned hash, so you don't need a local Rust
74
+ build. Start it from the terminal's **Menu bar companion** action or run:
64
75
 
65
76
  ```sh
66
77
  bun run textbutler menubar start
@@ -120,9 +131,10 @@ sends plain text. The review shows the actual outgoing text. The send journal
120
131
  retains provider acceptance IDs when available; see the messaging guide for
121
132
  connection-specific attribution and delivery limits.
122
133
 
123
- Automatic replies remain a separate choice: they require a qualified agent,
124
- a ready messaging connection, explicit contact activation and global resume.
125
- Keep them paused until those requirements and the relevant live checks pass.
134
+ Automatic replies are a separate step. They need an AI account that passes
135
+ `providers check`, a working messaging connection, the contact turned on with
136
+ `contacts enable`, and the butler resumed with `resume`. Leave them paused until
137
+ all of that works and you've tested with a real recipient.
126
138
 
127
139
  ## Legacy Message Like Me history tools
128
140
 
@@ -167,7 +179,7 @@ Message Like Me requires Bun 1.3.14 or newer. Install the exact public npm
167
179
  package, then install both bundled Agent Skills:
168
180
 
169
181
  ```sh
170
- bun add --global @hraness/message-like-me@0.8.20
182
+ bun add --global @hraness/message-like-me@0.8.22
171
183
  messagelikeme skill install
172
184
  ```
173
185
 
@@ -909,8 +921,8 @@ Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a change.
909
921
  The canonical repository is
910
922
  [`hraness/textbutler`](https://github.com/hraness/textbutler).
911
923
  The informational project page is
912
- [`messagelikeme.com`](https://messagelikeme.com). The CLI does not connect to
913
- the site, and the site never receives message or contact data.
924
+ [textbutler.app](https://textbutler.app). The CLI does not connect to the site,
925
+ and the site never receives message or contact data.
914
926
 
915
927
  ## License
916
928
 
package/SECURITY.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Security
2
2
 
3
3
  Report suspected vulnerabilities privately through
4
- [GitHub Security Advisories](https://github.com/hraness/message-like-me/security/advisories/new).
4
+ [GitHub Security Advisories](https://github.com/hraness/textbutler/security/advisories/new).
5
5
  Do not open a public issue containing a message, handle, contact name, group
6
6
  title, attachment, local path, profile, study or Ensoul packet, installation key, or
7
7
  database detail that could identify a person.
package/dist/cli.js CHANGED
@@ -15453,7 +15453,7 @@ function commandFailure(cause3) {
15453
15453
  function translateIMessageError(error) {
15454
15454
  const code = error.code;
15455
15455
  if (code === "EACCES" || code === "EPERM" || code === "permission") {
15456
- throw new CliError("permission", "Messages data is not readable. Grant Full Disk Access to this terminal or agent host, then retry.", { cause: error });
15456
+ throw new CliError("permission", "Message Like Me can't read your Messages data: macOS access is off for the app running this command. Turn on your terminal or agent app in System Settings \u203A Privacy & Security \u203A Full Disk Access (x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles), then retry.", { cause: error });
15457
15457
  }
15458
15458
  if (code === "ENOENT") {
15459
15459
  throw new CliError("not-found", "The selected Messages database does not exist", { cause: error });
@@ -15463,7 +15463,7 @@ function translateIMessageError(error) {
15463
15463
  function translateContactsError(error) {
15464
15464
  const code = error.code;
15465
15465
  if (code === "EACCES" || code === "EPERM") {
15466
- throw new CliError("permission", "Contacts data is not readable. Grant Full Disk Access to this terminal or agent host, then retry.", { cause: error });
15466
+ throw new CliError("permission", "Message Like Me can't read your Contacts data: macOS access is off for the app running this command. Turn on your terminal or agent app in System Settings \u203A Privacy & Security \u203A Full Disk Access (x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles), then retry.", { cause: error });
15467
15467
  }
15468
15468
  if (code === "ENOENT") {
15469
15469
  throw new CliError("not-found", "The selected AddressBook source does not exist", { cause: error });
@@ -25088,14 +25088,14 @@ function commandPlatformLive(io, cleanupFailure) {
25088
25088
  import { isAbsolute as isAbsolute7, resolve as resolve8 } from "path";
25089
25089
 
25090
25090
  // src/version.ts
25091
- var MESSAGE_LIKE_ME_VERSION = "0.8.20";
25091
+ var MESSAGE_LIKE_ME_VERSION = "0.8.22";
25092
25092
 
25093
25093
  // src/command-input.ts
25094
25094
  var HELP = `Message Like Me ${MESSAGE_LIKE_ME_VERSION}
25095
25095
 
25096
25096
  Usage:
25097
- messagelikeme support [protocol --json|offer --json|shown ID|release ID|dismiss|snooze|enable|status --json]
25098
- Optional support; agents use support protocol --json at closeout.
25097
+ messagelikeme support [--json]
25098
+ Optional ways to support Message Like Me.
25099
25099
  messagelikeme [--data-dir PATH] init [--json]
25100
25100
  messagelikeme [--data-dir PATH] ingest imessage [--database PATH] [--json]
25101
25101
  messagelikeme [--data-dir PATH] ingest bundle --input ABS_PATH
@@ -25139,6 +25139,8 @@ Message Like Me reads caller-owned macOS Messages, official X archives,
25139
25139
  optional Contacts data, and strict private local message bundles, then stores
25140
25140
  private analysis locally. It has no network, account, AI-provider, or
25141
25141
  message-sending surface.
25142
+
25143
+ Optional support: messagelikeme support \xB7 Turn off: HRANESS_SUPPORT=off
25142
25144
  `;
25143
25145
  function metricOptions(parsed) {
25144
25146
  return {
@@ -27844,19 +27846,6 @@ function runClosed(effect2) {
27844
27846
  return exports_Effect.runPromise(effect2);
27845
27847
  }
27846
27848
 
27847
- // src/cli-intro.ts
27848
- function terminalIntro(terminal) {
27849
- if (terminal.isTTY !== true || terminal.term === "dumb" || (terminal.columns ?? 80) < 48)
27850
- return "";
27851
- return ` _|_
27852
- .----- . textbutler
27853
- | o o | A little help in your conversations.
27854
- | === |
27855
- '-----'
27856
-
27857
- `;
27858
- }
27859
-
27860
27849
  // src/io.ts
27861
27850
  var processIo = {
27862
27851
  stdout: (text3) => process.stdout.write(text3),
@@ -27880,12 +27869,7 @@ async function main(argv, io = processIo, supportEnv) {
27880
27869
  try {
27881
27870
  if (argv[0] === "support")
27882
27871
  return await runProductSupportCommand(argv.slice(1), io, supportEnv === undefined ? {} : { env: supportEnv });
27883
- const rootHelp = argv.length === 0 || argv.length === 1 && argv[0] === "--help";
27884
- const output = rootHelp && io === processIo ? {
27885
- ...io,
27886
- stdout: (text3) => io.stdout((text3 === HELP ? terminalIntro({ isTTY: process.stdout.isTTY, columns: process.stdout.columns, term: process.env.TERM }) : "") + text3)
27887
- } : io;
27888
- await runCommand(argv, output);
27872
+ await runCommand(argv, io);
27889
27873
  return 0;
27890
27874
  } catch (error) {
27891
27875
  io.stderr(`${errorMessage(error)}