Add session labels (get/set/unset/clear) and list --where filtering#185
Add session labels (get/set/unset/clear) and list --where filtering#185maxandersen wants to merge 2 commits into
Conversation
|
I've been using this for a while now and it's really nice to have decoupled grouping and context sharing for terminals. ATM I have to specify all labels again when new sessions created. Default I think make sense to have default be to inherit labels but allow to set zmx_inherit_labels which can contain 0 to N comma separated labels. This makes default children has same state but you tweak as you need. |
|
How do you know when to inherit labels from another session? |
|
I mean like ZMX_SESSION_PREFIX is used to prefix, I would use the current ZMX_SESSION labels based on value/presence of ZMX_INHERIT_LABELS. |
|
note, my usecase was mainly just for when starting/running other zmx sessions from within another zmx started process. I guess could also point to another session for "copying" but that wasn't on my mind in this case. wuold that be useful? |
|
Do you think we actually need |
|
So emptystring means remove ? Yeah; |
|
Dropped |
There was a problem hiding this comment.
Overall, excellent job on this PR. I think I would prefer to start simpler with labels: no prefix matching --where and no label inheritance. If we find there's too much friction and those feature are truly table-stakes we can re-evaluate.
What do you think? You don't need to make those changes, I'll do that myself, I just wanted to discuss with you before committing to it as I can be persuaded.
Thanks again!
| if (idx == 0) return null; | ||
| const key = expr[0..idx]; | ||
| const raw_value = expr[idx + 1 ..]; | ||
| const is_prefix = raw_value.len > 0 and raw_value[raw_value.len - 1] == '*'; |
There was a problem hiding this comment.
Hmm, do you think we actually need --where key=value*? I feel like at a certain point we are just re-inventing other tools like grep.
| /// ponytail: inherit labels from parent session into a newly created daemon. | ||
| /// Uses $ZMX_SESSION if set, silently skips otherwise. | ||
| /// ZMX_INHERIT_LABELS controls filtering: | ||
| /// unset → inherit all | ||
| /// empty string → inherit nothing | ||
| /// "a,b" → inherit only keys a and b |
There was a problem hiding this comment.
The fact that we need an override for this feature feels like a smell. I'm not sure I want to include this into the initial version, I'd rather start simple and see where the friction exists before implementing inheritance with an env var override.
| return help(); | ||
| } else if (std.mem.eql(u8, arg, "--short")) { | ||
| short = true; | ||
| } else if (std.mem.startsWith(u8, arg, "--where")) { |
There was a problem hiding this comment.
Now that I'm thinking about it, I wonder if we should drop --where entirely and let users rely on pipes to filter based on labels
There was a problem hiding this comment.
How ? That would be some tab character matching extracting key=value ?
|
I'll need to create and set those inherited labels but attach won't return the created session nor can I see the parent inside the created session. How do you envision users do this if no inherit ? |
|
If we make get and set be symmetrical, we could do something like this: zmx a first
zmx set . project=pico
zmx a second
zmx set . "$(zmx get first)"Lemme know if that doesn't work for you. |
|
I think it make sense get can be piped into set. Those are useful especially when creating a set of zmx attaches or some tool want control. The issue with removing inherit labels is that you also need others to do these extra calls. By having inherit labels (or sticky labels) any user or any tool can use zmx at any depth can share labels without having any understanding of zmx So I would be sad and feel it makes it hard to be used :) |
|
Fair enough. I'm working on your PR now and playing around with some different ideas. I'm going to start with the simplest version and then we can layer more complex workflows on top. I'll keep thinking about inheritance and if your solution is the best option. Thanks again! |
|
Cool. I've come to dislike the inheritance name/feel. It's more like what labels are sticky. It doesn't change the implementation but make for simpler explanation imo. All labels are by default sticky when creating new sessions from an existing session. You can decide what labels you want to be sticky by setting ZMX_STICKY_LABELS to a comma separated list. Including the empty list which means nothing will stick. Looking forward to where it will land :) |
Implements #183 — session labels for discovery and filtering.
Fair warning: this is my first time writing Zig, so treat this as a "works but could use a more experienced eye on idioms" kind of PR. Happy to adjust anything that doesn't fit zmx conventions.
What this adds
Key-value labels that live on the session daemon, scoped to the session lifetime. Four new top-level commands:
Inside a session,
.resolves via$ZMX_SESSION:Labels show up automatically in
zmx listoutput as extra tab-separated fields.Filtering with
--whereBuilt-in fields
name,start_dir, andcmdwork as virtual labels in--wherequeries without setting anything — sozmx list --where start_dir=/Users/max/code*works out of the box. These fields are read-only;zmx set mysession name=foois rejected.Multiple
--whereflags combine with AND logic.How it works
LabelGet,LabelSet,LabelUnset,LabelClear,LabelData. Old daemons silently ignore unknown tags via the existing_arm, so there's no backward compat issue.zmx listsends bothInfoandLabelGetin a single batch on the same socket connection. If the daemon responds withLabelData, great. If not (old daemon), a 50ms poll times out and we move on. No extra connection per session.--whereonly filters on built-in fields, label fetching is skipped entirely — same speed as before.What's included
probeSessionWithLabelsfor batched Info+Label fetch,roundTripForTagfor single-session label opsStringHashMapUnmanagedlabel store with proper allocation/deallocationget/set/unset/clearcommands with aliases (g,z,un,cl)list --wherewith exact and prefix matching.without$ZMX_SESSION--wherefilteringparseWhereExpr,whereMatch, andisReservedKeyBuild fix
The ghostty dependency was trying to build an iOS XCFramework on macOS without full Xcode. Added
emit-lib-vt=true,emit-xcframework=false,emit-macos-app=falseto all threeb.dependency("ghostty", ...)calls. This might already be fixed upstream — just needed it to build locally with Command Line Tools only.