From b6af059305ffff0776753af5ce42da6f584cfc11 Mon Sep 17 00:00:00 2001 From: Trillium Smith Date: Fri, 31 Jul 2026 10:12:25 -0700 Subject: [PATCH 1/2] Add optional --label flag to fm-spawn.sh - Add --label flag to fm-spawn.sh flag parsing - When provided, use it for the tab label with fm- prefix (e.g., fm-) - Fall back to default fm- behavior when --label is absent (fully backward compatible) - Record label= in state/.meta when a non-default label is used - Document the new optional label field in docs/configuration.md --- bin/fm-spawn.sh | 13 ++++++++++++- docs/configuration.md | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/bin/fm-spawn.sh b/bin/fm-spawn.sh index 597893bfc0..4d6a68c73d 100755 --- a/bin/fm-spawn.sh +++ b/bin/fm-spawn.sh @@ -191,10 +191,12 @@ HARNESS_ARG= MODEL= EFFORT= BACKEND_ARG= +LABEL_ARG= HARNESS_SET=0 MODEL_SET=0 EFFORT_SET=0 BACKEND_SET=0 +LABEL_SET=0 POS=() want_value= for a in "$@"; do @@ -207,6 +209,7 @@ for a in "$@"; do model) MODEL=$a; MODEL_SET=1 ;; effort) EFFORT=$a; EFFORT_SET=1 ;; backend) BACKEND_ARG=$a; BACKEND_SET=1 ;; + label) LABEL_ARG=$a; LABEL_SET=1 ;; *) echo "error: internal parser state for --$want_value" >&2; exit 1 ;; esac want_value= @@ -223,6 +226,8 @@ for a in "$@"; do --effort=*) EFFORT=${a#--effort=}; EFFORT_SET=1 ;; --backend) want_value=backend ;; --backend=*) BACKEND_ARG=${a#--backend=}; BACKEND_SET=1 ;; + --label) want_value=label ;; + --label=*) LABEL_ARG=${a#--label=}; LABEL_SET=1 ;; *) POS+=("$a") ;; esac done @@ -231,6 +236,7 @@ done [ "$MODEL_SET" -eq 0 ] || [ -n "$MODEL" ] || { echo "error: --model requires a non-empty value" >&2; exit 1; } [ "$EFFORT_SET" -eq 0 ] || [ -n "$EFFORT" ] || { echo "error: --effort requires a non-empty value" >&2; exit 1; } [ "$BACKEND_SET" -eq 0 ] || [ -n "$BACKEND_ARG" ] || { echo "error: --backend requires a non-empty value" >&2; exit 1; } +[ "$LABEL_SET" -eq 0 ] || [ -n "$LABEL_ARG" ] || { echo "error: --label requires a non-empty value" >&2; exit 1; } case "$EFFORT" in ''|low|medium|high|xhigh|max) ;; *) echo "error: --effort must be one of low, medium, high, xhigh, max" >&2; exit 1 ;; @@ -978,7 +984,11 @@ herdr_projection_existing_meta_allows_flat() { # esac } -W="fm-$ID" +if [ -n "$LABEL_ARG" ]; then + W="fm-$LABEL_ARG" +else + W="fm-$ID" +fi case "$BACKEND" in tmux) SES=$(fm_backend_tmux_container_ensure) @@ -1623,6 +1633,7 @@ META_WINDOW=$T echo "model=${MODEL:-default}" echo "effort=${EFFORT:-default}" [ -z "${BUSY_GEN:-}" ] || echo "busy_gen=$BUSY_GEN" + [ -z "$LABEL_ARG" ] || echo "label=$LABEL_ARG" # backend= is written only for a non-default (non-tmux) backend, so the # default path's meta stays byte-identical (absent backend= means tmux; # data/fm-backend-design-d7's P1 compatibility contract). diff --git a/docs/configuration.md b/docs/configuration.md index 1d98172b9d..913ebdf8d1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -72,6 +72,7 @@ A zellij spawn additionally version-gates against the installed `zellij` binary' A cmux spawn additionally version-gates against the installed `cmux` binary's version, requires `jq`, and requires the control socket to be reachable and accessible (see [`docs/cmux-backend.md`](cmux-backend.md) "Setup" for the one-time socket-access configuration this needs; Automation mode is the recommended socket control mode, with Password mode supported via `config/cmux-socket-password`), refusing loudly and non-retryably on a `cmuxOnly`/unauthenticated socket. A backend spawn refusal from a missing dependency, version gate, or unauthenticated socket is terminal for that selected backend; firstmate surfaces it as a blocker instead of silently retrying another backend. Task meta records `backend=` only for a non-default backend; an absent `backend=` means `tmux`, preserving existing default-path meta files. +Task meta records `label=` only when `--label` was passed at spawn; an absent `label=` means the default tab label was used. Every new task records `endpoint_task_id=` as the cleanup binding between the metadata filename and its opaque runtime endpoint. A herdr task additionally records `herdr_session=`, `herdr_workspace_id=`, `herdr_tab_id=`, and `herdr_pane_id=`. A zellij task additionally records `zellij_session=`, `zellij_tab_id=`, and `zellij_pane_id=`. From 63482862c7563238c33f2985393008dce99fd043 Mon Sep 17 00:00:00 2001 From: Trillium Smith Date: Fri, 31 Jul 2026 10:24:21 -0700 Subject: [PATCH 2/2] no-mistakes(document): Document --label flag in fm-spawn.sh and related docs. --- AGENTS.md | 2 +- bin/fm-spawn.sh | 11 ++++++++--- docs/configuration.md | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 743c14bea3..4a99e28438 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -91,7 +91,7 @@ state/ volatile runtime signals; gitignored .grok-turnend-token firstmate-owned grok hook registry token for the task; removed by teardown .kimi-turnend-token firstmate-owned Kimi hook registry token for the task; removed by teardown .parlay-listen-pid background `parlay listen` pid from a best-effort Parlay chat-panel enrollment at spawn (bin/fm-spawn.sh header); killed and removed by teardown - .meta written by fm-spawn: window=, endpoint_task_id=, worktree=, project=, harness=, model=, effort=, kind=, mode=, yolo=, tasktmp=; kind=secondmate also records home= and projects=; a non-default runtime backend records further backend-specific fields (docs/configuration.md "Runtime backend"; bin/fm-backend.sh, section 8); fm-pr-check, including through fm-pr-merge, records one canonical pr= and the forge's pr_head= when available (GitHub pull requests and GitLab merge requests; docs/gitlab-merge-watch.md); fm-x-link appends x_request=, x_request_ts=, x_followups=, and optional x_platform=/x_reply_max_chars= for an X-mode-originated task (section 14) + .meta written by fm-spawn: window=, endpoint_task_id=, worktree=, project=, harness=, model=, effort=, kind=, mode=, yolo=, tasktmp=; kind=secondmate also records home= and projects=; a non-default runtime backend records further backend-specific fields (docs/configuration.md "Runtime backend"; bin/fm-backend.sh, section 8); optional label= is recorded only when --label was passed at spawn; fm-pr-check, including through fm-pr-merge, records one canonical pr= and the forge's pr_head= when available (GitHub pull requests and GitLab merge requests; docs/gitlab-merge-watch.md); fm-x-link appends x_request=, x_request_ts=, x_followups=, and optional x_platform=/x_reply_max_chars= for an X-mode-originated task (section 14) .herdr-presentation quarantinable attempt and restart-binding journal for Herdr's optional visual projection; never task or endpoint authority; see docs/herdr-backend.md "Optional presentation spaces" .check.sh authenticated slow poll; the watcher dispatches validated PR data and the byte-identified X shim through trusted repository scripts, runs registered custom checks from hash-validated private snapshots, and rejects every other state check without execution .check-trust private content binding created by fm-check-register.sh for an intentional custom check diff --git a/bin/fm-spawn.sh b/bin/fm-spawn.sh index 4d6a68c73d..c21c33fdcd 100755 --- a/bin/fm-spawn.sh +++ b/bin/fm-spawn.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash # Spawn a direct report: a crewmate in a treehouse or Orca worktree, or a # secondmate in its isolated firstmate home. -# Usage: fm-spawn.sh [--harness |harness|launch-command] [--model ] [--effort ] [--backend ] [--scout] -# fm-spawn.sh [] [--harness |harness|launch-command] [--model ] [--effort ] [--backend ] --secondmate +# Usage: fm-spawn.sh [--harness |harness|launch-command] [--model ] [--effort ] [--backend ] [--label ] [--scout] +# fm-spawn.sh [] [--harness |harness|launch-command] [--model ] [--effort ] [--backend ] [--label ] --secondmate # --harness is the explicit per-spawn harness/profile adapter. The old # positional harness arg still works for back-compat. # --model and --effort are concrete profile @@ -27,6 +27,11 @@ # A backend spawn refusal (missing dependency, version gate, unauthenticated # socket, or unsupported secondmate mode) is terminal for that selected backend; # callers must surface it instead of silently retrying another backend. +# --label overrides the default tab/window label for the spawned task. +# Without --label, the window is named by the task ID in the form fm-. +# With --label, the window is named fm-