env-secrets 0.5.3 → 0.5.4

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 (52) hide show
  1. package/.claude/rules/cicd.md +189 -0
  2. package/.claude/rules/docs.md +96 -0
  3. package/.claude/rules/git-hooks.md +43 -0
  4. package/.claude/rules/local-dev-badges.md +91 -0
  5. package/.claude/rules/local-dev-env.md +382 -0
  6. package/.claude/rules/local-dev-license.md +104 -0
  7. package/.claude/rules/local-dev-mcp.md +70 -0
  8. package/.claude/rules/observability.md +23 -0
  9. package/.claude/rules/publishing-api.md +158 -0
  10. package/.claude/rules/publishing-apps.md +204 -0
  11. package/.claude/rules/publishing-apt.md +146 -0
  12. package/.claude/rules/publishing-brew.md +110 -0
  13. package/.claude/rules/publishing-cli.md +238 -0
  14. package/.claude/rules/publishing-libraries.md +115 -0
  15. package/.claude/rules/publishing-sdks.md +109 -0
  16. package/.claude/rules/publishing-web.md +185 -0
  17. package/.claude/rules/typescript-linting.md +141 -0
  18. package/.claude/rules/typescript-logging.md +356 -0
  19. package/.claude/rules/typescript-testing.md +185 -0
  20. package/.claude/settings.json +18 -0
  21. package/.claude/skills/github-health-check.skill +0 -0
  22. package/.codex/rules/cicd.md +21 -0
  23. package/.codex/rules/docs.md +98 -0
  24. package/.codex/rules/git-hooks.md +43 -0
  25. package/.codex/rules/github-health-check.md +440 -0
  26. package/.codex/rules/local-dev-env.md +47 -0
  27. package/.codex/rules/local-dev-license.md +3 -1
  28. package/.codex/rules/publishing-api.md +160 -0
  29. package/.codex/rules/publishing-apps.md +206 -0
  30. package/.codex/rules/publishing-apt.md +148 -0
  31. package/.codex/rules/publishing-brew.md +112 -0
  32. package/.codex/rules/publishing-cli.md +240 -0
  33. package/.codex/rules/publishing-libraries.md +117 -0
  34. package/.codex/rules/publishing-sdks.md +111 -0
  35. package/.codex/rules/publishing-web.md +187 -0
  36. package/.codex/rules/typescript-linting.md +143 -0
  37. package/.codex/rules/typescript-logging.md +358 -0
  38. package/.codex/rules/typescript-testing.md +187 -0
  39. package/.github/workflows/deploy-docs.yml +1 -1
  40. package/.github/workflows/unittests.yaml +1 -1
  41. package/.rulesrc.json +20 -0
  42. package/AGENTS.md +34 -0
  43. package/CLAUDE.md +58 -0
  44. package/README.md +17 -3
  45. package/__e2e__/aws-secret-value-args.test.ts +142 -0
  46. package/__tests__/cli/helpers.test.ts +35 -0
  47. package/dist/cli/helpers.js +13 -1
  48. package/dist/index.js +79 -40
  49. package/docs/AWS.md +42 -13
  50. package/package.json +5 -5
  51. package/src/cli/helpers.ts +16 -0
  52. package/src/index.ts +97 -48
@@ -25,6 +25,27 @@ You are a CI/CD specialist for TypeScript/JavaScript projects.
25
25
  - Integration with package registries and deployment targets.
26
26
  - `.github/dependabot.yml` for version and security updates.
27
27
 
28
+ ## Concurrency
29
+
30
+ Add a `concurrency` block to every GitHub Actions workflow so that redundant runs triggered by rapid pushes are handled correctly.
31
+
32
+ - **CI workflows** (lint, test, build): cancel in-progress runs when a newer commit is pushed to the same branch.
33
+ - **Publish/release workflows**: do not cancel in-progress runs — a publish that is already in flight should complete.
34
+
35
+ ```yaml
36
+ # CI workflows (lint, test, build) — cancel superseded runs
37
+ concurrency:
38
+ group: ${{ github.workflow }}-${{ github.ref }}
39
+ cancel-in-progress: true
40
+
41
+ # Publish/release workflows — let in-flight publishes finish
42
+ concurrency:
43
+ group: ${{ github.workflow }}-${{ github.ref }}
44
+ cancel-in-progress: false
45
+ ```
46
+
47
+ Apply the appropriate block at the workflow level (outside any `jobs:` key) for every workflow you create or update.
48
+
28
49
  ## Dependabot
29
50
 
30
51
  Create a `.github/dependabot.yml` file for the current project. Dependabot monitors dependencies and opens pull requests for updates. Always include both the project's package ecosystem (npm/yarn/pnpm) and `github-actions` so workflow actions stay current.
@@ -0,0 +1,98 @@
1
+ # Documentation Rules
2
+
3
+ These rules are intended for Codex (CLI and app).
4
+
5
+ These rules keep documentation accurate and current using GitHub Markdown by default, or an existing Docusaurus site when the repository already uses one.
6
+
7
+ ---
8
+
9
+ # Documentation Agent
10
+
11
+ You are a documentation specialist responsible for keeping product documentation accurate, approachable, and current with the codebase.
12
+
13
+ ## Core Policy
14
+
15
+ Documentation is part of the product. When application behavior, CLI commands, configuration, architecture, workflows, or operating assumptions change, update the docs in the same change.
16
+
17
+ ## Documentation Stack Decision
18
+
19
+ Default to a GitHub-readable Markdown documentation set under `docs/`.
20
+
21
+ Only use Docusaurus when the repository is already using it or the user explicitly asks for it. Detect an existing Docusaurus site from signals such as:
22
+
23
+ - `docusaurus.config.js`, `docusaurus.config.ts`, `sidebars.js`, or `sidebars.ts`
24
+ - `docs/`, `blog/`, `src/pages/`, or `static/` directories that match a Docusaurus layout
25
+ - `package.json` dependencies referencing `@docusaurus/*`
26
+
27
+ If Docusaurus is already present:
28
+
29
+ - Keep using Docusaurus instead of replacing it with plain Markdown.
30
+ - Maintain the existing sidebar, frontmatter, assets, and generated navigation structure.
31
+ - Ensure a `publish-docs` GitHub Actions workflow exists to build and publish the docs site.
32
+
33
+ If Docusaurus is not present:
34
+
35
+ - Do not introduce it by default.
36
+ - Keep docs as plain Markdown files that render correctly on GitHub.
37
+ - Ensure `docs/README.md` acts as the documentation index.
38
+
39
+ ## Required Documentation Outcomes
40
+
41
+ For every meaningful product change, update the documentation that answers these questions:
42
+
43
+ 1. What changed?
44
+ 2. Why would a user care?
45
+ 3. How does a new user get started?
46
+ 4. How does an advanced user configure, extend, debug, or operate it?
47
+ 5. What commands, flags, configuration fields, files, or APIs are affected?
48
+
49
+ Documentation should be structured so a beginner can follow the happy path quickly, while advanced users can find precise reference material without reverse-engineering the code.
50
+
51
+ ## Minimum Documentation Set
52
+
53
+ For Markdown-based docs, prefer a structure close to:
54
+
55
+ - `README.md` for the short project overview and entry points
56
+ - `docs/README.md` for the docs index
57
+ - `docs/getting-started.md` or equivalent onboarding material
58
+ - task-specific guides under `docs/`
59
+ - reference material for commands, configuration, architecture, and troubleshooting
60
+
61
+ For Docusaurus-based docs, preserve the existing site organization and place the same content in the appropriate pages.
62
+
63
+ ## Documentation Quality Bar
64
+
65
+ - Put the fastest working path first.
66
+ - Use concrete commands, file paths, and examples that match the implementation.
67
+ - Keep terminology and naming consistent with the code and CLI help output.
68
+ - Explain defaults, prerequisites, limitations, and failure modes.
69
+ - Avoid marketing language and vague summaries.
70
+ - Prefer short sections, descriptive headings, and examples over long prose blocks.
71
+
72
+ ## Diagrams
73
+
74
+ Create Mermaid diagrams when they materially improve understanding.
75
+
76
+ Required expectations:
77
+
78
+ - Add a high-level system diagram for non-trivial applications or workflows.
79
+ - If the system has a meaningful data model, configuration model, or persisted entities, document that with Mermaid using `erDiagram` or `classDiagram`.
80
+ - Add sequence diagrams for request flows, background jobs, or user interactions when behavior is easier to understand as a timeline.
81
+ - Add state diagrams when lifecycle or status transitions matter.
82
+
83
+ Do not add decorative diagrams. Each diagram should answer a real user or operator question and be explained in surrounding text.
84
+
85
+ ## Validation
86
+
87
+ Before finishing:
88
+
89
+ - Verify doc links, commands, file paths, flags, and config snippets against the implementation.
90
+ - Update `README.md`, installation docs, command docs, and architecture docs when they are affected.
91
+ - If Docusaurus is used, ensure the docs build still works and the `publish-docs` workflow matches the current site layout.
92
+ - If plain Markdown is used, ensure the docs remain readable on GitHub without requiring a local docs build.
93
+
94
+ ## When Completed
95
+
96
+ - Summarize which docs were updated.
97
+ - Call out any intentionally deferred documentation gaps.
98
+ - Treat missing docs for shipped behavior as a bug, not an optional follow-up.
@@ -0,0 +1,43 @@
1
+ # Git Hooks Rules
2
+
3
+ These rules are intended for Codex (CLI and app).
4
+
5
+ These rules keep local Git hook orchestration consistent with the repository layout and testing strategy.
6
+
7
+ ---
8
+
9
+ You are a Git hook specialist. Your role is to establish local Git hook orchestration that complements Ballast linting and testing rules without duplicating ownership.
10
+
11
+ ## Your Responsibilities
12
+
13
+ 1. Select the correct hook tool for the repository layout.
14
+ 2. Configure fast checks for `pre-commit`.
15
+ 3. Configure unit tests for `pre-push`.
16
+ 4. Keep hook configuration current as commands and repo layout evolve.
17
+ 5. Keep hook scripts executable and easy to audit.
18
+
19
+ ## Hook Strategy
20
+
21
+ ## Git Hooks
22
+
23
+ Use `pre-commit` for this repository layout.
24
+
25
+ - Create `.pre-commit-config.yaml` at the repo root.
26
+ - Install hooks with `pre-commit install`.
27
+ - Install the pre-push hook with `pre-commit install --hook-type pre-push`.
28
+ - Configure `.pre-commit-config.yaml` so fast lint and format checks run on `pre-commit` and unit tests run on `pre-push`.
29
+ - Keep the configuration current with `pre-commit autoupdate`.
30
+ - Verify the hook configuration with `pre-commit run --all-files`.
31
+
32
+ ## Important Notes
33
+
34
+ - Keep commit-time hooks fast enough that developers do not bypass them.
35
+ - Keep `pre-push` focused on the repo's unit test command and required build step.
36
+ - Update hook commands when lint, format, build, or test scripts change.
37
+ - Verify the hook setup after changes before handing off the repo.
38
+
39
+ ## When Completed
40
+
41
+ 1. Show the user the hook files and commands you added or updated.
42
+ 2. Explain how commit-time checks differ from push-time checks.
43
+ 3. Explain how to verify the hook setup locally.
@@ -0,0 +1,440 @@
1
+ # GitHub Repository Health Check Skill
2
+
3
+ Runs a comprehensive health audit of the current GitHub repository using the `gh` CLI. Produces a structured report with status indicators and actionable items. Auto-merges safe Dependabot PRs.
4
+
5
+ ---
6
+
7
+ ## Prerequisites
8
+
9
+ ```bash
10
+ # Verify gh is authenticated and repo context is available
11
+ gh auth status
12
+ gh repo view --json name,owner,defaultBranchRef
13
+ ```
14
+
15
+ Capture the repo owner and name for use in API calls:
16
+
17
+ ```bash
18
+ REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
19
+ OWNER=$(gh repo view --json owner --jq '.owner.login')
20
+ NAME=$(gh repo view --json name --jq '.name')
21
+ DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Check 1 — GitHub Actions Status (default branch)
27
+
28
+ ```bash
29
+ # Recent workflow runs on the default branch
30
+ gh run list --branch "$DEFAULT_BRANCH" --limit 20 \
31
+ --json status,conclusion,name,workflowName,createdAt,url \
32
+ --jq '.[] | {workflow: .workflowName, status: .status, conclusion: .conclusion, created: .createdAt, url: .url}'
33
+ ```
34
+
35
+ **Interpret results:**
36
+
37
+ - Group runs by workflow name; show the latest run per workflow
38
+ - Flag any workflow whose latest run concluded with `failure` or `cancelled`
39
+ - Flag workflows that haven't run in more than 14 days
40
+ - Show overall summary: X workflows passing, Y failing
41
+
42
+ ```bash
43
+ # Check for any in-progress or queued runs
44
+ gh run list --branch "$DEFAULT_BRANCH" --status in_progress --json workflowName,url
45
+ gh run list --branch "$DEFAULT_BRANCH" --status queued --json workflowName,url
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Check 2 — Branch Freshness vs Latest Release
51
+
52
+ ```bash
53
+ # Get the latest release tag
54
+ LATEST_TAG=$(gh release list --limit 1 --json tagName --jq '.[0].tagName // "none"')
55
+ echo "Latest release: $LATEST_TAG"
56
+
57
+ # Count commits on default branch since last release
58
+ if [ "$LATEST_TAG" != "none" ]; then
59
+ git fetch --tags 2>/dev/null || true
60
+ COMMITS_AHEAD=$(git rev-list "${LATEST_TAG}..HEAD" --count 2>/dev/null || echo "unknown")
61
+ echo "Commits since last release: $COMMITS_AHEAD"
62
+
63
+ # Show recent unreleased commits
64
+ git log "${LATEST_TAG}..HEAD" --oneline 2>/dev/null | head -10 || true
65
+ fi
66
+
67
+ # Get last release date
68
+ gh release list --limit 1 --json tagName,publishedAt \
69
+ --jq '.[] | "Tag: \(.tagName) Published: \(.publishedAt)"'
70
+ ```
71
+
72
+ **Interpret results:**
73
+
74
+ - If commits ahead > 20: warn that a release may be overdue
75
+ - If last release was more than 30 days ago: note it
76
+ - If no releases exist: note that versioned releases are not configured
77
+
78
+ ---
79
+
80
+ ## Check 3 — Open Pull Requests
81
+
82
+ ```bash
83
+ # List all open PRs with key metadata
84
+ gh pr list --state open --json number,title,author,isDraft,createdAt,labels,headRefName,reviewDecision,statusCheckRollup \
85
+ --jq '.[] | {
86
+ number: .number,
87
+ title: .title,
88
+ author: .author.login,
89
+ isDraft: .isDraft,
90
+ created: .createdAt,
91
+ branch: .headRefName,
92
+ review: .reviewDecision,
93
+ checks: (.statusCheckRollup // [] | {
94
+ total: length,
95
+ passing: map(select(.conclusion == "SUCCESS")) | length,
96
+ failing: map(select(.conclusion == "FAILURE")) | length
97
+ })
98
+ }'
99
+ ```
100
+
101
+ **Report:**
102
+
103
+ - Total open PRs, draft vs ready
104
+ - PRs older than 7 days without activity (stale)
105
+ - PRs with failing checks
106
+ - PRs awaiting review
107
+
108
+ ### Dependabot PR Auto-Merge
109
+
110
+ ```bash
111
+ # Get all open Dependabot PRs
112
+ gh pr list --state open --author "app/dependabot" \
113
+ --json number,title,headRefName,statusCheckRollup,isDraft,mergeable
114
+ ```
115
+
116
+ For each Dependabot PR returned, apply this decision logic:
117
+
118
+ 1. **Parse the version bump** from the PR title (format: "Bump X from A.B.C to D.E.F"):
119
+
120
+ - Extract `from` version and `to` version
121
+ - Compare the major version (first number): if major version changes → **SKIP** (major upgrade)
122
+ - If only minor/patch changes → candidate for auto-merge
123
+
124
+ 2. **Check CI status**: all checks must be `SUCCESS` (no failures, no pending)
125
+
126
+ ```bash
127
+ gh pr checks <PR_NUMBER> --json name,state,conclusion
128
+ ```
129
+
130
+ 3. **Verify not a draft** and **mergeable** state is not `CONFLICTING`
131
+
132
+ 4. **Auto-merge if all conditions pass** (no confirmation needed):
133
+
134
+ ```bash
135
+ gh pr merge <PR_NUMBER> --squash --auto
136
+ ```
137
+
138
+ 5. **Report each decision**: merged / skipped (major) / skipped (CI failing) / skipped (conflicts)
139
+
140
+ **Example major version detection:**
141
+
142
+ - "Bump eslint from 8.57.0 to 9.0.0" → major (8→9) → SKIP
143
+ - "Bump typescript from 5.3.3 to 5.4.0" → minor → merge
144
+ - "Bump lodash from 4.17.20 to 4.17.21" → patch → merge
145
+
146
+ ---
147
+
148
+ ## Check 4 — Code Coverage (Codecov)
149
+
150
+ ```bash
151
+ # Check for codecov configuration file
152
+ ls .codecov.yml codecov.yml .codecov.yaml codecov.yaml 2>/dev/null || echo "No codecov config file found"
153
+
154
+ # Check for codecov in CI workflows
155
+ grep -rl "codecov" .github/workflows/ 2>/dev/null || echo "No codecov step found in workflows"
156
+
157
+ # Check README for codecov badge
158
+ grep -i "codecov" README.md 2>/dev/null | head -3 || echo "No codecov badge in README"
159
+
160
+ # Check if codecov token is configured as a repo secret (presence only, not value)
161
+ gh api "/repos/${OWNER}/${NAME}/actions/secrets" --jq '.secrets[].name' 2>/dev/null | grep -i codecov || echo "No CODECOV secret found"
162
+ ```
163
+
164
+ **Interpret results:**
165
+
166
+ - If no codecov config AND no codecov in workflows AND no badge: **WARN** — Codecov does not appear to be configured. Recommend adding the `codecov/codecov-action` to CI workflows.
167
+ - If present: confirm coverage reporting is active
168
+
169
+ ---
170
+
171
+ ## Check 5 — Security Alerts
172
+
173
+ ```bash
174
+ # Count open Dependabot security alerts
175
+ gh api "/repos/${OWNER}/${NAME}/dependabot/alerts?state=open&per_page=100" \
176
+ --jq 'length' 2>/dev/null | xargs -I{} echo "Open Dependabot alerts: {}" || \
177
+ echo "Could not fetch Dependabot alert count (check repo permissions)"
178
+
179
+ # Show top severity alerts
180
+ gh api "/repos/${OWNER}/${NAME}/dependabot/alerts?state=open&sort=severity&direction=desc&per_page=10" \
181
+ --jq '.[] | "[\(.security_advisory.severity | ascii_upcase)] \(.security_advisory.summary) — \(.dependency.package.name)"' 2>/dev/null || true
182
+
183
+ # Code scanning alerts (SAST / CodeQL)
184
+ gh api "/repos/${OWNER}/${NAME}/code-scanning/alerts?state=open&per_page=100" \
185
+ --jq 'length' 2>/dev/null | xargs -I{} echo "Open code scanning alerts: {}" || \
186
+ echo "Code scanning: not enabled or no access"
187
+
188
+ # Secret scanning alerts
189
+ gh api "/repos/${OWNER}/${NAME}/secret-scanning/alerts?state=open&per_page=100" \
190
+ --jq 'length' 2>/dev/null | xargs -I{} echo "Open secret scanning alerts: {}" || \
191
+ echo "Secret scanning: not enabled or no access"
192
+ ```
193
+
194
+ **Interpret results:**
195
+
196
+ - Open Dependabot security alerts > 0: list them with severity (critical/high first)
197
+ - Code scanning alerts: show count and any critical/high items
198
+ - Secret scanning alerts > 0: flag as **CRITICAL** — leaked secrets need immediate rotation
199
+ - If code scanning is not enabled: recommend enabling CodeQL in GitHub Advanced Security
200
+
201
+ ---
202
+
203
+ ## Check 6 — Snyk Integration
204
+
205
+ ```bash
206
+ # Check for .snyk policy file
207
+ ls .snyk 2>/dev/null && echo "Snyk policy file found: .snyk" || echo "No .snyk file"
208
+
209
+ # Check CI workflows for Snyk
210
+ grep -rl "snyk" .github/workflows/ 2>/dev/null || echo "No Snyk step found in workflows"
211
+
212
+ # Check README for Snyk badge
213
+ grep -i "snyk" README.md 2>/dev/null | head -3 || echo "No Snyk badge in README"
214
+
215
+ # Check for snyk-related secrets
216
+ gh api "/repos/${OWNER}/${NAME}/actions/secrets" --jq '.secrets[].name' 2>/dev/null | grep -i snyk || echo "No SNYK secret found"
217
+ ```
218
+
219
+ **Interpret results:**
220
+
221
+ - If no `.snyk`, no Snyk in workflows, no badge, and no Snyk secret: **WARN** — Snyk does not appear to be integrated. Recommend adding Snyk for dependency and container vulnerability scanning (snyk.io).
222
+ - If partially configured: note what's present and what's missing
223
+
224
+ ---
225
+
226
+ ## Check 7 — Branch Protection Rules
227
+
228
+ ```bash
229
+ # Check protection rules on the default branch
230
+ gh api "/repos/${OWNER}/${NAME}/branches/${DEFAULT_BRANCH}/protection" 2>/dev/null || \
231
+ echo "WARNING: No branch protection rules found on ${DEFAULT_BRANCH}"
232
+
233
+ # Parse and summarize key protections
234
+ gh api "/repos/${OWNER}/${NAME}/branches/${DEFAULT_BRANCH}/protection" 2>/dev/null | \
235
+ python3 -c "
236
+ import sys, json
237
+ try:
238
+ p = json.load(sys.stdin)
239
+ good, bad = [], []
240
+ if p.get('required_pull_request_reviews'): good.append('PR reviews required')
241
+ else: bad.append('No required PR reviews')
242
+ if p.get('required_status_checks'): good.append('Status checks required')
243
+ else: bad.append('No required status checks')
244
+ if p.get('enforce_admins', {}).get('enabled'): good.append('Rules enforced for admins')
245
+ if p.get('allow_force_pushes', {}).get('enabled'): bad.append('Force pushes allowed on main')
246
+ if p.get('allow_deletions', {}).get('enabled'): bad.append('Branch deletion allowed')
247
+ for g in good: print('OK:', g)
248
+ for b in bad: print('WARN:', b)
249
+ except Exception as e: print('Could not parse:', e)
250
+ " 2>/dev/null || true
251
+ ```
252
+
253
+ **Flag missing protections:**
254
+
255
+ - No required PR reviews: warn
256
+ - No required status checks: warn
257
+ - Force pushes allowed on main: warn
258
+ - No branch protection at all: flag as high priority
259
+
260
+ ---
261
+
262
+ ## Check 8 — Stale Branches
263
+
264
+ ```bash
265
+ # List remote branches not merged to default branch, sorted by last commit date
266
+ git fetch --prune 2>/dev/null || true
267
+ git branch -r --no-merged "origin/${DEFAULT_BRANCH}" \
268
+ --sort=-committerdate \
269
+ --format='%(committerdate:relative)|%(refname:short)' 2>/dev/null | \
270
+ grep -v "HEAD\|${DEFAULT_BRANCH}" | head -20
271
+
272
+ # Count stale branches (no commits in 30+ days, not yet merged)
273
+ STALE_COUNT=$(git branch -r --no-merged "origin/${DEFAULT_BRANCH}" \
274
+ --format='%(committerdate:unix)|%(refname:short)' 2>/dev/null | \
275
+ python3 -c "
276
+ import sys
277
+ from datetime import datetime, timezone
278
+ cutoff = datetime.now(timezone.utc).timestamp() - 30 * 86400
279
+ count = 0
280
+ for line in sys.stdin:
281
+ parts = line.strip().split('|')
282
+ if len(parts) == 2 and parts[0].isdigit() and int(parts[0]) < cutoff:
283
+ count += 1
284
+ print(count)
285
+ " 2>/dev/null || echo "0")
286
+ echo "Stale branches (30+ days, unmerged): $STALE_COUNT"
287
+ ```
288
+
289
+ ---
290
+
291
+ ## Check 9 — Repository Housekeeping
292
+
293
+ ```bash
294
+ # Check for essential files
295
+ for f in README.md LICENSE .gitignore .github/dependabot.yml SECURITY.md .github/CODEOWNERS CODEOWNERS; do
296
+ [ -f "$f" ] && echo "OK: $f" || echo "MISSING: $f"
297
+ done
298
+
299
+ # Dependabot config check
300
+ if [ -f ".github/dependabot.yml" ]; then
301
+ echo "Dependabot ecosystems configured:"
302
+ grep "package-ecosystem" .github/dependabot.yml | sort | uniq -c
303
+ else
304
+ echo "WARNING: No .github/dependabot.yml — automated dependency updates not configured"
305
+ fi
306
+
307
+ # Check repo has a description and topics
308
+ gh repo view --json description,repositoryTopics \
309
+ --jq '"Description: \(.description // "MISSING — add in repo settings")\nTopics: \(.repositoryTopics.nodes | map(.topic.name) | join(", ") | if . == "" then "NONE — add topics for discoverability" else . end)"'
310
+ ```
311
+
312
+ ---
313
+
314
+ ## Check 10 — Workflow Health Patterns
315
+
316
+ ```bash
317
+ # Detect consistently failing workflows (>50% failure rate over recent runs)
318
+ gh run list --branch "$DEFAULT_BRANCH" --limit 50 \
319
+ --json workflowName,conclusion,createdAt \
320
+ --jq 'group_by(.workflowName) | .[] | {
321
+ workflow: .[0].workflowName,
322
+ runs: length,
323
+ failures: map(select(.conclusion == "failure")) | length
324
+ } | select(.runs >= 3) |
325
+ "\(.workflow): \(.failures)/\(.runs) recent runs failed\(if (.failures / .runs) > 0.5 then " ⚠️ CONSISTENTLY FAILING" else "" end)"'
326
+ ```
327
+
328
+ ---
329
+
330
+ ## Check 11 — Release & Tag Health
331
+
332
+ ```bash
333
+ # List recent releases
334
+ gh release list --limit 5 --json tagName,publishedAt,isDraft,isPrerelease \
335
+ --jq '.[] | "\(.tagName) [\(if .isDraft then "DRAFT" elif .isPrerelease then "PRE-RELEASE" else "RELEASED" end)] — \(.publishedAt)"'
336
+
337
+ # Check for unpublished draft releases
338
+ DRAFT_COUNT=$(gh release list --json isDraft --jq '[.[] | select(.isDraft)] | length' 2>/dev/null || echo "0")
339
+ [ "$DRAFT_COUNT" -gt 0 ] && echo "WARNING: $DRAFT_COUNT unpublished draft release(s)" || true
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Check 12 — Actions Permissions & Secrets Health
345
+
346
+ ```bash
347
+ # Check default workflow permissions
348
+ gh api "/repos/${OWNER}/${NAME}/actions/permissions" \
349
+ --jq '"Actions enabled: \(.enabled)\nDefault permission: \(.default_workflow_permissions // "unknown")"' 2>/dev/null
350
+
351
+ # List repo secret names and ages (values never shown)
352
+ echo "--- Repository Secrets ---"
353
+ gh api "/repos/${OWNER}/${NAME}/actions/secrets" \
354
+ --jq '.secrets[] | "\(.name) (last updated: \(.updated_at))"' 2>/dev/null
355
+
356
+ # Warn about secrets not rotated in 180+ days
357
+ gh api "/repos/${OWNER}/${NAME}/actions/secrets" 2>/dev/null | \
358
+ python3 -c "
359
+ import sys, json
360
+ from datetime import datetime, timezone
361
+ try:
362
+ data = json.load(sys.stdin)
363
+ for s in data.get('secrets', []):
364
+ updated = s.get('updated_at', '')
365
+ try:
366
+ dt = datetime.fromisoformat(updated.replace('Z', '+00:00'))
367
+ age = (datetime.now(timezone.utc) - dt).days
368
+ if age > 180:
369
+ print(f'STALE SECRET ({age} days): {s[\"name\"]} — consider rotating')
370
+ except: pass
371
+ except: pass
372
+ " 2>/dev/null || true
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Generate Health Report
378
+
379
+ After running all checks, present findings in this structure:
380
+
381
+ ```text
382
+ ## GitHub Repository Health Report
383
+ **Repo**: owner/name
384
+ **Date**: <today>
385
+ **Default Branch**: main
386
+
387
+ ---
388
+ ### Overall Status: [HEALTHY | NEEDS ATTENTION | CRITICAL]
389
+
390
+ ---
391
+ ### CI/CD ✅/⚠️/❌
392
+ | Workflow | Latest Status | Last Run |
393
+ |----------|--------------|----------|
394
+ | ... | ✅/❌ | ... |
395
+
396
+ ---
397
+ ### Pull Requests
398
+ - Open PRs: N (D draft, R ready for review)
399
+ - Stale PRs (>7 days, no activity): N
400
+ - Dependabot PRs auto-merged: N (list titles)
401
+ - Dependabot PRs skipped: N (list with reason)
402
+
403
+ ---
404
+ ### Security ✅/⚠️/❌
405
+ - Dependabot alerts: N open (X critical, Y high)
406
+ - Code scanning (CodeQL): enabled/NOT ENABLED
407
+ - Secret scanning: N open alerts
408
+ - Snyk: configured / NOT CONFIGURED ⚠️
409
+ - Branch protection on main: summary of rules
410
+
411
+ ---
412
+ ### Code Coverage ✅/⚠️
413
+ - Codecov: configured / NOT CONFIGURED ⚠️
414
+
415
+ ---
416
+ ### Repository Housekeeping ✅/⚠️
417
+ - Missing essential files: list or "none"
418
+ - Dependabot auto-updates: configured / missing
419
+ - Stale unmerged branches: N
420
+ - Draft releases: N
421
+
422
+ ---
423
+ ### Recommended Actions (prioritized)
424
+ 1. [CRITICAL] ...
425
+ 2. [HIGH] ...
426
+ 3. [MEDIUM] ...
427
+ 4. [LOW/NICE-TO-HAVE] ...
428
+ ```
429
+
430
+ ---
431
+
432
+ ## Edge Cases
433
+
434
+ - **Private repo without security features**: Some APIs require admin access; note when commands fail with 403/404 and suggest the user checks repo settings manually
435
+ - **Org-managed repos**: Branch protection and secrets may be inherited from org settings; note this if the API returns 403
436
+ - **No releases yet**: Skip release freshness checks; note that versioned releases are not configured
437
+ - **Rate limiting**: If `gh` returns 429, note that data may be incomplete and suggest retrying
438
+ - **Monorepo**: If multiple `package.json` / `go.mod` / `pyproject.toml` found, note this when scanning Dependabot PRs and check all ecosystems are covered in `.github/dependabot.yml`
439
+ - **gh not authenticated**: Exit immediately with instructions: run `gh auth login`
440
+ - **No open PRs**: Confirm the repo is clean; no merging needed
@@ -24,6 +24,53 @@ You are a local development environment specialist for TypeScript/JavaScript pro
24
24
 
25
25
  ---
26
26
 
27
+ ## Pull Request Workflow
28
+
29
+ When the user is creating or landing a pull request as part of local development workflow, treat PR hygiene as part of the job.
30
+
31
+ ### Your Responsibilities
32
+
33
+ 1. **Ensure Copilot is assigned to the PR**
34
+
35
+ - When a PR exists or is being created, check whether GitHub Copilot is assigned for code review/agent assistance when the repository workflow expects it.
36
+ - If Copilot is not assigned, assign it before considering the PR ready.
37
+ - Do not assume assignment happened automatically; verify it.
38
+ - For Copilot or any other reviewer, summarize the review comments and requested changes so the user can decide what should be fixed next.
39
+
40
+ 2. **Use a sub-agent to monitor PR checks**
41
+
42
+ - After pushing commits or creating/updating a PR, use a sub-agent to watch the PR checks while the main agent continues with other work.
43
+ - Have the sub-agent report back when checks succeed or when a check fails.
44
+ - Treat pending or failing checks as part of the task, not as an afterthought.
45
+ - Do not tell the user the PR is ready until the sub-agent confirms the required checks are green.
46
+
47
+ 3. **Use `gh` to inspect failures**
48
+
49
+ - If PR checks fail, use the GitHub CLI to inspect the failing runs, jobs, logs, and annotations.
50
+ - Prefer `gh pr checks`, `gh run view`, and related `gh` commands so the user gets concrete failure context tied to the PR.
51
+ - Pass the failing details from the sub-agent back to the main agent, then summarize the failing check, the relevant error, and what needs to be fixed next.
52
+
53
+ 4. **Reply directly to GitHub review comments when fixing them**
54
+
55
+ - When a specific GitHub review comment is addressed, reply on that review comment thread directly instead of posting a general summary comment on the PR.
56
+ - The reply should say what was changed or why the requested change was not made.
57
+ - Use general PR comments only for overall status or cross-cutting updates, not for resolving line-specific review feedback.
58
+ - This applies to Copilot review comments and human review comments alike.
59
+ - Do not stop at making the code change locally; if the review comment was addressed, add the thread reply.
60
+ - If multiple review comments were addressed, reply on each relevant thread rather than collapsing them into one PR-level summary.
61
+
62
+ 5. **Summarize review asks before changing code**
63
+ - For Copilot reviews and human reviews alike, summarize the concrete asks, group duplicates, and identify which comments actually require code changes.
64
+ - If a comment is informational or already satisfied, say that explicitly.
65
+
66
+ ### When to Apply
67
+
68
+ - When the user asks to create, update, review, or land a PR.
69
+ - When the task includes “open a PR”, “get the PR ready”, “make sure CI passes”, or similar language.
70
+ - When local work is complete and the next step is validating PR readiness.
71
+
72
+ ---
73
+
27
74
  ## Node Version Management (nvm)
28
75
 
29
76
  When setting up or working on Node.js/TypeScript projects, use **nvm** (Node Version Manager) to ensure consistent Node versions across developers and environments.
@@ -65,9 +65,11 @@ Replace `<YEAR>` with the current year and `<COPYRIGHT HOLDER>` with the author/
65
65
  ```markdown
66
66
  ## License
67
67
 
68
- MIT License - see [LICENSE](LICENSE) file for details.
68
+ Default license for this project: Apache-2.0 (or ISC, BSD-3-Clause, etc.)
69
69
  ```
70
70
 
71
+ When such a section exists, use the specified license instead of MIT. If both files define a license, prefer `AGENTS.md` (it is agent-facing and typically more authoritative for automation).
72
+
71
73
  ## Example package.json Addition
72
74
 
73
75
  ```json