@osfactory/har 1.0.0-rc.1 → 1.0.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 +5070 -8444
- package/dist/templates/AGENTS.md.template +19 -66
- package/dist/templates/CLAUDE.md.template +1 -5
- package/dist/templates/adaptation-prompt-init.md +7 -6
- package/dist/templates/adaptation-prompt-maintain.md +4 -4
- package/dist/templates/adaptation-prompt-plugin.md +40 -0
- package/dist/templates/agent-skills/har-wt.md +1 -1
- package/dist/templates/cursor-rule.mdc.template +7 -72
- package/dist/templates/har-boilerplate/gitignore.template +3 -1
- package/dist/templates/har-boilerplate-cli/gitignore.template +3 -1
- package/dist/templates/har-boilerplate-ios/gitignore.template +2 -0
- package/dist/templates/migration-prompt.md +2 -1
- package/dist/templates/profiles/cli/docs/{claude-agent → readme}/definition-of-done.md +3 -3
- package/dist/templates/profiles/cli/docs/{claude-agent → readme}/do-not.md +1 -1
- package/dist/templates/profiles/cli/docs/{claude-agent → readme}/environment.md +3 -3
- package/dist/templates/profiles/cli/docs/readme/for-coding-agents.md +5 -7
- package/dist/templates/profiles/cli/docs/readme/port-shared-services-cli-profile.md +3 -3
- package/dist/templates/profiles/cli/docs/readme/quick-start.md +3 -9
- package/dist/templates/profiles/cli/docs/readme/verification-contract.md +2 -2
- package/dist/templates/profiles/cli/docs/readme/what-s-in-here.md +2 -2
- package/dist/templates/profiles/cli/profile.manifest.json +14 -11
- package/dist/templates/profiles/default/docs/readme/architecture.md +1 -1
- package/dist/templates/profiles/default/docs/{claude-agent → readme}/definition-of-done.md +3 -3
- package/dist/templates/profiles/default/docs/{claude-agent → readme}/do-not.md +2 -2
- package/dist/templates/profiles/default/docs/readme/environment.md +19 -0
- package/dist/templates/profiles/default/docs/readme/for-coding-agents.md +4 -6
- package/dist/templates/profiles/default/docs/readme/port-shared-services.md +5 -5
- package/dist/templates/profiles/default/docs/readme/quick-start.md +3 -9
- package/dist/templates/profiles/default/docs/readme/readiness-layers.md +4 -4
- package/dist/templates/profiles/default/docs/{claude-agent → readme}/readiness.md +1 -1
- package/dist/templates/profiles/default/docs/readme/verification-contract.md +1 -1
- package/dist/templates/profiles/default/docs/readme/what-s-in-here.md +2 -2
- package/dist/templates/profiles/default/profile.manifest.json +21 -13
- package/dist/templates/profiles/ios/docs/{claude-agent → readme}/definition-of-done.md +3 -3
- package/dist/templates/profiles/ios/docs/{claude-agent → readme}/do-not.md +1 -1
- package/dist/templates/profiles/ios/docs/{claude-agent → readme}/environment.md +4 -4
- package/dist/templates/profiles/ios/docs/readme/port-shared-services-ios-profile.md +3 -3
- package/dist/templates/profiles/ios/docs/{claude-agent → readme}/project-commands.md +4 -4
- package/dist/templates/profiles/ios/docs/readme/quick-start.md +3 -9
- package/dist/templates/profiles/ios/docs/readme/simulators.md +2 -2
- package/dist/templates/profiles/ios/docs/{claude-agent → readme}/user-flow-validation-rocketsim.md +2 -2
- package/dist/templates/profiles/ios/docs/readme/verification-contract.md +1 -1
- package/dist/templates/profiles/ios/docs/readme/what-s-in-here.md +2 -2
- package/dist/templates/profiles/ios/profile.manifest.json +15 -12
- package/dist/templates/runtime-bundles/pm2-runtime/attach.sh +44 -6
- package/dist/templates/runtime-bundles/shared-kernel/agent-cli.sh +20 -3
- package/dist/templates/runtime-bundles/shared-kernel/launch.sh +20 -3
- package/dist/templates/runtime-bundles/shared-kernel/preflight.sh +20 -3
- package/dist/templates/runtime-bundles/shared-kernel/setup-infra.sh +20 -3
- package/dist/templates/runtime-bundles/shared-kernel/teardown.sh +20 -3
- package/dist/templates/runtime-bundles/shared-kernel/verify.sh +20 -3
- package/package.json +2 -1
- package/dist/prompts/system-authoring.md +0 -155
- package/dist/templates/profiles/default/docs/claude-agent/environment.md +0 -19
- package/dist/templates/profiles/ios/docs/claude-agent/intro.md +0 -3
- package/dist/templates/shared-docs/claude-agent/intro.md +0 -3
- /package/dist/templates/profiles/cli/docs/{claude-agent → readme}/project-commands.md +0 -0
- /package/dist/templates/profiles/cli/docs/{claude-agent → readme}/readiness.md +0 -0
- /package/dist/templates/profiles/default/docs/{claude-agent → readme}/project-commands.md +0 -0
- /package/dist/templates/profiles/ios/docs/{claude-agent → readme}/readiness.md +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Environment
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
|--|--|
|
|
5
|
+
| **Agent ID** | <id> |
|
|
6
|
+
| **Frontend** | http://localhost:${FE_PORT} |
|
|
7
|
+
| **API** | http://localhost:${API_PORT} |
|
|
8
|
+
| **Database** | `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-<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 env agent <id> restart` if a change doesn't take. An occupied slot always blocks a new launch — run `har env teardown <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 — `har env setup-infra` manages them; never start them yourself.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
har env agent <id> status
|
|
17
|
+
har env agent <id> logs api
|
|
18
|
+
har env agent <id> health
|
|
19
|
+
```
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
## For coding agents
|
|
2
2
|
|
|
3
3
|
1. Read repo [`AGENTS.md`](../AGENTS.md)
|
|
4
|
-
2. Read this file and `stages.json`
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Always use `./.har/agent-cli.sh <id> ...` — never hardcoded ports.
|
|
4
|
+
2. Read this file and `stages.json` — this file is the harness reference:
|
|
5
|
+
slot environment, readiness, definition of done, project commands
|
|
6
|
+
3. Drive the harness with HAR MCP tools or `har env …`; never hardcode ports —
|
|
7
|
+
ask `har env agent <id> url`
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
| Mailpit | Per machine | `HARNESS_MAILPIT_*_PORT_DEFAULT` | Scan configured ranges |
|
|
13
13
|
| Headless browser | Per machine | `HARNESS_BROWSER_PORT_DEFAULT` | Scan configured ranges |
|
|
14
14
|
|
|
15
|
-
Resolved ports may differ from the formula when something else is already bound. Always use
|
|
15
|
+
Resolved ports may differ from the formula when something else is already bound. Always use `har env agent <id>` or read `.har/slots/agent-<id>.json` — never hardcode `3010`, `15432`, etc. in app code or tests.
|
|
16
16
|
|
|
17
17
|
### Shared vs per-slot
|
|
18
18
|
|
|
@@ -24,18 +24,18 @@ Resolved ports may differ from the formula when something else is already bound.
|
|
|
24
24
|
| Primary application | One PM2 ecosystem per slot (isolated ports) | `HARNESS_PRIMARY_APP`, `ecosystem.agent.template.cjs` |
|
|
25
25
|
| Internal supporting services | Shared across all slots | `docker-compose.agent.yml` or `ecosystem.shared.config.cjs` |
|
|
26
26
|
|
|
27
|
-
Shared infra starts once via
|
|
27
|
+
Shared infra starts once via `har env setup-infra` (also run automatically by `har env launch`). Per-slot databases are cloned in `har env launch`.
|
|
28
28
|
|
|
29
29
|
### Do not
|
|
30
30
|
|
|
31
31
|
- Hardcode default ports (`3000`, `15432`, `3847`, …) in application code, tests, or agent docs — read from `.env.agent.<id>`, `agent-cli.sh`, or the slot registry
|
|
32
|
-
- Run raw `docker compose` for harness infrastructure — use `setup-infra
|
|
32
|
+
- Run raw `docker compose` for harness infrastructure — use `har env setup-infra` / `har env launch` so ports are scanned and persisted in `.har/state/infra.env`
|
|
33
33
|
|
|
34
34
|
### Primary app vs shared services
|
|
35
35
|
|
|
36
36
|
Each slot runs **only the primary application** (`HARNESS_PRIMARY_APP` in `harness.env`) — the app agents modify. Everything else runs **once**, shared by all slots on fixed ports:
|
|
37
37
|
|
|
38
|
-
- **External dependencies** (Postgres, Redis, mail, ...): services in `docker-compose.agent.yml`, enabled via the `HARNESS_INFRA_SERVICES` list in `harness.env`, started by `setup-infra
|
|
39
|
-
- **Internal supporting services** (other services of a monolith/monorepo the agent depends on but does not change): either compose services in `docker-compose.agent.yml`, or PM2 processes in an optional `.har/ecosystem.shared.config.cjs` (named `har-shared-<name>`, started by `setup-infra
|
|
38
|
+
- **External dependencies** (Postgres, Redis, mail, ...): services in `docker-compose.agent.yml`, enabled via the `HARNESS_INFRA_SERVICES` list in `harness.env`, started by `har env setup-infra`.
|
|
39
|
+
- **Internal supporting services** (other services of a monolith/monorepo the agent depends on but does not change): either compose services in `docker-compose.agent.yml`, or PM2 processes in an optional `.har/ecosystem.shared.config.cjs` (named `har-shared-<name>`, started by `har env setup-infra`).
|
|
40
40
|
|
|
41
41
|
Isolation still applies where it matters: each slot gets its own database (`agent_<id>`, cloned from the template DB), ports, and git worktree.
|
|
@@ -11,14 +11,8 @@ har env teardown 1
|
|
|
11
11
|
|
|
12
12
|
In Cursor with HAR MCP configured: use `har_launch_environment`, `har_run_verification`, and `har_teardown_environment`.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 + health
|
|
20
|
-
./.har/verify.sh 1 --full # + conventional tests/lint, browser-e2e (if installed)
|
|
21
|
-
./.har/teardown.sh 1
|
|
22
|
-
```
|
|
14
|
+
`./.har/*.sh` exist as compatibility shims over the same runtime — generated,
|
|
15
|
+
never edited, and not the way to drive the harness. Take explicit ownership of
|
|
16
|
+
them with `har env eject`.
|
|
23
17
|
|
|
24
18
|
Read **`stages.json`** for registered stages and **`verificationStages`** for the expected pass set.
|
|
@@ -5,10 +5,10 @@ section for the repository:
|
|
|
5
5
|
|
|
6
6
|
| Layer | What it means | Where to encode it |
|
|
7
7
|
|-------|---------------|--------------------|
|
|
8
|
-
| Infra ready | Shared services and template data stores exist | `setup-infra
|
|
9
|
-
| Slot data ready | Every per-slot data store is created/cloned | `launch
|
|
10
|
-
| Process ready | Primary app is running and health passes | `launch
|
|
11
|
-
| Agent usable | Login/API/UI smoke works with documented data | `HARNESS_READINESS_CMD`, browser-e2e,
|
|
8
|
+
| Infra ready | Shared services and template data stores exist | `har env setup-infra`, `docker-compose.agent.yml` |
|
|
9
|
+
| Slot data ready | Every per-slot data store is created/cloned | `har env launch` |
|
|
10
|
+
| Process ready | Primary app is running and health passes | `har env launch`, `har env verify` |
|
|
11
|
+
| Agent usable | Login/API/UI smoke works with documented data | `HARNESS_READINESS_CMD`, browser-e2e, `.har/README.md` |
|
|
12
12
|
|
|
13
13
|
If full local-dev setup is too heavy to run in the harness, document the skipped
|
|
14
14
|
steps and add the minimum substitute directly in `.har/` scripts (for example an
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Adapt this section for the repository. A passing health check means the process
|
|
4
4
|
is alive; it does not automatically mean an agent can use the app.
|
|
5
5
|
|
|
6
|
-
- **Health**:
|
|
6
|
+
- **Health**: `har env agent <id> health`
|
|
7
7
|
- **Agent-usable smoke**: document the login/API/UI workflow agents should try,
|
|
8
8
|
or wire it into `HARNESS_READINESS_CMD` / full verify.
|
|
9
9
|
- **Credentials/default data**: document any test users, tenants, projects, or
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Verification contract
|
|
2
2
|
|
|
3
|
-
Steps in `verify
|
|
3
|
+
Steps in `har env verify` are **project-specific examples** — adapt them to your stack
|
|
4
4
|
during `har env init` / `har env maintain`. The table describes each tier's intent,
|
|
5
5
|
not a fixed command list.
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
| `ecosystem.agent.template.cjs` | PM2 processes for the **primary app only** (expanded at launch) |
|
|
15
15
|
| `ecosystem.shared.config.cjs` | Optional — shared app services started once with the infra (only when the repo has supporting services) |
|
|
16
16
|
| `docker-compose.agent.yml` | Shared infrastructure containers (services listed in `HARNESS_INFRA_SERVICES`) |
|
|
17
|
-
|
|
|
17
|
+
| `.har/README.md` | Detailed instructions for coding agents |
|
|
18
18
|
| `STAGES.md` | Stage registry and script-contract guide |
|
|
19
19
|
| `justfile` | Optional shortcuts (requires `just`) |
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
| File | Purpose |
|
|
24
24
|
|------|---------|
|
|
25
|
-
| `launch
|
|
25
|
+
| `har env launch` / `har env verify` / `har env teardown` / `har env setup-infra` / `preflight.sh` / `agent-cli.sh` / `attach.sh` | Thin shims forwarding to the packaged runtime (`har env …`); same run records on every surface |
|
|
26
26
|
| `manifest.json` | Runtime version, profile, checksums — managed by the har CLI |
|
|
27
27
|
| `runs/` | Run history from every entry point — `.har/runs/YYYY-MM-DD/HH-mm-ss_<stageId>_agent-<id>.json` (gitignored) |
|
|
28
28
|
| `artifacts/` | Stage outputs: reports, traces, screenshots, logs |
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "default",
|
|
3
|
-
"description": "Web app
|
|
3
|
+
"description": "Web app \u2014 shared kernel + PM2 runtime + Docker infra",
|
|
4
4
|
"bundles": [
|
|
5
|
-
{
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
{
|
|
6
|
+
"id": "shared-kernel",
|
|
7
|
+
"path": "runtime-bundles/shared-kernel"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "pm2-runtime",
|
|
11
|
+
"path": "runtime-bundles/pm2-runtime"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "runtime-default",
|
|
15
|
+
"path": "har-boilerplate"
|
|
16
|
+
}
|
|
8
17
|
],
|
|
9
18
|
"capabilities": {
|
|
10
19
|
"processManager": "pm2",
|
|
11
20
|
"appPortLanes": true,
|
|
12
21
|
"infra": {
|
|
13
|
-
"defaultServices": [
|
|
22
|
+
"defaultServices": [
|
|
23
|
+
"db"
|
|
24
|
+
],
|
|
14
25
|
"portLanes": "db=15432:15432-15499 minio=19000:19000-19049 minio-console=19050:19050-19099 browser=13001:13001-13099 mailpit-web=18025:18025-18099 mailpit-smtp=11025:11025-11099"
|
|
15
26
|
},
|
|
16
27
|
"defaultStages": [
|
|
@@ -49,22 +60,19 @@
|
|
|
49
60
|
"intro",
|
|
50
61
|
"what-s-in-here",
|
|
51
62
|
"quick-start",
|
|
63
|
+
"environment",
|
|
52
64
|
"verification-contract",
|
|
65
|
+
"definition-of-done",
|
|
66
|
+
"readiness",
|
|
53
67
|
"readiness-layers",
|
|
54
68
|
"run-history",
|
|
55
69
|
"for-coding-agents",
|
|
70
|
+
"project-commands",
|
|
56
71
|
"architecture",
|
|
57
72
|
"port-shared-services",
|
|
73
|
+
"do-not",
|
|
58
74
|
"maintaining-this-harness",
|
|
59
75
|
"session-lifecycle"
|
|
60
|
-
],
|
|
61
|
-
"CLAUDE.agent.md": [
|
|
62
|
-
"intro",
|
|
63
|
-
"environment",
|
|
64
|
-
"readiness",
|
|
65
|
-
"definition-of-done",
|
|
66
|
-
"project-commands",
|
|
67
|
-
"do-not"
|
|
68
76
|
]
|
|
69
77
|
}
|
|
70
78
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
## Definition of done
|
|
2
2
|
|
|
3
|
-
- [ ] Full verification returns `"status": "pass"` (`har env verify
|
|
3
|
+
- [ ] Full verification returns `"status": "pass"` (`har env verify <id> --full`, MCP `har_run_verification` with `full: true`, or `har env verify <id> --full`)
|
|
4
4
|
- [ ] The slot is agent-usable for this repo's documented smoke workflow when runtime services are involved
|
|
5
5
|
- [ ] When `stages/rocketsim-flows.sh` exists, full verify includes user-flow validation — add or update flow scripts in `flows/` for UI changes
|
|
6
6
|
- [ ] New behavior has automated test coverage (unit tests via XCTest)
|
|
7
7
|
- [ ] Changes committed **in the session worktree** with a clear message
|
|
8
8
|
- [ ] Present session handoff (summary, branch, preview URLs) and **wait for user** before `complete`, push, or PR
|
|
9
|
-
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete
|
|
9
|
+
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) — full verify + validation + teardown, branch kept
|
|
10
10
|
|
|
11
11
|
### Session handoff
|
|
12
12
|
|
|
@@ -18,6 +18,6 @@ else as alternatives. If PR tooling is unavailable, recommend complete and repor
|
|
|
18
18
|
the session branch for a manual push. Prefer `complete` over bare `teardown` when
|
|
19
19
|
the work succeeded. See `.cursor/rules/har-workflow.mdc` for the handoff shape.
|
|
20
20
|
|
|
21
|
-
Quick loop: MCP `har_run_verification`, `har env verify
|
|
21
|
+
Quick loop: MCP `har_run_verification`, `har env verify <id>`, or `har env verify <id>`
|
|
22
22
|
|
|
23
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`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Do not
|
|
2
2
|
|
|
3
3
|
- Work around a failing harness command with ad-hoc setup — fix the harness or report the failure
|
|
4
|
-
- Edit `.env.agent
|
|
4
|
+
- Edit `.env.agent.<id>` by hand
|
|
5
5
|
- Run verify before launch (the simulator and worktree must be set up first)
|
|
6
6
|
- Edit the main checkout — all edits go under the session work dir
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
| | |
|
|
4
4
|
|--|--|
|
|
5
|
-
| **Agent ID** |
|
|
6
|
-
| **Work dir** | Fresh session worktree per launch — see the launch output or `.har/slots/agent
|
|
7
|
-
| **Simulator** | Created for this slot at launch — `HARNESS_SIMULATOR_UDID` in `.env.agent
|
|
5
|
+
| **Agent ID** | <id> |
|
|
6
|
+
| **Work dir** | Fresh session worktree per launch — see the launch output or `.har/slots/agent-<id>.json` |
|
|
7
|
+
| **Simulator** | Created for this slot at launch — `HARNESS_SIMULATOR_UDID` in `.env.agent.<id>` |
|
|
8
8
|
| **Scheme** | Configured in `.har/harness.env` — `HARNESS_XCODE_SCHEME` |
|
|
9
9
|
|
|
10
10
|
**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.
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
|
|
13
|
+
har env agent <id> status
|
|
14
14
|
```
|
|
@@ -9,17 +9,17 @@ Pure iOS apps have **no per-slot TCP ports** — agents build and run on a share
|
|
|
9
9
|
| Optional backend (compose) | Per machine | `HARNESS_*_PORT_DEFAULT` for that service | Scan configured ranges in `harness.env` |
|
|
10
10
|
| iOS Simulator | Per slot | One device created per agent — no harness port | None: `har-<project>-agent-<id>-<model>` is unique per slot |
|
|
11
11
|
|
|
12
|
-
When your app talks to a local backend, read the resolved host port from `.env.agent.<id>` (set by `setup-infra
|
|
12
|
+
When your app talks to a local backend, read the resolved host port from `.env.agent.<id>` (set by `har env setup-infra`) — never hardcode `15432` or similar in tests or flow scripts.
|
|
13
13
|
|
|
14
14
|
### Shared vs per-slot
|
|
15
15
|
|
|
16
16
|
| Resource | Model | Configuration |
|
|
17
17
|
|----------|-------|---------------|
|
|
18
|
-
| iOS Simulator | One device created per slot, deleted at teardown | `HARNESS_SIMULATOR_*`, `launch
|
|
18
|
+
| iOS Simulator | One device created per slot, deleted at teardown | `HARNESS_SIMULATOR_*`, `har env launch` |
|
|
19
19
|
| Optional backend | One shared compose service | `HARNESS_INFRA_SERVICES` (e.g. `"mock-server"`) |
|
|
20
20
|
| Application code | Isolated git worktree per slot | `HARNESS_USE_WORKTREE=true` |
|
|
21
21
|
|
|
22
22
|
### Do not
|
|
23
23
|
|
|
24
24
|
- Hardcode backend ports in RocketSim flows or unit tests — read from agent env
|
|
25
|
-
- Run raw `docker compose` for harness infrastructure — use `setup-infra
|
|
25
|
+
- Run raw `docker compose` for harness infrastructure — use `har env setup-infra`
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Target **this slot's** simulator, never `booted` — another agent's device may also
|
|
4
4
|
be booted. `HARNESS_IOS_DESTINATION` and `HARNESS_SIMULATOR_UDID` come from
|
|
5
|
-
`.env.agent
|
|
5
|
+
`.env.agent.<id>`.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
source .env.agent
|
|
8
|
+
source .env.agent.<id>
|
|
9
9
|
|
|
10
10
|
# Build
|
|
11
11
|
xcodebuild build -scheme MyApp -destination "$HARNESS_IOS_DESTINATION" CODE_SIGNING_ALLOWED=NO
|
|
@@ -14,8 +14,8 @@ xcodebuild build -scheme MyApp -destination "$HARNESS_IOS_DESTINATION" CODE_SIGN
|
|
|
14
14
|
xcodebuild test -scheme MyApp -destination "$HARNESS_IOS_DESTINATION"
|
|
15
15
|
|
|
16
16
|
# Install and launch on this slot's device
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
har env agent <id> install path/to/MyApp.app
|
|
18
|
+
har env agent <id> launch-app
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Adapt for your scheme — see `.har/harness.env`.
|
|
@@ -11,12 +11,6 @@ har env teardown 1
|
|
|
11
11
|
|
|
12
12
|
In Cursor with HAR MCP configured: use `har_launch_environment`, `har_run_verification`, and `har_teardown_environment`.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
./.har/setup-infra.sh # boots the iOS Simulator
|
|
18
|
-
./.har/launch.sh 1
|
|
19
|
-
./.har/verify.sh 1 # quick: build smoke (compile-only)
|
|
20
|
-
./.har/verify.sh 1 --full # + unit tests, lint, rocketsim-flows (if installed)
|
|
21
|
-
./.har/teardown.sh 1
|
|
22
|
-
```
|
|
14
|
+
`./.har/*.sh` exist as compatibility shims over the same runtime — generated,
|
|
15
|
+
never edited, and not the way to drive the harness. Take explicit ownership of
|
|
16
|
+
them with `har env eject`.
|
|
@@ -12,7 +12,7 @@ store, nothing carried over from the previous session.
|
|
|
12
12
|
| `HARNESS_SIMULATOR_NAME` | The model to create — `iPhone 16`, `iPhone 17 Pro`, `iPad Air 11-inch (M2)`. Empty means the newest model of the family. See `xcrun simctl list devicetypes`. |
|
|
13
13
|
| `HARNESS_SIMULATOR_FAMILY` | `auto` (read from the name) \| `iPhone` \| `iPad`. An iPad is only created when this resolves to iPad. |
|
|
14
14
|
| `HARNESS_SIMULATOR_UDID` | Run every slot on one existing device instead. Slots then share it — for one-off debugging. |
|
|
15
|
-
| `HARNESS_SIMULATOR_SHARED` | `true` restores one shared simulator for all slots, booted by `setup-infra
|
|
15
|
+
| `HARNESS_SIMULATOR_SHARED` | `true` restores one shared simulator for all slots, booted by `har env setup-infra`. |
|
|
16
16
|
|
|
17
17
|
The runtime is the newest installed iOS that supports the model — a model retired
|
|
18
18
|
from recent runtimes still resolves against an older one. When nothing matches,
|
|
@@ -42,4 +42,4 @@ blaming a sandbox.
|
|
|
42
42
|
The device lands in `.env.agent.<id>` as `HARNESS_SIMULATOR_UDID`,
|
|
43
43
|
`HARNESS_SIMULATOR_DEVICE_NAME` and `HARNESS_IOS_DESTINATION` — the model stays in
|
|
44
44
|
`HARNESS_SIMULATOR_NAME`, so the two never mean the same thing in one place; what a slot holds is tracked in `.har/simulators/`.
|
|
45
|
-
Use
|
|
45
|
+
Use `har env agent <id> simulator` to see it.
|
package/dist/templates/profiles/ios/docs/{claude-agent → readme}/user-flow-validation-rocketsim.md
RENAMED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
If the RocketSim plugin is installed (`har env add-plugin rocketsim`):
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
./.har/stages/rocketsim-flows.sh
|
|
6
|
+
./.har/stages/rocketsim-flows.sh <id>
|
|
7
7
|
# included in:
|
|
8
|
-
|
|
8
|
+
har env verify <id> --full
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Add and edit user flow scripts in `flows/`. Read `.har/stages/ROCKETSIM.md` for the full authoring guide.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Verification contract
|
|
2
2
|
|
|
3
|
-
Steps in `verify
|
|
3
|
+
Steps in `har env verify` are **project-specific examples** — adapt them to your stack.
|
|
4
4
|
The table describes each tier's intent, not a fixed command list.
|
|
5
5
|
|
|
6
6
|
| Mode | Command | Typical steps |
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
| `hooks/` | Optional lifecycle hooks (`pre-launch.sh`, `post-launch.sh`, `pre-verify.sh`, `pre-teardown.sh`, `post-teardown.sh`) |
|
|
12
12
|
| `plugins/` | Optional local plugins (`har plugin create <id>`) |
|
|
13
13
|
| `docker-compose.agent.yml` | Optional shared backend services |
|
|
14
|
-
|
|
|
14
|
+
| `.har/README.md` | Detailed instructions for coding agents |
|
|
15
15
|
| `STAGES.md` | Stage registry and script-contract guide |
|
|
16
16
|
| `justfile` | Optional shortcuts (requires `just`) |
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
| File | Purpose |
|
|
21
21
|
|------|---------|
|
|
22
|
-
| `launch
|
|
22
|
+
| `har env launch` / `har env verify` / `har env teardown` / `har env setup-infra` / `preflight.sh` / `agent-cli.sh` | Thin shims forwarding to the packaged runtime (`har env …`); same run records on every surface |
|
|
23
23
|
| `manifest.json` | Runtime version, profile, checksums — managed by the har CLI |
|
|
24
24
|
| `runs/` | Run history from every entry point — `.har/runs/YYYY-MM-DD/HH-mm-ss_<stageId>_agent-<id>.json` (gitignored) |
|
|
25
25
|
| `artifacts/` | Stage outputs: test results, screenshots, logs |
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "ios",
|
|
3
|
-
"description": "iOS
|
|
3
|
+
"description": "iOS \u2014 shared kernel + Xcode/Simulator overlay (simulator runtime lives in the package)",
|
|
4
4
|
"bundles": [
|
|
5
|
-
{
|
|
6
|
-
|
|
5
|
+
{
|
|
6
|
+
"id": "shared-kernel",
|
|
7
|
+
"path": "runtime-bundles/shared-kernel"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "runtime-ios",
|
|
11
|
+
"path": "har-boilerplate-ios"
|
|
12
|
+
}
|
|
7
13
|
],
|
|
8
14
|
"capabilities": {
|
|
9
15
|
"processManager": "simulator",
|
|
@@ -45,21 +51,18 @@
|
|
|
45
51
|
"intro",
|
|
46
52
|
"what-s-in-here",
|
|
47
53
|
"quick-start",
|
|
54
|
+
"environment",
|
|
48
55
|
"user-flow-validation",
|
|
49
56
|
"verification-contract",
|
|
57
|
+
"definition-of-done",
|
|
58
|
+
"readiness",
|
|
59
|
+
"project-commands",
|
|
60
|
+
"user-flow-validation-rocketsim",
|
|
50
61
|
"configuration",
|
|
51
62
|
"simulators",
|
|
52
63
|
"port-shared-services-ios-profile",
|
|
64
|
+
"do-not",
|
|
53
65
|
"session-lifecycle"
|
|
54
|
-
],
|
|
55
|
-
"CLAUDE.agent.md": [
|
|
56
|
-
"intro",
|
|
57
|
-
"environment",
|
|
58
|
-
"readiness",
|
|
59
|
-
"definition-of-done",
|
|
60
|
-
"project-commands",
|
|
61
|
-
"user-flow-validation-rocketsim",
|
|
62
|
-
"do-not"
|
|
63
66
|
]
|
|
64
67
|
}
|
|
65
68
|
}
|
|
@@ -5,11 +5,49 @@
|
|
|
5
5
|
set -euo pipefail
|
|
6
6
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
7
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
# Loop guard (#291): a pre-1.0 har does not own this runtime kind in the
|
|
9
|
+
# package — it executes this script as authoritative, which would exec back
|
|
10
|
+
# into har forever (one node process per cycle). Trip on re-entry for this
|
|
11
|
+
# harness root, and skip har binaries older than the pinned runtime (#298).
|
|
12
|
+
HAR_SHIM_GUARD="attach@${REPO_ROOT}"
|
|
13
|
+
case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
14
|
+
echo "Error: runtime loop detected — the har CLI that ran this shim delegated back into it." >&2
|
|
15
|
+
echo " The har runtime handling this repo is older than the harness contract (pinned: @osfactory/har@__HAR_VERSION__)." >&2
|
|
16
|
+
echo " Fix: npm i -g @osfactory/har@latest # or in this repo: npm i -D @osfactory/har" >&2
|
|
17
|
+
exit 86
|
|
18
|
+
;;
|
|
19
|
+
esac
|
|
20
|
+
export HAR_SHIM_REENTRY="${HAR_SHIM_REENTRY:-}:${HAR_SHIM_GUARD}"
|
|
21
|
+
# True when $1 reports a version >= the pinned runtime. Comparing only the
|
|
22
|
+
# major (#298) made the floor inert for the whole 0.x line: every pre-1.0 har
|
|
23
|
+
# passed it and then bounced straight back into this shim. Compare the full
|
|
24
|
+
# release triple, and treat anything unparseable as unusable.
|
|
25
|
+
har_runtime_compatible() {
|
|
26
|
+
local v pinned="__HAR_VERSION__" i a b
|
|
27
|
+
v="$("$1" --version 2>/dev/null | head -n1)" || return 1
|
|
28
|
+
v="${v#v}"
|
|
29
|
+
v="${v%%[-+ ]*}"
|
|
30
|
+
local -a have pin
|
|
31
|
+
IFS=. read -r -a have <<<"$v"
|
|
32
|
+
IFS=. read -r -a pin <<<"${pinned%%[-+]*}"
|
|
33
|
+
for i in 0 1 2; do
|
|
34
|
+
a="${have[i]:-0}"
|
|
35
|
+
b="${pin[i]:-0}"
|
|
36
|
+
case "$a" in ''|*[!0-9]*) return 1 ;; esac
|
|
37
|
+
case "$b" in ''|*[!0-9]*) return 1 ;; esac
|
|
38
|
+
[ "$a" -gt "$b" ] && return 0
|
|
39
|
+
[ "$a" -lt "$b" ] && return 1
|
|
40
|
+
done
|
|
41
|
+
return 0
|
|
42
|
+
}
|
|
43
|
+
# `$1` (not a named var) so `har env eject` can lift this delegate verbatim.
|
|
44
|
+
if command -v har >/dev/null 2>&1 && har_runtime_compatible har; then
|
|
45
|
+
exec har env agent "${1:?Usage: attach.sh <agent-id>}" attach
|
|
46
|
+
elif [ -x "$REPO_ROOT/node_modules/.bin/har" ] && har_runtime_compatible "$REPO_ROOT/node_modules/.bin/har"; then
|
|
47
|
+
exec "$REPO_ROOT/node_modules/.bin/har" env agent "${1:?Usage: attach.sh <agent-id>}" attach
|
|
48
|
+
elif command -v npx >/dev/null 2>&1; then
|
|
49
|
+
exec npx --yes @osfactory/har@__HAR_VERSION__ env agent "${1:?Usage: attach.sh <agent-id>}" attach
|
|
13
50
|
fi
|
|
14
|
-
echo "Error: the 'har'
|
|
51
|
+
echo "Error: cannot run the HAR runtime — 'har' is not on PATH and Node.js (npx) is unavailable." >&2
|
|
52
|
+
echo " Install Node.js, then: npm i -D @osfactory/har # or: npx @osfactory/har@__HAR_VERSION__ env agent" >&2
|
|
15
53
|
exit 127
|
|
@@ -8,7 +8,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
8
8
|
# Loop guard (#291): a pre-1.0 har does not own this runtime kind in the
|
|
9
9
|
# package — it executes this script as authoritative, which would exec back
|
|
10
10
|
# into har forever (one node process per cycle). Trip on re-entry for this
|
|
11
|
-
# harness root, and skip har binaries older than the pinned runtime
|
|
11
|
+
# harness root, and skip har binaries older than the pinned runtime (#298).
|
|
12
12
|
HAR_SHIM_GUARD="agent@${REPO_ROOT}"
|
|
13
13
|
case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
14
14
|
echo "Error: runtime loop detected — the har CLI that ran this shim delegated back into it." >&2
|
|
@@ -18,10 +18,27 @@ case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
|
18
18
|
;;
|
|
19
19
|
esac
|
|
20
20
|
export HAR_SHIM_REENTRY="${HAR_SHIM_REENTRY:-}:${HAR_SHIM_GUARD}"
|
|
21
|
+
# True when $1 reports a version >= the pinned runtime. Comparing only the
|
|
22
|
+
# major (#298) made the floor inert for the whole 0.x line: every pre-1.0 har
|
|
23
|
+
# passed it and then bounced straight back into this shim. Compare the full
|
|
24
|
+
# release triple, and treat anything unparseable as unusable.
|
|
21
25
|
har_runtime_compatible() {
|
|
22
|
-
local v pinned="__HAR_VERSION__"
|
|
26
|
+
local v pinned="__HAR_VERSION__" i a b
|
|
23
27
|
v="$("$1" --version 2>/dev/null | head -n1)" || return 1
|
|
24
|
-
|
|
28
|
+
v="${v#v}"
|
|
29
|
+
v="${v%%[-+ ]*}"
|
|
30
|
+
local -a have pin
|
|
31
|
+
IFS=. read -r -a have <<<"$v"
|
|
32
|
+
IFS=. read -r -a pin <<<"${pinned%%[-+]*}"
|
|
33
|
+
for i in 0 1 2; do
|
|
34
|
+
a="${have[i]:-0}"
|
|
35
|
+
b="${pin[i]:-0}"
|
|
36
|
+
case "$a" in ''|*[!0-9]*) return 1 ;; esac
|
|
37
|
+
case "$b" in ''|*[!0-9]*) return 1 ;; esac
|
|
38
|
+
[ "$a" -gt "$b" ] && return 0
|
|
39
|
+
[ "$a" -lt "$b" ] && return 1
|
|
40
|
+
done
|
|
41
|
+
return 0
|
|
25
42
|
}
|
|
26
43
|
if command -v har >/dev/null 2>&1 && har_runtime_compatible har; then
|
|
27
44
|
exec har env agent "$@"
|
|
@@ -8,7 +8,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
8
8
|
# Loop guard (#291): a pre-1.0 har does not own this runtime kind in the
|
|
9
9
|
# package — it executes this script as authoritative, which would exec back
|
|
10
10
|
# into har forever (one node process per cycle). Trip on re-entry for this
|
|
11
|
-
# harness root, and skip har binaries older than the pinned runtime
|
|
11
|
+
# harness root, and skip har binaries older than the pinned runtime (#298).
|
|
12
12
|
HAR_SHIM_GUARD="launch@${REPO_ROOT}"
|
|
13
13
|
case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
14
14
|
echo "Error: runtime loop detected — the har CLI that ran this shim delegated back into it." >&2
|
|
@@ -18,10 +18,27 @@ case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
|
18
18
|
;;
|
|
19
19
|
esac
|
|
20
20
|
export HAR_SHIM_REENTRY="${HAR_SHIM_REENTRY:-}:${HAR_SHIM_GUARD}"
|
|
21
|
+
# True when $1 reports a version >= the pinned runtime. Comparing only the
|
|
22
|
+
# major (#298) made the floor inert for the whole 0.x line: every pre-1.0 har
|
|
23
|
+
# passed it and then bounced straight back into this shim. Compare the full
|
|
24
|
+
# release triple, and treat anything unparseable as unusable.
|
|
21
25
|
har_runtime_compatible() {
|
|
22
|
-
local v pinned="__HAR_VERSION__"
|
|
26
|
+
local v pinned="__HAR_VERSION__" i a b
|
|
23
27
|
v="$("$1" --version 2>/dev/null | head -n1)" || return 1
|
|
24
|
-
|
|
28
|
+
v="${v#v}"
|
|
29
|
+
v="${v%%[-+ ]*}"
|
|
30
|
+
local -a have pin
|
|
31
|
+
IFS=. read -r -a have <<<"$v"
|
|
32
|
+
IFS=. read -r -a pin <<<"${pinned%%[-+]*}"
|
|
33
|
+
for i in 0 1 2; do
|
|
34
|
+
a="${have[i]:-0}"
|
|
35
|
+
b="${pin[i]:-0}"
|
|
36
|
+
case "$a" in ''|*[!0-9]*) return 1 ;; esac
|
|
37
|
+
case "$b" in ''|*[!0-9]*) return 1 ;; esac
|
|
38
|
+
[ "$a" -gt "$b" ] && return 0
|
|
39
|
+
[ "$a" -lt "$b" ] && return 1
|
|
40
|
+
done
|
|
41
|
+
return 0
|
|
25
42
|
}
|
|
26
43
|
if command -v har >/dev/null 2>&1 && har_runtime_compatible har; then
|
|
27
44
|
exec har env launch "$@"
|
|
@@ -8,7 +8,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
8
8
|
# Loop guard (#291): a pre-1.0 har does not own this runtime kind in the
|
|
9
9
|
# package — it executes this script as authoritative, which would exec back
|
|
10
10
|
# into har forever (one node process per cycle). Trip on re-entry for this
|
|
11
|
-
# harness root, and skip har binaries older than the pinned runtime
|
|
11
|
+
# harness root, and skip har binaries older than the pinned runtime (#298).
|
|
12
12
|
HAR_SHIM_GUARD="preflight@${REPO_ROOT}"
|
|
13
13
|
case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
14
14
|
echo "Error: runtime loop detected — the har CLI that ran this shim delegated back into it." >&2
|
|
@@ -18,10 +18,27 @@ case ":${HAR_SHIM_REENTRY:-}:" in *":${HAR_SHIM_GUARD}:"*)
|
|
|
18
18
|
;;
|
|
19
19
|
esac
|
|
20
20
|
export HAR_SHIM_REENTRY="${HAR_SHIM_REENTRY:-}:${HAR_SHIM_GUARD}"
|
|
21
|
+
# True when $1 reports a version >= the pinned runtime. Comparing only the
|
|
22
|
+
# major (#298) made the floor inert for the whole 0.x line: every pre-1.0 har
|
|
23
|
+
# passed it and then bounced straight back into this shim. Compare the full
|
|
24
|
+
# release triple, and treat anything unparseable as unusable.
|
|
21
25
|
har_runtime_compatible() {
|
|
22
|
-
local v pinned="__HAR_VERSION__"
|
|
26
|
+
local v pinned="__HAR_VERSION__" i a b
|
|
23
27
|
v="$("$1" --version 2>/dev/null | head -n1)" || return 1
|
|
24
|
-
|
|
28
|
+
v="${v#v}"
|
|
29
|
+
v="${v%%[-+ ]*}"
|
|
30
|
+
local -a have pin
|
|
31
|
+
IFS=. read -r -a have <<<"$v"
|
|
32
|
+
IFS=. read -r -a pin <<<"${pinned%%[-+]*}"
|
|
33
|
+
for i in 0 1 2; do
|
|
34
|
+
a="${have[i]:-0}"
|
|
35
|
+
b="${pin[i]:-0}"
|
|
36
|
+
case "$a" in ''|*[!0-9]*) return 1 ;; esac
|
|
37
|
+
case "$b" in ''|*[!0-9]*) return 1 ;; esac
|
|
38
|
+
[ "$a" -gt "$b" ] && return 0
|
|
39
|
+
[ "$a" -lt "$b" ] && return 1
|
|
40
|
+
done
|
|
41
|
+
return 0
|
|
25
42
|
}
|
|
26
43
|
if command -v har >/dev/null 2>&1 && har_runtime_compatible har; then
|
|
27
44
|
exec har env preflight "$@"
|