@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.
Files changed (141) hide show
  1. package/dist/index.js +15675 -6536
  2. package/dist/prompts/system-authoring.md +155 -0
  3. package/dist/templates/adaptation-prompt-init.md +67 -43
  4. package/dist/templates/adaptation-prompt-maintain.md +38 -38
  5. package/dist/templates/agent-skills/har-maintain.md +2 -2
  6. package/dist/templates/agent-skills/setup-har.md +6 -4
  7. package/dist/templates/cursor-rule.mdc.template +3 -3
  8. package/dist/templates/har-boilerplate/docker-compose.agent.yml +1 -1
  9. package/dist/templates/har-boilerplate/harness.env +11 -155
  10. package/dist/templates/har-boilerplate/stages.json +51 -2
  11. package/dist/templates/har-boilerplate-cli/docker-compose.agent.yml +1 -1
  12. package/dist/templates/har-boilerplate-cli/harness.env +12 -138
  13. package/dist/templates/har-boilerplate-cli/stages.json +42 -2
  14. package/dist/templates/har-boilerplate-ios/harness.env +10 -126
  15. package/dist/templates/har-boilerplate-ios/stages.json +42 -2
  16. package/dist/templates/migration-prompt.md +54 -0
  17. package/dist/templates/plugins/custom-stage-skeleton.sh +11 -20
  18. package/dist/templates/plugins/gitleaks/.github/workflows/gitleaks.yml +1 -1
  19. package/dist/templates/plugins/gitleaks/.har/stages/GITLEAKS.md +1 -1
  20. package/dist/templates/plugins/gitleaks/.har/stages/secrets-scan.sh +8 -23
  21. package/dist/templates/plugins/gitleaks/README.md +1 -1
  22. package/dist/templates/plugins/gitleaks/template.manifest.json +20 -5
  23. package/dist/templates/plugins/kerno/.github/workflows/kerno.yml +1 -1
  24. package/dist/templates/plugins/kerno/.har/stages/backend-validation.sh +8 -23
  25. package/dist/templates/plugins/kerno/README.md +1 -1
  26. package/dist/templates/plugins/kerno/template.manifest.json +20 -9
  27. package/dist/templates/plugins/local-plugin-skeleton/README.md +46 -0
  28. package/dist/templates/plugins/playwright/.har/stages/browser-e2e.sh +8 -23
  29. package/dist/templates/plugins/playwright/template.manifest.json +36 -13
  30. package/dist/templates/plugins/rocketsim/.har/stages/rocketsim-flows.sh +8 -23
  31. package/dist/templates/plugins/rocketsim/template.manifest.json +20 -8
  32. package/dist/templates/plugins/semgrep/.har/stages/sast.sh +10 -26
  33. package/dist/templates/plugins/semgrep/README.md +1 -1
  34. package/dist/templates/plugins/semgrep/template.manifest.json +16 -7
  35. package/dist/templates/plugins/trivy/.har/stages/vuln-scan.sh +8 -23
  36. package/dist/templates/plugins/trivy/README.md +1 -1
  37. package/dist/templates/plugins/trivy/template.manifest.json +20 -8
  38. package/dist/templates/{har-boilerplate-cli/CLAUDE.agent.md → profiles/cli/docs/claude-agent/definition-of-done.md} +0 -42
  39. package/dist/templates/profiles/cli/docs/claude-agent/do-not.md +6 -0
  40. package/dist/templates/profiles/cli/docs/claude-agent/environment.md +12 -0
  41. package/dist/templates/profiles/cli/docs/claude-agent/project-commands.md +10 -0
  42. package/dist/templates/profiles/cli/docs/claude-agent/readiness.md +6 -0
  43. package/dist/templates/profiles/cli/docs/readme/for-coding-agents.md +9 -0
  44. package/dist/templates/profiles/cli/docs/readme/intro.md +7 -0
  45. package/dist/templates/profiles/cli/docs/readme/port-shared-services-cli-profile.md +25 -0
  46. package/dist/templates/profiles/cli/docs/readme/quick-start.md +24 -0
  47. package/dist/templates/profiles/cli/docs/readme/verification-contract.md +22 -0
  48. package/dist/templates/profiles/cli/docs/readme/what-s-in-here.md +27 -0
  49. package/dist/templates/profiles/cli/profile.manifest.json +56 -1
  50. package/dist/templates/profiles/default/docs/claude-agent/definition-of-done.md +24 -0
  51. package/dist/templates/profiles/default/docs/claude-agent/do-not.md +10 -0
  52. package/dist/templates/profiles/default/docs/claude-agent/environment.md +19 -0
  53. package/dist/templates/profiles/default/docs/claude-agent/project-commands.md +10 -0
  54. package/dist/templates/profiles/default/docs/claude-agent/readiness.md +12 -0
  55. package/dist/templates/profiles/default/docs/readme/architecture.md +11 -0
  56. package/dist/templates/profiles/default/docs/readme/for-coding-agents.md +9 -0
  57. package/dist/templates/profiles/default/docs/readme/intro.md +7 -0
  58. package/dist/templates/profiles/default/docs/readme/port-shared-services.md +41 -0
  59. package/dist/templates/profiles/default/docs/readme/quick-start.md +24 -0
  60. package/dist/templates/profiles/default/docs/readme/readiness-layers.md +16 -0
  61. package/dist/templates/profiles/default/docs/readme/verification-contract.md +17 -0
  62. package/dist/templates/profiles/default/docs/readme/what-s-in-here.md +28 -0
  63. package/dist/templates/profiles/default/profile.manifest.json +62 -1
  64. package/dist/templates/profiles/ios/docs/claude-agent/definition-of-done.md +23 -0
  65. package/dist/templates/profiles/ios/docs/claude-agent/do-not.md +6 -0
  66. package/dist/templates/profiles/ios/docs/claude-agent/environment.md +14 -0
  67. package/dist/templates/profiles/ios/docs/claude-agent/intro.md +3 -0
  68. package/dist/templates/profiles/ios/docs/claude-agent/project-commands.md +21 -0
  69. package/dist/templates/profiles/ios/docs/claude-agent/readiness.md +6 -0
  70. package/dist/templates/profiles/ios/docs/claude-agent/user-flow-validation-rocketsim.md +11 -0
  71. package/dist/templates/profiles/ios/docs/readme/configuration.md +7 -0
  72. package/dist/templates/profiles/ios/docs/readme/intro.md +7 -0
  73. package/dist/templates/profiles/ios/docs/readme/port-shared-services-ios-profile.md +25 -0
  74. package/dist/templates/profiles/ios/docs/readme/quick-start.md +22 -0
  75. package/dist/templates/profiles/ios/docs/readme/simulators.md +45 -0
  76. package/dist/templates/profiles/ios/docs/readme/user-flow-validation.md +9 -0
  77. package/dist/templates/profiles/ios/docs/readme/verification-contract.md +13 -0
  78. package/dist/templates/profiles/ios/docs/readme/what-s-in-here.md +27 -0
  79. package/dist/templates/profiles/ios/profile.manifest.json +59 -3
  80. package/dist/templates/runtime-bundles/pm2-runtime/attach.sh +8 -15
  81. package/dist/templates/runtime-bundles/pm2-runtime/env.template +1 -1
  82. package/dist/templates/runtime-bundles/pm2-runtime/stages/api-health.sh +9 -0
  83. package/dist/templates/runtime-bundles/shared-kernel/STAGES.md +32 -18
  84. package/dist/templates/runtime-bundles/shared-kernel/agent-cli.sh +35 -0
  85. package/dist/templates/runtime-bundles/shared-kernel/launch.sh +35 -0
  86. package/dist/templates/runtime-bundles/shared-kernel/lib/verify-runner.mjs +129 -0
  87. package/dist/templates/runtime-bundles/shared-kernel/preflight.sh +35 -0
  88. package/dist/templates/runtime-bundles/shared-kernel/setup-infra.sh +35 -0
  89. package/dist/templates/runtime-bundles/shared-kernel/stages/README.sh +1 -1
  90. package/dist/templates/runtime-bundles/shared-kernel/stages/readiness.sh +14 -0
  91. package/dist/templates/runtime-bundles/shared-kernel/teardown.sh +35 -0
  92. package/dist/templates/runtime-bundles/shared-kernel/verify.sh +35 -0
  93. package/dist/templates/shared-docs/claude-agent/intro.md +3 -0
  94. package/dist/templates/shared-docs/readme/maintaining-this-harness.md +14 -0
  95. package/dist/templates/shared-docs/readme/run-history.md +5 -0
  96. package/dist/templates/shared-docs/readme/session-lifecycle.md +20 -0
  97. package/package.json +1 -1
  98. package/dist/templates/har-boilerplate/CLAUDE.agent.md +0 -83
  99. package/dist/templates/har-boilerplate/README.md +0 -199
  100. package/dist/templates/har-boilerplate/STAGES.md +0 -99
  101. package/dist/templates/har-boilerplate/agent-cli.sh +0 -225
  102. package/dist/templates/har-boilerplate/agent-slot.sh +0 -850
  103. package/dist/templates/har-boilerplate/attach.sh +0 -22
  104. package/dist/templates/har-boilerplate/ecosystem.agent.template.cjs +0 -52
  105. package/dist/templates/har-boilerplate/env.template +0 -40
  106. package/dist/templates/har-boilerplate/launch.sh +0 -323
  107. package/dist/templates/har-boilerplate/preflight.sh +0 -32
  108. package/dist/templates/har-boilerplate/provision-toolchain.sh +0 -766
  109. package/dist/templates/har-boilerplate/setup-infra.sh +0 -178
  110. package/dist/templates/har-boilerplate/stages/README.sh +0 -11
  111. package/dist/templates/har-boilerplate/teardown.sh +0 -87
  112. package/dist/templates/har-boilerplate/verify.sh +0 -249
  113. package/dist/templates/har-boilerplate-cli/README.md +0 -157
  114. package/dist/templates/har-boilerplate-cli/STAGES.md +0 -99
  115. package/dist/templates/har-boilerplate-cli/agent-cli.sh +0 -160
  116. package/dist/templates/har-boilerplate-cli/agent-slot.sh +0 -832
  117. package/dist/templates/har-boilerplate-cli/launch.sh +0 -216
  118. package/dist/templates/har-boilerplate-cli/preflight.sh +0 -28
  119. package/dist/templates/har-boilerplate-cli/provision-toolchain.sh +0 -766
  120. package/dist/templates/har-boilerplate-cli/setup-infra.sh +0 -178
  121. package/dist/templates/har-boilerplate-cli/stages/README.sh +0 -11
  122. package/dist/templates/har-boilerplate-cli/teardown.sh +0 -66
  123. package/dist/templates/har-boilerplate-cli/verify.sh +0 -210
  124. package/dist/templates/har-boilerplate-ios/ADAPT-PROMPT.md +0 -63
  125. package/dist/templates/har-boilerplate-ios/CLAUDE.agent.md +0 -90
  126. package/dist/templates/har-boilerplate-ios/README.md +0 -173
  127. package/dist/templates/har-boilerplate-ios/STAGES.md +0 -99
  128. package/dist/templates/har-boilerplate-ios/agent-cli.sh +0 -149
  129. package/dist/templates/har-boilerplate-ios/agent-slot.sh +0 -479
  130. package/dist/templates/har-boilerplate-ios/launch.sh +0 -206
  131. package/dist/templates/har-boilerplate-ios/provision-toolchain.sh +0 -766
  132. package/dist/templates/har-boilerplate-ios/setup-infra.sh +0 -112
  133. package/dist/templates/har-boilerplate-ios/simulator.sh +0 -492
  134. package/dist/templates/har-boilerplate-ios/stages/README.sh +0 -11
  135. package/dist/templates/har-boilerplate-ios/teardown.sh +0 -68
  136. package/dist/templates/har-boilerplate-ios/verify.sh +0 -185
  137. package/dist/templates/runtime-bundles/pm2-runtime/README.md +0 -4
  138. package/dist/templates/runtime-bundles/shared-kernel/README.md +0 -3
  139. package/dist/templates/runtime-bundles/shared-kernel/provision-toolchain.sh +0 -766
  140. package/dist/templates/runtime-bundles/xcode-sim/README.md +0 -4
  141. package/dist/templates/runtime-bundles/xcode-sim/simulator.sh +0 -492
@@ -1,5 +1,9 @@
1
1
  # Shared harness configuration — edit to match your project
2
2
  # Generated by har env init, maintained over time with har env maintain
3
+ #
4
+ # This file is pure KEY=value config (plus comments) and is schema-validated
5
+ # on read. Runtime helpers (har_infra_enabled, har_pg, port resolution) live
6
+ # in .har/lib/ — never define functions here.
3
7
 
4
8
  export HARNESS_PROJECT_NAME=__PROJECT_NAME__
5
9
  export HARNESS_USE_WORKTREE=true
@@ -21,26 +25,10 @@ export HARNESS_PORT_STEP=10
21
25
  export HARNESS_HEALTH_CHECK_PATH=/health
22
26
 
23
27
  # ── Shared infra host ports (one per machine) ─────────────────────────────────
24
- # setup-infra.sh tries DEFAULT first, then scans SCAN_START..SCAN_END when busy.
28
+ # One lane per infra service: <lane>=<default>:<scan_start>-<scan_end>.
29
+ # setup-infra.sh tries the default first, then scans the range when busy.
25
30
  # Persisted in .har/state/infra.env — do not hardcode these ports in app code.
26
- export HARNESS_DB_PORT_DEFAULT=15432
27
- export HARNESS_DB_PORT_SCAN_START=15432
28
- export HARNESS_DB_PORT_SCAN_END=15499
29
- export HARNESS_MINIO_PORT_DEFAULT=19000
30
- export HARNESS_MINIO_PORT_SCAN_START=19000
31
- export HARNESS_MINIO_PORT_SCAN_END=19099
32
- export HARNESS_MINIO_CONSOLE_PORT_DEFAULT=19001
33
- export HARNESS_MINIO_CONSOLE_PORT_SCAN_START=19001
34
- export HARNESS_MINIO_CONSOLE_PORT_SCAN_END=19099
35
- export HARNESS_BROWSER_PORT_DEFAULT=13001
36
- export HARNESS_BROWSER_PORT_SCAN_START=13001
37
- export HARNESS_BROWSER_PORT_SCAN_END=13099
38
- export HARNESS_MAILPIT_WEB_PORT_DEFAULT=18025
39
- export HARNESS_MAILPIT_WEB_PORT_SCAN_START=18025
40
- export HARNESS_MAILPIT_WEB_PORT_SCAN_END=18099
41
- export HARNESS_MAILPIT_SMTP_PORT_DEFAULT=11025
42
- export HARNESS_MAILPIT_SMTP_PORT_SCAN_START=11025
43
- export HARNESS_MAILPIT_SMTP_PORT_SCAN_END=11099
31
+ export HARNESS_INFRA_PORT_LANES="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"
44
32
 
45
33
  # Agent slot limits — canonical source: .har/stages.json (agentSlots).
46
34
  # Legacy fallback below; har env maintain --finalize syncs these from stages.json.
@@ -62,142 +50,10 @@ export HARNESS_ECOSYSTEM="auto"
62
50
  # list the ones this project needs here (e.g. "db redis mailpit").
63
51
  export HARNESS_INFRA_SERVICES="db"
64
52
 
65
- # Returns 0 when a shared infra service is enabled: har_infra_enabled db
66
- har_infra_enabled() {
67
- case " ${HARNESS_INFRA_SERVICES:-} " in
68
- *" $1 "*) return 0 ;;
69
- *) return 1 ;;
70
- esac
71
- }
72
-
73
- # ── Node package manager helpers ──────────────────────────────────────────────
74
- # Mirrored verbatim in harness.env and provision-toolchain.sh so a sourcing
75
- # script and the provisioning subprocess resolve the same tool.
76
-
77
- # Package managers HAR can drive, in fallback preference order.
78
- HAR_NODE_PACKAGE_MANAGERS="npm bun pnpm yarn"
79
-
80
- # Package manager the repo declares: an explicit HARNESS_NODE_PACKAGE_MANAGER
81
- # wins, then package.json "packageManager", then the lockfile. Empty when the
82
- # repo says nothing.
83
- har_node_declared_package_manager() {
84
- local dir="${1:-.}"
85
-
86
- if [ -n "${HARNESS_NODE_PACKAGE_MANAGER:-}" ]; then
87
- echo "$HARNESS_NODE_PACKAGE_MANAGER"
88
- return
89
- fi
90
- if [ -f "$dir/package.json" ]; then
91
- local field
92
- field="$(sed -n 's/.*"packageManager"[[:space:]]*:[[:space:]]*"\([a-z]*\)@.*/\1/p' "$dir/package.json" | head -1)"
93
- if [ -n "$field" ]; then
94
- echo "$field"
95
- return
96
- fi
97
- fi
98
- if [ -f "$dir/bun.lock" ] || [ -f "$dir/bun.lockb" ]; then echo bun; return; fi
99
- if [ -f "$dir/pnpm-lock.yaml" ]; then echo pnpm; return; fi
100
- if [ -f "$dir/yarn.lock" ]; then echo yarn; return; fi
101
- if [ -f "$dir/package-lock.json" ]; then echo npm; return; fi
102
- echo ""
103
- }
104
-
105
- # Package manager to actually run. A manager the repo declares but this machine
106
- # lacks falls back to one that is installed, so a repo pinned to npm still
107
- # provisions on a bun-only machine (and the reverse).
108
- har_node_package_manager() {
109
- local dir="${1:-.}"
110
- local declared
111
- declared="$(har_node_declared_package_manager "$dir")"
112
-
113
- if [ -n "$declared" ] && command -v "$declared" >/dev/null 2>&1; then
114
- echo "$declared"
115
- return
116
- fi
117
-
118
- local candidate
119
- for candidate in $HAR_NODE_PACKAGE_MANAGERS; do
120
- if command -v "$candidate" >/dev/null 2>&1; then
121
- echo "$candidate"
122
- return
123
- fi
124
- done
125
-
126
- echo "${declared:-npm}"
127
- }
128
-
129
- # Lockfile a manager writes, so a substitute install can clean up after itself.
130
- har_node_lockfile() {
131
- case "$1" in
132
- bun) echo "bun.lock" ;;
133
- npm) echo "package-lock.json" ;;
134
- pnpm) echo "pnpm-lock.yaml" ;;
135
- yarn) echo "yarn.lock" ;;
136
- *) echo "" ;;
137
- esac
138
- }
139
-
140
- # Install dependencies in a directory. When a substitute manager stands in for
141
- # the one the repo declares, any lockfile it creates is removed afterwards:
142
- # provisioning must not migrate the repo to a different package manager.
143
- # (bun writes bun.lock even under --no-save, so the flags alone are not enough.)
144
- har_node_install() {
145
- local dir="$1"
146
- local manager="$2"
147
- local declared="${3:-}"
148
- local substituting=false
149
- local lockfile=""
150
- local had_lockfile=false
151
-
152
- if [ -n "$declared" ] && [ "$declared" != "$manager" ]; then
153
- substituting=true
154
- lockfile="$(har_node_lockfile "$manager")"
155
- if [ -n "$lockfile" ] && [ -e "$dir/$lockfile" ]; then
156
- had_lockfile=true
157
- fi
158
- fi
159
-
160
- local code=0
161
- (cd "$dir" && "$manager" install --silent) || code=$?
162
-
163
- if [ "$substituting" = true ] && [ "$had_lockfile" = false ] && [ -n "$lockfile" ]; then
164
- rm -f "$dir/$lockfile"
165
- [ "$manager" = "bun" ] && rm -f "$dir/bun.lockb"
166
- fi
167
- return $code
168
- }
169
-
170
- # Package runner (npx equivalent) for one-off CLIs such as pm2, including the
171
- # flag that keeps it non-interactive. Takes a manager name, or none to resolve
172
- # from the environment and PATH.
173
- har_pkg_exec() {
174
- case "${1:-${HARNESS_NODE_PACKAGE_MANAGER:-}}" in
175
- bun) echo "bunx"; return ;;
176
- pnpm) echo "pnpm dlx"; return ;;
177
- yarn) echo "yarn dlx"; return ;;
178
- npm) echo "npx --yes"; return ;;
179
- esac
180
- if command -v npx >/dev/null 2>&1; then echo "npx --yes"; return; fi
181
- if command -v bunx >/dev/null 2>&1; then echo "bunx"; return; fi
182
- if command -v pnpm >/dev/null 2>&1; then echo "pnpm dlx"; return; fi
183
- echo "npx --yes"
184
- }
185
-
186
- # Postgres client — uses host tools when installed, otherwise docker exec into
187
- # the shared db container. Usage: har_pg psql -d postgres -c "SELECT 1"
188
- # har_pg createdb -T template_x agent_1
189
- har_pg() {
190
- local tool="$1"; shift
191
- if command -v "$tool" >/dev/null 2>&1; then
192
- PGPASSWORD=password "$tool" -h localhost -p "${AGENT_DB_PORT:-15432}" -U postgres "$@"
193
- else
194
- docker exec -i -e PGPASSWORD=password "har-${HARNESS_PROJECT_NAME}-db-1" "$tool" -U postgres "$@"
195
- fi
196
- }
197
-
198
- # Database setup commands (run once against template DB in setup-infra.sh)
199
- export HARNESS_DB_MIGRATE_CMD="echo 'TODO: set migrate command'"
200
- export HARNESS_DB_SEED_CMD="echo 'TODO: set seed command'"
53
+ # Database setup commands (run once against template DB in setup-infra.sh).
54
+ # Empty = not configured; setup-infra.sh skips the step.
55
+ export HARNESS_DB_MIGRATE_CMD=""
56
+ export HARNESS_DB_SEED_CMD=""
201
57
 
202
58
  # Optional readiness/data hooks for larger apps. Enable only when this project
203
59
  # needs them, and keep the scripts idempotent.
@@ -32,9 +32,11 @@
32
32
  {
33
33
  "id": "verify",
34
34
  "kind": "verify",
35
- "description": "Verification pipeline (quick smoke by default; --full runs the registry's verificationStages)",
35
+ "description": "Verification pipeline: runs stages.json verificationStages in order (tier \"quick\" by default; --full runs the whole list)",
36
36
  "command": "./.har/verify.sh {agentId}",
37
- "acceptsArgs": ["--full"],
37
+ "acceptsArgs": [
38
+ "--full"
39
+ ],
38
40
  "artifacts": [
39
41
  {
40
42
  "path": ".har/artifacts",
@@ -67,6 +69,53 @@
67
69
  "kind": "teardown",
68
70
  "description": "Stop processes and release agent slot resources",
69
71
  "command": "./.har/teardown.sh {agentId}"
72
+ },
73
+ {
74
+ "id": "typecheck",
75
+ "kind": "test",
76
+ "tier": "quick",
77
+ "description": "Ecosystem quick smoke (registered from HARNESS_ECOSYSTEM at init; adapt to this repo)",
78
+ "command": "${NPM_BIN:-npm} run typecheck",
79
+ "requiresAgentId": true
80
+ },
81
+ {
82
+ "id": "api-health",
83
+ "kind": "test",
84
+ "tier": "quick",
85
+ "description": "API health endpoint for the slot's primary app",
86
+ "script": "stages/api-health.sh",
87
+ "requiresAgentId": true
88
+ },
89
+ {
90
+ "id": "unit-tests",
91
+ "kind": "test",
92
+ "tier": "full",
93
+ "description": "Unit tests",
94
+ "command": "${NPM_BIN:-npm} test",
95
+ "requiresAgentId": true
96
+ },
97
+ {
98
+ "id": "lint",
99
+ "kind": "test",
100
+ "tier": "full",
101
+ "description": "Lint",
102
+ "command": "${NPM_BIN:-npm} run lint",
103
+ "requiresAgentId": true
104
+ },
105
+ {
106
+ "id": "readiness",
107
+ "kind": "test",
108
+ "tier": "full",
109
+ "description": "Project readiness smoke (HARNESS_READINESS_CMD)",
110
+ "script": "stages/readiness.sh",
111
+ "requiresAgentId": true
70
112
  }
113
+ ],
114
+ "verificationStages": [
115
+ "typecheck",
116
+ "api-health",
117
+ "unit-tests",
118
+ "lint",
119
+ "readiness"
71
120
  ]
72
121
  }
@@ -32,7 +32,7 @@ services:
32
32
  image: coollabsio/minio:latest
33
33
  ports:
34
34
  - "${AGENT_MINIO_PORT:-19000}:9000"
35
- - "${AGENT_MINIO_CONSOLE_PORT:-19001}:9001"
35
+ - "${AGENT_MINIO_CONSOLE_PORT:-19050}:9001"
36
36
  volumes:
37
37
  - agent-minio-data:/minio/data
38
38
  environment:
@@ -1,5 +1,9 @@
1
1
  # CLI / library harness — optional Docker via HARNESS_INFRA_SERVICES, no PM2
2
2
  # Generated by har env init --profile cli
3
+ #
4
+ # This file is pure KEY=value config (plus comments) and is schema-validated
5
+ # on read. Runtime helpers (har_infra_enabled, har_pg, port resolution) live
6
+ # in .har/lib/ — never define functions here.
3
7
 
4
8
  export HARNESS_PROJECT_NAME=__PROJECT_NAME__
5
9
  export HARNESS_USE_WORKTREE=true
@@ -10,10 +14,10 @@ export HARNESS_API_BASE_PORT=8000
10
14
  export HARNESS_PORT_STEP=10
11
15
  export HARNESS_HEALTH_CHECK_PATH=
12
16
 
13
- # Shared infra host ports — setup-infra.sh tries DEFAULT first, scans when busy.
14
- export HARNESS_DB_PORT_DEFAULT=15432
15
- export HARNESS_DB_PORT_SCAN_START=15432
16
- export HARNESS_DB_PORT_SCAN_END=15499
17
+ # Shared infra host ports — one lane per infra service:
18
+ # <lane>=<default>:<scan_start>-<scan_end>. setup-infra.sh tries the default
19
+ # first, scans the range when busy.
20
+ export HARNESS_INFRA_PORT_LANES="db=15432:15432-15499"
17
21
 
18
22
  export HARNESS_AGENT_SLOT_MIN=1
19
23
  export HARNESS_AGENT_SLOT_MAX=3
@@ -34,140 +38,10 @@ export HARNESS_ECOSYSTEM="auto"
34
38
  # compose file, then list the ones this project needs here (e.g. "db redis").
35
39
  export HARNESS_INFRA_SERVICES=""
36
40
 
37
- # Returns 0 when a shared infra service is enabled: har_infra_enabled db
38
- har_infra_enabled() {
39
- case " ${HARNESS_INFRA_SERVICES:-} " in
40
- *" $1 "*) return 0 ;;
41
- *) return 1 ;;
42
- esac
43
- }
44
-
45
- # ── Node package manager helpers ──────────────────────────────────────────────
46
- # Mirrored verbatim in harness.env and provision-toolchain.sh so a sourcing
47
- # script and the provisioning subprocess resolve the same tool.
48
-
49
- # Package managers HAR can drive, in fallback preference order.
50
- HAR_NODE_PACKAGE_MANAGERS="npm bun pnpm yarn"
51
-
52
- # Package manager the repo declares: an explicit HARNESS_NODE_PACKAGE_MANAGER
53
- # wins, then package.json "packageManager", then the lockfile. Empty when the
54
- # repo says nothing.
55
- har_node_declared_package_manager() {
56
- local dir="${1:-.}"
57
-
58
- if [ -n "${HARNESS_NODE_PACKAGE_MANAGER:-}" ]; then
59
- echo "$HARNESS_NODE_PACKAGE_MANAGER"
60
- return
61
- fi
62
- if [ -f "$dir/package.json" ]; then
63
- local field
64
- field="$(sed -n 's/.*"packageManager"[[:space:]]*:[[:space:]]*"\([a-z]*\)@.*/\1/p' "$dir/package.json" | head -1)"
65
- if [ -n "$field" ]; then
66
- echo "$field"
67
- return
68
- fi
69
- fi
70
- if [ -f "$dir/bun.lock" ] || [ -f "$dir/bun.lockb" ]; then echo bun; return; fi
71
- if [ -f "$dir/pnpm-lock.yaml" ]; then echo pnpm; return; fi
72
- if [ -f "$dir/yarn.lock" ]; then echo yarn; return; fi
73
- if [ -f "$dir/package-lock.json" ]; then echo npm; return; fi
74
- echo ""
75
- }
76
-
77
- # Package manager to actually run. A manager the repo declares but this machine
78
- # lacks falls back to one that is installed, so a repo pinned to npm still
79
- # provisions on a bun-only machine (and the reverse).
80
- har_node_package_manager() {
81
- local dir="${1:-.}"
82
- local declared
83
- declared="$(har_node_declared_package_manager "$dir")"
84
-
85
- if [ -n "$declared" ] && command -v "$declared" >/dev/null 2>&1; then
86
- echo "$declared"
87
- return
88
- fi
89
-
90
- local candidate
91
- for candidate in $HAR_NODE_PACKAGE_MANAGERS; do
92
- if command -v "$candidate" >/dev/null 2>&1; then
93
- echo "$candidate"
94
- return
95
- fi
96
- done
97
-
98
- echo "${declared:-npm}"
99
- }
100
-
101
- # Lockfile a manager writes, so a substitute install can clean up after itself.
102
- har_node_lockfile() {
103
- case "$1" in
104
- bun) echo "bun.lock" ;;
105
- npm) echo "package-lock.json" ;;
106
- pnpm) echo "pnpm-lock.yaml" ;;
107
- yarn) echo "yarn.lock" ;;
108
- *) echo "" ;;
109
- esac
110
- }
111
-
112
- # Install dependencies in a directory. When a substitute manager stands in for
113
- # the one the repo declares, any lockfile it creates is removed afterwards:
114
- # provisioning must not migrate the repo to a different package manager.
115
- # (bun writes bun.lock even under --no-save, so the flags alone are not enough.)
116
- har_node_install() {
117
- local dir="$1"
118
- local manager="$2"
119
- local declared="${3:-}"
120
- local substituting=false
121
- local lockfile=""
122
- local had_lockfile=false
123
-
124
- if [ -n "$declared" ] && [ "$declared" != "$manager" ]; then
125
- substituting=true
126
- lockfile="$(har_node_lockfile "$manager")"
127
- if [ -n "$lockfile" ] && [ -e "$dir/$lockfile" ]; then
128
- had_lockfile=true
129
- fi
130
- fi
131
-
132
- local code=0
133
- (cd "$dir" && "$manager" install --silent) || code=$?
134
-
135
- if [ "$substituting" = true ] && [ "$had_lockfile" = false ] && [ -n "$lockfile" ]; then
136
- rm -f "$dir/$lockfile"
137
- [ "$manager" = "bun" ] && rm -f "$dir/bun.lockb"
138
- fi
139
- return $code
140
- }
141
-
142
- # Package runner (npx equivalent) for one-off CLIs such as pm2, including the
143
- # flag that keeps it non-interactive. Takes a manager name, or none to resolve
144
- # from the environment and PATH.
145
- har_pkg_exec() {
146
- case "${1:-${HARNESS_NODE_PACKAGE_MANAGER:-}}" in
147
- bun) echo "bunx"; return ;;
148
- pnpm) echo "pnpm dlx"; return ;;
149
- yarn) echo "yarn dlx"; return ;;
150
- npm) echo "npx --yes"; return ;;
151
- esac
152
- if command -v npx >/dev/null 2>&1; then echo "npx --yes"; return; fi
153
- if command -v bunx >/dev/null 2>&1; then echo "bunx"; return; fi
154
- if command -v pnpm >/dev/null 2>&1; then echo "pnpm dlx"; return; fi
155
- echo "npx --yes"
156
- }
157
-
158
- # Postgres client — uses host tools when installed, otherwise docker exec into
159
- # the shared db container. Usage: har_pg psql -d postgres -c "SELECT 1"
160
- har_pg() {
161
- local tool="$1"; shift
162
- if command -v "$tool" >/dev/null 2>&1; then
163
- PGPASSWORD=password "$tool" -h localhost -p "${AGENT_DB_PORT:-15432}" -U postgres "$@"
164
- else
165
- docker exec -i -e PGPASSWORD=password "har-${HARNESS_PROJECT_NAME}-db-1" "$tool" -U postgres "$@"
166
- fi
167
- }
168
-
169
- export HARNESS_DB_MIGRATE_CMD="true"
170
- export HARNESS_DB_SEED_CMD="true"
41
+ # Database setup commands (run once against template DB in setup-infra.sh).
42
+ # Empty = not configured; setup-infra.sh skips the step.
43
+ export HARNESS_DB_MIGRATE_CMD=""
44
+ export HARNESS_DB_SEED_CMD=""
171
45
 
172
46
  # Optional readiness/data hooks for repositories that need more than static
173
47
  # CLI/library checks. Enable only when this project needs them, and keep scripts
@@ -32,9 +32,11 @@
32
32
  {
33
33
  "id": "verify",
34
34
  "kind": "verify",
35
- "description": "Verification pipeline (quick smoke by default; --full runs the registry's verificationStages)",
35
+ "description": "Verification pipeline: runs stages.json verificationStages in order (tier \"quick\" by default; --full runs the whole list)",
36
36
  "command": "./.har/verify.sh {agentId}",
37
- "acceptsArgs": ["--full"],
37
+ "acceptsArgs": [
38
+ "--full"
39
+ ],
38
40
  "artifacts": [
39
41
  {
40
42
  "path": ".har/artifacts",
@@ -61,6 +63,44 @@
61
63
  "kind": "teardown",
62
64
  "description": "Remove worktree and env file for the slot",
63
65
  "command": "./.har/teardown.sh {agentId}"
66
+ },
67
+ {
68
+ "id": "typecheck",
69
+ "kind": "test",
70
+ "tier": "quick",
71
+ "description": "Ecosystem quick smoke (registered from HARNESS_ECOSYSTEM at init; adapt to this repo)",
72
+ "command": "${NPM_BIN:-npm} run typecheck",
73
+ "requiresAgentId": true
74
+ },
75
+ {
76
+ "id": "unit-tests",
77
+ "kind": "test",
78
+ "tier": "full",
79
+ "description": "Unit tests",
80
+ "command": "${NPM_BIN:-npm} test",
81
+ "requiresAgentId": true
82
+ },
83
+ {
84
+ "id": "lint",
85
+ "kind": "test",
86
+ "tier": "full",
87
+ "description": "Lint",
88
+ "command": "${NPM_BIN:-npm} run lint",
89
+ "requiresAgentId": true
90
+ },
91
+ {
92
+ "id": "readiness",
93
+ "kind": "test",
94
+ "tier": "full",
95
+ "description": "Project readiness smoke (HARNESS_READINESS_CMD)",
96
+ "script": "stages/readiness.sh",
97
+ "requiresAgentId": true
64
98
  }
99
+ ],
100
+ "verificationStages": [
101
+ "typecheck",
102
+ "unit-tests",
103
+ "lint",
104
+ "readiness"
65
105
  ]
66
106
  }
@@ -1,5 +1,9 @@
1
1
  # iOS mobile app harness — Xcode / iOS Simulator, no PM2, no Docker infra
2
2
  # Generated by har env init --profile ios
3
+ #
4
+ # This file is pure KEY=value config (plus comments) and is schema-validated
5
+ # on read. Runtime helpers (har_infra_enabled, port resolution) live in
6
+ # .har/lib/ — never define functions here.
3
7
 
4
8
  export HARNESS_PROJECT_NAME=__PROJECT_NAME__
5
9
  export HARNESS_USE_WORKTREE=true
@@ -60,139 +64,19 @@ export HARNESS_SIMULATOR_FAMILY="auto"
60
64
  export HARNESS_SIMULATOR_SHARED=false
61
65
 
62
66
  # Destination used when slots share a simulator; per-slot launches override it
63
- # with the reserved device's UDID.
64
- export HARNESS_IOS_DESTINATION="platform=iOS Simulator,name=${HARNESS_SIMULATOR_NAME}"
67
+ # with the reserved device's UDID. Empty = derived from HARNESS_SIMULATOR_NAME.
68
+ export HARNESS_IOS_DESTINATION=""
65
69
 
66
- # Optional SwiftLint path (leave empty to use system-installed swiftlint).
67
- export HARNESS_SWIFTLINT_CMD="${HARNESS_SWIFTLINT_CMD:-swiftlint}"
70
+ # Optional SwiftLint path (empty = system-installed swiftlint).
71
+ # export HARNESS_SWIFTLINT_CMD="swiftlint"
68
72
 
69
73
  # ── Infrastructure ────────────────────────────────────────────────────────────
70
74
  # No Docker infra for pure iOS apps. Set service names here (space-separated)
71
75
  # only if your app needs a local backend container (e.g. a mock server).
72
- # When enabled, add matching HARNESS_*_PORT_DEFAULT / SCAN_* vars for each service.
76
+ # When enabled, declare a matching port lane for each service:
77
+ # export HARNESS_INFRA_PORT_LANES="mock-server=18080:18080-18099"
73
78
  export HARNESS_INFRA_SERVICES=""
74
79
 
75
- # Returns 0 when a shared infra service is enabled: har_infra_enabled mock-server
76
- har_infra_enabled() {
77
- case " ${HARNESS_INFRA_SERVICES:-} " in
78
- *" $1 "*) return 0 ;;
79
- *) return 1 ;;
80
- esac
81
- }
82
-
83
- # ── Node package manager helpers ──────────────────────────────────────────────
84
- # Mirrored verbatim in harness.env and provision-toolchain.sh so a sourcing
85
- # script and the provisioning subprocess resolve the same tool.
86
-
87
- # Package managers HAR can drive, in fallback preference order.
88
- HAR_NODE_PACKAGE_MANAGERS="npm bun pnpm yarn"
89
-
90
- # Package manager the repo declares: an explicit HARNESS_NODE_PACKAGE_MANAGER
91
- # wins, then package.json "packageManager", then the lockfile. Empty when the
92
- # repo says nothing.
93
- har_node_declared_package_manager() {
94
- local dir="${1:-.}"
95
-
96
- if [ -n "${HARNESS_NODE_PACKAGE_MANAGER:-}" ]; then
97
- echo "$HARNESS_NODE_PACKAGE_MANAGER"
98
- return
99
- fi
100
- if [ -f "$dir/package.json" ]; then
101
- local field
102
- field="$(sed -n 's/.*"packageManager"[[:space:]]*:[[:space:]]*"\([a-z]*\)@.*/\1/p' "$dir/package.json" | head -1)"
103
- if [ -n "$field" ]; then
104
- echo "$field"
105
- return
106
- fi
107
- fi
108
- if [ -f "$dir/bun.lock" ] || [ -f "$dir/bun.lockb" ]; then echo bun; return; fi
109
- if [ -f "$dir/pnpm-lock.yaml" ]; then echo pnpm; return; fi
110
- if [ -f "$dir/yarn.lock" ]; then echo yarn; return; fi
111
- if [ -f "$dir/package-lock.json" ]; then echo npm; return; fi
112
- echo ""
113
- }
114
-
115
- # Package manager to actually run. A manager the repo declares but this machine
116
- # lacks falls back to one that is installed, so a repo pinned to npm still
117
- # provisions on a bun-only machine (and the reverse).
118
- har_node_package_manager() {
119
- local dir="${1:-.}"
120
- local declared
121
- declared="$(har_node_declared_package_manager "$dir")"
122
-
123
- if [ -n "$declared" ] && command -v "$declared" >/dev/null 2>&1; then
124
- echo "$declared"
125
- return
126
- fi
127
-
128
- local candidate
129
- for candidate in $HAR_NODE_PACKAGE_MANAGERS; do
130
- if command -v "$candidate" >/dev/null 2>&1; then
131
- echo "$candidate"
132
- return
133
- fi
134
- done
135
-
136
- echo "${declared:-npm}"
137
- }
138
-
139
- # Lockfile a manager writes, so a substitute install can clean up after itself.
140
- har_node_lockfile() {
141
- case "$1" in
142
- bun) echo "bun.lock" ;;
143
- npm) echo "package-lock.json" ;;
144
- pnpm) echo "pnpm-lock.yaml" ;;
145
- yarn) echo "yarn.lock" ;;
146
- *) echo "" ;;
147
- esac
148
- }
149
-
150
- # Install dependencies in a directory. When a substitute manager stands in for
151
- # the one the repo declares, any lockfile it creates is removed afterwards:
152
- # provisioning must not migrate the repo to a different package manager.
153
- # (bun writes bun.lock even under --no-save, so the flags alone are not enough.)
154
- har_node_install() {
155
- local dir="$1"
156
- local manager="$2"
157
- local declared="${3:-}"
158
- local substituting=false
159
- local lockfile=""
160
- local had_lockfile=false
161
-
162
- if [ -n "$declared" ] && [ "$declared" != "$manager" ]; then
163
- substituting=true
164
- lockfile="$(har_node_lockfile "$manager")"
165
- if [ -n "$lockfile" ] && [ -e "$dir/$lockfile" ]; then
166
- had_lockfile=true
167
- fi
168
- fi
169
-
170
- local code=0
171
- (cd "$dir" && "$manager" install --silent) || code=$?
172
-
173
- if [ "$substituting" = true ] && [ "$had_lockfile" = false ] && [ -n "$lockfile" ]; then
174
- rm -f "$dir/$lockfile"
175
- [ "$manager" = "bun" ] && rm -f "$dir/bun.lockb"
176
- fi
177
- return $code
178
- }
179
-
180
- # Package runner (npx equivalent) for one-off CLIs such as pm2, including the
181
- # flag that keeps it non-interactive. Takes a manager name, or none to resolve
182
- # from the environment and PATH.
183
- har_pkg_exec() {
184
- case "${1:-${HARNESS_NODE_PACKAGE_MANAGER:-}}" in
185
- bun) echo "bunx"; return ;;
186
- pnpm) echo "pnpm dlx"; return ;;
187
- yarn) echo "yarn dlx"; return ;;
188
- npm) echo "npx --yes"; return ;;
189
- esac
190
- if command -v npx >/dev/null 2>&1; then echo "npx --yes"; return; fi
191
- if command -v bunx >/dev/null 2>&1; then echo "bunx"; return; fi
192
- if command -v pnpm >/dev/null 2>&1; then echo "pnpm dlx"; return; fi
193
- echo "npx --yes"
194
- }
195
-
196
80
  # Optional "agent usable" smoke beyond build/test, such as a simulator flow or
197
81
  # backend-auth check. Enable only when this project needs it.
198
82
  # export HARNESS_READINESS_CMD="./.har/readiness.sh"