@osfactory/har 0.64.2 → 1.0.0-rc.1
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 +15675 -6536
- package/dist/prompts/system-authoring.md +155 -0
- package/dist/templates/adaptation-prompt-init.md +67 -43
- package/dist/templates/adaptation-prompt-maintain.md +38 -38
- package/dist/templates/agent-skills/har-maintain.md +2 -2
- package/dist/templates/agent-skills/setup-har.md +6 -4
- package/dist/templates/cursor-rule.mdc.template +3 -3
- package/dist/templates/har-boilerplate/docker-compose.agent.yml +1 -1
- package/dist/templates/har-boilerplate/harness.env +11 -155
- package/dist/templates/har-boilerplate/stages.json +51 -2
- package/dist/templates/har-boilerplate-cli/docker-compose.agent.yml +1 -1
- package/dist/templates/har-boilerplate-cli/harness.env +12 -138
- package/dist/templates/har-boilerplate-cli/stages.json +42 -2
- package/dist/templates/har-boilerplate-ios/harness.env +10 -126
- package/dist/templates/har-boilerplate-ios/stages.json +42 -2
- package/dist/templates/migration-prompt.md +54 -0
- package/dist/templates/plugins/custom-stage-skeleton.sh +11 -20
- package/dist/templates/plugins/gitleaks/.github/workflows/gitleaks.yml +1 -1
- package/dist/templates/plugins/gitleaks/.har/stages/GITLEAKS.md +1 -1
- package/dist/templates/plugins/gitleaks/.har/stages/secrets-scan.sh +8 -23
- package/dist/templates/plugins/gitleaks/README.md +1 -1
- package/dist/templates/plugins/gitleaks/template.manifest.json +20 -5
- package/dist/templates/plugins/kerno/.github/workflows/kerno.yml +1 -1
- package/dist/templates/plugins/kerno/.har/stages/backend-validation.sh +8 -23
- package/dist/templates/plugins/kerno/README.md +1 -1
- package/dist/templates/plugins/kerno/template.manifest.json +20 -9
- package/dist/templates/plugins/local-plugin-skeleton/README.md +46 -0
- package/dist/templates/plugins/playwright/.har/stages/browser-e2e.sh +8 -23
- package/dist/templates/plugins/playwright/template.manifest.json +36 -13
- package/dist/templates/plugins/rocketsim/.har/stages/rocketsim-flows.sh +8 -23
- package/dist/templates/plugins/rocketsim/template.manifest.json +20 -8
- package/dist/templates/plugins/semgrep/.har/stages/sast.sh +10 -26
- package/dist/templates/plugins/semgrep/README.md +1 -1
- package/dist/templates/plugins/semgrep/template.manifest.json +16 -7
- package/dist/templates/plugins/trivy/.har/stages/vuln-scan.sh +8 -23
- package/dist/templates/plugins/trivy/README.md +1 -1
- package/dist/templates/plugins/trivy/template.manifest.json +20 -8
- package/dist/templates/{har-boilerplate-cli/CLAUDE.agent.md → profiles/cli/docs/claude-agent/definition-of-done.md} +0 -42
- package/dist/templates/profiles/cli/docs/claude-agent/do-not.md +6 -0
- package/dist/templates/profiles/cli/docs/claude-agent/environment.md +12 -0
- package/dist/templates/profiles/cli/docs/claude-agent/project-commands.md +10 -0
- package/dist/templates/profiles/cli/docs/claude-agent/readiness.md +6 -0
- package/dist/templates/profiles/cli/docs/readme/for-coding-agents.md +9 -0
- package/dist/templates/profiles/cli/docs/readme/intro.md +7 -0
- package/dist/templates/profiles/cli/docs/readme/port-shared-services-cli-profile.md +25 -0
- package/dist/templates/profiles/cli/docs/readme/quick-start.md +24 -0
- package/dist/templates/profiles/cli/docs/readme/verification-contract.md +22 -0
- package/dist/templates/profiles/cli/docs/readme/what-s-in-here.md +27 -0
- package/dist/templates/profiles/cli/profile.manifest.json +56 -1
- package/dist/templates/profiles/default/docs/claude-agent/definition-of-done.md +24 -0
- package/dist/templates/profiles/default/docs/claude-agent/do-not.md +10 -0
- package/dist/templates/profiles/default/docs/claude-agent/environment.md +19 -0
- package/dist/templates/profiles/default/docs/claude-agent/project-commands.md +10 -0
- package/dist/templates/profiles/default/docs/claude-agent/readiness.md +12 -0
- package/dist/templates/profiles/default/docs/readme/architecture.md +11 -0
- package/dist/templates/profiles/default/docs/readme/for-coding-agents.md +9 -0
- package/dist/templates/profiles/default/docs/readme/intro.md +7 -0
- package/dist/templates/profiles/default/docs/readme/port-shared-services.md +41 -0
- package/dist/templates/profiles/default/docs/readme/quick-start.md +24 -0
- package/dist/templates/profiles/default/docs/readme/readiness-layers.md +16 -0
- package/dist/templates/profiles/default/docs/readme/verification-contract.md +17 -0
- package/dist/templates/profiles/default/docs/readme/what-s-in-here.md +28 -0
- package/dist/templates/profiles/default/profile.manifest.json +62 -1
- package/dist/templates/profiles/ios/docs/claude-agent/definition-of-done.md +23 -0
- package/dist/templates/profiles/ios/docs/claude-agent/do-not.md +6 -0
- package/dist/templates/profiles/ios/docs/claude-agent/environment.md +14 -0
- package/dist/templates/profiles/ios/docs/claude-agent/intro.md +3 -0
- package/dist/templates/profiles/ios/docs/claude-agent/project-commands.md +21 -0
- package/dist/templates/profiles/ios/docs/claude-agent/readiness.md +6 -0
- package/dist/templates/profiles/ios/docs/claude-agent/user-flow-validation-rocketsim.md +11 -0
- package/dist/templates/profiles/ios/docs/readme/configuration.md +7 -0
- package/dist/templates/profiles/ios/docs/readme/intro.md +7 -0
- package/dist/templates/profiles/ios/docs/readme/port-shared-services-ios-profile.md +25 -0
- package/dist/templates/profiles/ios/docs/readme/quick-start.md +22 -0
- package/dist/templates/profiles/ios/docs/readme/simulators.md +45 -0
- package/dist/templates/profiles/ios/docs/readme/user-flow-validation.md +9 -0
- package/dist/templates/profiles/ios/docs/readme/verification-contract.md +13 -0
- package/dist/templates/profiles/ios/docs/readme/what-s-in-here.md +27 -0
- package/dist/templates/profiles/ios/profile.manifest.json +59 -3
- package/dist/templates/runtime-bundles/pm2-runtime/attach.sh +8 -15
- package/dist/templates/runtime-bundles/pm2-runtime/env.template +1 -1
- package/dist/templates/runtime-bundles/pm2-runtime/stages/api-health.sh +9 -0
- package/dist/templates/runtime-bundles/shared-kernel/STAGES.md +32 -18
- package/dist/templates/runtime-bundles/shared-kernel/agent-cli.sh +35 -0
- package/dist/templates/runtime-bundles/shared-kernel/launch.sh +35 -0
- package/dist/templates/runtime-bundles/shared-kernel/lib/verify-runner.mjs +129 -0
- package/dist/templates/runtime-bundles/shared-kernel/preflight.sh +35 -0
- package/dist/templates/runtime-bundles/shared-kernel/setup-infra.sh +35 -0
- package/dist/templates/runtime-bundles/shared-kernel/stages/README.sh +1 -1
- package/dist/templates/runtime-bundles/shared-kernel/stages/readiness.sh +14 -0
- package/dist/templates/runtime-bundles/shared-kernel/teardown.sh +35 -0
- package/dist/templates/runtime-bundles/shared-kernel/verify.sh +35 -0
- package/dist/templates/shared-docs/claude-agent/intro.md +3 -0
- package/dist/templates/shared-docs/readme/maintaining-this-harness.md +14 -0
- package/dist/templates/shared-docs/readme/run-history.md +5 -0
- package/dist/templates/shared-docs/readme/session-lifecycle.md +20 -0
- package/package.json +1 -1
- package/dist/templates/har-boilerplate/CLAUDE.agent.md +0 -83
- package/dist/templates/har-boilerplate/README.md +0 -199
- package/dist/templates/har-boilerplate/STAGES.md +0 -99
- package/dist/templates/har-boilerplate/agent-cli.sh +0 -225
- package/dist/templates/har-boilerplate/agent-slot.sh +0 -850
- package/dist/templates/har-boilerplate/attach.sh +0 -22
- package/dist/templates/har-boilerplate/ecosystem.agent.template.cjs +0 -52
- package/dist/templates/har-boilerplate/env.template +0 -40
- package/dist/templates/har-boilerplate/launch.sh +0 -323
- package/dist/templates/har-boilerplate/preflight.sh +0 -32
- package/dist/templates/har-boilerplate/provision-toolchain.sh +0 -766
- package/dist/templates/har-boilerplate/setup-infra.sh +0 -178
- package/dist/templates/har-boilerplate/stages/README.sh +0 -11
- package/dist/templates/har-boilerplate/teardown.sh +0 -87
- package/dist/templates/har-boilerplate/verify.sh +0 -249
- package/dist/templates/har-boilerplate-cli/README.md +0 -157
- package/dist/templates/har-boilerplate-cli/STAGES.md +0 -99
- package/dist/templates/har-boilerplate-cli/agent-cli.sh +0 -160
- package/dist/templates/har-boilerplate-cli/agent-slot.sh +0 -832
- package/dist/templates/har-boilerplate-cli/launch.sh +0 -216
- package/dist/templates/har-boilerplate-cli/preflight.sh +0 -28
- package/dist/templates/har-boilerplate-cli/provision-toolchain.sh +0 -766
- package/dist/templates/har-boilerplate-cli/setup-infra.sh +0 -178
- package/dist/templates/har-boilerplate-cli/stages/README.sh +0 -11
- package/dist/templates/har-boilerplate-cli/teardown.sh +0 -66
- package/dist/templates/har-boilerplate-cli/verify.sh +0 -210
- package/dist/templates/har-boilerplate-ios/ADAPT-PROMPT.md +0 -63
- package/dist/templates/har-boilerplate-ios/CLAUDE.agent.md +0 -90
- package/dist/templates/har-boilerplate-ios/README.md +0 -173
- package/dist/templates/har-boilerplate-ios/STAGES.md +0 -99
- package/dist/templates/har-boilerplate-ios/agent-cli.sh +0 -149
- package/dist/templates/har-boilerplate-ios/agent-slot.sh +0 -479
- package/dist/templates/har-boilerplate-ios/launch.sh +0 -206
- package/dist/templates/har-boilerplate-ios/provision-toolchain.sh +0 -766
- package/dist/templates/har-boilerplate-ios/setup-infra.sh +0 -112
- package/dist/templates/har-boilerplate-ios/simulator.sh +0 -492
- package/dist/templates/har-boilerplate-ios/stages/README.sh +0 -11
- package/dist/templates/har-boilerplate-ios/teardown.sh +0 -68
- package/dist/templates/har-boilerplate-ios/verify.sh +0 -185
- package/dist/templates/runtime-bundles/pm2-runtime/README.md +0 -4
- package/dist/templates/runtime-bundles/shared-kernel/README.md +0 -3
- package/dist/templates/runtime-bundles/shared-kernel/provision-toolchain.sh +0 -766
- package/dist/templates/runtime-bundles/xcode-sim/README.md +0 -4
- package/dist/templates/runtime-bundles/xcode-sim/simulator.sh +0 -492
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Sets up shared infrastructure for all agents.
|
|
3
|
-
# Starts the docker compose services listed in HARNESS_INFRA_SERVICES, creates
|
|
4
|
-
# the template database (when "db" is enabled), and starts optional shared app
|
|
5
|
-
# services (ecosystem.shared.config.cjs). One instance serves every agent slot.
|
|
6
|
-
# Idempotent — safe to run multiple times.
|
|
7
|
-
#
|
|
8
|
-
# Usage: ./.har/setup-infra.sh
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
13
|
-
COMPOSE_FILE="$SCRIPT_DIR/docker-compose.agent.yml"
|
|
14
|
-
INFRA_STATE="$SCRIPT_DIR/state/infra.env"
|
|
15
|
-
|
|
16
|
-
# shellcheck source=/dev/null
|
|
17
|
-
source "$SCRIPT_DIR/harness.env"
|
|
18
|
-
# shellcheck source=/dev/null
|
|
19
|
-
source "$SCRIPT_DIR/agent-slot.sh"
|
|
20
|
-
|
|
21
|
-
COMPOSE_PROJECT="har-${HARNESS_PROJECT_NAME}"
|
|
22
|
-
PSQL="har_pg psql -d postgres"
|
|
23
|
-
|
|
24
|
-
log() { echo "==> $*" >&2; }
|
|
25
|
-
|
|
26
|
-
har_compose_service_running() {
|
|
27
|
-
local service="$1"
|
|
28
|
-
docker ps --filter "name=${COMPOSE_PROJECT}-${service}-1" --format '{{.Names}}' 2>/dev/null \
|
|
29
|
-
| grep -q "^${COMPOSE_PROJECT}-${service}-1\$"
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
har_resolve_infra_port() {
|
|
33
|
-
local var_name="$1"
|
|
34
|
-
local default_port="$2"
|
|
35
|
-
local scan_start="$3"
|
|
36
|
-
local scan_end="$4"
|
|
37
|
-
local service="${5:-}"
|
|
38
|
-
local current="${!var_name:-}"
|
|
39
|
-
|
|
40
|
-
if [ -n "$current" ] && { ! port_in_use "$current" || { [ -n "$service" ] && har_compose_service_running "$service"; }; }; then
|
|
41
|
-
echo "$current"
|
|
42
|
-
return 0
|
|
43
|
-
fi
|
|
44
|
-
har_allocate_port "$default_port" "$scan_start" "$scan_end"
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
mkdir -p "$(dirname "$INFRA_STATE")"
|
|
48
|
-
if [ -f "$INFRA_STATE" ]; then
|
|
49
|
-
# shellcheck source=/dev/null
|
|
50
|
-
source "$INFRA_STATE"
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
DB_PORT="$(har_resolve_infra_port AGENT_DB_PORT \
|
|
54
|
-
"${HARNESS_DB_PORT_DEFAULT:-15432}" \
|
|
55
|
-
"${HARNESS_DB_PORT_SCAN_START:-15432}" \
|
|
56
|
-
"${HARNESS_DB_PORT_SCAN_END:-15499}" \
|
|
57
|
-
db)"
|
|
58
|
-
MINIO_PORT="$(har_resolve_infra_port AGENT_MINIO_PORT \
|
|
59
|
-
"${HARNESS_MINIO_PORT_DEFAULT:-19000}" \
|
|
60
|
-
"${HARNESS_MINIO_PORT_SCAN_START:-19000}" \
|
|
61
|
-
"${HARNESS_MINIO_PORT_SCAN_END:-19099}" \
|
|
62
|
-
minio)"
|
|
63
|
-
MINIO_CONSOLE_PORT="$(har_resolve_infra_port AGENT_MINIO_CONSOLE_PORT \
|
|
64
|
-
"${HARNESS_MINIO_CONSOLE_PORT_DEFAULT:-19001}" \
|
|
65
|
-
"${HARNESS_MINIO_CONSOLE_PORT_SCAN_START:-19001}" \
|
|
66
|
-
"${HARNESS_MINIO_CONSOLE_PORT_SCAN_END:-19099}")"
|
|
67
|
-
BROWSER_PORT="$(har_resolve_infra_port AGENT_BROWSER_PORT \
|
|
68
|
-
"${HARNESS_BROWSER_PORT_DEFAULT:-13001}" \
|
|
69
|
-
"${HARNESS_BROWSER_PORT_SCAN_START:-13001}" \
|
|
70
|
-
"${HARNESS_BROWSER_PORT_SCAN_END:-13099}" \
|
|
71
|
-
headless-browser)"
|
|
72
|
-
MAILPIT_WEB_PORT="$(har_resolve_infra_port AGENT_MAILPIT_WEB_PORT \
|
|
73
|
-
"${HARNESS_MAILPIT_WEB_PORT_DEFAULT:-18025}" \
|
|
74
|
-
"${HARNESS_MAILPIT_WEB_PORT_SCAN_START:-18025}" \
|
|
75
|
-
"${HARNESS_MAILPIT_WEB_PORT_SCAN_END:-18099}" \
|
|
76
|
-
mailpit)"
|
|
77
|
-
MAILPIT_SMTP_PORT="$(har_resolve_infra_port AGENT_MAILPIT_SMTP_PORT \
|
|
78
|
-
"${HARNESS_MAILPIT_SMTP_PORT_DEFAULT:-11025}" \
|
|
79
|
-
"${HARNESS_MAILPIT_SMTP_PORT_SCAN_START:-11025}" \
|
|
80
|
-
"${HARNESS_MAILPIT_SMTP_PORT_SCAN_END:-11099}")"
|
|
81
|
-
|
|
82
|
-
export AGENT_DB_PORT="$DB_PORT"
|
|
83
|
-
export AGENT_MINIO_PORT="$MINIO_PORT"
|
|
84
|
-
export AGENT_MINIO_CONSOLE_PORT="$MINIO_CONSOLE_PORT"
|
|
85
|
-
export AGENT_BROWSER_PORT="$BROWSER_PORT"
|
|
86
|
-
export AGENT_MAILPIT_WEB_PORT="$MAILPIT_WEB_PORT"
|
|
87
|
-
export AGENT_MAILPIT_SMTP_PORT="$MAILPIT_SMTP_PORT"
|
|
88
|
-
|
|
89
|
-
cat > "$INFRA_STATE" <<EOF
|
|
90
|
-
# Persisted by setup-infra.sh — host ports for shared docker compose services.
|
|
91
|
-
export AGENT_DB_PORT=${DB_PORT}
|
|
92
|
-
export AGENT_MINIO_PORT=${MINIO_PORT}
|
|
93
|
-
export AGENT_MINIO_CONSOLE_PORT=${MINIO_CONSOLE_PORT}
|
|
94
|
-
export AGENT_BROWSER_PORT=${BROWSER_PORT}
|
|
95
|
-
export AGENT_MAILPIT_WEB_PORT=${MAILPIT_WEB_PORT}
|
|
96
|
-
export AGENT_MAILPIT_SMTP_PORT=${MAILPIT_SMTP_PORT}
|
|
97
|
-
EOF
|
|
98
|
-
|
|
99
|
-
SERVICES="${HARNESS_INFRA_SERVICES:-}"
|
|
100
|
-
|
|
101
|
-
if [ -n "$SERVICES" ]; then
|
|
102
|
-
log "Starting shared infrastructure (project: $COMPOSE_PROJECT): $SERVICES"
|
|
103
|
-
AGENT_DB_PORT="$DB_PORT" \
|
|
104
|
-
AGENT_MINIO_PORT="$MINIO_PORT" \
|
|
105
|
-
AGENT_MINIO_CONSOLE_PORT="$MINIO_CONSOLE_PORT" \
|
|
106
|
-
AGENT_BROWSER_PORT="$BROWSER_PORT" \
|
|
107
|
-
AGENT_MAILPIT_WEB_PORT="$MAILPIT_WEB_PORT" \
|
|
108
|
-
AGENT_MAILPIT_SMTP_PORT="$MAILPIT_SMTP_PORT" \
|
|
109
|
-
docker compose -p "$COMPOSE_PROJECT" -f "$COMPOSE_FILE" up -d $SERVICES
|
|
110
|
-
else
|
|
111
|
-
log "No shared infra services enabled in harness.env (HARNESS_INFRA_SERVICES)"
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
# Wait for PostgreSQL and prepare the template database
|
|
115
|
-
if har_infra_enabled db; then
|
|
116
|
-
log "Waiting for PostgreSQL on port $DB_PORT..."
|
|
117
|
-
for i in $(seq 1 30); do
|
|
118
|
-
if har_pg pg_isready -q 2>/dev/null; then
|
|
119
|
-
log "PostgreSQL is ready."
|
|
120
|
-
break
|
|
121
|
-
fi
|
|
122
|
-
if [ "$i" = "30" ]; then
|
|
123
|
-
echo "Error: PostgreSQL did not become ready within 30 seconds." >&2
|
|
124
|
-
exit 1
|
|
125
|
-
fi
|
|
126
|
-
sleep 1
|
|
127
|
-
done
|
|
128
|
-
|
|
129
|
-
log "Enabling pg_stat_statements extension..."
|
|
130
|
-
$PSQL -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements" 2>/dev/null || true
|
|
131
|
-
|
|
132
|
-
if [ -n "${HARNESS_TEMPLATE_DB:-}" ]; then
|
|
133
|
-
if $PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '$HARNESS_TEMPLATE_DB'" | grep -q 1; then
|
|
134
|
-
log "Template database '$HARNESS_TEMPLATE_DB' already exists. Skipping creation."
|
|
135
|
-
else
|
|
136
|
-
log "Creating template database '$HARNESS_TEMPLATE_DB'..."
|
|
137
|
-
$PSQL -c "CREATE DATABASE $HARNESS_TEMPLATE_DB"
|
|
138
|
-
|
|
139
|
-
if [ -n "${HARNESS_DB_MIGRATE_CMD:-}" ] && [ "$HARNESS_DB_MIGRATE_CMD" != "echo 'TODO: set migrate command'" ]; then
|
|
140
|
-
log "Running migrations..."
|
|
141
|
-
PGPASSWORD=password PGHOST=localhost PGPORT="$DB_PORT" PGUSER=postgres \
|
|
142
|
-
PGDATABASE="$HARNESS_TEMPLATE_DB" \
|
|
143
|
-
bash -c "cd '$REPO_ROOT' && $HARNESS_DB_MIGRATE_CMD"
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
if [ -n "${HARNESS_DB_SEED_CMD:-}" ] && [ "$HARNESS_DB_SEED_CMD" != "echo 'TODO: set seed command'" ]; then
|
|
147
|
-
log "Running seeds..."
|
|
148
|
-
PGPASSWORD=password PGHOST=localhost PGPORT="$DB_PORT" PGUSER=postgres \
|
|
149
|
-
PGDATABASE="$HARNESS_TEMPLATE_DB" \
|
|
150
|
-
bash -c "cd '$REPO_ROOT' && $HARNESS_DB_SEED_CMD"
|
|
151
|
-
fi
|
|
152
|
-
|
|
153
|
-
log "Marking '$HARNESS_TEMPLATE_DB' as a PostgreSQL template..."
|
|
154
|
-
$PSQL -c "UPDATE pg_database SET datistemplate = true WHERE datname = '$HARNESS_TEMPLATE_DB'"
|
|
155
|
-
log "Template database ready: $HARNESS_TEMPLATE_DB"
|
|
156
|
-
fi
|
|
157
|
-
fi
|
|
158
|
-
fi
|
|
159
|
-
|
|
160
|
-
# Shared app services — supporting services of a monolith/monorepo that agents
|
|
161
|
-
# depend on but do not modify. Started ONCE on fixed ports, shared by all slots.
|
|
162
|
-
# Create .har/ecosystem.shared.config.cjs (PM2 format, processes named
|
|
163
|
-
# "har-${HARNESS_PROJECT_NAME}-shared-<name>") only when the primary app needs
|
|
164
|
-
# sibling services running.
|
|
165
|
-
SHARED_ECOSYSTEM="$SCRIPT_DIR/ecosystem.shared.config.cjs"
|
|
166
|
-
if [ -f "$SHARED_ECOSYSTEM" ]; then
|
|
167
|
-
log "Starting shared app services from ecosystem.shared.config.cjs..."
|
|
168
|
-
(cd "$REPO_ROOT" && $(har_pkg_exec) pm2 startOrReload "$SHARED_ECOSYSTEM" >/dev/null)
|
|
169
|
-
log "Shared app services running (pm2 ls | grep har-${HARNESS_PROJECT_NAME}-shared-)."
|
|
170
|
-
fi
|
|
171
|
-
|
|
172
|
-
echo ""
|
|
173
|
-
log "Infrastructure is ready."
|
|
174
|
-
har_infra_enabled db && log " PostgreSQL: localhost:$DB_PORT"
|
|
175
|
-
har_infra_enabled minio && log " MinIO: http://localhost:${MINIO_CONSOLE_PORT}"
|
|
176
|
-
har_infra_enabled headless-browser && log " Browser: http://localhost:${BROWSER_PORT}"
|
|
177
|
-
har_infra_enabled mailpit && log " Mailpit: http://localhost:${MAILPIT_WEB_PORT}"
|
|
178
|
-
exit 0
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Per-stage scripts live here (e.g. ./.har/stages/browser-e2e.sh <agent-id>).
|
|
3
|
-
#
|
|
4
|
-
# Read .har/STAGES.md for the authoring guide: the stage script contract,
|
|
5
|
-
# command vs script stages, and how verificationStages controls verify --full.
|
|
6
|
-
#
|
|
7
|
-
# Scaffold a new one with:
|
|
8
|
-
# har env add-stage <id> --custom --script
|
|
9
|
-
|
|
10
|
-
echo "Add stage scripts under .har/stages/ and register them in stages.json — see .har/STAGES.md." >&2
|
|
11
|
-
exit 1
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Safely tears down one agent: stops PM2, drops DB, removes bucket, cleans up files.
|
|
3
|
-
# The session's git branch is KEPT by default so you can push it / open a PR —
|
|
4
|
-
# pass --delete-branch to remove it too.
|
|
5
|
-
#
|
|
6
|
-
# Usage: ./.har/teardown.sh <agent-id> [--delete-branch]
|
|
7
|
-
set -euo pipefail
|
|
8
|
-
|
|
9
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
11
|
-
|
|
12
|
-
# shellcheck source=/dev/null
|
|
13
|
-
source "$SCRIPT_DIR/harness.env"
|
|
14
|
-
# shellcheck source=/dev/null
|
|
15
|
-
source "$SCRIPT_DIR/agent-slot.sh"
|
|
16
|
-
|
|
17
|
-
AGENT_ID="${1:?Usage: teardown.sh <agent-id> [--delete-branch]}"
|
|
18
|
-
DELETE_BRANCH=false
|
|
19
|
-
|
|
20
|
-
for arg in "${@:2}"; do
|
|
21
|
-
case "$arg" in
|
|
22
|
-
--delete-branch) DELETE_BRANCH=true ;;
|
|
23
|
-
esac
|
|
24
|
-
done
|
|
25
|
-
|
|
26
|
-
validate_agent_id "$AGENT_ID"
|
|
27
|
-
|
|
28
|
-
echo "==> Tearing down agent ${AGENT_ID}..."
|
|
29
|
-
|
|
30
|
-
# Resolve the session from the registry; fall back to the legacy fixed path so
|
|
31
|
-
# pre-registry sessions stay removable.
|
|
32
|
-
REGISTRY_FILE="$(slot_registry_file "$AGENT_ID")"
|
|
33
|
-
WORKTREE_PATH=""
|
|
34
|
-
WORK_DIR=""
|
|
35
|
-
BRANCH=""
|
|
36
|
-
if [ -f "$REGISTRY_FILE" ]; then
|
|
37
|
-
WORKTREE_PATH="$(read_slot_field "$REGISTRY_FILE" worktreePath || true)"
|
|
38
|
-
WORK_DIR="$(read_slot_field "$REGISTRY_FILE" workDir || true)"
|
|
39
|
-
BRANCH="$(read_slot_field "$REGISTRY_FILE" branch || true)"
|
|
40
|
-
fi
|
|
41
|
-
[ -n "$WORKTREE_PATH" ] || WORKTREE_PATH="$HOME/worktrees/${HARNESS_PROJECT_NAME}-agent-${AGENT_ID}"
|
|
42
|
-
|
|
43
|
-
PM2_REGEX="$(har_pm2_delete_regex "$AGENT_ID")"
|
|
44
|
-
$(har_pkg_exec) pm2 delete "$PM2_REGEX" 2>/dev/null || true
|
|
45
|
-
echo "✓ Stopped PM2 processes"
|
|
46
|
-
|
|
47
|
-
if har_infra_enabled db; then
|
|
48
|
-
har_pg psql -d postgres -c \
|
|
49
|
-
"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname='agent_${AGENT_ID}';" \
|
|
50
|
-
>/dev/null 2>&1 || true
|
|
51
|
-
har_pg dropdb --if-exists "agent_${AGENT_ID}" 2>/dev/null || true
|
|
52
|
-
echo "✓ Dropped database: agent_${AGENT_ID}"
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
if har_infra_enabled minio; then
|
|
56
|
-
curl -sf -X DELETE "http://minioadmin:minioadmin@localhost:19000/agent-${AGENT_ID}?force=true" \
|
|
57
|
-
>/dev/null 2>&1 || true
|
|
58
|
-
echo "✓ Removed MinIO bucket: agent-${AGENT_ID}"
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
rm -f "$REPO_ROOT/.env.agent.${AGENT_ID}"
|
|
62
|
-
rm -f "$REPO_ROOT/ecosystem.agent.${AGENT_ID}.config.cjs"
|
|
63
|
-
if [ -n "$WORK_DIR" ] && [ -d "$WORK_DIR" ]; then
|
|
64
|
-
rm -f "$WORK_DIR/.env.agent.${AGENT_ID}"
|
|
65
|
-
rm -f "$WORK_DIR/ecosystem.agent.${AGENT_ID}.config.cjs"
|
|
66
|
-
fi
|
|
67
|
-
|
|
68
|
-
if [ -d "$WORKTREE_PATH" ]; then
|
|
69
|
-
rm -f "$WORKTREE_PATH/.env.agent.${AGENT_ID}"
|
|
70
|
-
rm -f "$WORKTREE_PATH/ecosystem.agent.${AGENT_ID}.config.cjs"
|
|
71
|
-
git -C "$REPO_ROOT" worktree remove "$WORKTREE_PATH" --force 2>/dev/null || rm -rf "$WORKTREE_PATH"
|
|
72
|
-
echo "✓ Removed worktree: $WORKTREE_PATH"
|
|
73
|
-
fi
|
|
74
|
-
git -C "$REPO_ROOT" worktree prune 2>/dev/null || true
|
|
75
|
-
|
|
76
|
-
if [ -n "$BRANCH" ]; then
|
|
77
|
-
if [ "$DELETE_BRANCH" = true ]; then
|
|
78
|
-
git -C "$REPO_ROOT" branch -D "$BRANCH" 2>/dev/null || true
|
|
79
|
-
echo "✓ Deleted branch: $BRANCH"
|
|
80
|
-
else
|
|
81
|
-
echo "✓ Kept branch: $BRANCH (push it or delete with: git branch -D $BRANCH)"
|
|
82
|
-
fi
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
remove_slot_registry "$AGENT_ID"
|
|
86
|
-
|
|
87
|
-
echo "✓ Agent ${AGENT_ID} torn down"
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Progressive verification pipeline for an agent environment.
|
|
3
|
-
# Outputs JSON to stdout (machine contract), human-readable progress to stderr.
|
|
4
|
-
# Passing steps omit `output`. `har env verify` streams progress only.
|
|
5
|
-
#
|
|
6
|
-
# Usage: ./.har/verify.sh <agent-id> [--full]
|
|
7
|
-
#
|
|
8
|
-
# Quick (default): ecosystem smoke + health only
|
|
9
|
-
# Full (--full): + conventional tests, lint, readiness, and every registered
|
|
10
|
-
# stage in stages.json verificationStages (see .har/STAGES.md)
|
|
11
|
-
# Stock steps are examples. Replace them during adaptation to match this repo.
|
|
12
|
-
set -euo pipefail
|
|
13
|
-
|
|
14
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
-
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
16
|
-
|
|
17
|
-
# shellcheck source=/dev/null
|
|
18
|
-
source "$SCRIPT_DIR/harness.env"
|
|
19
|
-
# shellcheck source=/dev/null
|
|
20
|
-
source "$SCRIPT_DIR/agent-slot.sh"
|
|
21
|
-
|
|
22
|
-
AGENT_ID="${1:?Usage: verify.sh <agent-id> [--full]}"
|
|
23
|
-
FULL=""
|
|
24
|
-
|
|
25
|
-
for arg in "${@:2}"; do
|
|
26
|
-
[ "$arg" = "--full" ] && FULL=1
|
|
27
|
-
done
|
|
28
|
-
|
|
29
|
-
validate_agent_id "$AGENT_ID"
|
|
30
|
-
|
|
31
|
-
API_PORT=$(( HARNESS_API_BASE_PORT + AGENT_ID * 10 ))
|
|
32
|
-
|
|
33
|
-
ENV_FILE="$(resolve_agent_env_file "$AGENT_ID" "$REPO_ROOT")" || {
|
|
34
|
-
echo "No .env.agent.${AGENT_ID} found." >&2
|
|
35
|
-
har_suggest_launch "$AGENT_ID" >&2
|
|
36
|
-
exit 1
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
set -a
|
|
40
|
-
# shellcheck source=/dev/null
|
|
41
|
-
source "$ENV_FILE"
|
|
42
|
-
set +a
|
|
43
|
-
|
|
44
|
-
WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
|
|
45
|
-
API_PORT="${API_PORT:-$(( HARNESS_API_BASE_PORT + AGENT_ID * 10 ))}"
|
|
46
|
-
|
|
47
|
-
echo "==> Verifying agent ${AGENT_ID} (work dir: ${WORK_DIR})..." >&2
|
|
48
|
-
REG_FILE="$(slot_registry_file "$AGENT_ID")"
|
|
49
|
-
echo " Work dir: ${WORK_DIR}" >&2
|
|
50
|
-
echo " Env file: ${ENV_FILE}" >&2
|
|
51
|
-
if [ -f "$REG_FILE" ]; then
|
|
52
|
-
echo " Registry: ${REG_FILE}" >&2
|
|
53
|
-
else
|
|
54
|
-
echo " Registry: missing (${REG_FILE})" >&2
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
OVERALL_PASS=true
|
|
58
|
-
START_TOTAL=$(now_ms)
|
|
59
|
-
RESULTS_JSON="[]"
|
|
60
|
-
|
|
61
|
-
run_step() {
|
|
62
|
-
local name="$1"
|
|
63
|
-
local cmd="$2"
|
|
64
|
-
local start end elapsed exit_code output
|
|
65
|
-
|
|
66
|
-
printf " → %-40s" "$name..." >&2
|
|
67
|
-
start=$(now_ms)
|
|
68
|
-
|
|
69
|
-
set +e
|
|
70
|
-
output=$(cd "$WORK_DIR" && set -a && . "$ENV_FILE" && set +a && eval "$cmd" 2>&1)
|
|
71
|
-
exit_code=$?
|
|
72
|
-
set -e
|
|
73
|
-
|
|
74
|
-
end=$(now_ms)
|
|
75
|
-
elapsed=$(( end - start ))
|
|
76
|
-
|
|
77
|
-
local pass_bool
|
|
78
|
-
if [ "$exit_code" = "0" ]; then
|
|
79
|
-
echo "✓ (${elapsed}ms)" >&2
|
|
80
|
-
pass_bool="true"
|
|
81
|
-
else
|
|
82
|
-
echo "✗ (${elapsed}ms)" >&2
|
|
83
|
-
echo "$output" | head -30 | sed 's/^/ /' >&2
|
|
84
|
-
pass_bool="false"
|
|
85
|
-
OVERALL_PASS=false
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
record_step_result "$name" "$pass_bool" "$elapsed" "$output"
|
|
89
|
-
|
|
90
|
-
if [ "$pass_bool" = "false" ] && [ -z "$FULL" ]; then
|
|
91
|
-
return 1
|
|
92
|
-
fi
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
run_http_step() {
|
|
96
|
-
local name="$1"
|
|
97
|
-
local url="$2"
|
|
98
|
-
local start end elapsed exit_code output
|
|
99
|
-
|
|
100
|
-
printf " → %-40s" "$name..." >&2
|
|
101
|
-
start=$(now_ms)
|
|
102
|
-
|
|
103
|
-
set +e
|
|
104
|
-
output=$(curl -sf "$url" 2>&1)
|
|
105
|
-
exit_code=$?
|
|
106
|
-
set -e
|
|
107
|
-
|
|
108
|
-
end=$(now_ms)
|
|
109
|
-
elapsed=$(( end - start ))
|
|
110
|
-
|
|
111
|
-
local pass_bool
|
|
112
|
-
if [ "$exit_code" = "0" ]; then
|
|
113
|
-
echo "✓ (${elapsed}ms)" >&2
|
|
114
|
-
pass_bool="true"
|
|
115
|
-
else
|
|
116
|
-
echo "✗ (${elapsed}ms)" >&2
|
|
117
|
-
pass_bool="false"
|
|
118
|
-
OVERALL_PASS=false
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
record_step_result "$name" "$pass_bool" "$elapsed" "$output"
|
|
122
|
-
|
|
123
|
-
if [ "$pass_bool" = "false" ] && [ -z "$FULL" ]; then
|
|
124
|
-
return 1
|
|
125
|
-
fi
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
node_package_script_exists() {
|
|
129
|
-
local script="$1"
|
|
130
|
-
"${NODE_BIN:-node}" -e "
|
|
131
|
-
const fs = require('fs');
|
|
132
|
-
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
133
|
-
const script = process.argv[1];
|
|
134
|
-
process.exit(pkg.scripts && pkg.scripts[script] ? 0 : 1);
|
|
135
|
-
" "$script"
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
run_node_script_or_skip() {
|
|
139
|
-
local name="$1"
|
|
140
|
-
local script="$2"
|
|
141
|
-
if node_package_script_exists "$script"; then
|
|
142
|
-
run_step "$name" "${NPM_BIN:-npm} run ${script}"
|
|
143
|
-
else
|
|
144
|
-
run_step "$name" "echo 'No ${script} script configured; skipping.'"
|
|
145
|
-
fi
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
run_node_quick_smoke() {
|
|
149
|
-
if node_package_script_exists typecheck; then
|
|
150
|
-
run_step "node-typecheck" '${NPM_BIN:-npm} run typecheck'
|
|
151
|
-
elif node_package_script_exists build; then
|
|
152
|
-
run_step "node-build" '${NPM_BIN:-npm} run build'
|
|
153
|
-
else
|
|
154
|
-
run_step "node-package-load" '${NODE_BIN:-node} -e "require(\"./package.json\")"'
|
|
155
|
-
fi
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
run_quick_smoke() {
|
|
159
|
-
case "${HARNESS_ECOSYSTEM:-none}" in
|
|
160
|
-
node)
|
|
161
|
-
run_node_quick_smoke
|
|
162
|
-
;;
|
|
163
|
-
python)
|
|
164
|
-
run_step "python-compile" '${PYTHON_BIN:-python3} -m compileall -q .'
|
|
165
|
-
;;
|
|
166
|
-
go)
|
|
167
|
-
run_step "go-build" '${GO_BIN:-go} build ./...'
|
|
168
|
-
;;
|
|
169
|
-
rust)
|
|
170
|
-
run_step "rust-check" '${CARGO_BIN:-cargo} check'
|
|
171
|
-
;;
|
|
172
|
-
java)
|
|
173
|
-
run_step "java-compile" 'if [ -x ./mvnw ]; then ./mvnw -q -DskipTests compile; elif command -v mvn >/dev/null 2>&1; then mvn -q -DskipTests compile; elif [ -x ./gradlew ]; then ./gradlew classes; elif command -v gradle >/dev/null 2>&1; then gradle classes; else echo "No Maven/Gradle command found; adapt verify.sh for this Java repo."; fi'
|
|
174
|
-
;;
|
|
175
|
-
ruby)
|
|
176
|
-
run_step "ruby-smoke" '${RUBY_BIN:-ruby} -e "puts RUBY_VERSION"'
|
|
177
|
-
;;
|
|
178
|
-
custom|none|*)
|
|
179
|
-
run_step "smoke-not-configured" 'echo "No stock smoke for HARNESS_ECOSYSTEM=${HARNESS_ECOSYSTEM:-none}; adapt .har/verify.sh for this repo."'
|
|
180
|
-
;;
|
|
181
|
-
esac
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
run_full_checks() {
|
|
185
|
-
case "${HARNESS_ECOSYSTEM:-none}" in
|
|
186
|
-
node)
|
|
187
|
-
run_node_script_or_skip "unit-tests" test || true
|
|
188
|
-
run_node_script_or_skip "lint" lint || true
|
|
189
|
-
;;
|
|
190
|
-
python)
|
|
191
|
-
run_step "unit-tests" 'if ${PYTHON_BIN:-python3} -c "import pytest" >/dev/null 2>&1; then ${PYTHON_BIN:-python3} -m pytest -q; else echo "pytest not installed; adapt verify.sh for this Python repo."; fi' || true
|
|
192
|
-
;;
|
|
193
|
-
go)
|
|
194
|
-
run_step "unit-tests" '${GO_BIN:-go} test ./...' || true
|
|
195
|
-
;;
|
|
196
|
-
rust)
|
|
197
|
-
run_step "unit-tests" '${CARGO_BIN:-cargo} test' || true
|
|
198
|
-
;;
|
|
199
|
-
java)
|
|
200
|
-
run_step "unit-tests" 'if [ -x ./mvnw ]; then ./mvnw -q test; elif command -v mvn >/dev/null 2>&1; then mvn -q test; elif [ -x ./gradlew ]; then ./gradlew test; elif command -v gradle >/dev/null 2>&1; then gradle test; else echo "No Maven/Gradle command found; adapt verify.sh for this Java repo."; fi' || true
|
|
201
|
-
;;
|
|
202
|
-
ruby)
|
|
203
|
-
run_step "unit-tests" 'if command -v "${BUNDLE_BIN:-bundle}" >/dev/null 2>&1 && [ -f Gemfile ]; then "${BUNDLE_BIN:-bundle}" exec rake test 2>/dev/null || "${BUNDLE_BIN:-bundle}" exec rspec; else echo "No Ruby test command detected; adapt verify.sh for this Ruby repo."; fi' || true
|
|
204
|
-
;;
|
|
205
|
-
custom|none|*)
|
|
206
|
-
run_step "unit-tests" 'echo "No stock full checks for HARNESS_ECOSYSTEM=${HARNESS_ECOSYSTEM:-none}; adapt .har/verify.sh for this repo."' || true
|
|
207
|
-
;;
|
|
208
|
-
esac
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
# ── Verification stages ─────────────────────────────────────────────────────
|
|
212
|
-
# These stock steps are intentionally generic conventions. Adapt this section
|
|
213
|
-
# to the repository's real commands from package.json, Makefile, CI, pyproject,
|
|
214
|
-
# Cargo.toml, go.mod, pom.xml, etc.
|
|
215
|
-
run_quick_smoke || { [ -z "$FULL" ] && true; }
|
|
216
|
-
run_http_step "api-health" "http://localhost:${API_PORT}${HARNESS_HEALTH_CHECK_PATH}" || { [ -z "$FULL" ] && true; }
|
|
217
|
-
|
|
218
|
-
if [ -n "$FULL" ]; then
|
|
219
|
-
run_full_checks
|
|
220
|
-
run_step "readiness" "run_readiness_if_configured \"$AGENT_ID\"" || true
|
|
221
|
-
# Registered verification stages from .har/stages.json (see .har/STAGES.md).
|
|
222
|
-
# Every stage listed in verificationStages with a registered script/command
|
|
223
|
-
# runs here -- plugins and custom stages alike.
|
|
224
|
-
while IFS=$'\t' read -r STAGE_ID STAGE_CMD; do
|
|
225
|
-
[ -n "$STAGE_ID" ] || continue
|
|
226
|
-
run_step "$STAGE_ID" "$STAGE_CMD" || true
|
|
227
|
-
done < <(list_registered_verification_stage_commands "$SCRIPT_DIR" "$AGENT_ID")
|
|
228
|
-
fi
|
|
229
|
-
|
|
230
|
-
# ── Output results ────────────────────────────────────────────────────────────
|
|
231
|
-
|
|
232
|
-
END_TOTAL=$(now_ms)
|
|
233
|
-
TOTAL_MS=$(( END_TOTAL - START_TOTAL ))
|
|
234
|
-
|
|
235
|
-
node -e "
|
|
236
|
-
const results = $RESULTS_JSON;
|
|
237
|
-
const overall = results.length > 0 && results.every(r => r.pass);
|
|
238
|
-
const out = {
|
|
239
|
-
status: overall ? 'pass' : 'fail',
|
|
240
|
-
agent_id: $AGENT_ID,
|
|
241
|
-
total_ms: $TOTAL_MS,
|
|
242
|
-
stages: results,
|
|
243
|
-
};
|
|
244
|
-
process.stdout.write(JSON.stringify(out, null, 2) + '\n');
|
|
245
|
-
" 2>/dev/null || echo "{\"status\":\"fail\",\"agent_id\":${AGENT_ID},\"stages\":[]}"
|
|
246
|
-
|
|
247
|
-
if [ "$OVERALL_PASS" = "false" ]; then
|
|
248
|
-
exit 1
|
|
249
|
-
fi
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
# .har — Agent Harness (CLI / library profile)
|
|
2
|
-
|
|
3
|
-
This directory is the **agent harness** for this repository. It lets AI coding agents run the project in isolated git worktrees with optional Docker-backed shared infra.
|
|
4
|
-
|
|
5
|
-
Generated and maintained by [`har`](https://github.com/os-factory/har). Run `har env maintain` when the repo stack changes.
|
|
6
|
-
|
|
7
|
-
**The harness is how you run this project.** Launch a slot to exercise the code in isolation; don't hand-roll setup. If a harness command fails, fix the harness or report it — don't silently fall back to ad-hoc commands.
|
|
8
|
-
|
|
9
|
-
## What's in here
|
|
10
|
-
|
|
11
|
-
| File | Purpose |
|
|
12
|
-
|------|---------|
|
|
13
|
-
| `README.md` | This file — index of the harness |
|
|
14
|
-
| `manifest.json` | Generator metadata (version, profile, checksums) — do not edit |
|
|
15
|
-
| `harness.env` | Shared config: worktree default, `HARNESS_INFRA_SERVICES`, toolchain provisioning (`HARNESS_ECOSYSTEM`, `HARNESS_INSTALL_CMD`), migrate/seed commands |
|
|
16
|
-
| `stages.json` | Machine-readable registry of runnable harness stages |
|
|
17
|
-
| `stages/` | Optional custom stage scripts registered from `stages.json` |
|
|
18
|
-
| `runs/` | Run history from `har env` / MCP only — `.har/runs/YYYY-MM-DD/HH-mm-ss_<stageId>_agent-<id>.json` (gitignore) |
|
|
19
|
-
| `artifacts/` | Stage outputs: reports, traces, screenshots, logs |
|
|
20
|
-
| `agent-slot.sh` | Shared agent-id validation (reads limits from `harness.env`) |
|
|
21
|
-
| `setup-infra.sh` | Start optional Docker Compose stack + template database |
|
|
22
|
-
| `launch.sh` | Launch one agent slot (git worktree by default, toolchain provisioning, env file) |
|
|
23
|
-
| `provision-toolchain.sh` | Install deps and write toolchain paths (`PYTHON_BIN`, `NPM_BIN`, …) to `.env.agent.<id>` |
|
|
24
|
-
| `verify.sh` | Verification pipeline (smoke by default; --full adds tests, lint, e2e) |
|
|
25
|
-
| `teardown.sh` | Tear down one agent slot (worktree + env file) |
|
|
26
|
-
| `agent-cli.sh` | Inspect slot status, run commands in the work dir |
|
|
27
|
-
| `docker-compose.agent.yml` | Shared infrastructure containers (services listed in `HARNESS_INFRA_SERVICES`) |
|
|
28
|
-
| `CLAUDE.agent.md` | Detailed instructions for coding agents |
|
|
29
|
-
| `justfile` | Optional shortcuts (requires `just`) |
|
|
30
|
-
|
|
31
|
-
No PM2 or `ecosystem.agent.template.cjs` in this profile — agents run project commands directly in their worktree.
|
|
32
|
-
|
|
33
|
-
## Quick start
|
|
34
|
-
|
|
35
|
-
**Preferred — har CLI or MCP** (persists run history under `.har/runs/`):
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
har env launch 1
|
|
39
|
-
har env verify 1
|
|
40
|
-
har env verify 1 --full
|
|
41
|
-
har env teardown 1
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
In Cursor with HAR MCP configured: use `har_launch_environment`, `har_run_verification`, and `har_teardown_environment`.
|
|
45
|
-
|
|
46
|
-
**Shell fallback** (no CLI/MCP installed):
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
./.har/setup-infra.sh # when HARNESS_INFRA_SERVICES is non-empty
|
|
50
|
-
./.har/launch.sh 1
|
|
51
|
-
./.har/verify.sh 1 # quick: ecosystem smoke (compile/import/build)
|
|
52
|
-
./.har/verify.sh 1 --full # + conventional tests, lint, browser-e2e (if installed)
|
|
53
|
-
./.har/teardown.sh 1
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Read **`stages.json`** and **`verificationStages`**. Optional: `har env add-plugin playwright`.
|
|
57
|
-
|
|
58
|
-
## Verification contract
|
|
59
|
-
|
|
60
|
-
Steps in `verify.sh` are **project-specific examples** — adapt them to your stack
|
|
61
|
-
during `har env init` / `har env maintain` / benchmark setup. The table describes
|
|
62
|
-
each tier's intent, not a fixed command list.
|
|
63
|
-
|
|
64
|
-
| Mode | Command | Typical steps |
|
|
65
|
-
|------|---------|---------------|
|
|
66
|
-
| Quick | `har env verify <id>` or `verify.sh <id>` | Stock ecosystem smoke: compile / import / build conventions |
|
|
67
|
-
| Full | `har env verify <id> --full` or `verify.sh <id> --full` | Stock conventional tests/lint + optional readiness smoke, **browser-e2e** when `stages/browser-e2e.sh` exists |
|
|
68
|
-
|
|
69
|
-
The stock commands are deliberately generic conventions keyed by
|
|
70
|
-
`HARNESS_ECOSYSTEM`. Replace them with the repository's real commands during
|
|
71
|
-
adaptation; do not leave Node/npm, Python, Go, Rust, Java, or Ruby defaults in
|
|
72
|
-
place when they do not match the project.
|
|
73
|
-
|
|
74
|
-
For repos that need runtime services, distinguish health from usability. If the
|
|
75
|
-
harness skips slow local-dev setup, document the skipped steps and add a minimal
|
|
76
|
-
bootstrap/readiness check when agents need default data, credentials, or an
|
|
77
|
-
authenticated workflow.
|
|
78
|
-
|
|
79
|
-
Use `har env launch 1 --no-worktree` or `./.har/launch.sh 1 --no-worktree` only when working in the repo root.
|
|
80
|
-
|
|
81
|
-
## Run history
|
|
82
|
-
|
|
83
|
-
| Entry point | Writes `.har/runs/`? |
|
|
84
|
-
|-------------|------------------------|
|
|
85
|
-
| `./.har/*.sh` | No |
|
|
86
|
-
| `har env …` / MCP | Yes — main checkout `.har/runs/YYYY-MM-DD/` |
|
|
87
|
-
|
|
88
|
-
With worktree slots, tests run in the worktree; run JSON lives in the main repo. See `workDir` in each record.
|
|
89
|
-
|
|
90
|
-
## For coding agents
|
|
91
|
-
|
|
92
|
-
**Start here:** read [`AGENTS.md`](../AGENTS.md) at the repo root for a short pointer, then [`.har/CLAUDE.agent.md`](./CLAUDE.agent.md) for full instructions.
|
|
93
|
-
|
|
94
|
-
Prefer HAR MCP tools or `har env …` for launch, verify, and teardown. Use `./.har/*.sh` only when the CLI is not installed.
|
|
95
|
-
|
|
96
|
-
Work in the isolated git worktree created by launch. Use `./.har/agent-cli.sh <id> exec ...` to run ad-hoc project commands in that work dir.
|
|
97
|
-
|
|
98
|
-
When the project needs Postgres, Redis, or similar, add the service to `docker-compose.agent.yml` (or keep one from the menu), list it in `HARNESS_INFRA_SERVICES` in `harness.env`, and use `setup-infra.sh` — never run raw `docker compose` for shared infra. Shared services run once on fixed ports and serve every agent slot.
|
|
99
|
-
|
|
100
|
-
## Port & shared services (CLI profile)
|
|
101
|
-
|
|
102
|
-
This profile has **no PM2 app ports** — agents run project commands directly in their worktree. Port variables in `harness.env` exist for optional test servers and for shared Docker infra.
|
|
103
|
-
|
|
104
|
-
### Port allocation
|
|
105
|
-
|
|
106
|
-
| Layer | Scope | Rule | On conflict |
|
|
107
|
-
|-------|-------|------|-------------|
|
|
108
|
-
| Shared Postgres | Per machine | `HARNESS_DB_PORT_DEFAULT` | Scan `HARNESS_DB_PORT_SCAN_START..END` |
|
|
109
|
-
| Other compose services | Per machine | `HARNESS_*_PORT_DEFAULT` for that service | Scan configured ranges in `harness.env` |
|
|
110
|
-
|
|
111
|
-
When a repo adds a local HTTP server for integration tests, prefer reading ports from `.env.agent.<id>` or `./.har/agent-cli.sh <id>` rather than hardcoding values.
|
|
112
|
-
|
|
113
|
-
### Shared vs per-slot
|
|
114
|
-
|
|
115
|
-
| Resource | Model | Configuration |
|
|
116
|
-
|----------|-------|---------------|
|
|
117
|
-
| Postgres / Redis / mail / … | One shared container on a scanned host port | `HARNESS_INFRA_SERVICES` + matching vars in `harness.env` |
|
|
118
|
-
| Per-slot databases | Cloned from template DB when `db` is enabled | `launch.sh` |
|
|
119
|
-
| Application code | Isolated git worktree per slot | `HARNESS_USE_WORKTREE=true` |
|
|
120
|
-
|
|
121
|
-
### Do not
|
|
122
|
-
|
|
123
|
-
- Hardcode `15432` or other default infra ports in tests — read `AGENT_DB_PORT` from `.env.agent.<id>` or `har_pg`
|
|
124
|
-
- Run raw `docker compose` for harness infrastructure — use `setup-infra.sh`
|
|
125
|
-
|
|
126
|
-
## Maintaining this harness
|
|
127
|
-
|
|
128
|
-
When the project stack changes (new test commands, database needs, env vars):
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
har env maintain
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
The authoring agent updates scripts and this README. Review changes before committing.
|
|
135
|
-
|
|
136
|
-
**Do not** put runtime behavior in YAML — edit the scripts directly.
|
|
137
|
-
|
|
138
|
-
## Session lifecycle
|
|
139
|
-
|
|
140
|
-
Every `launch` starts a **fresh session**: a new git worktree from the **main
|
|
141
|
-
checkout's current HEAD** at
|
|
142
|
-
`~/worktrees/<base-branch>-<sha4>-har-agent-<id>-<rand4>`, on a branch of the same name.
|
|
143
|
-
Switch that checkout to your intended base before launch. The session is recorded in
|
|
144
|
-
`.har/slots/agent-<id>.json` (the slot registry) — status, verify, and teardown resolve
|
|
145
|
-
the work dir through it. Make ALL file edits under the work dir printed by launch,
|
|
146
|
-
never in the main checkout.
|
|
147
|
-
|
|
148
|
-
- Occupied slots always block a new launch: `har env complete <id>` (or `teardown <id>`),
|
|
149
|
-
then `har env launch <id>`. A new launch never chooses `main` for you — switch the
|
|
150
|
-
main checkout to your intended base first.
|
|
151
|
-
- `teardown` removes the worktree but **keeps the session branch** so you can push it
|
|
152
|
-
or open a PR (`--delete-branch` to drop it).
|
|
153
|
-
- If launch fails after creating a worktree/env file, resume with
|
|
154
|
-
`har env launch <id> --resume` or `har env recover <id>`.
|
|
155
|
-
- `har env complete <id>` finishes a session: full verify (recorded as a validation),
|
|
156
|
-
then teardown — branch kept.
|
|
157
|
-
- `--no-worktree` runs the slot from the repo root instead (single-agent mode).
|