@1aboveio/skills 1.0.7 → 1.0.9

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 (224) hide show
  1. package/.codex-plugin/plugin.json +13 -0
  2. package/.codex-plugin/resources.json +1827 -0
  3. package/README.md +22 -0
  4. package/package.json +9 -2
  5. package/skills/app-dev/airflow/SKILL.md +1 -1
  6. package/skills/app-dev/airflow/release-check.mjs +3 -1
  7. package/skills/app-dev/android-foundation/SKILL.md +92 -34
  8. package/skills/app-dev/android-foundation/assets/android-ci-job.yml +13 -7
  9. package/skills/app-dev/android-foundation/references/ci.md +23 -13
  10. package/skills/app-dev/android-foundation/references/delivery-focus.md +29 -0
  11. package/skills/app-dev/android-foundation/references/diagnosis.md +136 -0
  12. package/skills/app-dev/android-foundation/references/gotchas.md +20 -11
  13. package/skills/app-dev/android-foundation/references/setup.md +15 -6
  14. package/skills/app-dev/android-foundation/release-check.mjs +3 -1
  15. package/skills/app-dev/android-foundation/scripts/device-run.sh +148 -42
  16. package/skills/app-dev/app-debug/SKILL.md +1 -1
  17. package/skills/app-dev/app-debug/release-check.mjs +3 -1
  18. package/skills/app-dev/better-auth/SKILL.md +1 -1
  19. package/skills/app-dev/better-auth/release-check.mjs +3 -1
  20. package/skills/app-dev/data-catalog/SKILL.md +1 -1
  21. package/skills/app-dev/data-catalog/release-check.mjs +3 -1
  22. package/skills/app-dev/data-quality/SKILL.md +1 -1
  23. package/skills/app-dev/data-quality/release-check.mjs +3 -1
  24. package/skills/app-dev/ios-foundation/SKILL.md +1 -1
  25. package/skills/app-dev/ios-foundation/release-check.mjs +3 -1
  26. package/skills/app-dev/monorepo/SKILL.md +1 -1
  27. package/skills/app-dev/monorepo/release-check.mjs +3 -1
  28. package/skills/app-dev/nextjs-fullstack/SKILL.md +1 -1
  29. package/skills/app-dev/nextjs-fullstack/release-check.mjs +3 -1
  30. package/skills/app-dev/prisma-setup/SKILL.md +1 -1
  31. package/skills/app-dev/prisma-setup/release-check.mjs +3 -1
  32. package/skills/app-dev/pyspark/SKILL.md +1 -1
  33. package/skills/app-dev/pyspark/release-check.mjs +3 -1
  34. package/skills/app-dev/python-backend/SKILL.md +1 -1
  35. package/skills/app-dev/python-backend/release-check.mjs +3 -1
  36. package/skills/app-dev/shadcn/SKILL.md +1 -1
  37. package/skills/app-dev/shadcn/release-check.mjs +3 -1
  38. package/skills/app-dev/zod-v4/SKILL.md +1 -1
  39. package/skills/app-dev/zod-v4/release-check.mjs +3 -1
  40. package/skills/cicd/cloud-build/SKILL.md +1 -1
  41. package/skills/cicd/cloud-build/release-check.mjs +3 -1
  42. package/skills/cicd/cloud-debug/SKILL.md +1 -1
  43. package/skills/cicd/cloud-debug/release-check.mjs +3 -1
  44. package/skills/cicd/cloud-deploy/SKILL.md +1 -1
  45. package/skills/cicd/cloud-deploy/release-check.mjs +3 -1
  46. package/skills/cicd/docker/SKILL.md +1 -1
  47. package/skills/cicd/docker/release-check.mjs +3 -1
  48. package/skills/cicd/github-actions/SKILL.md +1 -1
  49. package/skills/cicd/github-actions/release-check.mjs +3 -1
  50. package/skills/cicd/github-flow/SKILL.md +1 -1
  51. package/skills/cicd/github-flow/release-check.mjs +3 -1
  52. package/skills/cicd/google-cloud/SKILL.md +1 -1
  53. package/skills/cicd/google-cloud/release-check.mjs +3 -1
  54. package/skills/cicd/mergify/SKILL.md +1 -1
  55. package/skills/cicd/mergify/release-check.mjs +3 -1
  56. package/skills/cicd/podman/SKILL.md +1 -1
  57. package/skills/cicd/podman/release-check.mjs +3 -1
  58. package/skills/content/article-review/SKILL.md +1 -1
  59. package/skills/content/article-review/release-check.mjs +3 -1
  60. package/skills/content/article-to-image/SKILL.md +1 -1
  61. package/skills/content/article-to-image/release-check.mjs +3 -1
  62. package/skills/content/flowchart-svg/SKILL.md +1 -1
  63. package/skills/content/flowchart-svg/release-check.mjs +3 -1
  64. package/skills/content/image-gen/SKILL.md +1 -1
  65. package/skills/content/image-gen/release-check.mjs +3 -1
  66. package/skills/content/mermaid/SKILL.md +1 -1
  67. package/skills/content/mermaid/release-check.mjs +3 -1
  68. package/skills/content/wechat-article-writer/SKILL.md +1 -1
  69. package/skills/content/wechat-article-writer/release-check.mjs +3 -1
  70. package/skills/content/wechat-publisher/SKILL.md +1 -1
  71. package/skills/content/wechat-publisher/release-check.mjs +3 -1
  72. package/skills/content/wechat-search/SKILL.md +1 -1
  73. package/skills/content/wechat-search/release-check.mjs +3 -1
  74. package/skills/content/xai-search/SKILL.md +88 -13
  75. package/skills/content/xai-search/release-check.mjs +3 -1
  76. package/skills/content/xai-search/scripts/xai_search.sh +125 -149
  77. package/skills/core/distill-writing/SKILL.md +1 -1
  78. package/skills/core/distill-writing/release-check.mjs +3 -1
  79. package/skills/core/doc-to-md/SKILL.md +1 -1
  80. package/skills/core/doc-to-md/release-check.mjs +3 -1
  81. package/skills/core/editorial-review/SKILL.md +1 -1
  82. package/skills/core/editorial-review/release-check.mjs +3 -1
  83. package/skills/core/house-style/SKILL.md +1 -1
  84. package/skills/core/house-style/release-check.mjs +3 -1
  85. package/skills/core/plain-language/SKILL.md +1 -1
  86. package/skills/core/plain-language/release-check.mjs +3 -1
  87. package/skills/core/polish-cn/SKILL.md +1 -1
  88. package/skills/core/polish-cn/release-check.mjs +3 -1
  89. package/skills/core/reg-parser/SKILL.md +1 -1
  90. package/skills/core/reg-parser/release-check.mjs +3 -1
  91. package/skills/core/terminology/SKILL.md +1 -1
  92. package/skills/core/terminology/release-check.mjs +3 -1
  93. package/skills/core/write-doc/SKILL.md +1 -1
  94. package/skills/core/write-doc/release-check.mjs +3 -1
  95. package/skills/engineering/better-review/SKILL.md +1 -1
  96. package/skills/engineering/better-review/release-check.mjs +3 -1
  97. package/skills/engineering/contributing/SKILL.md +1 -1
  98. package/skills/engineering/contributing/release-check.mjs +3 -1
  99. package/skills/engineering/e2e-test/SKILL.md +1 -1
  100. package/skills/engineering/e2e-test/release-check.mjs +3 -1
  101. package/skills/engineering/engineering-runtime/SKILL.md +1 -1
  102. package/skills/engineering/engineering-runtime/coherence/workflow.json +13 -13
  103. package/skills/engineering/engineering-runtime/release-check.mjs +3 -1
  104. package/skills/engineering/engineering-runtime/scripts/installation-resolver.mjs +191 -0
  105. package/skills/engineering/engineering-runtime/scripts/workflow-coherence.mjs +51 -10
  106. package/skills/engineering/ensure-coverage/SKILL.md +1 -1
  107. package/skills/engineering/ensure-coverage/release-check.mjs +3 -1
  108. package/skills/engineering/golden-path/SKILL.md +1 -1
  109. package/skills/engineering/golden-path/release-check.mjs +3 -1
  110. package/skills/engineering/harness-runtime/SKILL.md +1 -1
  111. package/skills/engineering/harness-runtime/release-check.mjs +3 -1
  112. package/skills/engineering/resolve-issues/SKILL.md +11 -20
  113. package/skills/engineering/resolve-issues/references/delivery-progress.md +63 -0
  114. package/skills/engineering/resolve-issues/references/expire.md +24 -11
  115. package/skills/engineering/resolve-issues/references/implementation.md +9 -1
  116. package/skills/engineering/resolve-issues/references/preflight.md +7 -0
  117. package/skills/engineering/resolve-issues/references/shared-modules.md +27 -0
  118. package/skills/engineering/resolve-issues/references/task-plan.md +12 -5
  119. package/skills/engineering/resolve-issues/release-check.mjs +3 -1
  120. package/skills/engineering/resolve-issues/scripts/active-installation.mjs +32 -0
  121. package/skills/engineering/resolve-issues/scripts/install-hooks.mjs +3 -0
  122. package/skills/engineering/resolve-issues/scripts/rehydrate.mjs +17 -1
  123. package/skills/engineering/resolve-release/SKILL.md +1 -1
  124. package/skills/engineering/resolve-release/release-check.mjs +3 -1
  125. package/skills/engineering/rush-issues/SKILL.md +5 -2
  126. package/skills/engineering/rush-issues/release-check.mjs +3 -1
  127. package/skills/engineering/rush-release/SKILL.md +1 -1
  128. package/skills/engineering/rush-release/release-check.mjs +3 -1
  129. package/skills/engineering/test-quality/SKILL.md +1 -1
  130. package/skills/engineering/test-quality/release-check.mjs +3 -1
  131. package/skills/risk-compliance/compliance-audit/SKILL.md +1 -1
  132. package/skills/risk-compliance/compliance-audit/release-check.mjs +3 -1
  133. package/skills/risk-compliance/contract-compare/SKILL.md +1 -1
  134. package/skills/risk-compliance/contract-compare/release-check.mjs +3 -1
  135. package/skills/risk-compliance/contract-review/SKILL.md +1 -1
  136. package/skills/risk-compliance/contract-review/release-check.mjs +3 -1
  137. package/skills/risk-compliance/doc-authenticity/SKILL.md +1 -1
  138. package/skills/risk-compliance/doc-authenticity/release-check.mjs +3 -1
  139. package/skills/risk-compliance/fraud-analysis/SKILL.md +1 -1
  140. package/skills/risk-compliance/fraud-analysis/release-check.mjs +3 -1
  141. package/skills/risk-compliance/payment-analysis/SKILL.md +1 -1
  142. package/skills/risk-compliance/payment-analysis/release-check.mjs +3 -1
  143. package/skills/risk-compliance/similar-domain/SKILL.md +1 -1
  144. package/skills/risk-compliance/similar-domain/release-check.mjs +3 -1
  145. package/skills/risk-compliance/tld-detection/SKILL.md +1 -1
  146. package/skills/risk-compliance/tld-detection/release-check.mjs +3 -1
  147. package/skills/app-dev/android-foundation/scripts/device-run.test.mjs +0 -172
  148. package/skills/app-dev/data-catalog/scripts/data-catalog.test.mjs +0 -36
  149. package/skills/app-dev/data-quality/scripts/data-quality.test.mjs +0 -12
  150. package/skills/cicd/github-actions/scripts/ci-run-audit.test.mjs +0 -637
  151. package/skills/cicd/github-flow/scripts/flow.test.mjs +0 -114
  152. package/skills/cicd/github-flow/scripts/persist-conventions.test.mjs +0 -108
  153. package/skills/cicd/mergify/scripts/audit.test.mjs +0 -201
  154. package/skills/cicd/mergify/scripts/entrypoints.test.mjs +0 -106
  155. package/skills/cicd/mergify/scripts/pr-620-mergify-comments.fixture.json +0 -30
  156. package/skills/cicd/mergify/scripts/stack-push.test.mjs +0 -233
  157. package/skills/cicd/mergify/scripts/watch-pr-delivery.test.mjs +0 -1826
  158. package/skills/content/image-gen/scripts/credentials.test.mjs +0 -212
  159. package/skills/content/image-gen/scripts/options.test.mjs +0 -245
  160. package/skills/content/xai-search/tests/smoke_test.sh +0 -36
  161. package/skills/core/polish-cn/scripts/polish-cn.test.mjs +0 -244
  162. package/skills/core/reg-parser/scripts/reg-parser.test.mjs +0 -165
  163. package/skills/engineering/better-review/scripts/pr-context.test.mjs +0 -168
  164. package/skills/engineering/better-review/scripts/rereview-scope.test.mjs +0 -587
  165. package/skills/engineering/better-review/scripts/scan-diff.test.mjs +0 -414
  166. package/skills/engineering/better-review/scripts/vendor-sync.test.mjs +0 -96
  167. package/skills/engineering/contributing/scripts/persist-conventions.test.mjs +0 -118
  168. package/skills/engineering/e2e-test/scripts/presentation-checks.test.mjs +0 -106
  169. package/skills/engineering/e2e-test/scripts/presentation-perceivability.test.mjs +0 -117
  170. package/skills/engineering/e2e-test/scripts/presentation-reachability.test.mjs +0 -69
  171. package/skills/engineering/e2e-test/scripts/presentation-render-health.test.mjs +0 -98
  172. package/skills/engineering/e2e-test/scripts/presentation-sweep.test.mjs +0 -71
  173. package/skills/engineering/e2e-test/scripts/presentation-temporal.test.mjs +0 -59
  174. package/skills/engineering/e2e-test/scripts/project-route-manifest.test.mjs +0 -76
  175. package/skills/engineering/engineering-runtime/engineering-runtime.test.mjs +0 -68
  176. package/skills/engineering/engineering-runtime/scripts/invocation-policy.test.mjs +0 -95
  177. package/skills/engineering/engineering-runtime/scripts/main-module.test.mjs +0 -288
  178. package/skills/engineering/engineering-runtime/scripts/required-check-plan.test.mjs +0 -96
  179. package/skills/engineering/ensure-coverage/scripts/adapters/nextjs-inventory.test.mjs +0 -96
  180. package/skills/engineering/ensure-coverage/scripts/check-quarantine-expiry.test.mjs +0 -47
  181. package/skills/engineering/ensure-coverage/scripts/ci-audit.test.mjs +0 -86
  182. package/skills/engineering/ensure-coverage/scripts/coverage-ledger.test.mjs +0 -447
  183. package/skills/engineering/ensure-coverage/scripts/design-parity.test.mjs +0 -552
  184. package/skills/engineering/ensure-coverage/scripts/lint-tests.test.mjs +0 -289
  185. package/skills/engineering/ensure-coverage/scripts/mock-policy-config.test.mjs +0 -119
  186. package/skills/engineering/golden-path/scripts/golden-path.test.mjs +0 -1457
  187. package/skills/engineering/harness-runtime/discover-models.test.mjs +0 -363
  188. package/skills/engineering/harness-runtime/harness-runtime.test.mjs +0 -967
  189. package/skills/engineering/harness-runtime/model-catalog-seed.test.mjs +0 -829
  190. package/skills/engineering/harness-runtime/model-catalog.test.mjs +0 -366
  191. package/skills/engineering/resolve-issues/scripts/cleanup-runs.test.mjs +0 -280
  192. package/skills/engineering/resolve-issues/scripts/dropbox.test.mjs +0 -346
  193. package/skills/engineering/resolve-issues/scripts/findings-reuse.test.mjs +0 -88
  194. package/skills/engineering/resolve-issues/scripts/github-reviews.test.mjs +0 -264
  195. package/skills/engineering/resolve-issues/scripts/install-hooks.test.mjs +0 -79
  196. package/skills/engineering/resolve-issues/scripts/issue-tree.test.mjs +0 -107
  197. package/skills/engineering/resolve-issues/scripts/manual-invocation.test.mjs +0 -14
  198. package/skills/engineering/resolve-issues/scripts/next-actions-capacity.test.mjs +0 -149
  199. package/skills/engineering/resolve-issues/scripts/next-actions.test.mjs +0 -915
  200. package/skills/engineering/resolve-issues/scripts/plan-sync.test.mjs +0 -156
  201. package/skills/engineering/resolve-issues/scripts/preflight-models.test.mjs +0 -448
  202. package/skills/engineering/resolve-issues/scripts/ready-check.test.mjs +0 -217
  203. package/skills/engineering/resolve-issues/scripts/rehydrate.test.mjs +0 -91
  204. package/skills/engineering/resolve-issues/scripts/review-verdict.test.mjs +0 -1060
  205. package/skills/engineering/resolve-issues/scripts/size-check.test.mjs +0 -458
  206. package/skills/engineering/resolve-release/scripts/apply.test.mjs +0 -99
  207. package/skills/engineering/resolve-release/scripts/dark-flags.test.mjs +0 -100
  208. package/skills/engineering/resolve-release/scripts/flow.test.mjs +0 -340
  209. package/skills/engineering/resolve-release/scripts/green-head.test.mjs +0 -101
  210. package/skills/engineering/resolve-release/scripts/npm-version-absence.test.mjs +0 -426
  211. package/skills/engineering/resolve-release/scripts/plan-npm.test.mjs +0 -659
  212. package/skills/engineering/resolve-release/scripts/plan-toml-boundary.test.mjs +0 -317
  213. package/skills/engineering/resolve-release/scripts/plan-uv.test.mjs +0 -291
  214. package/skills/engineering/resolve-release/scripts/plan.test.mjs +0 -428
  215. package/skills/engineering/test-quality/scripts/lint-tests.test.mjs +0 -591
  216. package/skills/engineering/test-quality/scripts/mock-policy-config.test.mjs +0 -119
  217. package/skills/engineering/test-quality/scripts/persist-conventions.test.mjs +0 -104
  218. package/skills/risk-compliance/compliance-audit/scripts/compliance-audit.test.mjs +0 -14
  219. package/skills/risk-compliance/doc-authenticity/manual-invocation.test.mjs +0 -12
  220. package/skills/risk-compliance/doc-authenticity/scripts/validate_verdict.test.mjs +0 -212
  221. package/skills/risk-compliance/tld-detection/scripts/detect_ladders.test.mjs +0 -14
  222. package/skills/risk-compliance/tld-detection/scripts/detect_streams.test.mjs +0 -14
  223. package/skills/risk-compliance/tld-detection/tests/test_detect_ladders.py +0 -134
  224. package/skills/risk-compliance/tld-detection/tests/test_detect_streams.py +0 -520
@@ -177,8 +177,10 @@ matches, [confirm the suspected cause](#confirm-a-suspected-cause) before changi
177
177
 
178
178
  ### Postgres setup hooks time out
179
179
 
180
- - **Cause:** durability is on.
181
- - **Fix:** disable `fsync` and `synchronous_commit` on the disposable service.
180
+ - **Possible cause:** durability overhead, if timing or database logs establish it.
181
+ - **Fix:** investigate the slow hook first. Disable `fsync` and `synchronous_commit`
182
+ only on a disposable service when measured and when tests do not require persistence
183
+ or recovery semantics. A timeout by itself does not establish this cause.
182
184
 
183
185
  ### The job never starts
184
186
 
@@ -200,11 +202,13 @@ matches, [confirm the suspected cause](#confirm-a-suspected-cause) before changi
200
202
  - **Cause:** the journey's Backend runs on the runner itself, and the self-hosted runner
201
203
  image has no browser (or other app-launched tool). A developer machine does, so it only
202
204
  fails in CI.
203
- - **Fix:** don't install it on the runner, and don't treat it as a product bug. Point the
204
- app's browser variable (`CHROMIUM_PATH`) at a wrapper that runs the pinned Playwright
205
- image's browser: `github-actions` → `references/runners.md`, "A host process that needs
206
- a browser binary". Prove it in CI; Docker Desktop on macOS cannot reach the wrapper's
207
- host-network port.
205
+ - **Fix:** inspect the runner's supported browser packaging first. One option is the
206
+ pinned Playwright-image wrapper described by `github-actions` →
207
+ `references/runners.md`, "A host process that needs a browser binary". Reproduce the
208
+ failing command and verify the wrapper on a compatible isolated Linux environment
209
+ before CI acceptance; Docker Desktop on macOS cannot prove that host-network path.
210
+ If no compatible diagnostic environment is available, report that gap and collect
211
+ targeted evidence rather than sending an unverified configuration fix to CI.
208
212
 
209
213
  ### A failed run's Metro log is gone
210
214
 
@@ -215,7 +219,12 @@ matches, [confirm the suspected cause](#confirm-a-suspected-cause) before changi
215
219
 
216
220
  ## Confirm a suspected cause
217
221
 
218
- Inject the suspected cause on purpose, for example `adb reverse --remove tcp:8081` right
219
- before the failing step, and check that it reproduces the exact failure signature: the same
220
- step, error and error count. Then show that the fix passes the same injection. A cause that
221
- does not reproduce its signature is a guess, and a fix for a guess is not proof.
222
+ Choose a test that can distinguish the suspected cause from its alternatives, as described
223
+ in [diagnosis.md](diagnosis.md#choose-a-test-that-can-expose-the-defect). A regression test
224
+ that reproduces the defect and passes with the correction may suffice. When safe and
225
+ relevant, deliberate fault injection can strengthen the evidence: for example, remove a
226
+ reverse mapping on an owned test device and compare the failure signature before and
227
+ after the correction. Injection and A/B/A are optional techniques, not universal gates.
228
+ For intermittent failures, compare bounded samples under equivalent conditions rather
229
+ than requiring an identical error count. Report a cause as unconfirmed when the evidence
230
+ does not distinguish it; do not manufacture certainty from a passing run.
@@ -50,6 +50,8 @@ export SETUP_AVD=<new-unique-avd-name>
50
50
  export EMULATOR_PORT=<even-port-5554-5584>
51
51
  export ANDROID_BACKEND_PORT=<free-port>
52
52
  export ANDROID_METRO_PORT=<free-port>
53
+ # Choose the whole-journey deadline; zero disables it and is not suitable for unattended runs.
54
+ export JOURNEY_SECONDS=<positive-journey-timeout-seconds>
53
55
  ENV
54
56
  source .cache/android-env.sh
55
57
  mkdir -p "$TMPDIR" "$npm_config_cache" "$npm_config_devdir" \
@@ -63,8 +65,10 @@ for component in platforms/android-<api> build-tools/<build-tools> ndk/<ndk> cma
63
65
  done
64
66
  ```
65
67
 
66
- If the wrapper reads its port or Python variables under other names, export those names in
67
- `android-env.sh` instead.
68
+ If the wrapper reads ports or Python under other names, export aliases in
69
+ `android-env.sh` **as well as** the bundled runner's required names. For example,
70
+ `export APP_METRO_PORT="$ANDROID_METRO_PORT"`; both must select the same port. Adapt
71
+ `DB_URL_VAR` and `DB_NAME_VAR` to the actual harness, not its fallback defaults.
68
72
 
69
73
  ## 2. Install and check
70
74
 
@@ -152,13 +156,18 @@ Pass each command as separate words, not as one quoted string. The script:
152
156
  2. Refuses an emulator port outside 5554–5584 and any busy port.
153
157
  3. Starts the ADB server, then the emulator (its PID recorded), then `postgres` with
154
158
  `--cidfile` on a random loopback port. Override the image with `POSTGRES_IMAGE`.
155
- 4. Waits for `sys.boot_completed=1` and `pg_isready`. Every command has a 30-second limit
156
- (`BOUNDED_SECONDS`) that kills the command's whole process group; exit 124 is terminal.
159
+ 4. Waits for `sys.boot_completed=1` and `pg_isready`. Startup/readiness and cleanup
160
+ commands have a 30-second limit (`BOUNDED_SECONDS`); exit 124 is terminal. The journey
161
+ uses the separate `JOURNEY_SECONDS` deadline. Leave time for cleanup after that deadline.
157
162
  5. Exports `$DB_URL_VAR`, `$DB_NAME_VAR` (`$DB_NAME_PREFIX` plus a unique suffix) and
158
163
  `ANDROID_EMULATOR_SERIAL`, then runs the journey.
159
164
  6. Drops the database, stops the emulator PID (`TERM`, then `KILL` after 10 seconds),
160
165
  removes the container by its CID, and prints `original_stage_exit=<n> cleanup_exit=<n>`.
161
166
  It exits with the journey's status if the journey failed, else the cleanup status.
162
167
 
163
- The journey stops its own backend and Metro children. Capture the command's exit status and
164
- the last output line for the evidence record.
168
+ The runner supervises the journey's process group. Journey children must stay in that
169
+ group; a wrapper that deliberately creates detached services must stop those services
170
+ through its own owner. Send TERM to the launcher and allow its cleanup to finish rather
171
+ than killing it immediately. The generic runner inherits the caller's ADB endpoint and
172
+ does not stop that server: use a verified private endpoint on a shared host and close it
173
+ through the caller's owner. Capture the command's exit status and final summary line.
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -16,6 +16,13 @@
16
16
  # Optional environment:
17
17
  # POSTGRES_IMAGE (postgres:17) DB_URL_VAR (SHARD_ADMIN_URL) DB_NAME_VAR (SHARD_DB_NAME)
18
18
  # LOG_DIR (.cache/logs) BOUNDED_SECONDS (30) BOOT_ATTEMPTS (60) KILL_GRACE_SECONDS (10)
19
+ # JOURNEY_SECONDS (0 = no deadline; caller chooses a positive whole-journey limit)
20
+ #
21
+ # ADB_SERVER_SOCKET / ANDROID_ADB_SERVER_PORT are inherited unchanged. The caller
22
+ # selects a private ADB endpoint before entry; this script never stops that server.
23
+ # Journey children must stay in their process group (no daemonizing / setsid).
24
+ # Send TERM to this launcher and allow cleanup to finish, rather than killing it.
25
+ # A forced kill or host crash cannot clean up; keep the printed resource directory.
19
26
  #
20
27
  # Exports ANDROID_EMULATOR_SERIAL, $DB_URL_VAR and $DB_NAME_VAR to both commands.
21
28
  # Prints `original_stage_exit=<n> cleanup_exit=<n>` last and exits with the
@@ -47,6 +54,26 @@ LOG_DIR="${LOG_DIR:-.cache/logs}"
47
54
  BOUNDED_SECONDS="${BOUNDED_SECONDS:-30}"
48
55
  BOOT_ATTEMPTS="${BOOT_ATTEMPTS:-60}"
49
56
  KILL_GRACE_SECONDS="${KILL_GRACE_SECONDS:-10}"
57
+ JOURNEY_SECONDS="${JOURNEY_SECONDS:-0}"
58
+
59
+ # Reject invalid limits before creating any owned resources.
60
+ python3 -c 'import math, sys
61
+ for value in sys.argv[1:4]:
62
+ number = float(value)
63
+ if not math.isfinite(number) or number < 0: sys.exit("limits must be finite and non-negative")
64
+ if float(sys.argv[1]) == 0: sys.exit("BOUNDED_SECONDS must be positive")
65
+ if not sys.argv[4].isdigit() or int(sys.argv[4]) < 1: sys.exit("BOOT_ATTEMPTS must be a positive integer")' \
66
+ "$BOUNDED_SECONDS" "$KILL_GRACE_SECONDS" "$JOURNEY_SECONDS" "$BOOT_ATTEMPTS" || exit 2
67
+ for variable in "$DB_URL_VAR" "$DB_NAME_VAR"; do
68
+ if ! [[ "$variable" =~ ^[a-zA-Z_][a-zA-Z_0-9]*$ ]]; then
69
+ echo "invalid database environment variable: $variable" >&2
70
+ exit 2
71
+ fi
72
+ done
73
+ if test "$DB_URL_VAR" = "$DB_NAME_VAR"; then
74
+ echo "DB_URL_VAR and DB_NAME_VAR must differ" >&2
75
+ exit 2
76
+ fi
50
77
 
51
78
  if ! [[ "$EMULATOR_PORT" =~ ^[0-9]+$ ]] || (( EMULATOR_PORT < 5554 || EMULATOR_PORT > 5584 || EMULATOR_PORT % 2 )); then
52
79
  echo "EMULATOR_PORT must be an even port in 5554-5584: $EMULATOR_PORT" >&2
@@ -56,67 +83,139 @@ fi
56
83
  mkdir -p "$LOG_DIR"
57
84
  run_dir="$(mktemp -d "${TMPDIR:-/tmp}/android-device-run.XXXXXX")"
58
85
  emulator_pid=""
86
+ active_pid=""
59
87
  db_ready=""
88
+ container_started=""
89
+ launch_in_progress=0
90
+ pending_signal=0
91
+ handle_signal() {
92
+ pending_signal="$1"
93
+ # Do not abandon a spawned supervisor before its PID has been recorded.
94
+ if test "$launch_in_progress" -eq 0; then exit "$pending_signal"; fi
95
+ }
96
+ honor_pending_signal() {
97
+ if test "$pending_signal" -ne 0; then exit "$pending_signal"; fi
98
+ }
99
+ echo "Owned resource records: $run_dir" >&2
60
100
  export ANDROID_EMULATOR_SERIAL="emulator-$EMULATOR_PORT"
61
101
 
62
- bounded() {
63
- # Kill the whole process group on timeout: a surviving grandchild would hold
64
- # the output pipe open and stall the caller past the deadline.
65
- python3 -c 'import os, signal, subprocess, sys
66
- limit = float(sys.argv[1])
67
- child = subprocess.Popen(sys.argv[2:], start_new_session=True)
102
+ supervise() {
103
+ # Only called in a background subshell: exec makes $! the signal-aware owner.
104
+ # Keep the process group owned even if its original leader exits first.
105
+ exec python3 -c 'import os, signal, subprocess, sys, time
106
+ limit, grace = map(float, sys.argv[1:3])
107
+ mode = sys.argv[3]
108
+ cancelled = 0
109
+ def cancel(signum, frame):
110
+ global cancelled
111
+ cancelled = 128 + signum
112
+ signal.signal(signal.SIGTERM, cancel)
113
+ signal.signal(signal.SIGINT, cancel)
68
114
  try:
69
- sys.exit(child.wait(timeout=limit))
70
- except subprocess.TimeoutExpired:
71
- os.killpg(child.pid, signal.SIGKILL)
72
- child.wait()
73
- print("Command exceeded %s seconds: %s" % (sys.argv[1], " ".join(sys.argv[2:])), file=sys.stderr)
74
- sys.exit(124)' "$BOUNDED_SECONDS" "$@"
115
+ child = subprocess.Popen(sys.argv[4:], start_new_session=True)
116
+ except FileNotFoundError as error:
117
+ print(error, file=sys.stderr)
118
+ sys.exit(127)
119
+ except OSError as error:
120
+ print(error, file=sys.stderr)
121
+ sys.exit(126)
122
+ def group_alive():
123
+ # Ignore unreapable orphan zombies. macOS can return EPERM, not ESRCH, for
124
+ # an empty group under a sandbox, so inspect membership before signalling.
125
+ listing = subprocess.check_output(["ps", "-A", "-o", "pgid=,stat="], text=True)
126
+ return any(int(parts[0]) == child.pid and not parts[1].startswith("Z")
127
+ for line in listing.splitlines() if len(parts := line.split()) == 2)
128
+ def send(sig):
129
+ try: os.killpg(child.pid, sig)
130
+ except ProcessLookupError: pass
131
+ except PermissionError:
132
+ if group_alive(): raise
133
+ end = time.monotonic() + limit if limit else float("inf")
134
+ timed_out = False
135
+ while child.poll() is None and not cancelled:
136
+ if time.monotonic() >= end:
137
+ timed_out = True
138
+ break
139
+ time.sleep(0.02)
140
+ forced = False
141
+ if timed_out:
142
+ send(signal.SIGKILL)
143
+ else:
144
+ send(signal.SIGTERM)
145
+ stop = time.monotonic() + grace
146
+ while group_alive() and time.monotonic() < stop:
147
+ child.poll()
148
+ time.sleep(0.02)
149
+ if group_alive():
150
+ forced = True
151
+ send(signal.SIGKILL)
152
+ status = child.wait()
153
+ status = 128 - status if status < 0 else status
154
+ if timed_out:
155
+ print("Command exceeded %s seconds: %s" % (sys.argv[1], " ".join(sys.argv[4:])), file=sys.stderr)
156
+ sys.exit(124)
157
+ if mode == "emulator" and forced: sys.exit(1)
158
+ sys.exit(cancelled or status or (1 if forced else 0))' "$1" "$KILL_GRACE_SECONDS" "${@:2}"
159
+ }
160
+
161
+ managed() {
162
+ local limit="$1" status=0
163
+ shift
164
+ launch_in_progress=1
165
+ supervise "$limit" command "$@" <&0 &
166
+ active_pid=$!
167
+ launch_in_progress=0
168
+ honor_pending_signal
169
+ # Bash defers signal traps for foreground commands, but not for this wait.
170
+ wait "$active_pid" || status=$?
171
+ active_pid=""
172
+ return "$status"
75
173
  }
76
174
 
175
+ bounded() { managed "$BOUNDED_SECONDS" "$@"; }
176
+
77
177
  cleanup() {
78
178
  original_status=$?
79
- trap - EXIT INT TERM
179
+ trap - EXIT
180
+ trap '' INT TERM
181
+ pending_signal=0
182
+ launch_in_progress=0
80
183
  set +e
81
184
  cleanup_status=0
185
+ if test -n "$active_pid"; then
186
+ kill -TERM "$active_pid" 2>/dev/null
187
+ wait "$active_pid" || :
188
+ active_pid=""
189
+ fi
82
190
  if test -n "$db_ready"; then
83
191
  bounded "${drop_cmd[@]}" || cleanup_status=1
84
192
  fi
85
193
  if test -n "$emulator_pid"; then
86
- if kill -0 "$emulator_pid" 2>/dev/null; then
87
- kill -TERM "$emulator_pid" || cleanup_status=1
88
- fi
89
- for _ in $(seq 1 "$KILL_GRACE_SECONDS"); do
90
- kill -0 "$emulator_pid" 2>/dev/null || break
91
- sleep 1
92
- done
93
- if kill -0 "$emulator_pid" 2>/dev/null; then
94
- cleanup_status=1
95
- kill -KILL "$emulator_pid"
96
- sleep 1
97
- fi
98
- if kill -0 "$emulator_pid" 2>/dev/null; then
99
- cleanup_status=1
100
- else
101
- wait "$emulator_pid"
102
- emulator_status=$?
103
- # 0 = clean exit; 143 = ended by our TERM. A KILL was already counted above.
104
- case "$emulator_status" in 0|143) ;; *) cleanup_status=1 ;; esac
105
- fi
194
+ kill -TERM "$emulator_pid" 2>/dev/null
195
+ emulator_status=0
196
+ wait "$emulator_pid" || emulator_status=$?
197
+ case "$emulator_status" in 0|143) ;; *) cleanup_status=1 ;; esac
106
198
  fi
107
199
  if test -s "$run_dir/postgres.cid"; then
108
200
  container_id="$(< "$run_dir/postgres.cid")"
109
201
  bounded docker rm --force "$container_id" >/dev/null || cleanup_status=1
110
- remaining="$(bounded docker ps -a --no-trunc --filter "id=$container_id" --format '{{.ID}}')" || cleanup_status=1
111
- test -z "$remaining" || cleanup_status=1
202
+ bounded docker ps -a --no-trunc --filter "id=$container_id" --format '{{.ID}}' \
203
+ > "$run_dir/remaining" || cleanup_status=1
204
+ test ! -s "$run_dir/remaining" || cleanup_status=1
205
+ elif test -n "$container_started"; then
206
+ echo "Container startup not acknowledged; ownership unknown, inspect $run_dir before recovery" >&2
207
+ cleanup_status=1
112
208
  fi
113
- printf 'original_stage_exit=%s cleanup_exit=%s\n' "$original_status" "$cleanup_status"
209
+ printf 'original_stage_exit=%s cleanup_exit=%s\n' "$original_status" "$cleanup_status" >&3
114
210
  if test "$original_status" -ne 0; then exit "$original_status"; fi
115
211
  exit "$cleanup_status"
116
212
  }
213
+ # EXIT can run inside a redirected function (notably docker run >/dev/null).
214
+ # Keep the caller's output for the final status line, even on startup failure.
215
+ exec 3>&1
117
216
  trap cleanup EXIT
118
- trap 'exit 130' INT
119
- trap 'exit 143' TERM
217
+ trap 'handle_signal 130' INT
218
+ trap 'handle_signal 143' TERM
120
219
 
121
220
  # Every port this run listens on or dials must be free before anything starts.
122
221
  python3 -c 'import socket, sys
@@ -130,21 +229,28 @@ bounded adb start-server
130
229
 
131
230
  # -memory 4096 overrides the AVD's hw.ramSize, so a reused 2 GB AVD cannot starve the
132
231
  # guest kernel's vsock allocations and drop adb mid-journey (references/gotchas.md).
133
- "$ANDROID_HOME/emulator/emulator" -avd "$SETUP_AVD" -port "$EMULATOR_PORT" -memory 4096 \
232
+ launch_in_progress=1
233
+ supervise 0 emulator "$ANDROID_HOME/emulator/emulator" -avd "$SETUP_AVD" -port "$EMULATOR_PORT" -memory 4096 \
134
234
  -no-window -no-audio -no-snapshot -gpu swiftshader_indirect -accel on \
135
235
  > "$LOG_DIR/emulator.log" 2>&1 &
136
236
  emulator_pid=$!
237
+ launch_in_progress=0
238
+ honor_pending_signal
137
239
 
138
240
  container_name="android-device-run-$(date +%s)-$$"
241
+ container_started=1
242
+ printf '%s\n' "$container_name" > "$run_dir/container-name"
139
243
  bounded docker run --detach --name "$container_name" --cidfile "$run_dir/postgres.cid" \
140
244
  --publish 127.0.0.1::5432 --env POSTGRES_USER=postgres \
141
245
  --env POSTGRES_PASSWORD=postgres --env POSTGRES_DB=postgres "$POSTGRES_IMAGE" >/dev/null
142
- db_port="$(bounded docker port "$container_name" 5432/tcp | head -1 | awk -F: '{print $NF}')"
246
+ bounded docker port "$container_name" 5432/tcp > "$run_dir/postgres.port"
247
+ db_port="$(head -1 "$run_dir/postgres.port" | awk -F: '{print $NF}')"
143
248
  test -n "$db_port"
144
249
 
145
250
  boot_state=""
146
251
  for _ in $(seq 1 "$BOOT_ATTEMPTS"); do
147
- if boot_state="$(bounded adb -s "$ANDROID_EMULATOR_SERIAL" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')"; then
252
+ if bounded adb -s "$ANDROID_EMULATOR_SERIAL" shell getprop sys.boot_completed > "$run_dir/boot" 2>/dev/null; then
253
+ boot_state="$(tr -d '\r' < "$run_dir/boot")"
148
254
  if test "$boot_state" = 1; then break; fi
149
255
  else
150
256
  probe_status=$?
@@ -173,4 +279,4 @@ export "$DB_URL_VAR=postgresql://postgres:postgres@127.0.0.1:$db_port/postgres"
173
279
  export "$DB_NAME_VAR=${DB_NAME_PREFIX}$(date +%s)_$$"
174
280
  db_ready=1
175
281
 
176
- "${journey_cmd[@]}"
282
+ managed "$JOURNEY_SECONDS" "${journey_cmd[@]}"
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: app-debug
3
3
  description: "Diagnose runtime failures in deployed Cloud Run services — 5xx/422 errors, tracebacks, Next.js SSR/hydration or Server Action failures, DB/Secret Manager connection errors, cold-start timeouts, container OOM. NOT for build or deploy failures (cloud-debug)."
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # App Debug
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: better-auth
3
3
  description: "Add or debug Better Auth for Next.js App Router: login, sessions, protected routes, middleware, OAuth (including Feishu/Lark), cookies, Prisma, and Auth.js migration."
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # Better Auth for Next.js
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: data-catalog
3
3
  description: "Column definitions for warehouse tables, written inside the Spark/PySpark or SQL script that builds each table (CATALOG_TABLE / CATALOG_FIELDS, or a `-- @field` comment block), with a generated markdown catalog in docs/catalog/ and a CI check that fails a PR whose catalog is stale. Use when writing or changing a table script that adds, renames, removes, or changes the meaning of an output column or feature; when asked what a warehouse column or feature means; to set a repo up ('init the data catalog', 'generate the data dictionary', '字段字典', 'add catalog CI'); or to audit existing SQL or Spark scripts for undocumented columns. NOT for implementing or tuning the Spark job itself (pyspark), DAG wiring (airflow), or general workflow YAML (github-actions)."
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # Data catalog
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: data-quality
3
3
  description: "Check a published warehouse table's data against its data-catalog definitions with read-only SELECTs: columns never filled or stuck at one value, counts below zero, ratios outside 0–1, declared values that never appear and undeclared values that do. Then classify each finding as a wrong definition, wrong code, or wrong data. Use when asked whether a table's data is right, to profile or sanity-check a dwd/ads table, to find dead or constant columns, to check a column's values against its documented list, after a pipeline change ships, or when a data-catalog definition and the data might disagree. NOT for validating a Spark change before it ships (pyspark canary and reconciliation), writing definitions (data-catalog), or monitoring dashboards."
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # Data quality
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: ios-foundation
3
3
  description: "Set up and prove an Expo / React Native native iOS workspace from a clean checkout to a manual Login smoke on an owned iOS Simulator: isolated worktree and private caches, Xcode/runtime/CocoaPods preflight, frozen install with `pod install --deployment`, platform-scoped prebuild, an ad-hoc-signed Debug simulator build, a private simulator by exact UDID, Metro on a free port, a disposable PostgreSQL backend with owned cleanup, and the evidence record (setup proof only; feature work reports the smoke result). Use for 'set up iOS', 'build the iOS app', 'run the app on the iOS simulator', 'add iOS to the React Native app', 'prove the iOS build', or when a pod install, xcodebuild, simulator boot, Metro connection or Keychain session fails. NOT for Android (android-foundation), signing, TestFlight or App Store release, or general workflow YAML (github-actions)."
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # iOS foundation
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: monorepo
3
3
  description: Turborepo architecture for shared packages, pnpm workspaces, DAL boundaries, and pipelines.
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # Turborepo Monorepo Architecture
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: nextjs-fullstack
3
3
  description: "Build or debug Next.js App Router features with React 19 — pages/layouts/route handlers, Server/Client Components, Server Actions, forms, middleware, DAL, strict TypeScript, Zod — plus our conventions: nuqs URL state, SWR cache, Skeleton/Progress + Sonner feedback, drag-and-drop upload, the portal app shell, list pages as filter/sort/paginate tables. shadcn component mechanics: see the shadcn skill."
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # Next.js 16 Fullstack Development
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: prisma-setup
3
3
  description: Use when adding or debugging Prisma with PostgreSQL, Next.js, or Turborepo, including schema.prisma, prisma.config.ts, client generation, migrations, seeds, relations, adapters, and DAL/database-layer setup. Triggers on phrases like "Prisma schema", "prisma migrate", "schema.prisma", "seed the database", "PrismaClient error", "relation issue", or "database layer".
4
- release-version: 0.43.0
4
+ release-version: 0.44.0
5
5
  ---
6
6
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
7
7
  # Prisma v7 Setup Guide
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));
@@ -12,7 +12,7 @@ description: >
12
12
  Connect, spark-submit, Hudi commits, backfills, validate-only canaries,
13
13
  cluster reconciliation, or Spark event-log profiling — including warehouse
14
14
  job timeouts, empty Hudi writes, or EMR/Dataproc performance regressions.
15
- release-version: 0.43.0
15
+ release-version: 0.44.0
16
16
  ---
17
17
  **Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
18
18
  # PySpark
@@ -2,7 +2,7 @@
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, join, resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const DAY_MS = 24 * 60 * 60 * 1000;
@@ -46,6 +46,8 @@ function writeCache(path, value) {
46
46
 
47
47
  function main(now = Date.now()) {
48
48
  if (process.env.ONEABOVEIO_NO_UPDATE_CHECK) return;
49
+ const bundle = readJson(join(resolve(here, '../../..'), 'package.json'));
50
+ if (bundle.name === '@1aboveio/skills' && bundle.nativeCodex?.schemaVersion === 1) return;
49
51
  const skill = readFileSync(join(here, 'SKILL.md'), 'utf8');
50
52
  const name = frontmatterValue(skill, 'name');
51
53
  const localVersion = stableVersion(frontmatterValue(skill, 'release-version'));