@osfactory/har 0.16.2 → 0.18.0
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/dist/index.js +736 -469
- package/dist/templates/cursor-rule.mdc.template +1 -1
- package/dist/templates/har-boilerplate/agent-slot.sh +3 -9
- package/dist/templates/har-boilerplate/launch.sh +1 -8
- package/dist/templates/har-boilerplate-cli/agent-cli.sh +0 -2
- package/dist/templates/har-boilerplate-cli/agent-slot.sh +3 -9
- package/dist/templates/har-boilerplate-cli/launch.sh +1 -8
- package/dist/templates/har-boilerplate-ios/agent-slot.sh +2 -5
- package/dist/templates/har-boilerplate-ios/launch.sh +1 -6
- package/package.json +1 -1
|
@@ -30,7 +30,7 @@ Relaunching a slot **replaces** its previous session (the old branch is kept). R
|
|
|
30
30
|
- **Never** set `force`/`confirmReplace` without the user explicitly approving replacement.
|
|
31
31
|
- **Commit early and often** in the session worktree — teardown keeps the branch, not uncommitted work.
|
|
32
32
|
- **Gitignored paths are ephemeral** (`state/`, `runs/`, local clones) — they are lost when the worktree is removed.
|
|
33
|
-
- Optional: set `HAR_SESSION_PURPOSE=label
|
|
33
|
+
- Optional: set `har env launch <id> --purpose=label`, `HAR_SESSION_PURPOSE=label`, or `./.har/launch.sh <id> --purpose=label` so occupied-slot warnings show what you were doing.
|
|
34
34
|
|
|
35
35
|
<!-- Monorepo: if this repository contains multiple .har harnesses, list them here
|
|
36
36
|
and pick by the files you are changing. Example:
|
|
@@ -233,7 +233,7 @@ slot_is_resumable() {
|
|
|
233
233
|
# Echo shell assignments for launch.sh — eval after validating resumability.
|
|
234
234
|
har_resume_session_assignments() {
|
|
235
235
|
local agent_id="$1"
|
|
236
|
-
local reg work_dir worktree branch suffix base_branch base_commit
|
|
236
|
+
local reg work_dir worktree branch suffix base_branch base_commit mode env_file
|
|
237
237
|
|
|
238
238
|
if ! slot_is_resumable "$agent_id"; then
|
|
239
239
|
local status
|
|
@@ -251,7 +251,6 @@ har_resume_session_assignments() {
|
|
|
251
251
|
suffix="$(read_slot_field "$reg" suffix || true)"
|
|
252
252
|
base_branch="$(read_slot_field "$reg" baseBranch || true)"
|
|
253
253
|
base_commit="$(read_slot_field "$reg" baseCommit || true)"
|
|
254
|
-
purpose="$(read_slot_field "$reg" purpose || true)"
|
|
255
254
|
mode="$(read_slot_field "$reg" mode || true)"
|
|
256
255
|
|
|
257
256
|
if [ -z "$work_dir" ] || [ ! -d "$work_dir" ]; then
|
|
@@ -274,7 +273,6 @@ har_resume_session_assignments() {
|
|
|
274
273
|
"SUFFIX='${suffix}'" \
|
|
275
274
|
"BASE_BRANCH='${base_branch}'" \
|
|
276
275
|
"BASE_COMMIT='${base_commit}'" \
|
|
277
|
-
"PURPOSE='${purpose}'" \
|
|
278
276
|
"USE_WORKTREE=$([ "$mode" = worktree ] && echo true || echo false)" \
|
|
279
277
|
"ENV_FILE='${env_file}'"
|
|
280
278
|
}
|
|
@@ -318,7 +316,6 @@ har_regenerate_agent_env_file() {
|
|
|
318
316
|
--work-dir "$work_dir" \
|
|
319
317
|
${SLOT_BRANCH:+--branch "$SLOT_BRANCH"} \
|
|
320
318
|
${SLOT_SUFFIX:+--suffix "$SLOT_SUFFIX"} \
|
|
321
|
-
${SLOT_PURPOSE:+--purpose "$SLOT_PURPOSE"} \
|
|
322
319
|
>/dev/null 2>&1 || true
|
|
323
320
|
fi
|
|
324
321
|
}
|
|
@@ -450,7 +447,7 @@ try {
|
|
|
450
447
|
# required: SLOT_AGENT_ID, SLOT_MODE (worktree|root), SLOT_WORK_DIR
|
|
451
448
|
# optional: SLOT_SUFFIX, SLOT_WORKTREE_PATH, SLOT_BRANCH, SLOT_BASE_BRANCH,
|
|
452
449
|
# SLOT_BASE_COMMIT, SLOT_PORTS_JSON, SLOT_PREVIEW_URLS_JSON,
|
|
453
|
-
#
|
|
450
|
+
# SLOT_STATUS, SLOT_LAST_ERROR
|
|
454
451
|
write_slot_registry() {
|
|
455
452
|
local file
|
|
456
453
|
file="$(slot_registry_file "$SLOT_AGENT_ID")"
|
|
@@ -472,7 +469,6 @@ if (e.SLOT_WORKTREE_PATH) entry.worktreePath = e.SLOT_WORKTREE_PATH;
|
|
|
472
469
|
if (e.SLOT_BRANCH) entry.branch = e.SLOT_BRANCH;
|
|
473
470
|
if (e.SLOT_BASE_BRANCH) entry.baseBranch = e.SLOT_BASE_BRANCH;
|
|
474
471
|
if (e.SLOT_BASE_COMMIT) entry.baseCommit = e.SLOT_BASE_COMMIT;
|
|
475
|
-
if (e.SLOT_PURPOSE) entry.purpose = e.SLOT_PURPOSE;
|
|
476
472
|
if (e.SLOT_LAST_ERROR) entry.lastError = e.SLOT_LAST_ERROR;
|
|
477
473
|
for (const [key, env] of [["ports", "SLOT_PORTS_JSON"], ["previewUrls", "SLOT_PREVIEW_URLS_JSON"]]) {
|
|
478
474
|
if (e[env]) try { entry[key] = JSON.parse(e[env]); } catch {}
|
|
@@ -516,12 +512,11 @@ slot_dirty_summary() {
|
|
|
516
512
|
# Print a warning before replacing an occupied slot (stdout — visible to agents).
|
|
517
513
|
print_slot_replace_warning() {
|
|
518
514
|
local agent_id="$1"
|
|
519
|
-
local reg wt branch work_dir
|
|
515
|
+
local reg wt branch work_dir created status last_error dirty_summary head
|
|
520
516
|
reg="$(slot_registry_file "$agent_id")"
|
|
521
517
|
wt="$(existing_slot_worktree "$agent_id")"
|
|
522
518
|
branch="$(read_slot_field "$reg" branch || true)"
|
|
523
519
|
work_dir="$(read_slot_field "$reg" workDir || true)"
|
|
524
|
-
purpose="$(read_slot_field "$reg" purpose || true)"
|
|
525
520
|
created="$(read_slot_field "$reg" createdAt || true)"
|
|
526
521
|
status="$(read_slot_field "$reg" status || true)"
|
|
527
522
|
last_error="$(read_slot_field "$reg" lastError || true)"
|
|
@@ -532,7 +527,6 @@ print_slot_replace_warning() {
|
|
|
532
527
|
|
|
533
528
|
echo "" >&2
|
|
534
529
|
echo "⚠ Slot ${agent_id} is already in use — replacing will REMOVE the worktree." >&2
|
|
535
|
-
[ -n "$purpose" ] && echo " Purpose: ${purpose}" >&2
|
|
536
530
|
[ -n "$wt" ] && echo " Worktree: ${wt}" >&2
|
|
537
531
|
[ -n "$work_dir" ] && echo " Work dir: ${work_dir}" >&2
|
|
538
532
|
[ -n "$branch" ] && echo " Branch: ${branch}${head:+ @ ${head}}" >&2
|
|
@@ -20,7 +20,6 @@ USE_CLAUDE=false
|
|
|
20
20
|
FORCE=false
|
|
21
21
|
REPLACE=false
|
|
22
22
|
RESUME=false
|
|
23
|
-
PURPOSE="${HAR_SESSION_PURPOSE:-}"
|
|
24
23
|
|
|
25
24
|
for arg in "$@"; do
|
|
26
25
|
case "$arg" in
|
|
@@ -30,13 +29,12 @@ for arg in "$@"; do
|
|
|
30
29
|
--replace) REPLACE=true ;;
|
|
31
30
|
--force) FORCE=true ;;
|
|
32
31
|
--resume) RESUME=true ;;
|
|
33
|
-
--purpose=*) PURPOSE="${arg#--purpose=}" ;;
|
|
34
32
|
esac
|
|
35
33
|
done
|
|
36
34
|
|
|
37
35
|
if [[ -z "$AGENT_ID" ]]; then
|
|
38
36
|
har_load_agent_slot_limits
|
|
39
|
-
echo "Usage: $0 <agent-id> [--no-worktree] [--claude] [--replace] [--force] [--resume]
|
|
37
|
+
echo "Usage: $0 <agent-id> [--no-worktree] [--claude] [--replace] [--force] [--resume] " >&2
|
|
40
38
|
echo " agent-id must be between ${HARNESS_AGENT_SLOT_MIN} and ${HARNESS_AGENT_SLOT_MAX}" >&2
|
|
41
39
|
exit 1
|
|
42
40
|
fi
|
|
@@ -71,7 +69,6 @@ if [ "$RESUME" = true ]; then
|
|
|
71
69
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
72
70
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
73
71
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
74
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
75
72
|
SLOT_PORTS_JSON="{\"frontend\":${FE_PORT},\"api\":${API_PORT},\"debug\":${DEBUG_PORT},\"db\":${DB_PORT}}" \
|
|
76
73
|
SLOT_PREVIEW_URLS_JSON="{\"frontend\":\"http://localhost:${FE_PORT}\",\"api\":\"http://localhost:${API_PORT}\"}" \
|
|
77
74
|
SLOT_STATUS="failed" \
|
|
@@ -179,7 +176,6 @@ if [ "$RESUME" != true ]; then
|
|
|
179
176
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
180
177
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
181
178
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
182
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
183
179
|
SLOT_PORTS_JSON="{\"frontend\":${FE_PORT},\"api\":${API_PORT},\"debug\":${DEBUG_PORT},\"db\":${DB_PORT}}" \
|
|
184
180
|
SLOT_PREVIEW_URLS_JSON="{\"frontend\":\"http://localhost:${FE_PORT}\",\"api\":\"http://localhost:${API_PORT}\"}" \
|
|
185
181
|
SLOT_STATUS="failed" \
|
|
@@ -200,7 +196,6 @@ if [ "$RESUME" != true ]; then
|
|
|
200
196
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
201
197
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
202
198
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
203
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
204
199
|
SLOT_PORTS_JSON="{\"frontend\":${FE_PORT},\"api\":${API_PORT},\"debug\":${DEBUG_PORT},\"db\":${DB_PORT}}" \
|
|
205
200
|
SLOT_PREVIEW_URLS_JSON="{\"frontend\":\"http://localhost:${FE_PORT}\",\"api\":\"http://localhost:${API_PORT}\"}" \
|
|
206
201
|
SLOT_STATUS="starting" \
|
|
@@ -218,7 +213,6 @@ else
|
|
|
218
213
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
219
214
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
220
215
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
221
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
222
216
|
SLOT_PORTS_JSON="{\"frontend\":${FE_PORT},\"api\":${API_PORT},\"debug\":${DEBUG_PORT},\"db\":${DB_PORT}}" \
|
|
223
217
|
SLOT_PREVIEW_URLS_JSON="{\"frontend\":\"http://localhost:${FE_PORT}\",\"api\":\"http://localhost:${API_PORT}\"}" \
|
|
224
218
|
SLOT_STATUS="starting" \
|
|
@@ -293,7 +287,6 @@ SLOT_WORKTREE_PATH="${WORKTREE_DIR:-}" \
|
|
|
293
287
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
294
288
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
295
289
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
296
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
297
290
|
SLOT_PORTS_JSON="{\"frontend\":${FE_PORT},\"api\":${API_PORT},\"debug\":${DEBUG_PORT},\"db\":${DB_PORT}}" \
|
|
298
291
|
SLOT_PREVIEW_URLS_JSON="{\"frontend\":\"http://localhost:${FE_PORT}\",\"api\":\"http://localhost:${API_PORT}\"}" \
|
|
299
292
|
SLOT_STATUS="active" \
|
|
@@ -46,9 +46,7 @@ case "$COMMAND" in
|
|
|
46
46
|
echo " Work dir: $(resolve_agent_work_dir "$ENV_FILE" "$AGENT_ID")"
|
|
47
47
|
[ -n "$WT" ] && [ -d "$WT" ] && echo " Worktree: $WT"
|
|
48
48
|
BRANCH="$(read_slot_field "$REGISTRY_FILE" branch || true)"
|
|
49
|
-
PURPOSE="$(read_slot_field "$REGISTRY_FILE" purpose || true)"
|
|
50
49
|
CREATED="$(read_slot_field "$REGISTRY_FILE" createdAt || true)"
|
|
51
|
-
[ -n "$PURPOSE" ] && echo " Purpose: $PURPOSE"
|
|
52
50
|
[ -n "$BRANCH" ] && echo " Branch: $BRANCH"
|
|
53
51
|
[ -n "$CREATED" ] && echo " Since: $CREATED"
|
|
54
52
|
[ -n "$WT" ] && echo " Git: $(slot_dirty_summary "$WT")"
|
|
@@ -211,7 +211,7 @@ slot_is_resumable() {
|
|
|
211
211
|
|
|
212
212
|
har_resume_session_assignments() {
|
|
213
213
|
local agent_id="$1"
|
|
214
|
-
local reg work_dir worktree branch suffix base_branch base_commit
|
|
214
|
+
local reg work_dir worktree branch suffix base_branch base_commit mode env_file
|
|
215
215
|
|
|
216
216
|
if ! slot_is_resumable "$agent_id"; then
|
|
217
217
|
local status
|
|
@@ -229,7 +229,6 @@ har_resume_session_assignments() {
|
|
|
229
229
|
suffix="$(read_slot_field "$reg" suffix || true)"
|
|
230
230
|
base_branch="$(read_slot_field "$reg" baseBranch || true)"
|
|
231
231
|
base_commit="$(read_slot_field "$reg" baseCommit || true)"
|
|
232
|
-
purpose="$(read_slot_field "$reg" purpose || true)"
|
|
233
232
|
mode="$(read_slot_field "$reg" mode || true)"
|
|
234
233
|
|
|
235
234
|
if [ -z "$work_dir" ] || [ ! -d "$work_dir" ]; then
|
|
@@ -252,7 +251,6 @@ har_resume_session_assignments() {
|
|
|
252
251
|
"SUFFIX='${suffix}'" \
|
|
253
252
|
"BASE_BRANCH='${base_branch}'" \
|
|
254
253
|
"BASE_COMMIT='${base_commit}'" \
|
|
255
|
-
"PURPOSE='${purpose}'" \
|
|
256
254
|
"USE_WORKTREE=$([ "$mode" = worktree ] && echo true || echo false)" \
|
|
257
255
|
"ENV_FILE='${env_file}'"
|
|
258
256
|
}
|
|
@@ -302,7 +300,6 @@ EOF
|
|
|
302
300
|
--work-dir "$work_dir" \
|
|
303
301
|
${SLOT_BRANCH:+--branch "$SLOT_BRANCH"} \
|
|
304
302
|
${SLOT_SUFFIX:+--suffix "$SLOT_SUFFIX"} \
|
|
305
|
-
${SLOT_PURPOSE:+--purpose "$SLOT_PURPOSE"} \
|
|
306
303
|
>/dev/null 2>&1 || true
|
|
307
304
|
fi
|
|
308
305
|
}
|
|
@@ -430,7 +427,7 @@ try {
|
|
|
430
427
|
# required: SLOT_AGENT_ID, SLOT_MODE (worktree|root), SLOT_WORK_DIR
|
|
431
428
|
# optional: SLOT_SUFFIX, SLOT_WORKTREE_PATH, SLOT_BRANCH, SLOT_BASE_BRANCH,
|
|
432
429
|
# SLOT_BASE_COMMIT, SLOT_PORTS_JSON, SLOT_PREVIEW_URLS_JSON,
|
|
433
|
-
#
|
|
430
|
+
# SLOT_STATUS, SLOT_LAST_ERROR
|
|
434
431
|
write_slot_registry() {
|
|
435
432
|
local file
|
|
436
433
|
file="$(slot_registry_file "$SLOT_AGENT_ID")"
|
|
@@ -452,7 +449,6 @@ if (e.SLOT_WORKTREE_PATH) entry.worktreePath = e.SLOT_WORKTREE_PATH;
|
|
|
452
449
|
if (e.SLOT_BRANCH) entry.branch = e.SLOT_BRANCH;
|
|
453
450
|
if (e.SLOT_BASE_BRANCH) entry.baseBranch = e.SLOT_BASE_BRANCH;
|
|
454
451
|
if (e.SLOT_BASE_COMMIT) entry.baseCommit = e.SLOT_BASE_COMMIT;
|
|
455
|
-
if (e.SLOT_PURPOSE) entry.purpose = e.SLOT_PURPOSE;
|
|
456
452
|
if (e.SLOT_LAST_ERROR) entry.lastError = e.SLOT_LAST_ERROR;
|
|
457
453
|
for (const [key, env] of [["ports", "SLOT_PORTS_JSON"], ["previewUrls", "SLOT_PREVIEW_URLS_JSON"]]) {
|
|
458
454
|
if (e[env]) try { entry[key] = JSON.parse(e[env]); } catch {}
|
|
@@ -496,12 +492,11 @@ slot_dirty_summary() {
|
|
|
496
492
|
# Print a warning before replacing an occupied slot (stdout — visible to agents).
|
|
497
493
|
print_slot_replace_warning() {
|
|
498
494
|
local agent_id="$1"
|
|
499
|
-
local reg wt branch work_dir
|
|
495
|
+
local reg wt branch work_dir created status last_error dirty_summary head
|
|
500
496
|
reg="$(slot_registry_file "$agent_id")"
|
|
501
497
|
wt="$(existing_slot_worktree "$agent_id")"
|
|
502
498
|
branch="$(read_slot_field "$reg" branch || true)"
|
|
503
499
|
work_dir="$(read_slot_field "$reg" workDir || true)"
|
|
504
|
-
purpose="$(read_slot_field "$reg" purpose || true)"
|
|
505
500
|
created="$(read_slot_field "$reg" createdAt || true)"
|
|
506
501
|
status="$(read_slot_field "$reg" status || true)"
|
|
507
502
|
last_error="$(read_slot_field "$reg" lastError || true)"
|
|
@@ -512,7 +507,6 @@ print_slot_replace_warning() {
|
|
|
512
507
|
|
|
513
508
|
echo "" >&2
|
|
514
509
|
echo "⚠ Slot ${agent_id} is already in use — replacing will REMOVE the worktree." >&2
|
|
515
|
-
[ -n "$purpose" ] && echo " Purpose: ${purpose}" >&2
|
|
516
510
|
[ -n "$wt" ] && echo " Worktree: ${wt}" >&2
|
|
517
511
|
[ -n "$work_dir" ] && echo " Work dir: ${work_dir}" >&2
|
|
518
512
|
[ -n "$branch" ] && echo " Branch: ${branch}${head:+ @ ${head}}" >&2
|
|
@@ -19,7 +19,6 @@ USE_WORKTREE="${HARNESS_USE_WORKTREE:-true}"
|
|
|
19
19
|
FORCE=false
|
|
20
20
|
REPLACE=false
|
|
21
21
|
RESUME=false
|
|
22
|
-
PURPOSE="${HAR_SESSION_PURPOSE:-}"
|
|
23
22
|
|
|
24
23
|
for arg in "$@"; do
|
|
25
24
|
case "$arg" in
|
|
@@ -28,13 +27,12 @@ for arg in "$@"; do
|
|
|
28
27
|
--replace) REPLACE=true ;;
|
|
29
28
|
--force) FORCE=true ;;
|
|
30
29
|
--resume) RESUME=true ;;
|
|
31
|
-
--purpose=*) PURPOSE="${arg#--purpose=}" ;;
|
|
32
30
|
esac
|
|
33
31
|
done
|
|
34
32
|
|
|
35
33
|
if [[ -z "$AGENT_ID" ]]; then
|
|
36
34
|
har_load_agent_slot_limits
|
|
37
|
-
echo "Usage: $0 <agent-id> [--no-worktree] [--replace] [--force] [--resume]
|
|
35
|
+
echo "Usage: $0 <agent-id> [--no-worktree] [--replace] [--force] [--resume] " >&2
|
|
38
36
|
echo " agent-id must be between ${HARNESS_AGENT_SLOT_MIN} and ${HARNESS_AGENT_SLOT_MAX}" >&2
|
|
39
37
|
exit 1
|
|
40
38
|
fi
|
|
@@ -69,7 +67,6 @@ if [ "$RESUME" = true ]; then
|
|
|
69
67
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
70
68
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
71
69
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
72
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
73
70
|
SLOT_STATUS="failed" \
|
|
74
71
|
SLOT_LAST_ERROR="launch.sh --resume exited with code ${exit_code}" \
|
|
75
72
|
write_slot_registry
|
|
@@ -140,7 +137,6 @@ if [ "$RESUME" != true ]; then
|
|
|
140
137
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
141
138
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
142
139
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
143
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
144
140
|
SLOT_STATUS="failed" \
|
|
145
141
|
SLOT_LAST_ERROR="launch.sh exited with code ${exit_code}" \
|
|
146
142
|
write_slot_registry
|
|
@@ -159,7 +155,6 @@ if [ "$RESUME" != true ]; then
|
|
|
159
155
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
160
156
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
161
157
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
162
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
163
158
|
SLOT_STATUS="starting" \
|
|
164
159
|
write_slot_registry
|
|
165
160
|
REGISTRY_WRITTEN=true
|
|
@@ -175,7 +170,6 @@ else
|
|
|
175
170
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
176
171
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
177
172
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
178
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
179
173
|
SLOT_STATUS="starting" \
|
|
180
174
|
write_slot_registry
|
|
181
175
|
fi
|
|
@@ -203,7 +197,6 @@ SLOT_WORKTREE_PATH="${WORKTREE_DIR:-}" \
|
|
|
203
197
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
204
198
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
205
199
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
206
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
207
200
|
SLOT_STATUS="active" \
|
|
208
201
|
write_slot_registry
|
|
209
202
|
|
|
@@ -88,7 +88,7 @@ try {
|
|
|
88
88
|
# required: SLOT_AGENT_ID, SLOT_MODE (worktree|root), SLOT_WORK_DIR
|
|
89
89
|
# optional: SLOT_SUFFIX, SLOT_WORKTREE_PATH, SLOT_BRANCH, SLOT_BASE_BRANCH,
|
|
90
90
|
# SLOT_BASE_COMMIT, SLOT_PORTS_JSON, SLOT_PREVIEW_URLS_JSON,
|
|
91
|
-
#
|
|
91
|
+
# SLOT_STATUS, SLOT_LAST_ERROR
|
|
92
92
|
write_slot_registry() {
|
|
93
93
|
local file
|
|
94
94
|
file="$(slot_registry_file "$SLOT_AGENT_ID")"
|
|
@@ -110,7 +110,6 @@ if (e.SLOT_WORKTREE_PATH) entry.worktreePath = e.SLOT_WORKTREE_PATH;
|
|
|
110
110
|
if (e.SLOT_BRANCH) entry.branch = e.SLOT_BRANCH;
|
|
111
111
|
if (e.SLOT_BASE_BRANCH) entry.baseBranch = e.SLOT_BASE_BRANCH;
|
|
112
112
|
if (e.SLOT_BASE_COMMIT) entry.baseCommit = e.SLOT_BASE_COMMIT;
|
|
113
|
-
if (e.SLOT_PURPOSE) entry.purpose = e.SLOT_PURPOSE;
|
|
114
113
|
if (e.SLOT_LAST_ERROR) entry.lastError = e.SLOT_LAST_ERROR;
|
|
115
114
|
for (const [key, env] of [["ports", "SLOT_PORTS_JSON"], ["previewUrls", "SLOT_PREVIEW_URLS_JSON"]]) {
|
|
116
115
|
if (e[env]) try { entry[key] = JSON.parse(e[env]); } catch {}
|
|
@@ -154,12 +153,11 @@ slot_dirty_summary() {
|
|
|
154
153
|
# Print a warning before replacing an occupied slot (stdout — visible to agents).
|
|
155
154
|
print_slot_replace_warning() {
|
|
156
155
|
local agent_id="$1"
|
|
157
|
-
local reg wt branch work_dir
|
|
156
|
+
local reg wt branch work_dir created status last_error dirty_summary head
|
|
158
157
|
reg="$(slot_registry_file "$agent_id")"
|
|
159
158
|
wt="$(existing_slot_worktree "$agent_id")"
|
|
160
159
|
branch="$(read_slot_field "$reg" branch || true)"
|
|
161
160
|
work_dir="$(read_slot_field "$reg" workDir || true)"
|
|
162
|
-
purpose="$(read_slot_field "$reg" purpose || true)"
|
|
163
161
|
created="$(read_slot_field "$reg" createdAt || true)"
|
|
164
162
|
status="$(read_slot_field "$reg" status || true)"
|
|
165
163
|
last_error="$(read_slot_field "$reg" lastError || true)"
|
|
@@ -170,7 +168,6 @@ print_slot_replace_warning() {
|
|
|
170
168
|
|
|
171
169
|
echo "" >&2
|
|
172
170
|
echo "⚠ Slot ${agent_id} is already in use — replacing will REMOVE the worktree." >&2
|
|
173
|
-
[ -n "$purpose" ] && echo " Purpose: ${purpose}" >&2
|
|
174
171
|
[ -n "$wt" ] && echo " Worktree: ${wt}" >&2
|
|
175
172
|
[ -n "$work_dir" ] && echo " Work dir: ${work_dir}" >&2
|
|
176
173
|
[ -n "$branch" ] && echo " Branch: ${branch}${head:+ @ ${head}}" >&2
|
|
@@ -18,7 +18,6 @@ AGENT_ID="${1:-}"
|
|
|
18
18
|
USE_WORKTREE="${HARNESS_USE_WORKTREE:-true}"
|
|
19
19
|
FORCE=false
|
|
20
20
|
REPLACE=false
|
|
21
|
-
PURPOSE="${HAR_SESSION_PURPOSE:-}"
|
|
22
21
|
|
|
23
22
|
for arg in "$@"; do
|
|
24
23
|
case "$arg" in
|
|
@@ -26,13 +25,12 @@ for arg in "$@"; do
|
|
|
26
25
|
--worktree) USE_WORKTREE=true ;;
|
|
27
26
|
--replace) REPLACE=true ;;
|
|
28
27
|
--force) FORCE=true ;;
|
|
29
|
-
--purpose=*) PURPOSE="${arg#--purpose=}" ;;
|
|
30
28
|
esac
|
|
31
29
|
done
|
|
32
30
|
|
|
33
31
|
if [[ -z "$AGENT_ID" ]]; then
|
|
34
32
|
har_load_agent_slot_limits
|
|
35
|
-
echo "Usage: $0 <agent-id> [--no-worktree] [--replace] [--force]
|
|
33
|
+
echo "Usage: $0 <agent-id> [--no-worktree] [--replace] [--force] " >&2
|
|
36
34
|
echo " agent-id must be between ${HARNESS_AGENT_SLOT_MIN} and ${HARNESS_AGENT_SLOT_MAX}" >&2
|
|
37
35
|
exit 1
|
|
38
36
|
fi
|
|
@@ -109,7 +107,6 @@ mark_slot_failed() {
|
|
|
109
107
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
110
108
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
111
109
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
112
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
113
110
|
SLOT_STATUS="failed" \
|
|
114
111
|
SLOT_LAST_ERROR="launch.sh exited with code ${exit_code}" \
|
|
115
112
|
write_slot_registry
|
|
@@ -130,7 +127,6 @@ SLOT_WORKTREE_PATH="${WORKTREE_DIR:-}" \
|
|
|
130
127
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
131
128
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
132
129
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
133
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
134
130
|
SLOT_STATUS="starting" \
|
|
135
131
|
write_slot_registry
|
|
136
132
|
REGISTRY_WRITTEN=true
|
|
@@ -153,7 +149,6 @@ SLOT_WORKTREE_PATH="${WORKTREE_DIR:-}" \
|
|
|
153
149
|
SLOT_BRANCH="${BRANCH:-}" \
|
|
154
150
|
SLOT_BASE_BRANCH="${BASE_BRANCH:-}" \
|
|
155
151
|
SLOT_BASE_COMMIT="${BASE_COMMIT:-}" \
|
|
156
|
-
SLOT_PURPOSE="${PURPOSE}" \
|
|
157
152
|
SLOT_STATUS="active" \
|
|
158
153
|
write_slot_registry
|
|
159
154
|
|