relay-flow 0.2.3-alpha → 0.2.4-alpha
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.
- package/README.md +116 -10
- package/cmd/relay-flow/main.go +2 -0
- package/cmd/relay-flow/pi_wiring_test.go +64 -0
- package/cmd/relay-flow/serve.go +2 -0
- package/examples/beads-workflow.yaml +3 -3
- package/examples/config-reference.yaml +144 -0
- package/examples/minimal-beads-task-workflow.yaml +34 -0
- package/examples/minimal-jira-task-workflow.yaml +68 -0
- package/examples/workflow-reference.yaml +111 -0
- package/internal/harness/opencode/opencode_test.go +1 -1
- package/internal/harness/opencode/repo_setup.go +1 -1
- package/internal/harness/pi/config_test.go +46 -0
- package/internal/harness/pi/lifecycle_test.go +69 -0
- package/internal/harness/pi/pi.go +261 -0
- package/internal/harness/pi/pi_test.go +322 -0
- package/internal/harness/pi/prompt_test.go +121 -0
- package/internal/harness/pi/testdata/pi-0.84.1/capture.json +126 -0
- package/internal/harness/pi/testdata/pi-0.84.1/noninteractive-output.txt +11 -0
- package/internal/harness/pi/testdata/pi-0.84.1/tui-output-sanitized.txt +17 -0
- package/internal/harness/pi/validation_test.go +168 -0
- package/internal/runner/herdr/baseref.go +60 -0
- package/internal/runner/herdr/herdr.go +578 -0
- package/internal/runner/herdr/herdr_test.go +688 -0
- package/internal/runner/herdr/herdrcli/contract.go +128 -0
- package/internal/runner/herdr/herdrcli/exec.go +68 -0
- package/internal/runner/herdr/herdrcli/herdrcli_test.go +274 -0
- package/internal/runner/herdr/herdrcli/live_test.go +132 -0
- package/internal/runner/herdr/herdrcli/operations.go +281 -0
- package/internal/runner/herdr/herdrcli/response.go +116 -0
- package/internal/runner/herdr/herdrcli/testdata/empty-panes.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/empty-tabs.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/error-not-git-worktree.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/error-pane-not-found.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/error-workspace-not-found.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/error-worktree-not-found.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/malformed.json +1 -0
- package/internal/runner/herdr/herdrcli/testdata/pane-close.json +6 -0
- package/internal/runner/herdr/herdrcli/testdata/pane-get.json +25 -0
- package/internal/runner/herdr/herdrcli/testdata/pane-list.json +45 -0
- package/internal/runner/herdr/herdrcli/testdata/pane-process-info-shell.json +22 -0
- package/internal/runner/herdr/herdrcli/testdata/pane-process-info.json +23 -0
- package/internal/runner/herdr/herdrcli/testdata/pane-rename.json +23 -0
- package/internal/runner/herdr/herdrcli/testdata/snapshot.json +213 -0
- package/internal/runner/herdr/herdrcli/testdata/strict-herdr.sh +175 -0
- package/internal/runner/herdr/herdrcli/testdata/tab-create.json +31 -0
- package/internal/runner/herdr/herdrcli/testdata/tab-list.json +26 -0
- package/internal/runner/herdr/herdrcli/testdata/workspace-close.json +6 -0
- package/internal/runner/herdr/herdrcli/testdata/worktree-create.json +58 -0
- package/internal/runner/herdr/herdrcli/testdata/worktree-list.json +35 -0
- package/internal/runner/herdr/herdrcli/testdata/worktree-open.json +59 -0
- package/internal/task/beads/beads.go +0 -16
- package/internal/task/beads/config_compatibility_test.go +7 -8
- package/internal/task/jira/filters_test.go +32 -6
- package/internal/task/jira/jira.go +27 -17
- package/package.json +1 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cli:api:snapshot",
|
|
3
|
+
"result": {
|
|
4
|
+
"snapshot": {
|
|
5
|
+
"agents": [],
|
|
6
|
+
"focused_pane_id": "w1:p1",
|
|
7
|
+
"focused_tab_id": "w1:t1",
|
|
8
|
+
"focused_workspace_id": "w1",
|
|
9
|
+
"layouts": [
|
|
10
|
+
{
|
|
11
|
+
"area": {
|
|
12
|
+
"height": 39,
|
|
13
|
+
"width": 94,
|
|
14
|
+
"x": 26,
|
|
15
|
+
"y": 1
|
|
16
|
+
},
|
|
17
|
+
"focused_pane_id": "w1:p1",
|
|
18
|
+
"panes": [
|
|
19
|
+
{
|
|
20
|
+
"focused": true,
|
|
21
|
+
"pane_id": "w1:p1",
|
|
22
|
+
"rect": {
|
|
23
|
+
"height": 39,
|
|
24
|
+
"width": 94,
|
|
25
|
+
"x": 26,
|
|
26
|
+
"y": 1
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"splits": [],
|
|
31
|
+
"tab_id": "w1:t1",
|
|
32
|
+
"workspace_id": "w1",
|
|
33
|
+
"zoomed": false
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"area": {
|
|
37
|
+
"height": 39,
|
|
38
|
+
"width": 94,
|
|
39
|
+
"x": 26,
|
|
40
|
+
"y": 1
|
|
41
|
+
},
|
|
42
|
+
"focused_pane_id": "w2:p1",
|
|
43
|
+
"panes": [
|
|
44
|
+
{
|
|
45
|
+
"focused": true,
|
|
46
|
+
"pane_id": "w2:p1",
|
|
47
|
+
"rect": {
|
|
48
|
+
"height": 39,
|
|
49
|
+
"width": 94,
|
|
50
|
+
"x": 26,
|
|
51
|
+
"y": 1
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"splits": [],
|
|
56
|
+
"tab_id": "w2:t1",
|
|
57
|
+
"workspace_id": "w2",
|
|
58
|
+
"zoomed": false
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"area": {
|
|
62
|
+
"height": 39,
|
|
63
|
+
"width": 94,
|
|
64
|
+
"x": 26,
|
|
65
|
+
"y": 1
|
|
66
|
+
},
|
|
67
|
+
"focused_pane_id": "w2:p2",
|
|
68
|
+
"panes": [
|
|
69
|
+
{
|
|
70
|
+
"focused": true,
|
|
71
|
+
"pane_id": "w2:p2",
|
|
72
|
+
"rect": {
|
|
73
|
+
"height": 39,
|
|
74
|
+
"width": 94,
|
|
75
|
+
"x": 26,
|
|
76
|
+
"y": 1
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"splits": [],
|
|
81
|
+
"tab_id": "w2:t2",
|
|
82
|
+
"workspace_id": "w2",
|
|
83
|
+
"zoomed": false
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"panes": [
|
|
87
|
+
{
|
|
88
|
+
"agent_status": "unknown",
|
|
89
|
+
"cwd": "/work/payments",
|
|
90
|
+
"focused": true,
|
|
91
|
+
"foreground_cwd": "/work/payments",
|
|
92
|
+
"pane_id": "w1:p1",
|
|
93
|
+
"revision": 1,
|
|
94
|
+
"scroll": {
|
|
95
|
+
"max_offset_from_bottom": 0,
|
|
96
|
+
"offset_from_bottom": 0,
|
|
97
|
+
"viewport_rows": 39
|
|
98
|
+
},
|
|
99
|
+
"tab_id": "w1:t1",
|
|
100
|
+
"terminal_id": "term_65a5cfcc8c6361",
|
|
101
|
+
"terminal_title": "relay@relay-host:/work/payments",
|
|
102
|
+
"terminal_title_stripped": "relay@relay-host:/work/payments",
|
|
103
|
+
"workspace_id": "w1"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"agent_status": "unknown",
|
|
107
|
+
"cwd": "/work/worktrees/payments/pay-101",
|
|
108
|
+
"focused": false,
|
|
109
|
+
"foreground_cwd": "/work/worktrees/payments/pay-101",
|
|
110
|
+
"pane_id": "w2:p1",
|
|
111
|
+
"revision": 1,
|
|
112
|
+
"scroll": {
|
|
113
|
+
"max_offset_from_bottom": 0,
|
|
114
|
+
"offset_from_bottom": 0,
|
|
115
|
+
"viewport_rows": 39
|
|
116
|
+
},
|
|
117
|
+
"tab_id": "w2:t1",
|
|
118
|
+
"terminal_id": "term_65a5cfcc8cd9e2",
|
|
119
|
+
"terminal_title": "relay@relay-host:~/.herdr/worktrees/repo/pay-101",
|
|
120
|
+
"terminal_title_stripped": "relay@relay-host:~/.herdr/worktrees/repo/pay-101",
|
|
121
|
+
"workspace_id": "w2"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"agent_status": "unknown",
|
|
125
|
+
"cwd": "/work/worktrees/payments/pay-101",
|
|
126
|
+
"focused": false,
|
|
127
|
+
"foreground_cwd": "/work/worktrees/payments/pay-101",
|
|
128
|
+
"label": "PAY-101:coding",
|
|
129
|
+
"pane_id": "w2:p2",
|
|
130
|
+
"revision": 2,
|
|
131
|
+
"scroll": {
|
|
132
|
+
"max_offset_from_bottom": 0,
|
|
133
|
+
"offset_from_bottom": 0,
|
|
134
|
+
"viewport_rows": 39
|
|
135
|
+
},
|
|
136
|
+
"tab_id": "w2:t2",
|
|
137
|
+
"terminal_id": "term_65a5cfcc913e03",
|
|
138
|
+
"terminal_title": "sleep 300",
|
|
139
|
+
"terminal_title_stripped": "sleep 300",
|
|
140
|
+
"workspace_id": "w2"
|
|
141
|
+
}
|
|
142
|
+
],
|
|
143
|
+
"protocol": 20,
|
|
144
|
+
"tabs": [
|
|
145
|
+
{
|
|
146
|
+
"agent_status": "unknown",
|
|
147
|
+
"focused": true,
|
|
148
|
+
"label": "1",
|
|
149
|
+
"number": 1,
|
|
150
|
+
"pane_count": 1,
|
|
151
|
+
"tab_id": "w1:t1",
|
|
152
|
+
"workspace_id": "w1"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"agent_status": "unknown",
|
|
156
|
+
"focused": false,
|
|
157
|
+
"label": "1",
|
|
158
|
+
"number": 1,
|
|
159
|
+
"pane_count": 1,
|
|
160
|
+
"tab_id": "w2:t1",
|
|
161
|
+
"workspace_id": "w2"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"agent_status": "unknown",
|
|
165
|
+
"focused": false,
|
|
166
|
+
"label": "PAY-101:coding",
|
|
167
|
+
"number": 2,
|
|
168
|
+
"pane_count": 1,
|
|
169
|
+
"tab_id": "w2:t2",
|
|
170
|
+
"workspace_id": "w2"
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
"version": "0.8.2",
|
|
174
|
+
"workspaces": [
|
|
175
|
+
{
|
|
176
|
+
"active_tab_id": "w1:t1",
|
|
177
|
+
"agent_status": "unknown",
|
|
178
|
+
"focused": true,
|
|
179
|
+
"label": "repo",
|
|
180
|
+
"number": 1,
|
|
181
|
+
"pane_count": 1,
|
|
182
|
+
"tab_count": 1,
|
|
183
|
+
"workspace_id": "w1",
|
|
184
|
+
"worktree": {
|
|
185
|
+
"checkout_path": "/work/payments",
|
|
186
|
+
"is_linked_worktree": false,
|
|
187
|
+
"repo_key": "/work/payments/.git",
|
|
188
|
+
"repo_name": "repo",
|
|
189
|
+
"repo_root": "/work/payments"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"active_tab_id": "w2:t1",
|
|
194
|
+
"agent_status": "unknown",
|
|
195
|
+
"focused": false,
|
|
196
|
+
"label": "PAY-101",
|
|
197
|
+
"number": 2,
|
|
198
|
+
"pane_count": 2,
|
|
199
|
+
"tab_count": 2,
|
|
200
|
+
"workspace_id": "w2",
|
|
201
|
+
"worktree": {
|
|
202
|
+
"checkout_path": "/work/worktrees/payments/pay-101",
|
|
203
|
+
"is_linked_worktree": true,
|
|
204
|
+
"repo_key": "/work/payments/.git",
|
|
205
|
+
"repo_name": "repo",
|
|
206
|
+
"repo_root": "/work/payments"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
"type": "session_snapshot"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Strict fake `herdr`. It accepts only the exact production command shapes and
|
|
3
|
+
# reproduces the observed transport contract of herdr 0.8.2:
|
|
4
|
+
# success -> result envelope on stdout, exit 0 (pane run prints nothing)
|
|
5
|
+
# failure -> error envelope on stderr, exit 1, empty stdout
|
|
6
|
+
set -eu
|
|
7
|
+
|
|
8
|
+
fail() {
|
|
9
|
+
printf 'unsupported or malformed herdr invocation:' >&2
|
|
10
|
+
for arg in "$@"; do
|
|
11
|
+
printf ' <%s>' "$arg" >&2
|
|
12
|
+
done
|
|
13
|
+
printf '\n' >&2
|
|
14
|
+
exit 64
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
# The wrapper supplies selector configuration through the environment rather
|
|
18
|
+
# than adding session/socket flags to every Herdr command.
|
|
19
|
+
check_selector() {
|
|
20
|
+
actual_name=$1
|
|
21
|
+
expected_name=$2
|
|
22
|
+
eval "expected_set=\${${expected_name}+x}"
|
|
23
|
+
if [ "$expected_set" = x ]; then
|
|
24
|
+
eval "expected=\${${expected_name}-}"
|
|
25
|
+
eval "actual=\${${actual_name}-}"
|
|
26
|
+
[ "$actual" = "$expected" ] || fail "wrong $actual_name: $actual"
|
|
27
|
+
else
|
|
28
|
+
eval "actual_set=\${${actual_name}+x}"
|
|
29
|
+
[ "$actual_set" != x ] || fail "ambient $actual_name leaked"
|
|
30
|
+
fi
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
check_selector HERDR_SESSION HERDR_EXPECT_SESSION
|
|
34
|
+
check_selector HERDR_SOCKET_PATH HERDR_EXPECT_SOCKET_PATH
|
|
35
|
+
|
|
36
|
+
fixture_path() {
|
|
37
|
+
fixture_dir=${HERDR_FIXTURE_DIR-}
|
|
38
|
+
[ -n "$fixture_dir" ] || fail "HERDR_FIXTURE_DIR is unset"
|
|
39
|
+
[ -f "$fixture_dir/$1" ] || fail "missing fixture: $1"
|
|
40
|
+
printf '%s' "$fixture_dir/$1"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
emit_result() { cat "$(fixture_path "$1")"; exit 0; }
|
|
44
|
+
|
|
45
|
+
# Herdr writes error envelopes to stderr and exits 1.
|
|
46
|
+
emit_error() { cat "$(fixture_path "$1")" >&2; exit 1; }
|
|
47
|
+
|
|
48
|
+
check_absolute_cwd() {
|
|
49
|
+
case "$1" in
|
|
50
|
+
/*) ;;
|
|
51
|
+
*) fail "--cwd must be absolute: $1" ;;
|
|
52
|
+
esac
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
check_value() {
|
|
56
|
+
[ -n "$1" ] || fail "empty positional value"
|
|
57
|
+
case "$1" in
|
|
58
|
+
-*) fail "unexpected flag in positional value: $1" ;;
|
|
59
|
+
esac
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
case "$#:${1-}:${2-}" in
|
|
63
|
+
2:api:snapshot)
|
|
64
|
+
emit_result snapshot.json
|
|
65
|
+
;;
|
|
66
|
+
4:worktree:list)
|
|
67
|
+
[ "$3" = --cwd ] || fail "$@"
|
|
68
|
+
check_absolute_cwd "$4"
|
|
69
|
+
case "$4" in
|
|
70
|
+
*not-a-repo) emit_error error-not-git-worktree.json ;;
|
|
71
|
+
*) emit_result worktree-list.json ;;
|
|
72
|
+
esac
|
|
73
|
+
;;
|
|
74
|
+
11:worktree:create)
|
|
75
|
+
[ "$3" = --cwd ] || fail "$@"
|
|
76
|
+
check_absolute_cwd "$4"
|
|
77
|
+
[ "$5" = --branch ] || fail "$@"
|
|
78
|
+
check_value "$6"
|
|
79
|
+
[ "$7" = --base ] || fail "$@"
|
|
80
|
+
check_value "$8"
|
|
81
|
+
[ "$9" = --label ] || fail "$@"
|
|
82
|
+
check_value "${10}"
|
|
83
|
+
[ "${11}" = --no-focus ] || fail "$@"
|
|
84
|
+
emit_result worktree-create.json
|
|
85
|
+
;;
|
|
86
|
+
9:worktree:open)
|
|
87
|
+
[ "$3" = --cwd ] || fail "$@"
|
|
88
|
+
check_absolute_cwd "$4"
|
|
89
|
+
[ "$5" = --branch ] || fail "$@"
|
|
90
|
+
check_value "$6"
|
|
91
|
+
[ "$7" = --label ] || fail "$@"
|
|
92
|
+
check_value "$8"
|
|
93
|
+
[ "$9" = --no-focus ] || fail "$@"
|
|
94
|
+
case "$6" in
|
|
95
|
+
MISSING-*) emit_error error-worktree-not-found.json ;;
|
|
96
|
+
esac
|
|
97
|
+
emit_result worktree-open.json
|
|
98
|
+
;;
|
|
99
|
+
9:tab:create)
|
|
100
|
+
[ "$3" = --workspace ] || fail "$@"
|
|
101
|
+
check_value "$4"
|
|
102
|
+
[ "$5" = --cwd ] || fail "$@"
|
|
103
|
+
check_absolute_cwd "$6"
|
|
104
|
+
[ "$7" = --label ] || fail "$@"
|
|
105
|
+
check_value "$8"
|
|
106
|
+
[ "$9" = --no-focus ] || fail "$@"
|
|
107
|
+
emit_result tab-create.json
|
|
108
|
+
;;
|
|
109
|
+
4:tab:list)
|
|
110
|
+
[ "$3" = --workspace ] || fail "$@"
|
|
111
|
+
check_value "$4"
|
|
112
|
+
case "$4" in
|
|
113
|
+
empty) emit_result empty-tabs.json ;;
|
|
114
|
+
missing) emit_error error-workspace-not-found.json ;;
|
|
115
|
+
*) emit_result tab-list.json ;;
|
|
116
|
+
esac
|
|
117
|
+
;;
|
|
118
|
+
4:pane:list)
|
|
119
|
+
[ "$3" = --workspace ] || fail "$@"
|
|
120
|
+
check_value "$4"
|
|
121
|
+
case "$4" in
|
|
122
|
+
empty) emit_result empty-panes.json ;;
|
|
123
|
+
missing) emit_error error-workspace-not-found.json ;;
|
|
124
|
+
*) emit_result pane-list.json ;;
|
|
125
|
+
esac
|
|
126
|
+
;;
|
|
127
|
+
3:pane:get)
|
|
128
|
+
check_value "$3"
|
|
129
|
+
case "$3" in
|
|
130
|
+
malformed) emit_result malformed.json ;;
|
|
131
|
+
warning) printf 'captured warning\n' >&2; emit_result pane-get.json ;;
|
|
132
|
+
missing) emit_error error-pane-not-found.json ;;
|
|
133
|
+
*) emit_result pane-get.json ;;
|
|
134
|
+
esac
|
|
135
|
+
;;
|
|
136
|
+
4:pane:process-info)
|
|
137
|
+
[ "$3" = --pane ] || fail "$@"
|
|
138
|
+
check_value "$4"
|
|
139
|
+
case "$4" in
|
|
140
|
+
shell) emit_result pane-process-info-shell.json ;;
|
|
141
|
+
missing) emit_error error-pane-not-found.json ;;
|
|
142
|
+
*) emit_result pane-process-info.json ;;
|
|
143
|
+
esac
|
|
144
|
+
;;
|
|
145
|
+
4:pane:rename)
|
|
146
|
+
check_value "$3"
|
|
147
|
+
check_value "$4"
|
|
148
|
+
emit_result pane-rename.json
|
|
149
|
+
;;
|
|
150
|
+
4:pane:run)
|
|
151
|
+
# COMMAND is deliberately one logical argument: a command containing
|
|
152
|
+
# spaces or newlines must arrive as the same argument the wrapper passed
|
|
153
|
+
# to exec.CommandContext. Herdr prints nothing on success.
|
|
154
|
+
check_value "$3"
|
|
155
|
+
[ -n "$4" ] || fail "empty command"
|
|
156
|
+
exit 0
|
|
157
|
+
;;
|
|
158
|
+
3:pane:close)
|
|
159
|
+
check_value "$3"
|
|
160
|
+
case "$3" in
|
|
161
|
+
missing) emit_error error-pane-not-found.json ;;
|
|
162
|
+
*) emit_result pane-close.json ;;
|
|
163
|
+
esac
|
|
164
|
+
;;
|
|
165
|
+
3:workspace:close)
|
|
166
|
+
check_value "$3"
|
|
167
|
+
case "$3" in
|
|
168
|
+
missing) emit_error error-workspace-not-found.json ;;
|
|
169
|
+
*) emit_result workspace-close.json ;;
|
|
170
|
+
esac
|
|
171
|
+
;;
|
|
172
|
+
*)
|
|
173
|
+
fail "$@"
|
|
174
|
+
;;
|
|
175
|
+
esac
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cli:tab:create",
|
|
3
|
+
"result": {
|
|
4
|
+
"root_pane": {
|
|
5
|
+
"agent_status": "unknown",
|
|
6
|
+
"cwd": "/work/worktrees/payments/pay-101",
|
|
7
|
+
"focused": false,
|
|
8
|
+
"foreground_cwd": "/work/worktrees/payments/pay-101",
|
|
9
|
+
"pane_id": "w2:p2",
|
|
10
|
+
"revision": 0,
|
|
11
|
+
"scroll": {
|
|
12
|
+
"max_offset_from_bottom": 0,
|
|
13
|
+
"offset_from_bottom": 0,
|
|
14
|
+
"viewport_rows": 39
|
|
15
|
+
},
|
|
16
|
+
"tab_id": "w2:t2",
|
|
17
|
+
"terminal_id": "term_65a5cfcc913e03",
|
|
18
|
+
"workspace_id": "w2"
|
|
19
|
+
},
|
|
20
|
+
"tab": {
|
|
21
|
+
"agent_status": "unknown",
|
|
22
|
+
"focused": false,
|
|
23
|
+
"label": "PAY-101:coding",
|
|
24
|
+
"number": 2,
|
|
25
|
+
"pane_count": 1,
|
|
26
|
+
"tab_id": "w2:t2",
|
|
27
|
+
"workspace_id": "w2"
|
|
28
|
+
},
|
|
29
|
+
"type": "tab_created"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cli:tab:list",
|
|
3
|
+
"result": {
|
|
4
|
+
"tabs": [
|
|
5
|
+
{
|
|
6
|
+
"agent_status": "unknown",
|
|
7
|
+
"focused": false,
|
|
8
|
+
"label": "1",
|
|
9
|
+
"number": 1,
|
|
10
|
+
"pane_count": 1,
|
|
11
|
+
"tab_id": "w2:t1",
|
|
12
|
+
"workspace_id": "w2"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"agent_status": "unknown",
|
|
16
|
+
"focused": false,
|
|
17
|
+
"label": "PAY-101:coding",
|
|
18
|
+
"number": 2,
|
|
19
|
+
"pane_count": 1,
|
|
20
|
+
"tab_id": "w2:t2",
|
|
21
|
+
"workspace_id": "w2"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"type": "tab_list"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cli:worktree:create",
|
|
3
|
+
"result": {
|
|
4
|
+
"root_pane": {
|
|
5
|
+
"agent_status": "unknown",
|
|
6
|
+
"cwd": "/work/worktrees/payments/pay-101",
|
|
7
|
+
"focused": false,
|
|
8
|
+
"foreground_cwd": "/work/worktrees/payments/pay-101",
|
|
9
|
+
"pane_id": "w2:p1",
|
|
10
|
+
"revision": 0,
|
|
11
|
+
"scroll": {
|
|
12
|
+
"max_offset_from_bottom": 0,
|
|
13
|
+
"offset_from_bottom": 0,
|
|
14
|
+
"viewport_rows": 40
|
|
15
|
+
},
|
|
16
|
+
"tab_id": "w2:t1",
|
|
17
|
+
"terminal_id": "term_65a5cfcc8cd9e2",
|
|
18
|
+
"workspace_id": "w2"
|
|
19
|
+
},
|
|
20
|
+
"tab": {
|
|
21
|
+
"agent_status": "unknown",
|
|
22
|
+
"focused": false,
|
|
23
|
+
"label": "1",
|
|
24
|
+
"number": 1,
|
|
25
|
+
"pane_count": 1,
|
|
26
|
+
"tab_id": "w2:t1",
|
|
27
|
+
"workspace_id": "w2"
|
|
28
|
+
},
|
|
29
|
+
"type": "worktree_created",
|
|
30
|
+
"workspace": {
|
|
31
|
+
"active_tab_id": "w2:t1",
|
|
32
|
+
"agent_status": "unknown",
|
|
33
|
+
"focused": false,
|
|
34
|
+
"label": "PAY-101",
|
|
35
|
+
"number": 2,
|
|
36
|
+
"pane_count": 1,
|
|
37
|
+
"tab_count": 1,
|
|
38
|
+
"workspace_id": "w2",
|
|
39
|
+
"worktree": {
|
|
40
|
+
"checkout_path": "/work/worktrees/payments/pay-101",
|
|
41
|
+
"is_linked_worktree": true,
|
|
42
|
+
"repo_key": "/work/payments/.git",
|
|
43
|
+
"repo_name": "repo",
|
|
44
|
+
"repo_root": "/work/payments"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"worktree": {
|
|
48
|
+
"branch": "PAY-101",
|
|
49
|
+
"is_bare": false,
|
|
50
|
+
"is_detached": false,
|
|
51
|
+
"is_linked_worktree": true,
|
|
52
|
+
"is_prunable": false,
|
|
53
|
+
"label": "repo",
|
|
54
|
+
"open_workspace_id": "w2",
|
|
55
|
+
"path": "/work/worktrees/payments/pay-101"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cli:worktree:list",
|
|
3
|
+
"result": {
|
|
4
|
+
"source": {
|
|
5
|
+
"repo_key": "/work/payments/.git",
|
|
6
|
+
"repo_name": "repo",
|
|
7
|
+
"repo_root": "/work/payments",
|
|
8
|
+
"source_checkout_path": "/work/payments",
|
|
9
|
+
"source_workspace_id": "w1"
|
|
10
|
+
},
|
|
11
|
+
"type": "worktree_list",
|
|
12
|
+
"worktrees": [
|
|
13
|
+
{
|
|
14
|
+
"branch": "main",
|
|
15
|
+
"is_bare": false,
|
|
16
|
+
"is_detached": false,
|
|
17
|
+
"is_linked_worktree": false,
|
|
18
|
+
"is_prunable": false,
|
|
19
|
+
"label": "repo",
|
|
20
|
+
"open_workspace_id": "w1",
|
|
21
|
+
"path": "/work/payments"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"branch": "PAY-101",
|
|
25
|
+
"is_bare": false,
|
|
26
|
+
"is_detached": false,
|
|
27
|
+
"is_linked_worktree": true,
|
|
28
|
+
"is_prunable": false,
|
|
29
|
+
"label": "repo",
|
|
30
|
+
"open_workspace_id": "w2",
|
|
31
|
+
"path": "/work/worktrees/payments/pay-101"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cli:worktree:open",
|
|
3
|
+
"result": {
|
|
4
|
+
"already_open": true,
|
|
5
|
+
"root_pane": {
|
|
6
|
+
"agent_status": "unknown",
|
|
7
|
+
"cwd": "/work/worktrees/payments/pay-101",
|
|
8
|
+
"focused": false,
|
|
9
|
+
"foreground_cwd": "/work/worktrees/payments/pay-101",
|
|
10
|
+
"pane_id": "w2:p1",
|
|
11
|
+
"revision": 0,
|
|
12
|
+
"scroll": {
|
|
13
|
+
"max_offset_from_bottom": 0,
|
|
14
|
+
"offset_from_bottom": 0,
|
|
15
|
+
"viewport_rows": 39
|
|
16
|
+
},
|
|
17
|
+
"tab_id": "w2:t1",
|
|
18
|
+
"terminal_id": "term_65a5cfcc8cd9e2",
|
|
19
|
+
"workspace_id": "w2"
|
|
20
|
+
},
|
|
21
|
+
"tab": {
|
|
22
|
+
"agent_status": "unknown",
|
|
23
|
+
"focused": false,
|
|
24
|
+
"label": "1",
|
|
25
|
+
"number": 1,
|
|
26
|
+
"pane_count": 1,
|
|
27
|
+
"tab_id": "w2:t1",
|
|
28
|
+
"workspace_id": "w2"
|
|
29
|
+
},
|
|
30
|
+
"type": "worktree_opened",
|
|
31
|
+
"workspace": {
|
|
32
|
+
"active_tab_id": "w2:t1",
|
|
33
|
+
"agent_status": "unknown",
|
|
34
|
+
"focused": false,
|
|
35
|
+
"label": "PAY-101",
|
|
36
|
+
"number": 2,
|
|
37
|
+
"pane_count": 1,
|
|
38
|
+
"tab_count": 1,
|
|
39
|
+
"workspace_id": "w2",
|
|
40
|
+
"worktree": {
|
|
41
|
+
"checkout_path": "/work/worktrees/payments/pay-101",
|
|
42
|
+
"is_linked_worktree": true,
|
|
43
|
+
"repo_key": "/work/payments/.git",
|
|
44
|
+
"repo_name": "repo",
|
|
45
|
+
"repo_root": "/work/payments"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"worktree": {
|
|
49
|
+
"branch": "PAY-101",
|
|
50
|
+
"is_bare": false,
|
|
51
|
+
"is_detached": false,
|
|
52
|
+
"is_linked_worktree": true,
|
|
53
|
+
"is_prunable": false,
|
|
54
|
+
"label": "repo",
|
|
55
|
+
"open_workspace_id": "w2",
|
|
56
|
+
"path": "/work/worktrees/payments/pay-101"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -328,9 +328,6 @@ func (s *system) CompileFilter(workflowTaskConfig config.RawValues) (func(task.T
|
|
|
328
328
|
return nil, err
|
|
329
329
|
}
|
|
330
330
|
f := cfg.Filters
|
|
331
|
-
if !hasAssigneeFilter(merged) && cfg.Assignee != "" {
|
|
332
|
-
f.Assignees = []string{cfg.Assignee}
|
|
333
|
-
}
|
|
334
331
|
return func(ticket task.Ticket) bool {
|
|
335
332
|
if len(f.ParentStatuses) > 0 && !containsExact(f.ParentStatuses, stringField(ticket.Fields, "status")) {
|
|
336
333
|
return false
|
|
@@ -353,19 +350,6 @@ func (s *system) CompileFilter(workflowTaskConfig config.RawValues) (func(task.T
|
|
|
353
350
|
}, nil
|
|
354
351
|
}
|
|
355
352
|
|
|
356
|
-
func hasAssigneeFilter(raw config.RawValues) bool {
|
|
357
|
-
switch filters := raw["filters"].(type) {
|
|
358
|
-
case map[string]any:
|
|
359
|
-
_, ok := filters["assignees"]
|
|
360
|
-
return ok
|
|
361
|
-
case config.RawValues:
|
|
362
|
-
_, ok := filters["assignees"]
|
|
363
|
-
return ok
|
|
364
|
-
default:
|
|
365
|
-
return false
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
353
|
func containsExact(values []string, want string) bool {
|
|
370
354
|
for _, value := range values {
|
|
371
355
|
if value == want {
|
|
@@ -50,7 +50,7 @@ func TestBeadsConfigRejectsJiraOnlyFields(t *testing.T) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
func
|
|
53
|
+
func TestBeadsCompileFilterDoesNotUseTopLevelAssignee(t *testing.T) {
|
|
54
54
|
sys := &system{base: config.Merge(DefaultConfig(), config.RawValues{
|
|
55
55
|
"assignee": "Repo.Bot@Example.com",
|
|
56
56
|
})}
|
|
@@ -58,15 +58,14 @@ func TestBeadsCompileFilterUsesInheritedTopLevelAssignee(t *testing.T) {
|
|
|
58
58
|
if err != nil {
|
|
59
59
|
t.Fatalf("CompileFilter failed: %v", err)
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
t.Fatal("ticket assigned to another user matched the default assignee filter")
|
|
61
|
+
for _, assignee := range []string{"repo.bot@example.COM", "other@example.com"} {
|
|
62
|
+
if !match(task.Ticket{Fields: map[string]any{"assignee": assignee}}) {
|
|
63
|
+
t.Fatalf("assignee %q was filtered without filters.assignees", assignee)
|
|
64
|
+
}
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
func
|
|
68
|
+
func TestBeadsExplicitAssigneeFilterIsUsed(t *testing.T) {
|
|
70
69
|
sys := &system{base: config.Merge(DefaultConfig(), config.RawValues{
|
|
71
70
|
"assignee": "repo@example.com",
|
|
72
71
|
})}
|
|
@@ -84,7 +83,7 @@ func TestBeadsExplicitAssigneeFilterOverridesInheritedDefault(t *testing.T) {
|
|
|
84
83
|
}
|
|
85
84
|
for _, assignee := range []string{"repo@example.com", "workflow@example.com"} {
|
|
86
85
|
if match(task.Ticket{Fields: map[string]any{"assignee": assignee}}) {
|
|
87
|
-
t.Fatalf("
|
|
86
|
+
t.Fatalf("explicit assignee filter accepted %q", assignee)
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
}
|