@1aboveio/skills 1.0.14 → 1.0.15
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/.codex-plugin/plugin.json +1 -1
- package/.codex-plugin/resources.json +147 -147
- package/package.json +4 -4
- package/skills/app-dev/airflow/SKILL.md +1 -1
- package/skills/app-dev/android-development/SKILL.md +3 -2
- package/skills/app-dev/android-development/references/diagnosis.md +5 -0
- package/skills/app-dev/android-development/references/feature-work.md +15 -0
- package/skills/app-dev/android-development/references/init.md +26 -4
- package/skills/app-dev/android-development/scripts/init.mjs +105 -8
- package/skills/app-dev/app-debug/SKILL.md +1 -1
- package/skills/app-dev/better-auth/SKILL.md +1 -1
- package/skills/app-dev/data-catalog/SKILL.md +53 -16
- package/skills/app-dev/data-catalog/scripts/persist-conventions-core.mjs +231 -21
- package/skills/app-dev/data-catalog/scripts/persist-conventions.mjs +12 -1
- package/skills/app-dev/data-quality/SKILL.md +1 -1
- package/skills/app-dev/ios-foundation/SKILL.md +1 -1
- package/skills/app-dev/monorepo/SKILL.md +1 -1
- package/skills/app-dev/nextjs-fullstack/SKILL.md +1 -1
- package/skills/app-dev/prisma-setup/SKILL.md +1 -1
- package/skills/app-dev/pyspark/SKILL.md +1 -1
- package/skills/app-dev/python-backend/SKILL.md +1 -1
- package/skills/app-dev/shadcn/SKILL.md +1 -1
- package/skills/app-dev/zod-v4/SKILL.md +1 -1
- package/skills/cicd/cloud-build/SKILL.md +1 -1
- package/skills/cicd/cloud-debug/SKILL.md +1 -1
- package/skills/cicd/cloud-deploy/SKILL.md +1 -1
- package/skills/cicd/docker/SKILL.md +1 -1
- package/skills/cicd/github-actions/SKILL.md +1 -1
- package/skills/cicd/github-flow/SKILL.md +10 -1
- package/skills/cicd/github-flow/scripts/persist-conventions-core.mjs +231 -21
- package/skills/cicd/github-flow/scripts/persist-conventions.mjs +18 -1
- package/skills/cicd/google-cloud/SKILL.md +1 -1
- package/skills/cicd/mergify/SKILL.md +1 -1
- package/skills/cicd/podman/SKILL.md +1 -1
- package/skills/content/article-review/SKILL.md +1 -1
- package/skills/content/article-to-image/SKILL.md +1 -1
- package/skills/content/flowchart-svg/SKILL.md +1 -1
- package/skills/content/image-gen/SKILL.md +1 -1
- package/skills/content/mermaid/SKILL.md +1 -1
- package/skills/content/wechat-article-writer/SKILL.md +1 -1
- package/skills/content/wechat-publisher/SKILL.md +1 -1
- package/skills/content/wechat-search/SKILL.md +1 -1
- package/skills/content/xai-search/SKILL.md +1 -1
- package/skills/core/distill-writing/SKILL.md +7 -1
- package/skills/core/doc-to-md/SKILL.md +1 -1
- package/skills/core/editorial-review/SKILL.md +1 -1
- package/skills/core/house-style/SKILL.md +1 -1
- package/skills/core/house-style/references/persistence.md +8 -3
- package/skills/core/house-style/scripts/init-guidance.mjs +1 -1
- package/skills/core/plain-language/SKILL.md +1 -1
- package/skills/core/polish-cn/SKILL.md +1 -1
- package/skills/core/reg-parser/SKILL.md +1 -1
- package/skills/core/terminology/SKILL.md +1 -1
- package/skills/core/terminology/references/init.md +11 -0
- package/skills/core/write-doc/SKILL.md +1 -1
- package/skills/core/write-report/SKILL.md +1 -1
- package/skills/engineering/better-review/SKILL.md +1 -1
- package/skills/engineering/e2e-test/SKILL.md +1 -1
- package/skills/engineering/engineering/SKILL.md +19 -4
- package/skills/engineering/engineering/references/init-scope.md +5 -2
- package/skills/engineering/engineering/references/scope-management.md +4 -2
- package/skills/engineering/engineering/scripts/init.mjs +34 -9
- package/skills/engineering/engineering/scripts/persist-conventions-core.mjs +231 -21
- package/skills/engineering/engineering/scripts/persist-conventions.mjs +48 -21
- package/skills/engineering/engineering-runtime/SKILL.md +1 -1
- package/skills/engineering/engineering-runtime/coherence/workflow.json +13 -13
- package/skills/engineering/ensure-coverage/SKILL.md +1 -1
- package/skills/engineering/golden-path/SKILL.md +1 -1
- package/skills/engineering/harness-runtime/SKILL.md +1 -1
- package/skills/engineering/resolve-issues/SKILL.md +1 -1
- package/skills/engineering/resolve-issues/references/review.md +27 -4
- package/skills/engineering/resolve-release/SKILL.md +1 -1
- package/skills/engineering/rush-issues/SKILL.md +1 -1
- package/skills/engineering/rush-release/SKILL.md +1 -1
- package/skills/engineering/test-quality/SKILL.md +3 -1
- package/skills/engineering/test-quality/scripts/persist-conventions-core.mjs +231 -21
- package/skills/engineering/test-quality/scripts/persist-conventions.mjs +13 -1
- package/skills/risk-compliance/compliance-audit/SKILL.md +1 -1
- package/skills/risk-compliance/contract-compare/SKILL.md +1 -1
- package/skills/risk-compliance/contract-review/SKILL.md +1 -1
- package/skills/risk-compliance/doc-authenticity/SKILL.md +1 -1
- package/skills/risk-compliance/fraud-detection/SKILL.md +1 -1
- package/skills/risk-compliance/payment-analysis/SKILL.md +1 -1
- package/skills/risk-compliance/portfolio-payment-analysis/SKILL.md +1 -1
- package/skills/risk-compliance/similar-domain/SKILL.md +1 -1
- package/skills/risk-compliance/tld-detection/SKILL.md +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1aboveio/skills",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Every 1aboveio skill package in one: install once, then choose which packages Pi loads with npx @1aboveio/skills select.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"nativeCodex": {
|
|
29
29
|
"schemaVersion": 1,
|
|
30
30
|
"metadataPath": ".codex-plugin/resources.json",
|
|
31
|
-
"metadataDigest": "
|
|
32
|
-
"releaseIdentity": "
|
|
31
|
+
"metadataDigest": "2bdb58dba1de073baf79efe2c5118ad75c996710344a3cde581976921c1b23ec",
|
|
32
|
+
"releaseIdentity": "a8975fa459ebba2a3e2661d861bdb9d43c072c1b01adaf41def9a93523782800"
|
|
33
33
|
},
|
|
34
34
|
"pi": {
|
|
35
35
|
"skills": [
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
]
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
|
-
"digest": "
|
|
263
|
+
"digest": "6ad0dafe4a400162776b1bf6d7c9e5ab31bf37a86d18b035fcadc4c11d06f799"
|
|
264
264
|
},
|
|
265
265
|
"publishConfig": {
|
|
266
266
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: airflow
|
|
3
3
|
description: Airflow DAG architecture and conventions. Use when designing, writing, reviewing, testing, or debugging Airflow DAGs and tasks, including TaskGroups, data intervals, timezone-aware date parameters, CLI validation, environment-based scheduling, and pytest integrity tests.
|
|
4
4
|
user-invocable: true
|
|
5
|
-
release-version: 0.
|
|
5
|
+
release-version: 0.47.0
|
|
6
6
|
---
|
|
7
7
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
8
8
|
# Airflow DAG Development Patterns
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: android-development
|
|
3
3
|
description: "Prove and debug Expo / React Native apps on an owned Android emulator. Use for Android startup/rendering failures, Metro or ADB problems, UiAutomator/harness failures, APK builds, SDK/NDK/JDK workspace setup, native journey validation, and choosing Kotlin/Compose versus React Native for Android flows. Reproduce failed Android CI checkpoints off CI before fixing and redispatching. Standalone invocation offers Project or Session; init persists repo conventions. NOT for workflow YAML, CI speed or runners (github-actions), browser tests (e2e-test), iOS (ios-foundation), plain Jest tests, or signing/store release."
|
|
4
|
-
release-version: 0.
|
|
4
|
+
release-version: 0.47.0
|
|
5
5
|
---
|
|
6
6
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
7
7
|
# Android development
|
|
@@ -18,7 +18,8 @@ Project rules and required CI remain binding; this skill does not add acceptance
|
|
|
18
18
|
leaves files unchanged. Do not offer global persistence.
|
|
19
19
|
- **Project**, `/android-development init`, or an explicit request to save repo conventions:
|
|
20
20
|
follow [initialization](references/init.md). Preview, then apply the authorized missing
|
|
21
|
-
`CONTRIBUTING.md` section and `AGENTS.md`
|
|
21
|
+
`CONTRIBUTING.md` section and `AGENTS.md` task-entry loader and guide pointer. Check
|
|
22
|
+
the skill loader separately from an existing guide link. No second approval is needed unless
|
|
22
23
|
existing policy conflicts. Initialization is not a policy refresh or delivery permission.
|
|
23
24
|
- **Session:** apply this workflow without writing guidance or agent settings. Retain the
|
|
24
25
|
choice through reload/compaction in this session; a new session makes its own choice.
|
|
@@ -103,6 +103,11 @@ worker's "running" status does not impose a timeout or demonstrate progress. The
|
|
|
103
103
|
whole journey. Set a positive value for unattended runs; its backward-compatible
|
|
104
104
|
zero default disables that deadline. Allow time for the owner to finish cleanup.
|
|
105
105
|
|
|
106
|
+
Use the harness's background-task mechanism when a journey can exceed the foreground
|
|
107
|
+
command limit. Budget for the selected journey and owned cleanup; feedback-time targets
|
|
108
|
+
are not kill deadlines. Continue independent work and inspect the terminal result when
|
|
109
|
+
notified, rather than waiting or polling in the foreground. Do not add another watcher.
|
|
110
|
+
|
|
106
111
|
For a hung test, identify the actual outstanding command and last completed assertion.
|
|
107
112
|
If the test waits for a child to exit, check whether its input actually requires exit.
|
|
108
113
|
Reduce that question to a bounded host test before launching another emulator.
|
|
@@ -30,6 +30,21 @@ Native/build-input changes invalidate that reuse; unknown compatibility calls fo
|
|
|
30
30
|
rebuild, not an assertion that the old APK is current. Do not run `expo prebuild` routinely
|
|
31
31
|
against tracked native projects.
|
|
32
32
|
|
|
33
|
+
### Check journey admission before reserving devices
|
|
34
|
+
|
|
35
|
+
Before an expensive native journey, verify the exact selected case and supported arguments
|
|
36
|
+
against the existing runner, required installation/resource owners, effective test flags,
|
|
37
|
+
and device settings. Use existing help, parser tests or preflight commands when available;
|
|
38
|
+
do not invent a selector or build another preflight framework. Missing admission support
|
|
39
|
+
is a harness limitation to resolve, not a reason to allocate devices and discover it later.
|
|
40
|
+
Continue independent source tests while device prerequisites are checked.
|
|
41
|
+
|
|
42
|
+
Apply lifecycle-changing display size, density and other required presentation settings
|
|
43
|
+
before app launch when the journey relies on retaining that Activity or observation scope.
|
|
44
|
+
Read back the effective settings through the existing owner. A later setting change may
|
|
45
|
+
recreate the Activity; do not hide scope retirement with registration retries or relaxed
|
|
46
|
+
identity checks. Keep this check scoped to the selected case, not every possible device cell.
|
|
47
|
+
|
|
33
48
|
### Verify command expansion
|
|
34
49
|
|
|
35
50
|
Before adopting a native fast path, trace its package script, wrapper, Gradle tasks and
|
|
@@ -14,8 +14,9 @@ node {baseDir}/scripts/init.mjs [--repo-root <dir>] [--write]
|
|
|
14
14
|
- `--write` applies the plan. `--repo-root` selects the project; without it the nearest Git root
|
|
15
15
|
from the current directory is used, falling back to the current directory when there is none.
|
|
16
16
|
- `--help` prints the usage line.
|
|
17
|
-
- An unknown argument, an unresolvable root, a malformed marker
|
|
18
|
-
non-zero with a message and no
|
|
17
|
+
- An unknown argument, an unresolvable root, a malformed marker, an unsafe target or a file that
|
|
18
|
+
ends inside an unclosed fenced code block or HTML comment exits non-zero with a message and no
|
|
19
|
+
writes, in preview and with `--write` alike.
|
|
19
20
|
|
|
20
21
|
## Files and ownership
|
|
21
22
|
|
|
@@ -27,19 +28,35 @@ to a newly created Android section; report unresolved commands instead of guessi
|
|
|
27
28
|
| File | Write |
|
|
28
29
|
| --- | --- |
|
|
29
30
|
| `CONTRIBUTING.md` | The `## Android development` section, wrapped in `<!-- conventions:android:start -->` / `<!-- conventions:android:end -->`, with `references/android-conventions.md` as its body. |
|
|
30
|
-
| `AGENTS.md` |
|
|
31
|
+
| `AGENTS.md` | An `Android task entry` skill-loading block between `conventions:android-task-entry` markers, plus a pointer to the selected `CONTRIBUTING.md` when missing. Check these independently: a contributor-guide link alone is not a skill loader. |
|
|
31
32
|
|
|
32
33
|
Each file is created only when it is absent. The helper never edits `CLAUDE.md`, never writes into
|
|
33
34
|
a parent project, a home directory or global agent configuration, and never reaches outside the
|
|
34
35
|
selected root.
|
|
35
36
|
|
|
36
37
|
After applying authorized additions, verify that each existing supported agent entrypoint
|
|
37
|
-
reaches the
|
|
38
|
+
reaches both the skill task-entry instruction and the Android contributor-guide section,
|
|
39
|
+
directly or through its instruction chain. A direct link to `CONTRIBUTING.md` does not
|
|
40
|
+
establish that the entrypoint loads the skill rule in `AGENTS.md`. The helper configures
|
|
38
41
|
`AGENTS.md`; it does not certify an independent `CLAUDE.md` loader. Preserve existing chains
|
|
39
42
|
and do not edit that entrypoint under this init permission. If one does not reach the guide,
|
|
40
43
|
report the files configured and the unresolved loading path as partial setup. Obtain separate
|
|
41
44
|
authorization for any additional loader edit instead of silently claiming complete setup.
|
|
42
45
|
|
|
46
|
+
The task-entry block requires reading and applying the installed `android-development`
|
|
47
|
+
skill before Android-specific commands, during issue-unit preflight, in delegated Android
|
|
48
|
+
workers, and again after compaction when its rules are lost. Keep commands and validation
|
|
49
|
+
policy in `CONTRIBUTING.md`, not this loader. An existing direct read/load-before rule or
|
|
50
|
+
managed block is preserved. A managed block is preserved only while it still holds an active
|
|
51
|
+
loader: an empty block, or one whose only loader is commented out or written as a code example,
|
|
52
|
+
is refused rather than counted as configured. A direct `do not load`-style rule that conflicts
|
|
53
|
+
with the loader is refused too, wherever it sits in the file. Fenced code, indented code, HTML
|
|
54
|
+
comments and inline code are documentation, so an example never counts as an active loader or as
|
|
55
|
+
a conflict. An unrecognized `Android task entry` section requires manual reconciliation rather
|
|
56
|
+
than a competing block. Inspect existing rules for conflicts before applying the helper; it
|
|
57
|
+
cannot interpret every natural-language policy. This missing-loader addition is part of explicit
|
|
58
|
+
init even in previously initialized repos, not an automatic update.
|
|
59
|
+
|
|
43
60
|
## Resolve the repo command map
|
|
44
61
|
|
|
45
62
|
The initializer, not the deterministic writer, inspects existing scripts and guidance.
|
|
@@ -81,6 +98,11 @@ Existing guidance wins over the template:
|
|
|
81
98
|
- Refuse a mutation of a multiply hard-linked file or of an alias to the protected
|
|
82
99
|
`CLAUDE.md` entrypoint. This includes a shared AGENTS/CLAUDE target: preserve it and
|
|
83
100
|
report the boundary rather than silently granting a new write permission.
|
|
101
|
+
- Refuse an addition to a file that ends inside an unclosed fenced code block or HTML comment.
|
|
102
|
+
Appended guidance would land inside that construct, be inactive, and be appended again on
|
|
103
|
+
every run. The helper never closes it for you: preserve the manual text, repair the fence or
|
|
104
|
+
comment, and rerun. A file that needs no addition is reported unchanged, so an
|
|
105
|
+
already-configured project behind such a construct is not blocked.
|
|
84
106
|
- An existing pointer is reused only when its link resolves to the selected `CONTRIBUTING.md`,
|
|
85
107
|
and a new pointer is written relative to the real location of `AGENTS.md`. A link to some other
|
|
86
108
|
file, such as a nested package guide, does not count as this project's loader.
|
|
@@ -7,6 +7,14 @@ import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
|
7
7
|
|
|
8
8
|
const sectionTitle = 'Android development'
|
|
9
9
|
const sectionId = 'android'
|
|
10
|
+
const taskEntryTitle = 'Android task entry'
|
|
11
|
+
const taskEntryBody = `## ${taskEntryTitle}
|
|
12
|
+
|
|
13
|
+
For Android implementation, runtime debugging, native builds, or device validation,
|
|
14
|
+
read and apply the installed \`android-development\` skill before choosing
|
|
15
|
+
Android-specific commands. In issue workflows, load it during unit preflight.
|
|
16
|
+
Delegated Android workers must load it too. After compaction, reload it if its
|
|
17
|
+
instructions are no longer in context.`
|
|
10
18
|
const usage = 'node init.mjs [--repo-root <dir>] [--write]'
|
|
11
19
|
|
|
12
20
|
function parseArgs(argv) {
|
|
@@ -174,7 +182,7 @@ function stripHtmlComments(line, depth = 0) {
|
|
|
174
182
|
|
|
175
183
|
// Markdown-aware view: inactive lines are fenced code, indented code or HTML comments.
|
|
176
184
|
// Inline code and HTML comments are blanked from active text so examples never count.
|
|
177
|
-
function
|
|
185
|
+
function scanMarkdown(current) {
|
|
178
186
|
const lines = []
|
|
179
187
|
let fence = null
|
|
180
188
|
let commentDepth = 0
|
|
@@ -217,10 +225,63 @@ function markdownView(current) {
|
|
|
217
225
|
previousBlank = blank
|
|
218
226
|
lines.push({ raw: line, text: active ? text : '', active, comments })
|
|
219
227
|
}
|
|
220
|
-
|
|
228
|
+
// An open fence or comment at the end of the file would swallow anything appended after it.
|
|
229
|
+
return { lines, fence, commentDepth }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function markdownView(current) {
|
|
233
|
+
return scanMarkdown(current).lines
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// End of the paragraph starting at `start`; a span never pairs across a blank line.
|
|
237
|
+
function paragraphEnd(text, start) {
|
|
238
|
+
const blank = /\n[ \t]*\n/g
|
|
239
|
+
blank.lastIndex = start
|
|
240
|
+
const match = blank.exec(text)
|
|
241
|
+
return match ? match.index : text.length
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Marks inline code spans so a documented example is never read as a project rule.
|
|
245
|
+
// Runs of equal length pair up inside one paragraph; an unmatched run is literal text, so it
|
|
246
|
+
// never consumes a later rule. The rule text itself stays readable, only its span is marked.
|
|
247
|
+
function inlineCodeMask(text) {
|
|
248
|
+
const mask = new Uint8Array(text.length)
|
|
249
|
+
const runs = [...text.matchAll(/`+/g)]
|
|
250
|
+
let index = 0
|
|
251
|
+
while (index < runs.length) {
|
|
252
|
+
const opening = runs[index]
|
|
253
|
+
const limit = paragraphEnd(text, opening.index)
|
|
254
|
+
let closing = index + 1
|
|
255
|
+
while (closing < runs.length && runs[closing].index < limit
|
|
256
|
+
&& runs[closing][0].length !== opening[0].length) closing++
|
|
257
|
+
if (closing === runs.length || runs[closing].index >= limit) {
|
|
258
|
+
index += 1
|
|
259
|
+
continue
|
|
260
|
+
}
|
|
261
|
+
mask.fill(1, opening.index, runs[closing].index + runs[closing][0].length)
|
|
262
|
+
index = closing + 1
|
|
263
|
+
}
|
|
264
|
+
return mask
|
|
221
265
|
}
|
|
222
266
|
|
|
223
|
-
|
|
267
|
+
// Only a match that starts outside inline code is an instruction rather than an example.
|
|
268
|
+
// The rule itself keeps its text, because the skill name is normally written as code.
|
|
269
|
+
function matchesOutsideInlineCode(text, pattern) {
|
|
270
|
+
const flags = pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`
|
|
271
|
+
const global = new RegExp(pattern.source, flags)
|
|
272
|
+
const mask = inlineCodeMask(text)
|
|
273
|
+
for (const match of text.matchAll(global)) {
|
|
274
|
+
if (!mask[match.index]) return true
|
|
275
|
+
}
|
|
276
|
+
return false
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function append(current, body, name) {
|
|
280
|
+
const { fence, commentDepth } = scanMarkdown(current)
|
|
281
|
+
if (fence || commentDepth) {
|
|
282
|
+
const construct = fence ? 'an unclosed fenced code block' : 'an unclosed HTML comment'
|
|
283
|
+
throw new Error(`${name} ends inside ${construct}; appended Android guidance would be inactive and appended again on every run. Close it and rerun init; nothing was changed`)
|
|
284
|
+
}
|
|
224
285
|
const separator = current.endsWith('\n\n') ? '' : current.endsWith('\n') ? '\n' : '\n\n'
|
|
225
286
|
return `${current}${separator}${body.trim()}\n`
|
|
226
287
|
}
|
|
@@ -258,7 +319,7 @@ function countMarkers(lines, start, end) {
|
|
|
258
319
|
return { starts, ends }
|
|
259
320
|
}
|
|
260
321
|
|
|
261
|
-
function preserveOrAdd(current, title, id, body) {
|
|
322
|
+
function preserveOrAdd(current, name, title, id, body) {
|
|
262
323
|
const start = `<!-- conventions:${id}:start -->`
|
|
263
324
|
const end = `<!-- conventions:${id}:end -->`
|
|
264
325
|
const { starts, ends } = countMarkers(markdownView(current), start, end)
|
|
@@ -266,7 +327,7 @@ function preserveOrAdd(current, title, id, body) {
|
|
|
266
327
|
throw new Error(`malformed ${title} section markers; preserve and repair existing guidance first`)
|
|
267
328
|
}
|
|
268
329
|
if (starts.length || hasHeading(current, title)) return current
|
|
269
|
-
return append(current, `${start}\n${body}\n${end}
|
|
330
|
+
return append(current, `${start}\n${body}\n${end}`, name)
|
|
270
331
|
}
|
|
271
332
|
|
|
272
333
|
function linkFrom(from, to) {
|
|
@@ -295,6 +356,42 @@ function hasLoader(current, from, to) {
|
|
|
295
356
|
return false
|
|
296
357
|
}
|
|
297
358
|
|
|
359
|
+
function addTaskEntry(current, name) {
|
|
360
|
+
const start = '<!-- conventions:android-task-entry:start -->'
|
|
361
|
+
const end = '<!-- conventions:android-task-entry:end -->'
|
|
362
|
+
const lines = markdownView(current)
|
|
363
|
+
const { starts, ends } = countMarkers(lines, start, end)
|
|
364
|
+
if (starts.length !== ends.length || starts.length > 1 || (starts.length && starts[0] > ends[0])) {
|
|
365
|
+
throw new Error('malformed Android task entry markers; preserve and repair existing guidance first')
|
|
366
|
+
}
|
|
367
|
+
// Only active prose can hold a rule: fenced code, indented code, HTML comments, inline code
|
|
368
|
+
// and fenced examples are documentation. A rule keeps its own inline code, so the skill name
|
|
369
|
+
// written as `android-development` is still matched by its position outside a code span.
|
|
370
|
+
const prose = lines.map(line => line.active && line.text.trim()
|
|
371
|
+
? stripHtmlComments(line.raw).text : '')
|
|
372
|
+
const active = prose.join('\n')
|
|
373
|
+
// Recognize an existing direct loader, not a mere skill mention or guide link.
|
|
374
|
+
const loader = /^[ \t]*(?:(?:[-+*]|\d+[.)])\s+)?(?:read|load)\s+(?:and\s+apply\s+)?(?:the\s+)?(?:installed\s+)?`?android-development`?\s+skill\s+before\b/im
|
|
375
|
+
const negation = /\b(?:do not|don't|never|must not)\s+(?:automatically\s+)?(?:read|load|apply|use|follow)\b[^.]{0,120}\bandroid-development\b/i
|
|
376
|
+
if (matchesOutsideInlineCode(active, negation)) {
|
|
377
|
+
throw new Error('existing Android skill-loading rule conflicts with task entry; nothing was changed')
|
|
378
|
+
}
|
|
379
|
+
if (starts.length) {
|
|
380
|
+
const from = lines.findIndex(line => line.comments.includes(start))
|
|
381
|
+
const to = lines.findIndex(line => line.comments.includes(end))
|
|
382
|
+
const body = prose.slice(from + 1, to).join('\n')
|
|
383
|
+
if (!matchesOutsideInlineCode(body, loader)) {
|
|
384
|
+
throw new Error('preserved Android task entry has no active loader; nothing was changed')
|
|
385
|
+
}
|
|
386
|
+
return current
|
|
387
|
+
}
|
|
388
|
+
if (matchesOutsideInlineCode(active, loader)) return current
|
|
389
|
+
if (hasHeading(current, taskEntryTitle)) {
|
|
390
|
+
throw new Error('existing Android task entry needs manual reconciliation; nothing was changed')
|
|
391
|
+
}
|
|
392
|
+
return append(current, `${start}\n${taskEntryBody}\n${end}`, name)
|
|
393
|
+
}
|
|
394
|
+
|
|
298
395
|
function planInitialization(root) {
|
|
299
396
|
const claude = inspectClaude(root)
|
|
300
397
|
const [agents, contributing] = ['AGENTS.md', 'CONTRIBUTING.md'].map(name => resolveTarget(root, name))
|
|
@@ -316,13 +413,13 @@ function planInitialization(root) {
|
|
|
316
413
|
const agentsEntry = readGuidance(agents)
|
|
317
414
|
const contributingEntry = readGuidance(contributing)
|
|
318
415
|
|
|
319
|
-
let agentText = agentsEntry.current ?? '# Agent instructions\n'
|
|
416
|
+
let agentText = addTaskEntry(agentsEntry.current ?? '# Agent instructions\n', agentsEntry.name)
|
|
320
417
|
if (!hasLoader(agentText, agentsEntry, contributingEntry)) {
|
|
321
418
|
const heading = hasHeading(agentText, sectionTitle) ? '' : `## ${sectionTitle}\n\n`
|
|
322
|
-
agentText = append(agentText, `${heading}Follow [CONTRIBUTING.md](${linkFrom(agentsEntry, contributingEntry)}) for this project's Android validation ladder, device proof and required gates
|
|
419
|
+
agentText = append(agentText, `${heading}Follow [CONTRIBUTING.md](${linkFrom(agentsEntry, contributingEntry)}) for this project's Android validation ladder, device proof and required gates.`, agentsEntry.name)
|
|
323
420
|
}
|
|
324
421
|
|
|
325
|
-
const contributingText = preserveOrAdd(contributingEntry.current ?? '# Contributing\n', sectionTitle, sectionId, sectionBody())
|
|
422
|
+
const contributingText = preserveOrAdd(contributingEntry.current ?? '# Contributing\n', contributingEntry.name, sectionTitle, sectionId, sectionBody())
|
|
326
423
|
|
|
327
424
|
const plan = [
|
|
328
425
|
{ ...agentsEntry, next: agentText },
|
|
@@ -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.
|
|
4
|
+
release-version: 0.47.0
|
|
5
5
|
---
|
|
6
6
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
7
7
|
# App Debug
|
|
@@ -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.
|
|
4
|
+
release-version: 0.47.0
|
|
5
5
|
---
|
|
6
6
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
7
7
|
# Better Auth for Next.js
|
|
@@ -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.
|
|
4
|
+
release-version: 0.47.0
|
|
5
5
|
---
|
|
6
6
|
**Updates:** Once/session run `node <skill-base-dir>/release-check.mjs`.
|
|
7
7
|
# Data catalog
|
|
@@ -12,23 +12,49 @@ and CI fails a pull request when the pages and the scripts disagree.
|
|
|
12
12
|
|
|
13
13
|
## First use in a repo
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
No `data-catalog.json` means the repo is not set up. That is a fact about the repo,
|
|
16
|
+
not permission to write to it, and the `## Data catalog task entry` rule that loaded
|
|
17
|
+
this skill is not one either: an audit, a review, a column question or a table-script
|
|
18
|
+
change is the task, and it is done from the sources the repo already has.
|
|
19
|
+
|
|
20
|
+
- **Read what exists.** `docs/catalog/<table>.md` when the repo has pages, else the
|
|
21
|
+
script's `CATALOG_TABLE`/`CATALOG_FIELDS`, else its `-- @table`/`-- @field` block,
|
|
22
|
+
else the SQL or DataFrame code. A definition in the script answers the question;
|
|
23
|
+
never hand-write the missing page.
|
|
24
|
+
- **Audit read-only.** `python3 <skill-base-dir>/scripts/data_catalog.py audit
|
|
25
|
+
'jobs/**/*.py' 'sql/**/*.sql'` needs no config and writes nothing; it exits 2 only
|
|
26
|
+
with neither a config nor globs.
|
|
27
|
+
- **A check you cannot run stays pending.** `generate`, `generate --check` and `drift`
|
|
28
|
+
exit 2 without `data-catalog.json`. Report them pending — "the catalog is not set up
|
|
29
|
+
here" — not "no findings", "green" or "CI passes", and do not run `init --write` to
|
|
30
|
+
make them runnable: running them is the task, making them runnable is setup.
|
|
31
|
+
- **Offer setup once.** One short line: `init --write` with the `--scripts` globs and
|
|
32
|
+
`--languages` you would use, plus `persist-conventions.mjs --write` for the
|
|
33
|
+
conventions section, the `AGENTS.md` pointer and the task-entry rule. Say nothing was
|
|
34
|
+
written, keep working, once per session per repo. Not an approval checkpoint.
|
|
35
|
+
- **Setting up is an explicit request.** "init the data catalog", "generate the data
|
|
36
|
+
dictionary", "字段字典", "add catalog CI", "set up the catalog here" — that
|
|
37
|
+
authorizes these writes in that repo only. An automatic review, the loader rule, a
|
|
38
|
+
handoff from another skill, or having read this section do not.
|
|
39
|
+
|
|
40
|
+
With that request, setup is:
|
|
19
41
|
|
|
20
42
|
1. `python3 <skill-base-dir>/scripts/data_catalog.py audit '<globs>'` to find the
|
|
21
43
|
table scripts; choose `--scripts` globs that cover them and nothing else.
|
|
22
44
|
2. Pick `--languages` from the repo's existing docs (Chinese docs: `zh,en`;
|
|
23
45
|
otherwise `en`). Run `init` with them and `--write` ([Init](#init)).
|
|
24
46
|
3. `node <skill-base-dir>/scripts/persist-conventions.mjs --repo-root <repo> --write`
|
|
25
|
-
writes the `## Data catalog conventions` section of `CONTRIBUTING.md
|
|
26
|
-
`AGENTS.md` at it
|
|
47
|
+
writes the `## Data catalog conventions` section of `CONTRIBUTING.md`, points
|
|
48
|
+
`AGENTS.md` at it, and adds the `## Data catalog task entry` rule that loads this
|
|
49
|
+
skill for column or table-script work. It is the only writer of those files and
|
|
50
|
+
writes only with its own `--write`; an ordinary catalog task never runs it.
|
|
27
51
|
4. Then do the task. In the reply, list what setup added, and say the Data catalog
|
|
28
52
|
check runs on PRs but is not required.
|
|
29
53
|
|
|
30
|
-
|
|
31
|
-
|
|
54
|
+
Outside a git repo there is nothing to set up: say so. Never document tables during
|
|
55
|
+
setup unless the task asks for it. Repeating setup with the same inputs leaves the
|
|
56
|
+
configured files unchanged; report a missing input or a conflicting rule instead of
|
|
57
|
+
claiming success.
|
|
32
58
|
|
|
33
59
|
## Find your task
|
|
34
60
|
|
|
@@ -36,7 +62,7 @@ Never document tables during setup unless the task asks for it.
|
|
|
36
62
|
|---|---|
|
|
37
63
|
| Writing or changing a table script | [While coding](#while-coding), then [references/field-definitions.md](references/field-definitions.md) |
|
|
38
64
|
| "What does column X mean?" | Read `docs/catalog/<table>.md`; with no page, read the script's `CATALOG_FIELDS`, then its SQL |
|
|
39
|
-
| The repo has no `data-catalog.json` | [First use in a repo](#first-use-in-a-repo) |
|
|
65
|
+
| The repo has no `data-catalog.json` | Do the task read-only, then offer setup once ([First use in a repo](#first-use-in-a-repo)) |
|
|
40
66
|
| Find scripts with missing or weak definitions | [Audit](#audit) |
|
|
41
67
|
| Document an existing table | [Backfill one table](#backfill-one-table) |
|
|
42
68
|
| CI says the catalog is stale | `python3 <engine> generate`, commit the pages |
|
|
@@ -46,8 +72,8 @@ Never document tables during setup unless the task asks for it.
|
|
|
46
72
|
|
|
47
73
|
`<engine>` is `scripts/data-catalog/data_catalog.py` in the repo, or
|
|
48
74
|
`<skill-base-dir>/scripts/data_catalog.py` before the repo has a copy. When
|
|
49
|
-
`python3 <engine> version` differs from the skill's copy, refresh
|
|
50
|
-
`init --write
|
|
75
|
+
`python3 <engine> version` differs from the skill's copy, the refresh is
|
|
76
|
+
`init --write`, which needs a setup request ([First use in a repo](#first-use-in-a-repo)).
|
|
51
77
|
|
|
52
78
|
## The files
|
|
53
79
|
|
|
@@ -61,7 +87,7 @@ Never document tables during setup unless the task asks for it.
|
|
|
61
87
|
| `scripts/data-catalog/data_catalog.py` | engine copied from this skill | never; refresh with init |
|
|
62
88
|
| `.github/workflows/data-catalog.yml` | generated CI check | never; rerun init |
|
|
63
89
|
| `CONTRIBUTING.md` section between `conventions:data-catalog` markers | the conventions, for agents without this skill | never; rerun `persist-conventions.mjs --write`; the rest is yours |
|
|
64
|
-
| `AGENTS.md` `## Contributing` pointer
|
|
90
|
+
| `AGENTS.md` `## Contributing` pointer and `## Data catalog task entry` rule | reach `CONTRIBUTING.md` and this skill; the rule routes work and authorizes no write | written once by `persist-conventions.mjs`; re-run `--write` to restore a missing one |
|
|
65
91
|
|
|
66
92
|
## Rules
|
|
67
93
|
|
|
@@ -118,6 +144,11 @@ Never document tables during setup unless the task asks for it.
|
|
|
118
144
|
PR why it still holds.
|
|
119
145
|
6. Commit the script and the regenerated pages together.
|
|
120
146
|
|
|
147
|
+
A repo with no `data-catalog.json`: steps 4 and 5 cannot run, because both exit 2
|
|
148
|
+
without a config. Write the definitions the change needs, say those checks are
|
|
149
|
+
pending, and offer setup once ([First use in a repo](#first-use-in-a-repo)). Do not
|
|
150
|
+
run `init --write` to make them run.
|
|
151
|
+
|
|
121
152
|
Example: changing `WHERE status = 'POSTED'` to `status IN ('POSTED', 'SETTLED')`
|
|
122
153
|
passes CI, and `drift` reports "filters, joins or CTEs changed; no definition
|
|
123
154
|
changed" until the affected sources say "posted or settled".
|
|
@@ -141,6 +172,10 @@ to `data-catalog.json` take effect on the next `init --write`. After a skill upd
|
|
|
141
172
|
rerun both `init --write` and `persist-conventions.mjs --write` so the repo's copies
|
|
142
173
|
match.
|
|
143
174
|
|
|
175
|
+
Without `--write`, `init` only prints its plan, so a dry run is always safe. With
|
|
176
|
+
`--write` it is repo setup and needs the user's setup request
|
|
177
|
+
([First use in a repo](#first-use-in-a-repo)).
|
|
178
|
+
|
|
144
179
|
The scripts import `from catalog_fields import Field, Table` at run time, so the
|
|
145
180
|
module must ship with them like any sibling module (for example `--py-files` on
|
|
146
181
|
`spark-submit`). Check that before merging.
|
|
@@ -188,7 +223,8 @@ script is clean when its columns were `unknown`.
|
|
|
188
223
|
3. Add `CATALOG_TABLE` and `CATALOG_FIELDS` in contract order. Keep the literal
|
|
189
224
|
contract while you write.
|
|
190
225
|
4. Run `generate` until it passes, then derive the contract and run the repo's
|
|
191
|
-
schema tests (rule 5).
|
|
226
|
+
schema tests (rule 5). In a repo with no `data-catalog.json` it exits 2: report it
|
|
227
|
+
pending and offer setup once, and do not run `init --write` for it.
|
|
192
228
|
5. Rerun the audit for that script and fix its writing findings (`repeated-text`,
|
|
193
229
|
`code-in-description`, `long-definition`, `thin-definition`,
|
|
194
230
|
`relative-definition`), or leave one only when the text really belongs in that row.
|
|
@@ -201,8 +237,9 @@ empty text.
|
|
|
201
237
|
|
|
202
238
|
## Done when
|
|
203
239
|
|
|
204
|
-
- `python3 <engine> generate --check` exits 0
|
|
240
|
+
- `python3 <engine> generate --check` exits 0, or you said it is pending because the
|
|
241
|
+
repo has no `data-catalog.json`.
|
|
205
242
|
- `python3 <engine> drift` exits 0, or you said in the PR why each listed definition
|
|
206
|
-
still holds.
|
|
243
|
+
still holds, or you reported it pending for the same reason.
|
|
207
244
|
- `python3 <engine> audit` has no findings for the tables you touched, or you
|
|
208
245
|
reported the ones left and why.
|