@osfactory/har 0.64.1 → 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 +15981 -6646
- 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
|
@@ -15,22 +15,17 @@
|
|
|
15
15
|
# See: ./.har/stages/SEMGREP.md for the full adaptation guide.
|
|
16
16
|
set -euo pipefail
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
# 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
|
|
19
|
+
# HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
|
|
20
|
+
# agent-slot.sh is retired (1.0 migration).
|
|
21
|
+
HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
20
22
|
REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
|
|
21
|
-
# agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
|
|
22
|
-
SCRIPT_DIR="$HARNESS_DIR"
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# shellcheck source=/dev/null
|
|
27
|
-
source "$HARNESS_DIR/agent-slot.sh"
|
|
28
|
-
|
|
29
|
-
AGENT_ID="${1:?Usage: sast.sh <agent-id> [paths...]}"
|
|
30
|
-
shift
|
|
24
|
+
AGENT_ID="${1:-${AGENT_ID:?Usage: sast.sh <agent-id> [paths...]}}"
|
|
25
|
+
[ "$#" -gt 0 ] && shift
|
|
31
26
|
SCAN_PATHS=("$@")
|
|
32
27
|
|
|
33
|
-
|
|
28
|
+
now_ms() { node -e 'process.stdout.write(String(Date.now()))' 2>/dev/null || echo 0; }
|
|
34
29
|
|
|
35
30
|
log() { echo "==> [semgrep agent-$AGENT_ID] $*" >&2; }
|
|
36
31
|
|
|
@@ -46,22 +41,11 @@ if ! command -v semgrep >/dev/null 2>&1; then
|
|
|
46
41
|
fi
|
|
47
42
|
|
|
48
43
|
# ── Resolve agent env ─────────────────────────────────────────────────────────
|
|
49
|
-
|
|
50
|
-
echo "No .env.agent.${AGENT_ID} found." >&2
|
|
51
|
-
har_suggest_launch "$AGENT_ID" >&2
|
|
52
|
-
exit 1
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
# .env.agent.<id> exports REPO_ROOT pointing at the worktree — keep the main
|
|
56
|
-
# checkout path so artifacts land in the main repo root, not the worktree.
|
|
44
|
+
# Artifacts land in the main repo root (where .har/ lives), not the worktree.
|
|
57
45
|
MAIN_REPO_ROOT="$REPO_ROOT"
|
|
58
46
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
source "$ENV_FILE"
|
|
62
|
-
set +a
|
|
63
|
-
|
|
64
|
-
WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
|
|
47
|
+
ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
|
|
48
|
+
WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
|
|
65
49
|
|
|
66
50
|
# ── Artifact directory (main repo root, not the worktree) ─────────────────────
|
|
67
51
|
ARTIFACT_DIR="$MAIN_REPO_ROOT/.har/artifacts/sast"
|
|
@@ -13,7 +13,7 @@ har env add-plugin semgrep
|
|
|
13
13
|
|------|---------|
|
|
14
14
|
| `.har/stages/sast.sh` | Stage runner — scans the session worktree with Semgrep |
|
|
15
15
|
| `.har/stages/SEMGREP.md` | Adaptation guide: rulesets, noise tuning, CI/Vanta story |
|
|
16
|
-
| `.github/workflows/semgrep.yml` | Optional CI workflow (`--
|
|
16
|
+
| `.github/workflows/semgrep.yml` | Optional CI workflow (opt in with `--with-ci`) — official `semgrep ci` recipe |
|
|
17
17
|
|
|
18
18
|
## Workflow
|
|
19
19
|
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
"id": "semgrep",
|
|
3
3
|
"stageId": "sast",
|
|
4
4
|
"verificationStages": [
|
|
5
|
-
"typecheck",
|
|
6
|
-
"unit-tests",
|
|
7
|
-
"lint",
|
|
8
5
|
"sast"
|
|
9
6
|
],
|
|
10
7
|
"stage": {
|
|
@@ -23,14 +20,26 @@
|
|
|
23
20
|
"path": ".har/artifacts/sast/semgrep.json",
|
|
24
21
|
"kind": "report"
|
|
25
22
|
}
|
|
26
|
-
]
|
|
23
|
+
],
|
|
24
|
+
"tier": "full"
|
|
27
25
|
},
|
|
28
26
|
"files": [
|
|
29
|
-
{
|
|
30
|
-
|
|
27
|
+
{
|
|
28
|
+
"src": ".har/stages/sast.sh",
|
|
29
|
+
"dest": ".har/stages/sast.sh",
|
|
30
|
+
"executable": true
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"src": ".har/stages/SEMGREP.md",
|
|
34
|
+
"dest": ".har/stages/SEMGREP.md"
|
|
35
|
+
}
|
|
31
36
|
],
|
|
32
37
|
"optionalFiles": [
|
|
33
|
-
{
|
|
38
|
+
{
|
|
39
|
+
"src": ".github/workflows/semgrep.yml",
|
|
40
|
+
"dest": ".github/workflows/semgrep.yml",
|
|
41
|
+
"skipFlag": "skipCi"
|
|
42
|
+
}
|
|
34
43
|
],
|
|
35
44
|
"nextSteps": [
|
|
36
45
|
"pipx install semgrep # or: pip install semgrep / brew install semgrep",
|
|
@@ -16,20 +16,15 @@
|
|
|
16
16
|
# See: ./.har/stages/TRIVY.md for the full adaptation guide.
|
|
17
17
|
set -euo pipefail
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# 1.0 stage surface: the runner exports WORK_DIR, ENV_FILE, AGENT_ID and
|
|
20
|
+
# HAR_HARNESS_DIR, with harness.env and the slot env file already sourced —
|
|
21
|
+
# agent-slot.sh is retired (1.0 migration).
|
|
22
|
+
HARNESS_DIR="${HAR_HARNESS_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
21
23
|
REPO_ROOT="$(cd "$HARNESS_DIR/.." && pwd)"
|
|
22
|
-
# agent-slot.sh expects SCRIPT_DIR to be .har/ (slot registry lives there)
|
|
23
|
-
SCRIPT_DIR="$HARNESS_DIR"
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
source "$HARNESS_DIR/harness.env"
|
|
27
|
-
# shellcheck source=/dev/null
|
|
28
|
-
source "$HARNESS_DIR/agent-slot.sh"
|
|
25
|
+
AGENT_ID="${1:-${AGENT_ID:?Usage: vuln-scan.sh <agent-id>}}"
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
validate_agent_id "$AGENT_ID"
|
|
27
|
+
now_ms() { node -e 'process.stdout.write(String(Date.now()))' 2>/dev/null || echo 0; }
|
|
33
28
|
|
|
34
29
|
log() { echo "==> [vuln-scan agent-$AGENT_ID] $*" >&2; }
|
|
35
30
|
|
|
@@ -44,18 +39,8 @@ if ! command -v trivy >/dev/null 2>&1; then
|
|
|
44
39
|
fi
|
|
45
40
|
|
|
46
41
|
# ── Resolve agent env ─────────────────────────────────────────────────────────
|
|
47
|
-
ENV_FILE="$
|
|
48
|
-
|
|
49
|
-
har_suggest_launch "$AGENT_ID" >&2
|
|
50
|
-
exit 1
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
set -a
|
|
54
|
-
# shellcheck source=/dev/null
|
|
55
|
-
source "$ENV_FILE"
|
|
56
|
-
set +a
|
|
57
|
-
|
|
58
|
-
WORK_DIR="$(resolve_agent_work_dir "$ENV_FILE")"
|
|
42
|
+
ENV_FILE="${ENV_FILE:?No slot env for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
|
|
43
|
+
WORK_DIR="${WORK_DIR:?No slot work dir for agent ${AGENT_ID} — run ./.har/launch.sh ${AGENT_ID} first}"
|
|
59
44
|
|
|
60
45
|
# ── Configuration ─────────────────────────────────────────────────────────────
|
|
61
46
|
SEVERITY="${HARNESS_TRIVY_SEVERITY:-HIGH,CRITICAL}"
|
|
@@ -9,7 +9,7 @@ agent's worktree:
|
|
|
9
9
|
CloudFormation (Trivy absorbed tfsec, so this covers the Terraform use case)
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
har env add-plugin trivy # --
|
|
12
|
+
har env add-plugin trivy # --with-ci to include the GitHub workflow
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
What it adds:
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
"id": "trivy",
|
|
3
3
|
"stageId": "vuln-scan",
|
|
4
4
|
"verificationStages": [
|
|
5
|
-
"typecheck",
|
|
6
|
-
"unit-tests",
|
|
7
|
-
"lint",
|
|
8
5
|
"vuln-scan"
|
|
9
6
|
],
|
|
10
7
|
"stage": {
|
|
@@ -23,15 +20,30 @@
|
|
|
23
20
|
"path": ".har/artifacts/vuln-scan/report.json",
|
|
24
21
|
"kind": "report"
|
|
25
22
|
}
|
|
26
|
-
]
|
|
23
|
+
],
|
|
24
|
+
"tier": "full"
|
|
27
25
|
},
|
|
28
26
|
"files": [
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
{
|
|
28
|
+
"src": ".har/stages/vuln-scan.sh",
|
|
29
|
+
"dest": ".har/stages/vuln-scan.sh",
|
|
30
|
+
"executable": true
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"src": ".har/stages/TRIVY.md",
|
|
34
|
+
"dest": ".har/stages/TRIVY.md"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"src": ".trivyignore",
|
|
38
|
+
"dest": ".trivyignore"
|
|
39
|
+
}
|
|
32
40
|
],
|
|
33
41
|
"optionalFiles": [
|
|
34
|
-
{
|
|
42
|
+
{
|
|
43
|
+
"src": ".github/workflows/trivy.yml",
|
|
44
|
+
"dest": ".github/workflows/trivy.yml",
|
|
45
|
+
"skipFlag": "skipCi"
|
|
46
|
+
}
|
|
35
47
|
],
|
|
36
48
|
"nextSteps": [
|
|
37
49
|
"Install trivy: brew install trivy (or https://trivy.dev/latest/getting-started/installation/)",
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
# Agent ${AGENT_ID} — Development Environment
|
|
2
|
-
|
|
3
|
-
> [`AGENTS.md`](../AGENTS.md) · [`.har/README.md`](./README.md) · [`stages.json`](./stages.json)
|
|
4
|
-
|
|
5
|
-
## Environment
|
|
6
|
-
|
|
7
|
-
| | |
|
|
8
|
-
|--|--|
|
|
9
|
-
| **Agent ID** | ${AGENT_ID} |
|
|
10
|
-
| **Work dir** | Fresh session worktree per launch — see the launch output or `.har/slots/agent-${AGENT_ID}.json` |
|
|
11
|
-
|
|
12
|
-
**Never edit the main checkout** — launch FIRST, then make ALL file edits under the work dir from the launch output. An occupied slot always blocks a new launch — run `har env teardown <id>` (or `complete <id>`) first, then launch again.
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
./.har/agent-cli.sh ${AGENT_ID} status
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Readiness
|
|
19
|
-
|
|
20
|
-
Adapt this section for the repository. For pure CLI/library repos, full verify
|
|
21
|
-
may be enough. If the project needs services, auth, seeded data, or a sample
|
|
22
|
-
workflow, document the required credentials/default data and wire a smoke into
|
|
23
|
-
`HARNESS_READINESS_CMD` or full verify.
|
|
24
|
-
|
|
25
1
|
## Definition of done
|
|
26
2
|
|
|
27
3
|
- [ ] Full verification returns `"status": "pass"` (`har env verify ${AGENT_ID} --full`, MCP `har_run_verification` with `full: true`, or `./.har/verify.sh ${AGENT_ID} --full`)
|
|
@@ -45,21 +21,3 @@ the work succeeded. See `.cursor/rules/har-workflow.mdc` for the handoff shape.
|
|
|
45
21
|
Quick loop: MCP `har_run_verification`, `har env verify ${AGENT_ID}`, or `./.har/verify.sh ${AGENT_ID}`
|
|
46
22
|
|
|
47
23
|
Stages are the harness's single vocabulary for checks: templates and custom stages compile to generic kinds in `.har/stages.json`, and you interact with them only through the registry (`har_run_stage`, `verify`), never stack-specific tooling. Authoring guide: `.har/STAGES.md`.
|
|
48
|
-
|
|
49
|
-
## Project commands
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
# TODO: adapt for this repository. Examples:
|
|
53
|
-
# npm test
|
|
54
|
-
# pytest -q
|
|
55
|
-
# go test ./...
|
|
56
|
-
# cargo test
|
|
57
|
-
# make test
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Do not
|
|
61
|
-
|
|
62
|
-
- Work around a failing harness command with ad-hoc setup — fix the harness or report the failure
|
|
63
|
-
- Edit `.env.agent.${AGENT_ID}` by hand
|
|
64
|
-
- Run `verify` before `launch` when e2e needs a running server
|
|
65
|
-
- Edit the main checkout — all edits go under the session work dir
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
## Do not
|
|
2
|
+
|
|
3
|
+
- Work around a failing harness command with ad-hoc setup — fix the harness or report the failure
|
|
4
|
+
- Edit `.env.agent.${AGENT_ID}` by hand
|
|
5
|
+
- Run `verify` before `launch` when e2e needs a running server
|
|
6
|
+
- Edit the main checkout — all edits go under the session work dir
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Environment
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
|--|--|
|
|
5
|
+
| **Agent ID** | ${AGENT_ID} |
|
|
6
|
+
| **Work dir** | Fresh session worktree per launch — see the launch output or `.har/slots/agent-${AGENT_ID}.json` |
|
|
7
|
+
|
|
8
|
+
**Never edit the main checkout** — launch FIRST, then make ALL file edits under the work dir from the launch output. An occupied slot always blocks a new launch — run `har env teardown <id>` (or `complete <id>`) first, then launch again.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
./.har/agent-cli.sh ${AGENT_ID} status
|
|
12
|
+
```
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
## Readiness
|
|
2
|
+
|
|
3
|
+
Adapt this section for the repository. For pure CLI/library repos, full verify
|
|
4
|
+
may be enough. If the project needs services, auth, seeded data, or a sample
|
|
5
|
+
workflow, document the required credentials/default data and wire a smoke into
|
|
6
|
+
`HARNESS_READINESS_CMD` or full verify.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## For coding agents
|
|
2
|
+
|
|
3
|
+
**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.
|
|
4
|
+
|
|
5
|
+
Prefer HAR MCP tools or `har env …` for launch, verify, and teardown. Use `./.har/*.sh` only when the CLI is not installed.
|
|
6
|
+
|
|
7
|
+
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.
|
|
8
|
+
|
|
9
|
+
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.
|
|
@@ -0,0 +1,7 @@
|
|
|
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.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Port & shared services (CLI profile)
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
### Port allocation
|
|
6
|
+
|
|
7
|
+
| Layer | Scope | Rule | On conflict |
|
|
8
|
+
|-------|-------|------|-------------|
|
|
9
|
+
| Shared Postgres | Per machine | `HARNESS_DB_PORT_DEFAULT` | Scan `HARNESS_DB_PORT_SCAN_START..END` |
|
|
10
|
+
| Other compose services | Per machine | `HARNESS_*_PORT_DEFAULT` for that service | Scan configured ranges in `harness.env` |
|
|
11
|
+
|
|
12
|
+
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.
|
|
13
|
+
|
|
14
|
+
### Shared vs per-slot
|
|
15
|
+
|
|
16
|
+
| Resource | Model | Configuration |
|
|
17
|
+
|----------|-------|---------------|
|
|
18
|
+
| Postgres / Redis / mail / … | One shared container on a scanned host port | `HARNESS_INFRA_SERVICES` + matching vars in `harness.env` |
|
|
19
|
+
| Per-slot databases | Cloned from template DB when `db` is enabled | `launch.sh` |
|
|
20
|
+
| Application code | Isolated git worktree per slot | `HARNESS_USE_WORKTREE=true` |
|
|
21
|
+
|
|
22
|
+
### Do not
|
|
23
|
+
|
|
24
|
+
- Hardcode `15432` or other default infra ports in tests — read `AGENT_DB_PORT` from `.env.agent.<id>` or `har_pg`
|
|
25
|
+
- Run raw `docker compose` for harness infrastructure — use `setup-infra.sh`
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Quick start
|
|
2
|
+
|
|
3
|
+
**har CLI or MCP:**
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
har env launch 1
|
|
7
|
+
har env verify 1
|
|
8
|
+
har env verify 1 --full
|
|
9
|
+
har env teardown 1
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
In Cursor with HAR MCP configured: use `har_launch_environment`, `har_run_verification`, and `har_teardown_environment`.
|
|
13
|
+
|
|
14
|
+
**Shell shims** (same runtime — each `./.har/*.sh` forwards to `har env`, with a pinned `npx @osfactory/har` fallback):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
./.har/setup-infra.sh # when HARNESS_INFRA_SERVICES is non-empty
|
|
18
|
+
./.har/launch.sh 1
|
|
19
|
+
./.har/verify.sh 1 # quick: ecosystem smoke (compile/import/build)
|
|
20
|
+
./.har/verify.sh 1 --full # + conventional tests, lint, browser-e2e (if installed)
|
|
21
|
+
./.har/teardown.sh 1
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Read **`stages.json`** and **`verificationStages`**. Optional: `har env add-plugin playwright`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Verification contract
|
|
2
|
+
|
|
3
|
+
Steps in `verify.sh` are **project-specific examples** — adapt them to your stack
|
|
4
|
+
during `har env init` / `har env maintain` / benchmark setup. The table describes
|
|
5
|
+
each tier's intent, not a fixed command list.
|
|
6
|
+
|
|
7
|
+
| Mode | Command | Typical steps |
|
|
8
|
+
|------|---------|---------------|
|
|
9
|
+
| Quick | `har env verify <id>` or `verify.sh <id>` | Stock ecosystem smoke: compile / import / build conventions |
|
|
10
|
+
| 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 |
|
|
11
|
+
|
|
12
|
+
The stock commands are deliberately generic conventions keyed by
|
|
13
|
+
`HARNESS_ECOSYSTEM`. Replace them with the repository's real commands during
|
|
14
|
+
adaptation; do not leave Node/npm, Python, Go, Rust, Java, or Ruby defaults in
|
|
15
|
+
place when they do not match the project.
|
|
16
|
+
|
|
17
|
+
For repos that need runtime services, distinguish health from usability. If the
|
|
18
|
+
harness skips slow local-dev setup, document the skipped steps and add a minimal
|
|
19
|
+
bootstrap/readiness check when agents need default data, credentials, or an
|
|
20
|
+
authenticated workflow.
|
|
21
|
+
|
|
22
|
+
Use `har env launch 1 --no-worktree` or `./.har/launch.sh 1 --no-worktree` only when working in the repo root.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
## What's in here
|
|
2
|
+
|
|
3
|
+
**Yours — the configuration surface** (edit freely; drift tracking records adaptations):
|
|
4
|
+
|
|
5
|
+
| File | Purpose |
|
|
6
|
+
|------|---------|
|
|
7
|
+
| `README.md` | This file — index of the harness |
|
|
8
|
+
| `harness.env` | Schema-validated config: worktree default, `HARNESS_INFRA_SERVICES`, toolchain provisioning (`HARNESS_ECOSYSTEM`, `HARNESS_INSTALL_CMD`), migrate/seed commands |
|
|
9
|
+
| `stages.json` | Registered stages, verification tiers, artifacts, slot limits, gate policy |
|
|
10
|
+
| `stages/` | Project-owned stage scripts registered from `stages.json` |
|
|
11
|
+
| `hooks/` | Optional lifecycle hooks (`pre-launch.sh`, `post-launch.sh`, `pre-verify.sh`, `pre-teardown.sh`, `post-teardown.sh`) |
|
|
12
|
+
| `plugins/` | Optional local plugins (`har plugin create <id>`) |
|
|
13
|
+
| `docker-compose.agent.yml` | Optional shared infrastructure containers (services listed in `HARNESS_INFRA_SERVICES`) |
|
|
14
|
+
| `CLAUDE.agent.md` | Detailed instructions for coding agents |
|
|
15
|
+
| `STAGES.md` | Stage registry and script-contract guide |
|
|
16
|
+
| `justfile` | Optional shortcuts (requires `just`) |
|
|
17
|
+
|
|
18
|
+
**Generated shims and state** (don't edit — `har env eject` for full ownership):
|
|
19
|
+
|
|
20
|
+
| File | Purpose |
|
|
21
|
+
|------|---------|
|
|
22
|
+
| `launch.sh` / `verify.sh` / `teardown.sh` / `setup-infra.sh` / `preflight.sh` / `agent-cli.sh` | Thin shims forwarding to the packaged runtime (`har env …`); same run records on every surface |
|
|
23
|
+
| `manifest.json` | Runtime version, profile, checksums — managed by the har CLI |
|
|
24
|
+
| `runs/` | Run history from every entry point — `.har/runs/YYYY-MM-DD/HH-mm-ss_<stageId>_agent-<id>.json` (gitignored) |
|
|
25
|
+
| `artifacts/` | Stage outputs: reports, traces, logs |
|
|
26
|
+
|
|
27
|
+
No PM2 or `ecosystem.agent.template.cjs` in this profile — agents run project commands directly in their worktree.
|
|
@@ -4,5 +4,60 @@
|
|
|
4
4
|
"bundles": [
|
|
5
5
|
{ "id": "shared-kernel", "path": "runtime-bundles/shared-kernel" },
|
|
6
6
|
{ "id": "runtime-cli", "path": "har-boilerplate-cli" }
|
|
7
|
-
]
|
|
7
|
+
],
|
|
8
|
+
"capabilities": {
|
|
9
|
+
"processManager": "none",
|
|
10
|
+
"appPortLanes": false,
|
|
11
|
+
"infra": {
|
|
12
|
+
"defaultServices": [],
|
|
13
|
+
"portLanes": "db=15432:15432-15499"
|
|
14
|
+
},
|
|
15
|
+
"defaultStages": [
|
|
16
|
+
"setup-infra",
|
|
17
|
+
"launch",
|
|
18
|
+
"verify",
|
|
19
|
+
"status",
|
|
20
|
+
"teardown",
|
|
21
|
+
"typecheck",
|
|
22
|
+
"unit-tests",
|
|
23
|
+
"lint",
|
|
24
|
+
"readiness"
|
|
25
|
+
],
|
|
26
|
+
"defaultEnvKeys": [
|
|
27
|
+
"HARNESS_PROJECT_NAME",
|
|
28
|
+
"HARNESS_USE_WORKTREE",
|
|
29
|
+
"HARNESS_FE_BASE_PORT",
|
|
30
|
+
"HARNESS_API_BASE_PORT",
|
|
31
|
+
"HARNESS_PORT_STEP",
|
|
32
|
+
"HARNESS_HEALTH_CHECK_PATH",
|
|
33
|
+
"HARNESS_INFRA_PORT_LANES",
|
|
34
|
+
"HARNESS_AGENT_SLOT_MIN",
|
|
35
|
+
"HARNESS_AGENT_SLOT_MAX",
|
|
36
|
+
"HARNESS_ECOSYSTEM",
|
|
37
|
+
"HARNESS_INFRA_SERVICES",
|
|
38
|
+
"HARNESS_DB_MIGRATE_CMD",
|
|
39
|
+
"HARNESS_DB_SEED_CMD"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"docs": {
|
|
43
|
+
"README.md": [
|
|
44
|
+
"intro",
|
|
45
|
+
"what-s-in-here",
|
|
46
|
+
"quick-start",
|
|
47
|
+
"verification-contract",
|
|
48
|
+
"run-history",
|
|
49
|
+
"for-coding-agents",
|
|
50
|
+
"port-shared-services-cli-profile",
|
|
51
|
+
"maintaining-this-harness",
|
|
52
|
+
"session-lifecycle"
|
|
53
|
+
],
|
|
54
|
+
"CLAUDE.agent.md": [
|
|
55
|
+
"intro",
|
|
56
|
+
"environment",
|
|
57
|
+
"readiness",
|
|
58
|
+
"definition-of-done",
|
|
59
|
+
"project-commands",
|
|
60
|
+
"do-not"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
8
63
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Definition of done
|
|
2
|
+
|
|
3
|
+
- [ ] Full verification returns `"status": "pass"` (`har env verify ${AGENT_ID} --full`, MCP `har_run_verification` with `full: true`, or `./.har/verify.sh ${AGENT_ID} --full`)
|
|
4
|
+
- [ ] The slot is agent-usable for this repo's documented smoke workflow, not only health-check green
|
|
5
|
+
- [ ] Full verify runs every registered stage in `stages.json` `verificationStages` (Playwright, custom checks, …) — when `stages/browser-e2e.sh` exists, adapt specs under `tests/` for UI changes
|
|
6
|
+
- [ ] New behavior has automated test coverage (unit and/or browser as appropriate)
|
|
7
|
+
- [ ] Changes committed **in the session worktree** with a clear message
|
|
8
|
+
- [ ] The user got the preview URLs to test the app themselves
|
|
9
|
+
- [ ] Present session handoff (summary, branch, preview URLs) and **wait for user** before `complete`, push, or PR
|
|
10
|
+
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete ${AGENT_ID}` (or MCP `har_complete_environment`) — full verify + validation + teardown, branch kept
|
|
11
|
+
|
|
12
|
+
### Session handoff
|
|
13
|
+
|
|
14
|
+
After full verify and commit, stop and propose next steps. Never autonomously run
|
|
15
|
+
`complete`, `teardown`, `git push`, or open a PR. **Default recommendation:** when
|
|
16
|
+
`gh` or GitHub MCP is available, complete the slot **and** open a PR (push → PR →
|
|
17
|
+
`har env complete` / `har_complete_environment`). Offer complete-only or something
|
|
18
|
+
else as alternatives. If PR tooling is unavailable, recommend complete and report
|
|
19
|
+
the session branch for a manual push. Prefer `complete` over bare `teardown` when
|
|
20
|
+
the work succeeded. See `.cursor/rules/har-workflow.mdc` for the handoff shape.
|
|
21
|
+
|
|
22
|
+
Quick loop during development: MCP `har_run_verification`, `har env verify ${AGENT_ID}`, or `./.har/verify.sh ${AGENT_ID}` (smoke + health only; `--full` adds the registered verification stages).
|
|
23
|
+
|
|
24
|
+
Stages are the harness's single vocabulary for checks: templates and custom stages compile to generic kinds in `.har/stages.json`, and you interact with them only through the registry (`har_run_stage`, `verify`), never stack-specific tooling. Authoring guide: `.har/STAGES.md`.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Do not
|
|
2
|
+
|
|
3
|
+
- Hand-roll docker/dev-server startup — `launch` is how you run the app (manual testing, browser, screenshots included)
|
|
4
|
+
- Work around a failing harness command with ad-hoc setup — fix the harness or report the failure
|
|
5
|
+
- Hardcode ports — use agent env / `agent-cli.sh url`
|
|
6
|
+
- Run raw `docker compose` for shared harness infra — use `setup-infra.sh`
|
|
7
|
+
- Start other services of the repo in your slot — only the primary app runs per-slot; shared services are already running
|
|
8
|
+
- Edit `.env.agent.${AGENT_ID}` or PM2 ecosystem files by hand
|
|
9
|
+
- Run `verify` before `launch` when health or e2e steps need a running server
|
|
10
|
+
- Edit the main checkout — all edits go under the session work dir
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Environment
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
|--|--|
|
|
5
|
+
| **Agent ID** | ${AGENT_ID} |
|
|
6
|
+
| **Frontend** | http://localhost:${FE_PORT} |
|
|
7
|
+
| **API** | http://localhost:${API_PORT} |
|
|
8
|
+
| **Database** | `agent_${AGENT_ID}` on `localhost:${DB_PORT}` (when `db` is in `HARNESS_INFRA_SERVICES`) |
|
|
9
|
+
| **Work dir** | Fresh session worktree per launch — see the launch output or `.har/slots/agent-${AGENT_ID}.json` |
|
|
10
|
+
|
|
11
|
+
**Never edit the main checkout** — launch FIRST, then make ALL file edits under the work dir from the launch output. Edits there hot-reload in the running slot; use `./.har/agent-cli.sh ${AGENT_ID} restart` if a change doesn't take. An occupied slot always blocks a new launch — run `./.har/teardown.sh ${AGENT_ID}` (or `complete`) first, then launch again.
|
|
12
|
+
|
|
13
|
+
This slot runs **only the primary application** (`HARNESS_PRIMARY_APP`). External dependencies and any supporting services run once, shared by all slots — `setup-infra.sh` manages them; never start them yourself.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
./.har/agent-cli.sh ${AGENT_ID} status
|
|
17
|
+
./.har/agent-cli.sh ${AGENT_ID} logs api
|
|
18
|
+
./.har/agent-cli.sh ${AGENT_ID} health
|
|
19
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Readiness
|
|
2
|
+
|
|
3
|
+
Adapt this section for the repository. A passing health check means the process
|
|
4
|
+
is alive; it does not automatically mean an agent can use the app.
|
|
5
|
+
|
|
6
|
+
- **Health**: `./.har/agent-cli.sh ${AGENT_ID} health`
|
|
7
|
+
- **Agent-usable smoke**: document the login/API/UI workflow agents should try,
|
|
8
|
+
or wire it into `HARNESS_READINESS_CMD` / full verify.
|
|
9
|
+
- **Credentials/default data**: document any test users, tenants, projects, or
|
|
10
|
+
settings created by the harness.
|
|
11
|
+
- **Skipped full-dev setup**: document anything intentionally omitted from the
|
|
12
|
+
upstream developer setup and the minimal substitute in `.har/`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Architecture
|
|
2
|
+
|
|
3
|
+
Each agent slot gets isolated app ports. Defaults follow `BASE + (AGENT_ID × HARNESS_PORT_STEP)`; when a default is busy, `launch.sh` scans the slot lane (`STEP` increments) and writes the resolved ports to `.env.agent.<id>` and `.har/slots/agent-<id>.json`.
|
|
4
|
+
|
|
5
|
+
Configure how many slots your machine can run in parallel in `.har/stages.json` (`agentSlots`). Bash scripts and the CLI read that first; `harness.env` keeps legacy `HARNESS_AGENT_SLOT_*` exports in sync via `har env maintain --finalize`.
|
|
6
|
+
|
|
7
|
+
| Service | Agent 1 (default) | Agent 2 (default) |
|
|
8
|
+
|---------|-------------------|-------------------|
|
|
9
|
+
| Frontend | 3010 | 3020 |
|
|
10
|
+
| API | 8010 | 8020 |
|
|
11
|
+
| Node debug | 9210 | 9220 |
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## For coding agents
|
|
2
|
+
|
|
3
|
+
1. Read repo [`AGENTS.md`](../AGENTS.md)
|
|
4
|
+
2. Read this file and `stages.json`
|
|
5
|
+
3. After launch, read `.har/CLAUDE.agent.md` for slot URLs and definition of done
|
|
6
|
+
|
|
7
|
+
Prefer HAR MCP tools or `har env …` for launch, verify, and teardown. Use `./.har/*.sh` only when the CLI is not installed.
|
|
8
|
+
|
|
9
|
+
Always use `./.har/agent-cli.sh <id> ...` — never hardcoded ports.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# .har — Agent Harness
|
|
2
|
+
|
|
3
|
+
This directory is the **agent harness** for this repository. It lets AI coding agents (Cursor, Claude Code, etc.) run the project in isolated environments with their own ports, database, and verification workflow.
|
|
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.** Need the app live — manual testing, a browser session, screenshots? `launch` a slot; don't hand-roll docker/dev-server startup. If a harness command fails, fix the harness or report it — don't silently fall back to ad-hoc commands.
|