Address class

Where something is — the one identifier the GUI, fw, MCP and an artifact all carry.

fw://<project>/<space>/<the space's own path…>?<axes>

with exactly one space defined today:

fw:///worktrees                              the collection
fw:///worktrees/<name>                       one worktree's home
fw:///worktrees/<name>/<plugin>/<segments…>  a plugin panel

The framework parses up to and including the plugin segment. Everything after it is opaque to the framework and owned by the plugin — the catalog chooses its own entry addressing without this file knowing about it. That rule is what stops the parser growing a case per plugin.

Segments are identity; query parameters are applied axes. A catalog entry in dark mode is the same entry seen differently, so theme is a query parameter — which is what makes an address with its axes resolved a complete capture spec rather than an under-specified one.

Only project is the URI authority; everything else is a path segment. That is what lets Uri.parse agree with this parser instead of contradicting it — an authority is lowercased and a worktree name may have capitals. There is a test that asserts the agreement.

One exception, recorded because it cannot be fixed: a segment consisting only of dots is a relative-path operator, and Dart's Uri decodes before it normalises, so .. is resolved away however it is escaped. Nothing can produce such a segment — git sanitises worktree names, and no plugin id or entry id is only dots — so this is a note rather than a hazard.

Constructors

Address({String? project, String? space, String? worktree, String? plugin, List<String> segments = const [], Map<String, String> axes = const {}})
space defaults to the one a worktree lives in, so the many call sites that name a worktree and a plugin read exactly as they did before the space segment existed.

Properties

axes → Map<String, String>
Applied axes — theme, locale, device. Held sorted by key so that two addresses naming the same thing are == and hash alike regardless of the order they were written in.
final
bare → Address
The same address with no axes applied — the identity of the thing, which is what a tree or a list keys on.
no setter
hashCode → int
The hash code for this object.
no setteroverride
path → String
The plugin's remainder as a single slash-joined string, for plugins whose addressing is naturally a path.
no setter
plugin → String?
The declared plugin id — flutterware.previews. Null addresses the worktree itself, which is what "open this worktree" needs.
final
project → String?
Which project this address belongs to, or null for "the one the session reading it was launched in" — which is every address anything emits today, since a shell is opened on one repo and discovers that repo's worktrees.
final
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
segments → List<String>
The plugin's own remainder, already decoded. Empty when the address names only a plugin.
final
space → String?
The top-level namespace. worktreesSpace is the only one today; the slot exists so a cross-worktree screen can be addressed without competing with a checkout for the first path segment.
final
worktree → String?
Git's own name for the worktree (see Worktree.name), or null when the address names no worktree at all — which is where the shell sits before the first one opens.
final

Methods

child(String segment) → Address
The same address one segment deeper.
copyWith({String? project, String? space, String? worktree, String? plugin, List<String>? segments, Map<String, String>? axes}) → Address
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
override
withAxes(Map<String, String> axes) → Address
The same address with axes merged over the current ones.

Operators

operator ==(Object other) → bool
The equality operator.
override

Static Methods

parse(String source) → Address
tryParse(String source) → Address?
Null rather than throwing, for the many places that read user input.

Constants

scheme → const String
shellAbout → const String
fw:///worktrees/<worktree>/about — flutterware itself: its version, where it lives, and how to get in touch.
shellChanges → const String
fw:///worktrees/<worktree>/changes — what this checkout has changed against its base branch, committed and uncommitted together.
shellConfig → const String
The one name in the plugin slot that is not a plugin: fw:///worktrees/<worktree>/config is the shell's own screen for the worktree's tool/flutterware.dart — what it resolved to, what each reload cost, and why it failed when it did.
shellOwned → const Set<String>
Every id in the plugin slot the shell owns rather than a plugin.
shellSessionless → const Set<String>
The shell-owned ids that need no session to render, and therefore resolve for a worktree that is not open.
worktreesSpace → const String
The only space there is today. The slot exists so a cross-worktree screen can be addressed without competing with a checkout for the first path segment — the same reasoning that made Worktree.mainName a character git cannot produce, applied one level up.