@osfactory/har 0.20.0 → 0.21.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/README.md +14 -0
- package/dist/index.js +701 -283
- package/dist/templates/agent-skills/har-wt.md +11 -0
- package/dist/templates/har-boilerplate/agent-slot.sh +3 -1
- package/dist/templates/har-boilerplate/gitignore.template +3 -0
- package/dist/templates/har-boilerplate/launch.sh +10 -0
- package/dist/templates/har-boilerplate-cli/agent-slot.sh +3 -1
- package/dist/templates/har-boilerplate-cli/gitignore.template +3 -0
- package/dist/templates/har-boilerplate-cli/launch.sh +10 -0
- package/dist/templates/har-boilerplate-ios/agent-slot.sh +3 -1
- package/dist/templates/har-boilerplate-ios/gitignore.template +3 -0
- package/dist/templates/har-boilerplate-ios/launch.sh +10 -0
- package/package.json +1 -1
|
@@ -21,6 +21,17 @@ har env launch <id> # or ./.har/launch.sh <id>
|
|
|
21
21
|
|
|
22
22
|
Launch creates a fresh session worktree from HEAD and prints its **work dir** (also recorded in `.har/slots/agent-<id>.json`, path like `~/worktrees/<base>-<sha4>-har-agent-<id>-<rand4>`). If a previous launch failed partway, retry with `--resume` instead of replacing.
|
|
23
23
|
|
|
24
|
+
If the task already has a stable issue or ticket ID, bind it without changing the
|
|
25
|
+
methodology that produced it:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
har env launch <id> --work-id "<provider-neutral-id>" --work-title "<title>"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
External planning/TDD/review skills remain in control of implementation strategy.
|
|
32
|
+
They must delegate worktree creation, runtime launch, final verification, and
|
|
33
|
+
completion to HAR.
|
|
34
|
+
|
|
24
35
|
## 3. Do ALL work in the work dir
|
|
25
36
|
|
|
26
37
|
- `cd` into the work dir; every read-modify-write of project files happens there.
|
|
@@ -447,7 +447,7 @@ try {
|
|
|
447
447
|
# required: SLOT_AGENT_ID, SLOT_MODE (worktree|root), SLOT_WORK_DIR
|
|
448
448
|
# optional: SLOT_SUFFIX, SLOT_WORKTREE_PATH, SLOT_BRANCH, SLOT_BASE_BRANCH,
|
|
449
449
|
# SLOT_BASE_COMMIT, SLOT_PORTS_JSON, SLOT_PREVIEW_URLS_JSON,
|
|
450
|
-
# SLOT_STATUS, SLOT_LAST_ERROR
|
|
450
|
+
# SLOT_STATUS, SLOT_LAST_ERROR, SLOT_WORK_UNIT_ID, SLOT_ATTEMPT_ID
|
|
451
451
|
write_slot_registry() {
|
|
452
452
|
local file
|
|
453
453
|
file="$(slot_registry_file "$SLOT_AGENT_ID")"
|
|
@@ -470,6 +470,8 @@ if (e.SLOT_BRANCH) entry.branch = e.SLOT_BRANCH;
|
|
|
470
470
|
if (e.SLOT_BASE_BRANCH) entry.baseBranch = e.SLOT_BASE_BRANCH;
|
|
471
471
|
if (e.SLOT_BASE_COMMIT) entry.baseCommit = e.SLOT_BASE_COMMIT;
|
|
472
472
|
if (e.SLOT_LAST_ERROR) entry.lastError = e.SLOT_LAST_ERROR;
|
|
473
|
+
if (e.SLOT_WORK_UNIT_ID) entry.workUnitId = e.SLOT_WORK_UNIT_ID;
|
|
474
|
+
if (e.SLOT_ATTEMPT_ID) entry.attemptId = e.SLOT_ATTEMPT_ID;
|
|
473
475
|
for (const [key, env] of [["ports", "SLOT_PORTS_JSON"], ["previewUrls", "SLOT_PREVIEW_URLS_JSON"]]) {
|
|
474
476
|
if (e[env]) try { entry[key] = JSON.parse(e[env]); } catch {}
|
|
475
477
|
}
|
|
@@ -20,6 +20,8 @@ USE_CLAUDE=false
|
|
|
20
20
|
FORCE=false
|
|
21
21
|
REPLACE=false
|
|
22
22
|
RESUME=false
|
|
23
|
+
WORK_UNIT_ID="${HAR_WORK_UNIT_ID:-}"
|
|
24
|
+
ATTEMPT_ID="${HAR_ATTEMPT_ID:-}"
|
|
23
25
|
|
|
24
26
|
for arg in "$@"; do
|
|
25
27
|
case "$arg" in
|
|
@@ -29,9 +31,17 @@ for arg in "$@"; do
|
|
|
29
31
|
--replace) REPLACE=true ;;
|
|
30
32
|
--force) FORCE=true ;;
|
|
31
33
|
--resume) RESUME=true ;;
|
|
34
|
+
--work-id=*) WORK_UNIT_ID="${arg#*=}" ;;
|
|
35
|
+
--attempt-id=*) ATTEMPT_ID="${arg#*=}" ;;
|
|
32
36
|
esac
|
|
33
37
|
done
|
|
34
38
|
|
|
39
|
+
if [[ -n "$WORK_UNIT_ID" && -z "$ATTEMPT_ID" ]]; then
|
|
40
|
+
ATTEMPT_ID="$(node -e 'process.stdout.write(require("crypto").randomUUID())')"
|
|
41
|
+
fi
|
|
42
|
+
export SLOT_WORK_UNIT_ID="$WORK_UNIT_ID"
|
|
43
|
+
export SLOT_ATTEMPT_ID="$ATTEMPT_ID"
|
|
44
|
+
|
|
35
45
|
if [[ -z "$AGENT_ID" ]]; then
|
|
36
46
|
har_load_agent_slot_limits
|
|
37
47
|
echo "Usage: $0 <agent-id> [--no-worktree] [--claude] [--replace] [--force] [--resume] " >&2
|
|
@@ -427,7 +427,7 @@ try {
|
|
|
427
427
|
# required: SLOT_AGENT_ID, SLOT_MODE (worktree|root), SLOT_WORK_DIR
|
|
428
428
|
# optional: SLOT_SUFFIX, SLOT_WORKTREE_PATH, SLOT_BRANCH, SLOT_BASE_BRANCH,
|
|
429
429
|
# SLOT_BASE_COMMIT, SLOT_PORTS_JSON, SLOT_PREVIEW_URLS_JSON,
|
|
430
|
-
# SLOT_STATUS, SLOT_LAST_ERROR
|
|
430
|
+
# SLOT_STATUS, SLOT_LAST_ERROR, SLOT_WORK_UNIT_ID, SLOT_ATTEMPT_ID
|
|
431
431
|
write_slot_registry() {
|
|
432
432
|
local file
|
|
433
433
|
file="$(slot_registry_file "$SLOT_AGENT_ID")"
|
|
@@ -450,6 +450,8 @@ if (e.SLOT_BRANCH) entry.branch = e.SLOT_BRANCH;
|
|
|
450
450
|
if (e.SLOT_BASE_BRANCH) entry.baseBranch = e.SLOT_BASE_BRANCH;
|
|
451
451
|
if (e.SLOT_BASE_COMMIT) entry.baseCommit = e.SLOT_BASE_COMMIT;
|
|
452
452
|
if (e.SLOT_LAST_ERROR) entry.lastError = e.SLOT_LAST_ERROR;
|
|
453
|
+
if (e.SLOT_WORK_UNIT_ID) entry.workUnitId = e.SLOT_WORK_UNIT_ID;
|
|
454
|
+
if (e.SLOT_ATTEMPT_ID) entry.attemptId = e.SLOT_ATTEMPT_ID;
|
|
453
455
|
for (const [key, env] of [["ports", "SLOT_PORTS_JSON"], ["previewUrls", "SLOT_PREVIEW_URLS_JSON"]]) {
|
|
454
456
|
if (e[env]) try { entry[key] = JSON.parse(e[env]); } catch {}
|
|
455
457
|
}
|
|
@@ -19,6 +19,8 @@ USE_WORKTREE="${HARNESS_USE_WORKTREE:-true}"
|
|
|
19
19
|
FORCE=false
|
|
20
20
|
REPLACE=false
|
|
21
21
|
RESUME=false
|
|
22
|
+
WORK_UNIT_ID="${HAR_WORK_UNIT_ID:-}"
|
|
23
|
+
ATTEMPT_ID="${HAR_ATTEMPT_ID:-}"
|
|
22
24
|
|
|
23
25
|
for arg in "$@"; do
|
|
24
26
|
case "$arg" in
|
|
@@ -27,9 +29,17 @@ for arg in "$@"; do
|
|
|
27
29
|
--replace) REPLACE=true ;;
|
|
28
30
|
--force) FORCE=true ;;
|
|
29
31
|
--resume) RESUME=true ;;
|
|
32
|
+
--work-id=*) WORK_UNIT_ID="${arg#*=}" ;;
|
|
33
|
+
--attempt-id=*) ATTEMPT_ID="${arg#*=}" ;;
|
|
30
34
|
esac
|
|
31
35
|
done
|
|
32
36
|
|
|
37
|
+
if [[ -n "$WORK_UNIT_ID" && -z "$ATTEMPT_ID" ]]; then
|
|
38
|
+
ATTEMPT_ID="$(node -e 'process.stdout.write(require("crypto").randomUUID())')"
|
|
39
|
+
fi
|
|
40
|
+
export SLOT_WORK_UNIT_ID="$WORK_UNIT_ID"
|
|
41
|
+
export SLOT_ATTEMPT_ID="$ATTEMPT_ID"
|
|
42
|
+
|
|
33
43
|
if [[ -z "$AGENT_ID" ]]; then
|
|
34
44
|
har_load_agent_slot_limits
|
|
35
45
|
echo "Usage: $0 <agent-id> [--no-worktree] [--replace] [--force] [--resume] " >&2
|
|
@@ -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
|
-
# SLOT_STATUS, SLOT_LAST_ERROR
|
|
91
|
+
# SLOT_STATUS, SLOT_LAST_ERROR, SLOT_WORK_UNIT_ID, SLOT_ATTEMPT_ID
|
|
92
92
|
write_slot_registry() {
|
|
93
93
|
local file
|
|
94
94
|
file="$(slot_registry_file "$SLOT_AGENT_ID")"
|
|
@@ -111,6 +111,8 @@ 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
113
|
if (e.SLOT_LAST_ERROR) entry.lastError = e.SLOT_LAST_ERROR;
|
|
114
|
+
if (e.SLOT_WORK_UNIT_ID) entry.workUnitId = e.SLOT_WORK_UNIT_ID;
|
|
115
|
+
if (e.SLOT_ATTEMPT_ID) entry.attemptId = e.SLOT_ATTEMPT_ID;
|
|
114
116
|
for (const [key, env] of [["ports", "SLOT_PORTS_JSON"], ["previewUrls", "SLOT_PREVIEW_URLS_JSON"]]) {
|
|
115
117
|
if (e[env]) try { entry[key] = JSON.parse(e[env]); } catch {}
|
|
116
118
|
}
|
|
@@ -18,6 +18,8 @@ AGENT_ID="${1:-}"
|
|
|
18
18
|
USE_WORKTREE="${HARNESS_USE_WORKTREE:-true}"
|
|
19
19
|
FORCE=false
|
|
20
20
|
REPLACE=false
|
|
21
|
+
WORK_UNIT_ID="${HAR_WORK_UNIT_ID:-}"
|
|
22
|
+
ATTEMPT_ID="${HAR_ATTEMPT_ID:-}"
|
|
21
23
|
|
|
22
24
|
for arg in "$@"; do
|
|
23
25
|
case "$arg" in
|
|
@@ -25,9 +27,17 @@ for arg in "$@"; do
|
|
|
25
27
|
--worktree) USE_WORKTREE=true ;;
|
|
26
28
|
--replace) REPLACE=true ;;
|
|
27
29
|
--force) FORCE=true ;;
|
|
30
|
+
--work-id=*) WORK_UNIT_ID="${arg#*=}" ;;
|
|
31
|
+
--attempt-id=*) ATTEMPT_ID="${arg#*=}" ;;
|
|
28
32
|
esac
|
|
29
33
|
done
|
|
30
34
|
|
|
35
|
+
if [[ -n "$WORK_UNIT_ID" && -z "$ATTEMPT_ID" ]]; then
|
|
36
|
+
ATTEMPT_ID="$(node -e 'process.stdout.write(require("crypto").randomUUID())')"
|
|
37
|
+
fi
|
|
38
|
+
export SLOT_WORK_UNIT_ID="$WORK_UNIT_ID"
|
|
39
|
+
export SLOT_ATTEMPT_ID="$ATTEMPT_ID"
|
|
40
|
+
|
|
31
41
|
if [[ -z "$AGENT_ID" ]]; then
|
|
32
42
|
har_load_agent_slot_limits
|
|
33
43
|
echo "Usage: $0 <agent-id> [--no-worktree] [--replace] [--force] " >&2
|