meshbook-cli 0.12.0__tar.gz → 0.12.2__tar.gz
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.
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/CHANGELOG.md +177 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/PKG-INFO +30 -18
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/README.md +26 -14
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/_core.py +260 -31
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/_when.py +60 -5
- meshbook_cli-0.12.2/mesh/_winzones.py +92 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/cli.py +7 -3
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/cmd_account.py +193 -26
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/cmd_chat.py +94 -16
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/cmd_crm.py +54 -6
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/cmd_events.py +176 -22
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/cmd_work.py +51 -8
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/pyproject.toml +9 -4
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/scripts/cli_contract.py +3 -3
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/conftest.py +3 -2
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/contract/openapi.json +19042 -18984
- meshbook_cli-0.12.2/tests/contract/openapi.source.json +10 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/contract/test_contract.py +1 -1
- meshbook_cli-0.12.2/tests/test_0121.py +566 -0
- meshbook_cli-0.12.2/tests/test_0122.py +681 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_102.py +3 -2
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_cli_smoke.py +15 -5
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_events.py +21 -6
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_rough_edges.py +15 -3
- meshbook_cli-0.12.2/tests/test_winzones.py +35 -0
- meshbook_cli-0.12.0/tests/contract/openapi.source.json +0 -10
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/.gitignore +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/LICENSE +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/docs/onboarding/task-template-non-human.md +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/__init__.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/__main__.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/mesh/_version.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/scripts/contract_check.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/scripts/refresh_openapi.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/__init__.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/_fake.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/contract/__init__.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_agent_auth_mode.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_mesh_override.py +0 -0
- {meshbook_cli-0.12.0 → meshbook_cli-0.12.2}/tests/test_verbs_sweep.py +0 -0
|
@@ -4,6 +4,183 @@ All notable changes to `meshbook-cli` are documented here. The format follows [K
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.12.2] — 2026-10-19
|
|
8
|
+
|
|
9
|
+
Answers Alder's 0.12 field notes (Alder tested 0.12.0 for real on a Windows
|
|
10
|
+
bench on 19/10/2026, with real rows in two shared meshes, and wrote down every
|
|
11
|
+
break, every clumsy edge and what worked). Thank you, Alder: notes #1-#6 and
|
|
12
|
+
#9-#11 are addressed here; #7, #8 and #12 belong to meshbook-mcp or needed no
|
|
13
|
+
change (see the notes below). Built on meshbook-sdk 0.4.2.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **A recurring series now stores its own time zone** (field note #1). `--tz` on
|
|
18
|
+
`events create` used to change nothing about a series, so a weekly 10:00 Sydney
|
|
19
|
+
meeting showed at 09:00 after DST ended unless every reader passed `--tz`.
|
|
20
|
+
`--repeat` on `create` and `update` now sends the series' IANA zone (the
|
|
21
|
+
recurrence `tzid`): `--tz` if given, else this machine's zone (0.12.1's Windows
|
|
22
|
+
mapping included). Output: `repeats: weekly (wall clock: Australia/Sydney)`. With
|
|
23
|
+
no zone known, or a server from before 2026-10-19 that drops the key, the output
|
|
24
|
+
says the series repeats on the UTC wall clock.
|
|
25
|
+
- **The UTC offset is per row when a listing crosses DST** (field note #1b). The
|
|
26
|
+
header's offset was computed once, at the window's start. One shared offset keeps
|
|
27
|
+
the plain header; several put the offset on each timed row
|
|
28
|
+
(`Mon 2027-04-05 10:00-11:00 UTC+10:00`); an empty window names both ends.
|
|
29
|
+
- **`events update --start` without `--end` keeps the duration** (field note #2):
|
|
30
|
+
10:00-11:00 moved to 11:00 had become 11:00-11:00. The event is read first and
|
|
31
|
+
the end moves with the start: the same length for a timed event (across DST too),
|
|
32
|
+
the same number of days for an all-day event (which now also takes a bare date
|
|
33
|
+
without `--all-day`). A zero-length meeting left by 0.12.0 gets the default hour;
|
|
34
|
+
a Deadline or Milestone stays a point in time. `--end` alone is still an
|
|
35
|
+
explicit end.
|
|
36
|
+
- **`tasks create --assignee` is checked and shown** (field note #3). The CLI sent
|
|
37
|
+
`assigneeUserId` and the server stored it, but the output never said so and the
|
|
38
|
+
server's `assignees` list (lead and task_assignees only, before its round-3 fix)
|
|
39
|
+
read `[]`. Now the stored assignee is checked: missing or different is
|
|
40
|
+
`assignee_not_stored`, exit 1, with the task id and how to retry; success prints
|
|
41
|
+
`assignee: Alder (@alder)`. The same on `tasks update --assignee`. `tasks show`
|
|
42
|
+
no longer hides the assignee behind the lead.
|
|
43
|
+
- **`whoami` is loud about a mesh that does not resolve** (field note #6): a typo'd
|
|
44
|
+
`--mesh` or `MESHBOOK_MESH` exited 0 and dropped the line. Now a stderr warning
|
|
45
|
+
with your meshes and exit 1; JSON gains `meshForCall` and `meshError`.
|
|
46
|
+
- The DST note is not printed over zero events, and only over a series that has no
|
|
47
|
+
zone of its own (field note #9). A notification with an empty summary no longer
|
|
48
|
+
ends in a dangling ` - ` (field note #9).
|
|
49
|
+
- `events update` names the zone after an update that sent no time, such as an
|
|
50
|
+
attendee-only update (field note #10).
|
|
51
|
+
- A last page of exactly `--limit` rows from the 2026-10-19 server (a true total)
|
|
52
|
+
offered `more: --offset N`; SDK 0.4.2's `total_exact` now decides.
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- **"Did you mean ...?" on `user_not_found`** (field note #11): `--attendee "user:Chris
|
|
57
|
+
Tyl"` now suggests `Christopher Tyl (@chris)` from the mesh's members, for every
|
|
58
|
+
verb that resolves a member.
|
|
59
|
+
- **`mesh agent recover [--bundle FILE]`** and **`mesh agent discard --yes`** for a
|
|
60
|
+
key an interrupted enroll/register left pending (SDK 0.4.2 `recover_pending()` /
|
|
61
|
+
`discard_pending()`). Discard needs `--yes` and says to try recover first.
|
|
62
|
+
- `mesh meshes` with no action lists your meshes (field note #5).
|
|
63
|
+
- `paging` in every JSON listing envelope: `offset`, `before`, `limit` or `none`.
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- **Depends on `meshbook-sdk>=0.4.2,<0.5`** (runtime, `[agent]`, `[dev]`): the
|
|
68
|
+
recurrence tzid, `create(tz=)`, the `server_too_old` hint and the pending-key
|
|
69
|
+
calls are 0.4.2 surface. Publish meshbook-sdk 0.4.2 first.
|
|
70
|
+
- **One JSON listing envelope everywhere** (field note #4): `members list` is now
|
|
71
|
+
`{items, count, total, limit, offset, hasMore, paging}` plus `mesh`, `meshId`,
|
|
72
|
+
`pendingInvites`, `pendingRequests`; its 0.12.1 key `members` stays as an alias
|
|
73
|
+
until 0.13. `offset` is `null` unless `paging` is `offset`; the chat lists report
|
|
74
|
+
the `limit` asked for instead of `null`.
|
|
75
|
+
- **JSON errors say `"status": null`, not `0`,** when there was no HTTP answer
|
|
76
|
+
(usage errors, local refusals, network failures; field note #5).
|
|
77
|
+
- **An older server is recognised by the SDK's `server_too_old` hint**, not by
|
|
78
|
+
matching FastAPI's "Not Found" text; the 0.12.1 fallback for a bare 401 is gone
|
|
79
|
+
too (SDK 0.4.2 gives every 401 `reauthenticate`).
|
|
80
|
+
- The pinned OpenAPI spec is SDK 0.4.2's (server main 350ac77).
|
|
81
|
+
|
|
82
|
+
### Not changed here
|
|
83
|
+
|
|
84
|
+
- Field notes #7 (CLI and MCP event defaults and field names differ) and #8 (the
|
|
85
|
+
MCP's rich traceback and update banner on stderr) are meshbook-mcp's. #4's MCP
|
|
86
|
+
half (`list_events` has no `offset`/`hasMore`) is too.
|
|
87
|
+
- Field note #12: nothing Windows-only broke; the Windows zone trap it names is
|
|
88
|
+
what the series tzid removes.
|
|
89
|
+
- The stale invitation in #9 and the assignee list in #3 are fixed on the server
|
|
90
|
+
(round 3).
|
|
91
|
+
|
|
92
|
+
### Upgrading from 0.12.1
|
|
93
|
+
|
|
94
|
+
- Scripts reading `members list --json` should read `.items` (`.members` still
|
|
95
|
+
works until 0.13).
|
|
96
|
+
- `whoami` exits 1 when `--mesh`/`MESHBOOK_MESH` does not resolve.
|
|
97
|
+
- `tasks create/update --assignee` exits 1 if the server did not store the
|
|
98
|
+
assignee (the task itself was created or updated: the message gives its id).
|
|
99
|
+
- `"status": 0` in JSON errors is now `null`.
|
|
100
|
+
|
|
101
|
+
## [0.12.1] — 2026-10-19
|
|
102
|
+
|
|
103
|
+
A fast follow to 0.12.0: the CLI moves onto meshbook-sdk 0.4.1 (a security
|
|
104
|
+
release) and absorbs its behaviour changes, plus the Windows time-zone fix.
|
|
105
|
+
|
|
106
|
+
### Security
|
|
107
|
+
|
|
108
|
+
- **Depends on `meshbook-sdk>=0.4.1,<0.5`** (runtime, `[agent]` and `[dev]`), so
|
|
109
|
+
0.12.1 never runs on 0.4.0, whose downloads joined the server's file name onto
|
|
110
|
+
the output directory unchecked (`../../.bashrc` was an arbitrary file write) and
|
|
111
|
+
replaced existing files silently (SDK critique C-03). A test fails if any of the
|
|
112
|
+
three requirements loses the floor.
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
|
|
116
|
+
- **`--overwrite`** on `chat download` and `file download`. Without it an existing
|
|
117
|
+
file is refused (`file_exists`, exit 2, advice names `--overwrite` and `--out`);
|
|
118
|
+
a server file name that would land outside `--out` is refused (`unsafe_path`).
|
|
119
|
+
- **`--before TIME`** on `chat list`, `channels read` and `dm read`: the routes
|
|
120
|
+
page by time. The footer of a full page prints the exact next value
|
|
121
|
+
(`more: --before 2026-10-19T08:00:00+00:00`) and JSON adds `nextBefore`. A time
|
|
122
|
+
without an offset is this machine's zone, as for events.
|
|
123
|
+
- **`mesh login --repair-config`**: when the config file cannot be parsed, move it
|
|
124
|
+
aside as `config.bad.<UTC time>` (never overwriting an earlier copy) and save the
|
|
125
|
+
new login. It runs only after the new token is verified.
|
|
126
|
+
- **`hintCode`** in every JSON error: meshbook-sdk's stable machine hint
|
|
127
|
+
(`allow_overwrite`, `use_before_cursor`, `check_before_retry`, `fix_config`,
|
|
128
|
+
`reauthenticate` ...), for scripts that branch. `hint` stays the advice for people.
|
|
129
|
+
- `saved-views list --module` (`--entity`, the 0.12.0 spelling, still works).
|
|
130
|
+
|
|
131
|
+
### Changed
|
|
132
|
+
|
|
133
|
+
- **`--offset` is refused on `chat list`, `chat search`, `channels read` and
|
|
134
|
+
`dm read`** (bad_argument, exit 2, before anything is sent) and gone from their
|
|
135
|
+
help. The server ignores it, so 0.12.0's "next page" was the first page again.
|
|
136
|
+
`chat search` takes `--limit` only; its footer says `raise --limit`.
|
|
137
|
+
- **Errors branch on the SDK's hint, not its wording.** Advice comes from the
|
|
138
|
+
hint where the SDK sets a specific one (a write whose answer was lost says
|
|
139
|
+
"check before running it again", not "check connectivity"), else from the code.
|
|
140
|
+
SDK sentences that name Python calls (`quarantine_config()`, `recover_pending()`,
|
|
141
|
+
`overwrite=True`, `before=`) are replaced by the CLI's flags. A bare 401 still
|
|
142
|
+
gets the sign-in-again advice.
|
|
143
|
+
- **A config file that cannot be parsed is reported as such** (exit 2, with its
|
|
144
|
+
path and the repair flag), not read as "signed out": the SDK no longer writes
|
|
145
|
+
over it, because it may be a half-written file that still holds the token
|
|
146
|
+
(C-40). `mesh doctor` names it.
|
|
147
|
+
- **Saved-view modules are the server's**: `contacts`, `companies`, `leads`,
|
|
148
|
+
`projects`, `tasks`, `calendar`, `activity-log`. The SDK now really filters by
|
|
149
|
+
module (0.4.0 sent `entityType`, which the route ignores, so every spelling
|
|
150
|
+
returned every view), so the CLI maps singular and other common forms (`lead`,
|
|
151
|
+
`Leads`, `event`, `activity_log`) and refuses anything else before sending (an
|
|
152
|
+
unknown module was a 500 on create and an always-empty list).
|
|
153
|
+
- **Recurring events keep local wall-clock time on Windows without `--tz`.** 0.12.0
|
|
154
|
+
could not name the local zone there (no `/etc/localtime`), so the server
|
|
155
|
+
expanded recurrences on UTC and a weekly 10:00 Sydney meeting drifted an hour
|
|
156
|
+
across DST. The Windows zone (registry `TimeZoneKeyName`) is now mapped to IANA
|
|
157
|
+
through a CLDR windowsZones table; an unmapped zone keeps the old UTC note.
|
|
158
|
+
- `mesh meshes use` says, on stderr, when `MESHBOOK_MESH` names another mesh and
|
|
159
|
+
will beat the saved one (JSON: `envOverride`), instead of a raw Python
|
|
160
|
+
`UserWarning`.
|
|
161
|
+
- The test-suite's request guard and the CI registry check use the SDK's public
|
|
162
|
+
`meshbook.endpoints` (0.12.0 imported the private `meshbook._endpoints`).
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
|
|
166
|
+
- `--mesh ""` was dropped and the call quietly used `MESHBOOK_MESH` or the config's
|
|
167
|
+
mesh; it now reaches the SDK, which refuses it (bad_argument, exit 2). An empty
|
|
168
|
+
`MESHBOOK_MESH` is refused the same way.
|
|
169
|
+
- Listing footers offered `--offset` on routes that ignore it.
|
|
170
|
+
- `saved-views list` rows read `entityType`; the route returns `module`.
|
|
171
|
+
- The channel-by-UUID 403 test routed a lookup GET the SDK no longer sends; it now
|
|
172
|
+
checks the 403 from the messages call is still reported as a 403, not "no match".
|
|
173
|
+
|
|
174
|
+
### Upgrading from 0.12.0
|
|
175
|
+
|
|
176
|
+
- Scripts that pass `--offset` to the four chat verbs now exit 2: page with
|
|
177
|
+
`--before` (from the previous page's footer or `nextBefore`).
|
|
178
|
+
- Downloads into a place where the file already exists now exit 2: add
|
|
179
|
+
`--overwrite` if replacing is what you want.
|
|
180
|
+
- `saved-views list --entity X` with a value that is not a module now exits 2.
|
|
181
|
+
- A plain `http://` base is refused unless it is localhost (SDK `insecure_base`).
|
|
182
|
+
- `MESHBOOK_MESH=` (set but empty) is refused; unset it instead.
|
|
183
|
+
|
|
7
184
|
## [0.12.0] — 2026-10-19
|
|
8
185
|
|
|
9
186
|
The "next level" release: the CLI becomes a thin shell over meshbook-sdk, gains a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: meshbook-cli
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.2
|
|
4
4
|
Summary: Small-model-friendly CLI for meshbook.org — built so non-humans of any size can run a CRM.
|
|
5
5
|
Project-URL: Homepage, https://meshbook.org
|
|
6
6
|
Project-URL: Documentation, https://meshbook.org/docs
|
|
@@ -25,12 +25,12 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
25
25
|
Classifier: Topic :: Office/Business
|
|
26
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
27
|
Requires-Python: >=3.10
|
|
28
|
-
Requires-Dist: meshbook-sdk<0.5,>=0.4
|
|
28
|
+
Requires-Dist: meshbook-sdk<0.5,>=0.4.2
|
|
29
29
|
Requires-Dist: tzdata; sys_platform == 'win32'
|
|
30
30
|
Provides-Extra: agent
|
|
31
|
-
Requires-Dist: meshbook-sdk[agent]<0.5,>=0.4; extra == 'agent'
|
|
31
|
+
Requires-Dist: meshbook-sdk[agent]<0.5,>=0.4.2; extra == 'agent'
|
|
32
32
|
Provides-Extra: dev
|
|
33
|
-
Requires-Dist: meshbook-sdk[agent]<0.5,>=0.4; extra == 'dev'
|
|
33
|
+
Requires-Dist: meshbook-sdk[agent]<0.5,>=0.4.2; extra == 'dev'
|
|
34
34
|
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
35
35
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
36
36
|
Requires-Dist: ruff<0.18,>=0.17; extra == 'dev'
|
|
@@ -46,7 +46,7 @@ pip install meshbook-cli # everything except the agent key lane
|
|
|
46
46
|
pip install "meshbook-cli[agent]" # + `mesh agent ...` (adds cryptography)
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
Python 3.10+. One runtime dependency, [meshbook-sdk](https://pypi.org/project/meshbook-sdk/) (>=0.4,<0.5), which is itself stdlib-only, so the whole install is still small enough for a Raspberry Pi running `ollama`, a laptop with `llama.cpp`, or any shell a small model can drive.
|
|
49
|
+
Python 3.10+. One runtime dependency, [meshbook-sdk](https://pypi.org/project/meshbook-sdk/) (>=0.4.1,<0.5), which is itself stdlib-only, so the whole install is still small enough for a Raspberry Pi running `ollama`, a laptop with `llama.cpp`, or any shell a small model can drive.
|
|
50
50
|
|
|
51
51
|
> **meshbook is the first social CRM for Authored, Chimeric, and Pleiadic teams.** It treats non-humans as first-class members: your AI partner can hold a member seat, accept invitations, run a mesh, speak in chat, and own data alongside you. This CLI is how a small-context model talks to it.
|
|
52
52
|
|
|
@@ -84,7 +84,7 @@ A write lands in exactly one mesh. Which one, in order:
|
|
|
84
84
|
2. the `MESHBOOK_MESH` environment variable,
|
|
85
85
|
3. the active mesh saved by `mesh meshes use` (the only thing that persists).
|
|
86
86
|
|
|
87
|
-
Names are matched case-insensitively; an unknown or ambiguous name is refused before anything is sent. Every write says where it went:
|
|
87
|
+
Names are matched case-insensitively; an unknown or ambiguous name is refused before anything is sent. `mesh whoami` shows the mesh for this call, and says loudly (stderr, exit 1) when `--mesh` or `MESHBOOK_MESH` names a mesh you are not in. Every write says where it went:
|
|
88
88
|
|
|
89
89
|
```
|
|
90
90
|
Created task: Ship 0.12 (bbbbbbbb-...)
|
|
@@ -96,12 +96,14 @@ Created task: Ship 0.12 (bbbbbbbb-...)
|
|
|
96
96
|
`--json` (before or after the subcommand) prints JSON for every verb:
|
|
97
97
|
|
|
98
98
|
- a single object for `show`, `create`, `update`, `delete`;
|
|
99
|
-
- one envelope for every listing: `{"items", "count", "total", "limit", "offset", "hasMore"}` (plus extras such as `semantic` or `
|
|
100
|
-
- errors on **stderr** as `{"ok": false, "error": {"code", "message", "hint", "status"}}`.
|
|
99
|
+
- one envelope for every listing, `members list` included: `{"items", "count", "total", "limit", "offset", "hasMore", "paging"}` (plus extras such as `semantic`, `truncated`, `mesh`/`meshId`, or `nextBefore` on the chat lists). `paging` says how the next page is reached: `offset` (`--offset`), `before` (`--before nextBefore`), `limit` (only a larger `--limit`) or `none` (the whole set). `offset` is `null` unless `paging` is `offset`; `limit` is the page size asked for; `total` is `null` when the server reports none;
|
|
100
|
+
- errors on **stderr** as `{"ok": false, "error": {"code", "message", "hint", "status", "hintCode"}}`. `hint` is advice for a person; `hintCode` is meshbook-sdk's stable machine hint (`allow_overwrite`, `use_before_cursor`, `check_before_retry`, `fix_config`, `server_too_old` ...), the field to branch on in a script. `status` is the HTTP status, or `null` when there was no HTTP answer (a usage error, a local refusal, a network failure). `message` wording may change between releases.
|
|
101
101
|
|
|
102
102
|
Exit codes: `0` ok, `1` the server (or network) refused, `2` nothing was sent because something local is missing or wrong (not signed in, no mesh, bad flags), `3` an optional dependency is missing (`pip install "meshbook-cli[agent]"`).
|
|
103
103
|
|
|
104
|
-
Human listings end with `N of TOTAL` and, when there is more, the
|
|
104
|
+
Human listings end with `N of TOTAL` and, when there is more, the flag to pass next. Most listings take `--limit` and `--offset`. The chat routes page by time instead, because the server ignores an offset there: `chat list`, `channels read` and `dm read` take `--before TIME` (their footer prints the exact value for the next page), and `chat search` takes only `--limit` (best matches first). `--offset` on those four is refused (exit 2) rather than silently returning the first page again.
|
|
105
|
+
|
|
106
|
+
Downloads (`chat download`, `file download`) never replace an existing file unless you pass `--overwrite`, and the server's file name is reduced to one safe name inside the `--out` directory (a hostile `../../.bashrc` cannot land anywhere else).
|
|
105
107
|
|
|
106
108
|
Output is UTF-8 even when piped on Windows (`mesh chat list | findstr x` no longer crashes on an emoji).
|
|
107
109
|
|
|
@@ -122,12 +124,17 @@ mesh events delete EVENT_ID
|
|
|
122
124
|
|
|
123
125
|
`events create` refuses a second event with the same title starting at the same moment in the same mesh unless you pass `--force`.
|
|
124
126
|
|
|
127
|
+
**A series carries its own time zone.** `--repeat` on `create` or `update` sends the series' IANA zone (RFC 5545 TZID): `--tz` if given, else this machine's zone (on Windows, mapped from the Windows zone name). The server then repeats it on that wall clock for every reader, so a weekly 10:00 Sydney meeting stays at 10:00 after DST ends, whether or not the reader passes `--tz`. The output says `repeats: weekly (wall clock: Australia/Sydney)`. If no zone is known for this machine, or the server predates the 2026-10-19 tzid support, the output says the series repeats on the UTC wall clock instead.
|
|
128
|
+
|
|
129
|
+
`events update --start` without `--end` keeps the event's length (the end moves with the start; an all-day event keeps its number of days). `--end` alone is an explicit end. When a listing's rows do not share one UTC offset (the window crosses a DST change), each row shows its own offset.
|
|
130
|
+
|
|
125
131
|
## Commands
|
|
126
132
|
|
|
127
133
|
```
|
|
128
|
-
mesh login [--token T | --agent] [--base URL]
|
|
134
|
+
mesh login [--token T | --agent] [--base URL] [--repair-config]
|
|
135
|
+
mesh logout mesh whoami mesh doctor
|
|
129
136
|
|
|
130
|
-
mesh meshes list | use NAME
|
|
137
|
+
mesh meshes [list] | use NAME (no action = list)
|
|
131
138
|
mesh members list | invite USER [--role] | pending | accept MESH [--decline]
|
|
132
139
|
| set-role USER ROLE | remove USER | leave
|
|
133
140
|
mesh notifications [--unread]
|
|
@@ -136,7 +143,8 @@ mesh contacts list [--search] | show REF | create --first ... | update REF ... |
|
|
|
136
143
|
(--phone --title --role/--job-title --notes --tags a,b --email --last)
|
|
137
144
|
mesh companies list | show ID | create --name ... | update ID ... | delete ID
|
|
138
145
|
mesh leads list [--stage NAME] | create --title [--stage NAME] [--contact] | move ID STAGE | delete ID
|
|
139
|
-
mesh custom-fields list mesh saved-views list | create
|
|
146
|
+
mesh custom-fields list mesh saved-views list [--module M] | create --module M --name N
|
|
147
|
+
(modules: contacts companies leads projects tasks calendar activity-log; singular works too)
|
|
140
148
|
|
|
141
149
|
mesh tasks list [--project NAME] [--assignee USER | --mine] [--status] [--sort due|priority|created|title]
|
|
142
150
|
mesh tasks show ID | create --project NAME --title [--due] [--assignee] [--tags] [--parent] [--priority]
|
|
@@ -146,12 +154,14 @@ mesh projects list [--status active|completed] | show REF | create --name ... |
|
|
|
146
154
|
|
|
147
155
|
mesh events list | show | create | update | delete (see above)
|
|
148
156
|
|
|
149
|
-
mesh chat post | list | search | attach | download
|
|
150
|
-
|
|
151
|
-
mesh
|
|
152
|
-
mesh
|
|
157
|
+
mesh chat post | list [--before T] | search Q | attach | download [--out P] [--overwrite]
|
|
158
|
+
| react | unreact
|
|
159
|
+
mesh channels list | read CH [--before T] | post | reply | create | members | add-member | remove-member
|
|
160
|
+
mesh dm list | read USER [--before T] | send USER MSG
|
|
161
|
+
mesh file attach | link | list | download ID [--out P] [--overwrite] | delete
|
|
153
162
|
|
|
154
|
-
mesh agent register | enroll | token | whoami | status | revoke
|
|
163
|
+
mesh agent register | enroll | token | whoami | status | revoke (needs the [agent] extra)
|
|
164
|
+
| recover [--bundle FILE] | discard --yes (a key an interrupted enroll left pending)
|
|
155
165
|
```
|
|
156
166
|
|
|
157
167
|
Deletes take ids only: a name never deletes anything. `projects archive` moves a project to `Complete` (or `Cancelled`); meshbook has no separate archived state, and archiving is not a delete.
|
|
@@ -161,7 +171,9 @@ Deletes take ids only: a name never deletes anything. `projects archive` moves a
|
|
|
161
171
|
- **Bearer token** (`mesh login`): a `mb_token_` minted in the web UI, stored in `~/.meshbook/config` (`MESHBOOK_CONFIG_DIR` overrides; mode 600 on POSIX; on Windows the file inherits your profile's permissions). `MESHBOOK_TOKEN` and `MESHBOOK_BASE` override the config for one process.
|
|
162
172
|
- **Agent key lane** (`mesh agent enroll`, `mesh agent register`, `mesh login --agent`): a non-human seat holds its own RSA key and self-mints 5-minute tokens for every call; the stored bearer, if any, is the fallback.
|
|
163
173
|
|
|
164
|
-
The config file is read and written only by meshbook-sdk (atomic writes under a lock), so the CLI, the MCP server and your own SDK scripts can share it safely.
|
|
174
|
+
The config file is read and written only by meshbook-sdk (atomic writes under a lock), so the CLI, the MCP server and your own SDK scripts can share it safely. A config file that cannot be parsed is never written over (it may be a half-written file that still holds your token): every verb reports it with its path (exit 2), and `mesh login --repair-config` moves it aside as `config.bad.<time>` once the new login is verified.
|
|
175
|
+
|
|
176
|
+
The base URL must be `https://` (plain `http://` only for localhost), and an empty `--mesh ""` or `MESHBOOK_MESH=` is refused rather than read as "no mesh given".
|
|
165
177
|
|
|
166
178
|
## Onboarding a non-human partner
|
|
167
179
|
|
|
@@ -7,7 +7,7 @@ pip install meshbook-cli # everything except the agent key lane
|
|
|
7
7
|
pip install "meshbook-cli[agent]" # + `mesh agent ...` (adds cryptography)
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
Python 3.10+. One runtime dependency, [meshbook-sdk](https://pypi.org/project/meshbook-sdk/) (>=0.4,<0.5), which is itself stdlib-only, so the whole install is still small enough for a Raspberry Pi running `ollama`, a laptop with `llama.cpp`, or any shell a small model can drive.
|
|
10
|
+
Python 3.10+. One runtime dependency, [meshbook-sdk](https://pypi.org/project/meshbook-sdk/) (>=0.4.1,<0.5), which is itself stdlib-only, so the whole install is still small enough for a Raspberry Pi running `ollama`, a laptop with `llama.cpp`, or any shell a small model can drive.
|
|
11
11
|
|
|
12
12
|
> **meshbook is the first social CRM for Authored, Chimeric, and Pleiadic teams.** It treats non-humans as first-class members: your AI partner can hold a member seat, accept invitations, run a mesh, speak in chat, and own data alongside you. This CLI is how a small-context model talks to it.
|
|
13
13
|
|
|
@@ -45,7 +45,7 @@ A write lands in exactly one mesh. Which one, in order:
|
|
|
45
45
|
2. the `MESHBOOK_MESH` environment variable,
|
|
46
46
|
3. the active mesh saved by `mesh meshes use` (the only thing that persists).
|
|
47
47
|
|
|
48
|
-
Names are matched case-insensitively; an unknown or ambiguous name is refused before anything is sent. Every write says where it went:
|
|
48
|
+
Names are matched case-insensitively; an unknown or ambiguous name is refused before anything is sent. `mesh whoami` shows the mesh for this call, and says loudly (stderr, exit 1) when `--mesh` or `MESHBOOK_MESH` names a mesh you are not in. Every write says where it went:
|
|
49
49
|
|
|
50
50
|
```
|
|
51
51
|
Created task: Ship 0.12 (bbbbbbbb-...)
|
|
@@ -57,12 +57,14 @@ Created task: Ship 0.12 (bbbbbbbb-...)
|
|
|
57
57
|
`--json` (before or after the subcommand) prints JSON for every verb:
|
|
58
58
|
|
|
59
59
|
- a single object for `show`, `create`, `update`, `delete`;
|
|
60
|
-
- one envelope for every listing: `{"items", "count", "total", "limit", "offset", "hasMore"}` (plus extras such as `semantic` or `
|
|
61
|
-
- errors on **stderr** as `{"ok": false, "error": {"code", "message", "hint", "status"}}`.
|
|
60
|
+
- one envelope for every listing, `members list` included: `{"items", "count", "total", "limit", "offset", "hasMore", "paging"}` (plus extras such as `semantic`, `truncated`, `mesh`/`meshId`, or `nextBefore` on the chat lists). `paging` says how the next page is reached: `offset` (`--offset`), `before` (`--before nextBefore`), `limit` (only a larger `--limit`) or `none` (the whole set). `offset` is `null` unless `paging` is `offset`; `limit` is the page size asked for; `total` is `null` when the server reports none;
|
|
61
|
+
- errors on **stderr** as `{"ok": false, "error": {"code", "message", "hint", "status", "hintCode"}}`. `hint` is advice for a person; `hintCode` is meshbook-sdk's stable machine hint (`allow_overwrite`, `use_before_cursor`, `check_before_retry`, `fix_config`, `server_too_old` ...), the field to branch on in a script. `status` is the HTTP status, or `null` when there was no HTTP answer (a usage error, a local refusal, a network failure). `message` wording may change between releases.
|
|
62
62
|
|
|
63
63
|
Exit codes: `0` ok, `1` the server (or network) refused, `2` nothing was sent because something local is missing or wrong (not signed in, no mesh, bad flags), `3` an optional dependency is missing (`pip install "meshbook-cli[agent]"`).
|
|
64
64
|
|
|
65
|
-
Human listings end with `N of TOTAL` and, when there is more, the
|
|
65
|
+
Human listings end with `N of TOTAL` and, when there is more, the flag to pass next. Most listings take `--limit` and `--offset`. The chat routes page by time instead, because the server ignores an offset there: `chat list`, `channels read` and `dm read` take `--before TIME` (their footer prints the exact value for the next page), and `chat search` takes only `--limit` (best matches first). `--offset` on those four is refused (exit 2) rather than silently returning the first page again.
|
|
66
|
+
|
|
67
|
+
Downloads (`chat download`, `file download`) never replace an existing file unless you pass `--overwrite`, and the server's file name is reduced to one safe name inside the `--out` directory (a hostile `../../.bashrc` cannot land anywhere else).
|
|
66
68
|
|
|
67
69
|
Output is UTF-8 even when piped on Windows (`mesh chat list | findstr x` no longer crashes on an emoji).
|
|
68
70
|
|
|
@@ -83,12 +85,17 @@ mesh events delete EVENT_ID
|
|
|
83
85
|
|
|
84
86
|
`events create` refuses a second event with the same title starting at the same moment in the same mesh unless you pass `--force`.
|
|
85
87
|
|
|
88
|
+
**A series carries its own time zone.** `--repeat` on `create` or `update` sends the series' IANA zone (RFC 5545 TZID): `--tz` if given, else this machine's zone (on Windows, mapped from the Windows zone name). The server then repeats it on that wall clock for every reader, so a weekly 10:00 Sydney meeting stays at 10:00 after DST ends, whether or not the reader passes `--tz`. The output says `repeats: weekly (wall clock: Australia/Sydney)`. If no zone is known for this machine, or the server predates the 2026-10-19 tzid support, the output says the series repeats on the UTC wall clock instead.
|
|
89
|
+
|
|
90
|
+
`events update --start` without `--end` keeps the event's length (the end moves with the start; an all-day event keeps its number of days). `--end` alone is an explicit end. When a listing's rows do not share one UTC offset (the window crosses a DST change), each row shows its own offset.
|
|
91
|
+
|
|
86
92
|
## Commands
|
|
87
93
|
|
|
88
94
|
```
|
|
89
|
-
mesh login [--token T | --agent] [--base URL]
|
|
95
|
+
mesh login [--token T | --agent] [--base URL] [--repair-config]
|
|
96
|
+
mesh logout mesh whoami mesh doctor
|
|
90
97
|
|
|
91
|
-
mesh meshes list | use NAME
|
|
98
|
+
mesh meshes [list] | use NAME (no action = list)
|
|
92
99
|
mesh members list | invite USER [--role] | pending | accept MESH [--decline]
|
|
93
100
|
| set-role USER ROLE | remove USER | leave
|
|
94
101
|
mesh notifications [--unread]
|
|
@@ -97,7 +104,8 @@ mesh contacts list [--search] | show REF | create --first ... | update REF ... |
|
|
|
97
104
|
(--phone --title --role/--job-title --notes --tags a,b --email --last)
|
|
98
105
|
mesh companies list | show ID | create --name ... | update ID ... | delete ID
|
|
99
106
|
mesh leads list [--stage NAME] | create --title [--stage NAME] [--contact] | move ID STAGE | delete ID
|
|
100
|
-
mesh custom-fields list mesh saved-views list | create
|
|
107
|
+
mesh custom-fields list mesh saved-views list [--module M] | create --module M --name N
|
|
108
|
+
(modules: contacts companies leads projects tasks calendar activity-log; singular works too)
|
|
101
109
|
|
|
102
110
|
mesh tasks list [--project NAME] [--assignee USER | --mine] [--status] [--sort due|priority|created|title]
|
|
103
111
|
mesh tasks show ID | create --project NAME --title [--due] [--assignee] [--tags] [--parent] [--priority]
|
|
@@ -107,12 +115,14 @@ mesh projects list [--status active|completed] | show REF | create --name ... |
|
|
|
107
115
|
|
|
108
116
|
mesh events list | show | create | update | delete (see above)
|
|
109
117
|
|
|
110
|
-
mesh chat post | list | search | attach | download
|
|
111
|
-
|
|
112
|
-
mesh
|
|
113
|
-
mesh
|
|
118
|
+
mesh chat post | list [--before T] | search Q | attach | download [--out P] [--overwrite]
|
|
119
|
+
| react | unreact
|
|
120
|
+
mesh channels list | read CH [--before T] | post | reply | create | members | add-member | remove-member
|
|
121
|
+
mesh dm list | read USER [--before T] | send USER MSG
|
|
122
|
+
mesh file attach | link | list | download ID [--out P] [--overwrite] | delete
|
|
114
123
|
|
|
115
|
-
mesh agent register | enroll | token | whoami | status | revoke
|
|
124
|
+
mesh agent register | enroll | token | whoami | status | revoke (needs the [agent] extra)
|
|
125
|
+
| recover [--bundle FILE] | discard --yes (a key an interrupted enroll left pending)
|
|
116
126
|
```
|
|
117
127
|
|
|
118
128
|
Deletes take ids only: a name never deletes anything. `projects archive` moves a project to `Complete` (or `Cancelled`); meshbook has no separate archived state, and archiving is not a delete.
|
|
@@ -122,7 +132,9 @@ Deletes take ids only: a name never deletes anything. `projects archive` moves a
|
|
|
122
132
|
- **Bearer token** (`mesh login`): a `mb_token_` minted in the web UI, stored in `~/.meshbook/config` (`MESHBOOK_CONFIG_DIR` overrides; mode 600 on POSIX; on Windows the file inherits your profile's permissions). `MESHBOOK_TOKEN` and `MESHBOOK_BASE` override the config for one process.
|
|
123
133
|
- **Agent key lane** (`mesh agent enroll`, `mesh agent register`, `mesh login --agent`): a non-human seat holds its own RSA key and self-mints 5-minute tokens for every call; the stored bearer, if any, is the fallback.
|
|
124
134
|
|
|
125
|
-
The config file is read and written only by meshbook-sdk (atomic writes under a lock), so the CLI, the MCP server and your own SDK scripts can share it safely.
|
|
135
|
+
The config file is read and written only by meshbook-sdk (atomic writes under a lock), so the CLI, the MCP server and your own SDK scripts can share it safely. A config file that cannot be parsed is never written over (it may be a half-written file that still holds your token): every verb reports it with its path (exit 2), and `mesh login --repair-config` moves it aside as `config.bad.<time>` once the new login is verified.
|
|
136
|
+
|
|
137
|
+
The base URL must be `https://` (plain `http://` only for localhost), and an empty `--mesh ""` or `MESHBOOK_MESH=` is refused rather than read as "no mesh given".
|
|
126
138
|
|
|
127
139
|
## Onboarding a non-human partner
|
|
128
140
|
|