* Improve bug report template for desktop, remote, and mobile
Capture where users hit the bug (local desktop, SSH, remote server, WSL, mobile, web) without extra host jargon, and collect remote OS when relevant. Extend the OS labeler for mobile.
* Reconcile OS and mobile labels from the bug form's current state
Form: one "Where were you using Orca?" choice (Desktop only, + SSH host,
+ Orca server, + WSL, Mobile app, Web browser, Other), device OS with iOS
and Android, optional remote host OS, shorter help copy and per-platform
version instructions. Main's English request is kept.
Labeler: read the issue as it is now instead of the webhook snapshot,
recognize only a bug form at the very start of the body (optionally after
the exact machine-translation note line), and stop at the free-text
heading. Unknown, repeated, out-of-order or multi-line metadata leaves
labels untouched. Only os:macos, os:Windows, os:linux, os:mobile and
mobile are ever added or removed, one label at a time, so labels added
concurrently by people or other workflows survive. Each pass is verified
by a re-read and retried up to three times; runs are serialized per issue.
Fixes stale mobile labels after an edit to desktop, stale OS labels after
an edit to Other or blank, empty sections reading the next heading as a
value, quoted form sections relabeling unrelated issues, and prototype
names such as "constructor" being sent as labels. Retired Where option
strings and the Client / Host operating system headings keep working for
open issues.
Tests run the workflow's inline script against a stateful mock of the
issues API.
* Trim OS labeler tests to behaviour that fails when the fix is reverted
Review finding F11140-C1-1: several added tests pinned form copy, option
inventories, schema keys, workflow constants or script source, and kept
passing with the production change reverted.
- Delete bug-report-issue-form.test.mjs (schema keys, copy, option lists,
About-menu source regexes). The form/labeler contract is kept as one
behavioural case: every option the shipped form offers is recognised.
- Drop the workflow-constant and script-source regex tests, the log-copy
assertion, the note-length check and the plain-string label case.
- Replace the Where x OS matrix (with its test-side oracle) and the other
Cartesian tables with one literal case per distinct behaviour.
- Point negative fixtures at an OS the old script would label, so each
kept case fails against the reverted workflow rather than passing because
the old script skipped iOS.
220 -> 59 tests; all 59 fail with only the workflow reverted to main.
Test-only change; no runtime path changed.
* Keep the shadowed legacy value case in the heading-presence test
It covers a distinct rule (an invalid legacy value is ignored when the
current heading is present) and was dropped by mistake in the trim.
* fix(runtime): hold tui-idle until a cold-starting Claude has painted (STA-2380)
A shell auto-title (oh-my-zsh preexec) names the pane `claude` the moment
the command execs. Claude's `idle_title` rule counts that bare name as weak
idle once output has been quiet for 3s, so a Claude that took >3s to draw
its first frame settled `terminal wait --for tui-idle` on a blank screen.
`dispatch --inject` then pasted into a TUI that had not mounted yet and the
prompt was lost.
Name-only idle lanes (agent rule verdicts that require quiet, and the
sustained-title lane) now also require that the running command has painted
something since the shell's OSC 133;C command-start marker. Shells without
the marker keep today's behavior.
* fix(runtime): corroborate Claude's name-only idle with its own composer marker (STA-2380, C1 F1)
Orca's zsh OSC 133;C hook is first in preexec_functions, so a later user or
framework preexec hook (zsh-you-should-use, a custom echo) prints after the
command-start marker and before Claude runs. The any-visible-byte paint latch
counted that text as Claude's paint, so a silent cold start under such a hook
still settled tui-idle ready-weak on the shell's bare `claude` title.
For agents whose worker start already trusts their composer marker (Claude),
"painted" now means that marker (`❯`+NBSP after DECSET 2031, which no shell
sends) arrived since the command started. Other agents keep any-byte paint;
markerless shells and output gaps keep the permissive default.
Evidence: a real-zsh live-shell test under the production wrapper with
oh-my-zsh title-only, p10k/starship-style silent, and you-should-use-style
printing hooks, replayed through the real wait; runtime tests for the hook
text, a boot banner, the positive bare-title + composer path, and worker-start
readiness plus brief delivery timing.
* fix(ci): route command-paint attribution sources to shell_contracts; attribute live-shell bytes by stream offset (STA-2380, C2 F1/F2)
- pr-shell-contract-prefixes: the live-shell test, terminal-command-paint.ts,
tui-idle-evidence-source.ts and draft-paste-ready-scanner.ts route to the
shell_contracts job; a routing test reads the job's step from pr.yml and
asserts every listed test routes there.
- tui-idle-zsh-preexec-hook-order.live-shell.test: locate the DECSET 2031
anchor by offset in the accumulated stream, split a straddling read, carry
pending escapes across the shell/agent halves, and assert attribution is
invariant under coalescing and 3-byte re-chunking.
- terminal-command-paint: disclose the accepted trade-off (a known Claude with
marker history but no supported composer signal times out; markerless shells
and output gaps still fail open; no version cutoff claimed).
* test(ci): stream-offset launch-order proof, route tui-idle-evidence.ts, parse the whole shell-contracts step (STA-2380, C3-1/2/3)
- live-shell test: assert the launch order on the joined bytes by stream
offset (133;C, then the user hook's output, then the agent's anchor and
composer); no read-boundary or timestamp assertions remain. Re-chunk
cases add a split anchor and a shell-tail/agent-start coalesced read.
- pr-shell-contract-prefixes: route tui-idle-evidence.ts, the readiness
evaluator the live-shell replay exercises.
- routing ratchet: read the step's run script through the YAML parser so
a blank line or later command cannot truncate it; cross-check against
the real-shell tests UNIT_EXCLUDE drops so a dropped entry fails rather
than a smaller count; fixture tests for blank line, exact list, missing
step.
* test(ci): answer compinit's insecure-directory prompt in the zsh preexec live-shell test (STA-2380)
Ubuntu's global zshrc runs a plain compinit, which on CI runners stops at
"Ignore insecure directories and continue [y] or abort compinit [n]?"
before zle exists, so the stand-in never launched and the shell-contracts
job failed with "no composer frame from the stand-in". Answer the prompt
with y as zsh-startup-hook-pty-harness.ts does. The prompt bytes precede
Orca's OSC 133;C marker, so stream-offset attribution is unchanged.