opencode-skills-collection 4.0.54 → 4.0.55

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 (71) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +1 -1
  2. package/bundled-skills/antigravity-maintainer-batch-release/SKILL.md +10 -1
  3. package/bundled-skills/backend-security-coder/resources/implementation-playbook.md +23 -0
  4. package/bundled-skills/business-analyst/resources/implementation-playbook.md +23 -0
  5. package/bundled-skills/devops-troubleshooter/resources/implementation-playbook.md +23 -0
  6. package/bundled-skills/distributed-tracing/SKILL.md +22 -435
  7. package/bundled-skills/distributed-tracing/references/instrumentation.md +13 -0
  8. package/bundled-skills/distributed-tracing/references/jaeger-setup.md +13 -0
  9. package/bundled-skills/distributed-tracing/resources/implementation-playbook.md +23 -0
  10. package/bundled-skills/django-pro/resources/implementation-playbook.md +23 -0
  11. package/bundled-skills/embedding-strategies/SKILL.md +40 -64
  12. package/bundled-skills/embedding-strategies/resources/implementation-playbook.md +23 -0
  13. package/bundled-skills/fastapi-pro/resources/implementation-playbook.md +23 -0
  14. package/bundled-skills/find-complementary-founders/scripts/assess_profile.py +7 -1
  15. package/bundled-skills/frontend-security-coder/SKILL.md +5 -5
  16. package/bundled-skills/frontend-security-coder/resources/implementation-playbook.md +23 -0
  17. package/bundled-skills/github-actions-templates/SKILL.md +34 -314
  18. package/bundled-skills/github-actions-templates/references/common-workflows.md +13 -0
  19. package/bundled-skills/github-actions-templates/resources/implementation-playbook.md +23 -0
  20. package/bundled-skills/google-docs-automation/SKILL.md +19 -69
  21. package/bundled-skills/google-sheets-automation/SKILL.md +20 -128
  22. package/bundled-skills/google-slides-automation/SKILL.md +19 -128
  23. package/bundled-skills/grafana-dashboards/SKILL.md +6 -6
  24. package/bundled-skills/grafana-dashboards/references/dashboard-design.md +13 -0
  25. package/bundled-skills/grafana-dashboards/resources/implementation-playbook.md +23 -0
  26. package/bundled-skills/incident-responder/resources/implementation-playbook.md +23 -0
  27. package/bundled-skills/instagram/scripts/config.py +33 -8
  28. package/bundled-skills/ios-developer/resources/implementation-playbook.md +23 -0
  29. package/bundled-skills/junta-leiloeiros/scripts/.snyk +5 -0
  30. package/bundled-skills/junta-leiloeiros/scripts/requirements.txt +2 -0
  31. package/bundled-skills/kpi-dashboard-design/SKILL.md +7 -67
  32. package/bundled-skills/kpi-dashboard-design/resources/implementation-playbook.md +23 -0
  33. package/bundled-skills/kpi-dashboard-design/resources/metric-queries.sql +30 -0
  34. package/bundled-skills/lint-and-validate/SKILL.md +17 -45
  35. package/bundled-skills/lint-and-validate/scripts/lint_runner.py +17 -8
  36. package/bundled-skills/lint-and-validate/scripts/type_coverage.py +77 -167
  37. package/bundled-skills/mobile-developer/resources/implementation-playbook.md +23 -0
  38. package/bundled-skills/multi-platform-apps-multi-platform/resources/implementation-playbook.md +23 -0
  39. package/bundled-skills/notebooklm/scripts/config.py +33 -11
  40. package/bundled-skills/observability-and-instrumentation/SKILL.md +4 -1
  41. package/bundled-skills/observability-and-instrumentation/references/observability-checklist.md +13 -0
  42. package/bundled-skills/pci-compliance/SKILL.md +23 -469
  43. package/bundled-skills/pci-compliance/resources/implementation-playbook.md +23 -0
  44. package/bundled-skills/postmortem-writing/SKILL.md +1 -1
  45. package/bundled-skills/postmortem-writing/resources/implementation-playbook.md +23 -0
  46. package/bundled-skills/pydantic-models-py/SKILL.md +1 -3
  47. package/bundled-skills/secrets-management/SKILL.md +24 -349
  48. package/bundled-skills/secrets-management/references/github-secrets.md +13 -0
  49. package/bundled-skills/secrets-management/references/vault-setup.md +13 -0
  50. package/bundled-skills/security-and-hardening/SKILL.md +8 -6
  51. package/bundled-skills/security-and-hardening/references/security-checklist.md +13 -0
  52. package/bundled-skills/seo-content-planner/resources/implementation-playbook.md +23 -0
  53. package/bundled-skills/seo-content-writer/SKILL.md +2 -2
  54. package/bundled-skills/seo-content-writer/resources/implementation-playbook.md +23 -0
  55. package/bundled-skills/shopify-development/scripts/.snyk +3 -0
  56. package/bundled-skills/slack-gif-creator/.snyk +5 -0
  57. package/bundled-skills/slack-gif-creator/requirements.txt +2 -2
  58. package/bundled-skills/slo-implementation/SKILL.md +24 -9
  59. package/bundled-skills/slo-implementation/references/error-budget.md +13 -0
  60. package/bundled-skills/slo-implementation/references/slo-definitions.md +13 -0
  61. package/bundled-skills/slo-implementation/resources/implementation-playbook.md +23 -0
  62. package/bundled-skills/sql-optimization-patterns/SKILL.md +10 -6
  63. package/bundled-skills/sql-optimization-patterns/resources/implementation-playbook.md +52 -56
  64. package/bundled-skills/telegram/assets/boilerplate/nodejs/package-lock.json +1888 -0
  65. package/bundled-skills/telegram/assets/boilerplate/nodejs/package.json +3 -0
  66. package/bundled-skills/vector-database-engineer/resources/implementation-playbook.md +23 -0
  67. package/bundled-skills/videodb/scripts/ws_listener.py +8 -1
  68. package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/nodejs/package-lock.json +1881 -0
  69. package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/nodejs/package.json +3 -0
  70. package/bundled-skills/whatsapp-cloud-api/assets/boilerplate/python/.snyk +3 -0
  71. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ # Native iOS implementation
2
+
3
+ ## Inputs
4
+
5
+ Xcode/Swift versions, deployment target, project scheme, feature brief and available simulator/device.
6
+
7
+ ## Procedure
8
+
9
+ 1. Reuse the project's state and navigation architecture. Check API availability against the deployment target before adding platform features.
10
+ 2. Implement loading, success, failure and cancellation paths. Keep UI state changes on the appropriate actor and credentials in the project's secure storage abstraction.
11
+ 3. Build the actual scheme and test navigation, Dynamic Type, VoiceOver labels and interrupted network requests. State separately which checks used a simulator and which used hardware.
12
+
13
+ ## Worked example
14
+
15
+ Add a document list with retry. Leaving the screen during loading must not update a disposed view; large text must keep the retry action reachable.
16
+
17
+ ## Verification and handoff
18
+
19
+ Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
20
+
21
+ ## Limitations
22
+
23
+ Simulator success does not verify signing, push delivery, biometrics or App Store acceptance. Do not upload or distribute without authorization.
@@ -0,0 +1,5 @@
1
+ # Match the supported interpreter used to verify these requirements.
2
+ # Scoped to this manifest; does not change organization-wide settings.
3
+ version: v1.25.1
4
+ language-settings:
5
+ python: '3.14'
@@ -1,6 +1,8 @@
1
1
  # Dependências principais
2
2
  httpx>=0.27.0
3
3
  beautifulsoup4>=4.12.0
4
+ # Security floor for BeautifulSoup selector parsing (CVE-2026-49477).
5
+ soupsieve>=2.8.4
4
6
  lxml>=6.1.0
5
7
 
6
8
  # API
@@ -251,71 +251,10 @@ Efficiency:
251
251
 
252
252
  ### SQL for KPI Calculations
253
253
 
254
- ```sql
255
- -- Monthly Recurring Revenue (MRR)
256
- WITH mrr_calculation AS (
257
- SELECT
258
- DATE_TRUNC('month', billing_date) AS month,
259
- SUM(
260
- CASE subscription_interval
261
- WHEN 'monthly' THEN amount
262
- WHEN 'yearly' THEN amount / 12
263
- WHEN 'quarterly' THEN amount / 3
264
- END
265
- ) AS mrr
266
- FROM subscriptions
267
- WHERE status = 'active'
268
- GROUP BY DATE_TRUNC('month', billing_date)
269
- )
270
- SELECT
271
- month,
272
- mrr,
273
- LAG(mrr) OVER (ORDER BY month) AS prev_mrr,
274
- (mrr - LAG(mrr) OVER (ORDER BY month)) / LAG(mrr) OVER (ORDER BY month) * 100 AS growth_pct
275
- FROM mrr_calculation;
276
-
277
- -- Cohort Retention
278
- WITH cohorts AS (
279
- SELECT
280
- user_id,
281
- DATE_TRUNC('month', created_at) AS cohort_month
282
- FROM users
283
- ),
284
- activity AS (
285
- SELECT
286
- user_id,
287
- DATE_TRUNC('month', event_date) AS activity_month
288
- FROM user_events
289
- WHERE event_type = 'active_session'
290
- )
291
- SELECT
292
- c.cohort_month,
293
- EXTRACT(MONTH FROM age(a.activity_month, c.cohort_month)) AS months_since_signup,
294
- COUNT(DISTINCT a.user_id) AS active_users,
295
- COUNT(DISTINCT a.user_id)::FLOAT / COUNT(DISTINCT c.user_id) * 100 AS retention_rate
296
- FROM cohorts c
297
- LEFT JOIN activity a ON c.user_id = a.user_id
298
- AND a.activity_month >= c.cohort_month
299
- GROUP BY c.cohort_month, EXTRACT(MONTH FROM age(a.activity_month, c.cohort_month))
300
- ORDER BY c.cohort_month, months_since_signup;
301
-
302
- -- Customer Acquisition Cost (CAC)
303
- SELECT
304
- DATE_TRUNC('month', acquired_date) AS month,
305
- SUM(marketing_spend) / NULLIF(COUNT(new_customers), 0) AS cac,
306
- SUM(marketing_spend) AS total_spend,
307
- COUNT(new_customers) AS customers_acquired
308
- FROM (
309
- SELECT
310
- DATE_TRUNC('month', u.created_at) AS acquired_date,
311
- u.id AS new_customers,
312
- m.spend AS marketing_spend
313
- FROM users u
314
- JOIN marketing_spend m ON DATE_TRUNC('month', u.created_at) = m.month
315
- WHERE u.source = 'marketing'
316
- ) acquisition
317
- GROUP BY DATE_TRUNC('month', acquired_date);
318
- ```
254
+ Use `resources/metric-queries.sql` for executable normalized-input examples. `users` contains one row per customer, `events` contains user/month observations, `spend` contains source spend rows, and `monthly_revenue` contains one reconciled amount per month. Represent months as an integer year × 12 + month − 1 so offsets do not wrap after December.
255
+
256
+ The queries keep the original cohort denominator, deduplicate activity before counting, aggregate spend before joining customers, and return NULL for undefined growth or acquisition cost. Missing cohort/month combinations need an explicit reporting calendar if zero-activity rows must be displayed. Normalize subscription intervals, currency, refunds and revenue recognition before producing monthly revenue; these examples do not define accounting policy.
257
+
319
258
 
320
259
  ### Python Dashboard Code (Streamlit)
321
260
 
@@ -327,7 +266,8 @@ import plotly.graph_objects as go
327
266
 
328
267
  st.set_page_config(page_title="KPI Dashboard", layout="wide")
329
268
 
330
- # Header with date filter
269
+ # Synthetic layout illustration; this is not a connected or filterable dashboard.
270
+ # Header with illustrative date selector
331
271
  col1, col2 = st.columns([3, 1])
332
272
  with col1:
333
273
  st.title("Executive Dashboard")
@@ -363,7 +303,7 @@ col1, col2 = st.columns(2)
363
303
  with col1:
364
304
  st.subheader("Revenue Trend")
365
305
  revenue_data = pd.DataFrame({
366
- 'Month': pd.date_range('2024-01-01', periods=12, freq='M'),
306
+ 'Month': pd.date_range('2024-01-01', periods=12, freq='ME'),
367
307
  'Revenue': [180000, 195000, 210000, 225000, 240000, 255000,
368
308
  270000, 285000, 300000, 315000, 330000, 345000]
369
309
  })
@@ -0,0 +1,23 @@
1
+ # KPI dashboard verification
2
+
3
+ ## Inputs
4
+
5
+ Decision, audience, reporting grain, source tables, metric owner and period definitions.
6
+
7
+ ## Procedure
8
+
9
+ 1. Define each metric's numerator, denominator, exclusions, unit and freshness. Keep cohort size independent from later activity and aggregate spend before joining to customers.
10
+ 2. Build a small reconciliation table with hand-calculated results, zero denominators, duplicate events and cohorts older than twelve months.
11
+ 3. Connect every card and chart to the selected date range. Distinguish missing data from zero; show whether higher or lower is better and verify drill-down totals.
12
+
13
+ ## Worked example
14
+
15
+ A cohort has ten customers and four return in month thirteen. Retention is 40% at month 13, not 100% at month 1. Keep that fixture alongside the query.
16
+
17
+ ## Verification and handoff
18
+
19
+ Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
20
+
21
+ ## Limitations
22
+
23
+ Example dashboards use synthetic data. A visually correct dashboard is not proof that its financial or attribution definitions are valid.
@@ -0,0 +1,30 @@
1
+ -- Inputs are normalized month_index integers, one user per id, and spend rows at source grain.
2
+ -- query: retention
3
+ WITH cohort_sizes AS (
4
+ SELECT cohort_month, COUNT(*) AS cohort_size FROM users GROUP BY cohort_month
5
+ ), active AS (
6
+ SELECT DISTINCT u.cohort_month, e.month_index - u.cohort_month AS month_offset, u.id
7
+ FROM users u JOIN events e ON e.user_id = u.id
8
+ WHERE e.month_index >= u.cohort_month
9
+ )
10
+ SELECT a.cohort_month, a.month_offset, COUNT(*) AS active_users,
11
+ 100.0 * COUNT(*) / c.cohort_size AS retention_pct
12
+ FROM active a JOIN cohort_sizes c ON c.cohort_month = a.cohort_month
13
+ GROUP BY a.cohort_month, a.month_offset, c.cohort_size;
14
+ -- query: cac
15
+ WITH spend_by_month AS (
16
+ SELECT month_index, SUM(amount) AS spend FROM spend GROUP BY month_index
17
+ ), acquired AS (
18
+ SELECT cohort_month AS month_index, COUNT(*) AS customers
19
+ FROM users WHERE source = 'marketing' GROUP BY cohort_month
20
+ )
21
+ SELECT s.month_index, s.spend, COALESCE(a.customers, 0) AS customers,
22
+ 1.0 * s.spend / NULLIF(a.customers, 0) AS cac
23
+ FROM spend_by_month s LEFT JOIN acquired a ON a.month_index = s.month_index;
24
+ -- query: growth
25
+ WITH previous AS (
26
+ SELECT month_index, amount, LAG(amount) OVER (ORDER BY month_index) AS previous_amount
27
+ FROM monthly_revenue
28
+ )
29
+ SELECT month_index, amount, 100.0 * (amount - previous_amount) / NULLIF(previous_amount, 0) AS growth_pct
30
+ FROM previous;
@@ -1,62 +1,34 @@
1
1
  ---
2
2
  name: lint-and-validate
3
- description: "MANDATORY: Run appropriate validation tools after EVERY code change. Do not finish a task until the code is error-free."
3
+ description: "Run configured lint and type checks, distinguish failures from checks that did not run, and report concrete validation results."
4
4
  risk: critical
5
5
  source: community
6
6
  date_added: "2026-02-27"
7
7
  ---
8
8
 
9
- # Lint and Validate Skill
9
+ # Lint and Validate
10
10
 
11
- > **MANDATORY:** Run appropriate validation tools after EVERY code change. Do not finish a task until the code is error-free.
12
-
13
- ### Procedures by Ecosystem
14
-
15
- #### Node.js / TypeScript
16
- 1. **Lint/Fix:** `npm run lint` or `npx eslint "path" --fix`
17
- 2. **Types:** `npx tsc --noEmit`
18
- 3. **Security:** `npm audit --audit-level=high`
19
-
20
- #### Python
21
- 1. **Linter (Ruff):** `ruff check "path" --fix` (Fast & Modern)
22
- 2. **Security (Bandit):** `bandit -r "path" -ll`
23
- 3. **Types (MyPy):** `mypy "path"`
24
-
25
- ## The Quality Loop
26
- 1. **Write/Edit Code**
27
- 2. **Run Audit** for the project's ecosystem:
28
- - **Node.js / TypeScript:** `npm run lint && npx tsc --noEmit`
29
- - **Python:** `ruff check . --fix && mypy . && bandit -r . -ll`
30
- 3. **Analyze Report:** Check the "FINAL AUDIT REPORT" section.
31
- 4. **Fix & Repeat:** Submitting code with "FINAL AUDIT" failures is NOT allowed.
32
-
33
- ## Error Handling
34
- - If `lint` fails: Fix the style or syntax issues immediately.
35
- - If `tsc` fails: Correct type mismatches before proceeding.
36
- - If no tool is configured: Check the project root for `.eslintrc`, `tsconfig.json`, `pyproject.toml` and suggest creating one.
37
-
38
- ---
39
- **Strict Rule:** No code should be committed or reported as "done" without passing these checks.
40
-
41
- ---
11
+ ## When to Use
42
12
 
43
- ## Scripts
13
+ Use after behavior or configuration changes when a repository has relevant lint or type checks. Read the repository's instructions and package scripts first. Run focused checks during development and the required checks before completion.
44
14
 
45
- | Script | Purpose | Command |
46
- |--------|---------|---------|
47
- | `scripts/lint_runner.py` | Unified lint check | `python scripts/lint_runner.py <project_path>` |
48
- | `scripts/type_coverage.py` | Type coverage analysis | `python scripts/type_coverage.py <project_path>` |
15
+ ## Procedure
49
16
 
50
- ## When to Use
51
- This skill is applicable to execute the workflow or actions described in the overview.
17
+ 1. Identify the changed languages, configured commands, and installed tools. Inspect package scripts before executing them: a script named `lint` can modify files or run arbitrary project code.
18
+ 2. Run the project's read-only lint/type-check commands. For Node projects, prefer declared scripts such as `npm run lint` and `npm run typecheck`. Do not use `npx` to silently fetch an absent checker.
19
+ 3. For Python, use configured, already installed tools such as `ruff check .` or `mypy .`. Do not assume every `pyproject.toml` configures both. Never add `--fix` without inspecting the proposed changes and the task's authorization.
20
+ 4. Fix relevant failures without deleting user work, weakening rules, or raising timeouts just to pass. If a required tool is unavailable, report the exact check that did not run.
21
+ 5. Report commands, exit results, scope and remaining limitations. Passing lint does not prove the absence of runtime or security defects.
52
22
 
53
23
  ## Example
54
24
 
55
- **User request:**
25
+ After correcting a TypeScript behavior, inspect `package.json`, run the configured focused regression test, then `npm run lint` and `npm run typecheck` if those scripts exist. If TypeScript is declared but not installed, report the missing local checker; do not substitute a downloaded package or call the result a pass.
26
+
27
+ ## Bundled helpers
56
28
 
57
- > Use @lint-and-validate for this task: MANDATORY: Run appropriate validation tools after EVERY code change.
29
+ - `python scripts/lint_runner.py /absolute/project`: runs a conservative set of candidate checks. Node fallback checkers must exist in local `node_modules/.bin`; Python candidates must be installed. Inspect the project scripts first. A missing command or failing check exits 1; no configured checks or invalid project metadata exits 2. Exit 0 means the invoked checks passed, not that every needed check was discovered. Python detection is heuristic and may suggest unconfigured Ruff/MyPy commands.
30
+ - `python scripts/type_coverage.py /absolute/project`: read-only annotation inventory, despite its retained compatibility filename. Samples at most 30 files per language, skips links and build/dependency directories, and bounds file reads. Python uses AST nodes to avoid double-counting functions. TypeScript reports lexical `: any` occurrences, including possible comments and strings. No quality percentage or pass/fail threshold is inferred. Exit 2 means no applicable files; parse/read errors exit 1.
58
31
 
59
32
  ## Limitations
60
- - Use this skill only when the task clearly matches the scope described above.
61
- - Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
62
- - Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
33
+
34
+ The runner executes trusted project commands, which may mutate files or access the network. It does not install dependencies, detect every monorepo configuration, or replace the project's CI contract. The inventory is a bounded source sample, not semantic type coverage; inferred types, generics, decorator behavior and correctness require the actual type checker. Do not label unrun checks as successful.
@@ -7,13 +7,14 @@ Usage:
7
7
  python lint_runner.py <project_path>
8
8
 
9
9
  Supports:
10
- - Node.js: npm run lint, npx tsc --noEmit
10
+ - Node.js: npm run lint, installed local tsc --noEmit
11
11
  - Python: ruff check, mypy
12
12
  """
13
13
 
14
14
  import subprocess
15
15
  import sys
16
16
  import json
17
+ import os
17
18
  from pathlib import Path
18
19
  from datetime import datetime
19
20
 
@@ -44,14 +45,14 @@ def detect_project_type(project_path: Path) -> dict:
44
45
  if "lint" in scripts:
45
46
  result["linters"].append({"name": "npm lint", "cmd": ["npm", "run", "lint"]})
46
47
  elif "eslint" in deps:
47
- result["linters"].append({"name": "eslint", "cmd": ["npx", "eslint", "."]})
48
+ result["linters"].append({"name": "eslint", "cmd": [str(project_path / "node_modules" / ".bin" / ("eslint.cmd" if os.name == "nt" else "eslint")), "."]})
48
49
 
49
50
  # Check for TypeScript
50
51
  if "typescript" in deps or (project_path / "tsconfig.json").exists():
51
- result["linters"].append({"name": "tsc", "cmd": ["npx", "tsc", "--noEmit"]})
52
+ result["linters"].append({"name": "tsc", "cmd": [str(project_path / "node_modules" / ".bin" / ("tsc.cmd" if os.name == "nt" else "tsc")), "--noEmit"]})
52
53
 
53
- except:
54
- pass
54
+ except (OSError, ValueError, TypeError, AttributeError) as error:
55
+ raise ValueError(f"Cannot inspect package.json: {error}") from error
55
56
 
56
57
  # Python project
57
58
  if (project_path / "pyproject.toml").exists() or (project_path / "requirements.txt").exists():
@@ -111,7 +112,14 @@ def main():
111
112
  print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
112
113
 
113
114
  # Detect project type
114
- project_info = detect_project_type(project_path)
115
+ if not project_path.is_dir():
116
+ print("Project directory does not exist.", file=sys.stderr)
117
+ sys.exit(2)
118
+ try:
119
+ project_info = detect_project_type(project_path)
120
+ except ValueError as error:
121
+ print(str(error), file=sys.stderr)
122
+ sys.exit(2)
115
123
  print(f"Type: {project_info['type']}")
116
124
  print(f"Linters: {len(project_info['linters'])}")
117
125
  print("-"*60)
@@ -123,11 +131,12 @@ def main():
123
131
  "project": str(project_path),
124
132
  "type": project_info["type"],
125
133
  "checks": [],
126
- "passed": True,
134
+ "passed": False,
135
+ "status": "not-checked",
127
136
  "message": "No linters configured"
128
137
  }
129
138
  print(json.dumps(output, indent=2))
130
- sys.exit(0)
139
+ sys.exit(2)
131
140
 
132
141
  # Run each linter
133
142
  results = []
@@ -1,173 +1,83 @@
1
1
  #!/usr/bin/env python3
2
- """
3
- Type Coverage Checker - Measures TypeScript/Python type coverage.
4
- Identifies untyped functions, any usage, and type safety issues.
5
- """
6
- import sys
7
- import re
8
- import subprocess
2
+ """Bounded annotation inventory, not type coverage or a type-safety verdict."""
3
+ import ast
4
+ import json
5
+ import os
9
6
  from pathlib import Path
10
-
11
- # Fix Windows console encoding for Unicode output
12
- try:
13
- sys.stdout.reconfigure(encoding='utf-8', errors='replace')
14
- sys.stderr.reconfigure(encoding='utf-8', errors='replace')
15
- except AttributeError:
16
- pass # Python < 3.7
17
-
18
- def check_typescript_coverage(project_path: Path) -> dict:
19
- """Check TypeScript type coverage."""
20
- issues = []
21
- passed = []
22
- stats = {'any_count': 0, 'untyped_functions': 0, 'total_functions': 0}
23
-
24
- ts_files = list(project_path.rglob("*.ts")) + list(project_path.rglob("*.tsx"))
25
- ts_files = [f for f in ts_files if 'node_modules' not in str(f) and '.d.ts' not in str(f)]
26
-
27
- if not ts_files:
28
- return {'type': 'typescript', 'files': 0, 'passed': [], 'issues': ["[!] No TypeScript files found"], 'stats': stats}
29
-
30
- for file_path in ts_files[:30]: # Limit
31
- try:
32
- content = file_path.read_text(encoding='utf-8', errors='ignore')
33
-
34
- # Count 'any' usage
35
- any_matches = re.findall(r':\s*any\b', content)
36
- stats['any_count'] += len(any_matches)
37
-
38
- # Find functions without return types
39
- # function name(params) { - no return type
40
- untyped = re.findall(r'function\s+\w+\s*\([^)]*\)\s*{', content)
41
- # Arrow functions without types: const fn = (x) => or (x) =>
42
- untyped += re.findall(r'=\s*\([^:)]*\)\s*=>', content)
43
- stats['untyped_functions'] += len(untyped)
44
-
45
- # Count typed functions
46
- typed = re.findall(r'function\s+\w+\s*\([^)]*\)\s*:\s*\w+', content)
47
- typed += re.findall(r':\s*\([^)]*\)\s*=>\s*\w+', content)
48
- stats['total_functions'] += len(typed) + len(untyped)
49
-
50
- except Exception:
51
- continue
52
-
53
- # Analyze results
54
- if stats['any_count'] == 0:
55
- passed.append("[OK] No 'any' types found")
56
- elif stats['any_count'] <= 5:
57
- issues.append(f"[!] {stats['any_count']} 'any' types found (acceptable)")
58
- else:
59
- issues.append(f"[X] {stats['any_count']} 'any' types found (too many)")
60
-
61
- if stats['total_functions'] > 0:
62
- typed_ratio = (stats['total_functions'] - stats['untyped_functions']) / stats['total_functions'] * 100
63
- if typed_ratio >= 80:
64
- passed.append(f"[OK] Type coverage: {typed_ratio:.0f}%")
65
- elif typed_ratio >= 50:
66
- issues.append(f"[!] Type coverage: {typed_ratio:.0f}% (improve)")
67
- else:
68
- issues.append(f"[X] Type coverage: {typed_ratio:.0f}% (too low)")
69
-
70
- passed.append(f"[OK] Analyzed {len(ts_files)} TypeScript files")
71
-
72
- return {'type': 'typescript', 'files': len(ts_files), 'passed': passed, 'issues': issues, 'stats': stats}
73
-
74
- def check_python_coverage(project_path: Path) -> dict:
75
- """Check Python type hints coverage."""
76
- issues = []
77
- passed = []
78
- stats = {'untyped_functions': 0, 'typed_functions': 0, 'any_count': 0}
79
-
80
- py_files = list(project_path.rglob("*.py"))
81
- py_files = [f for f in py_files if not any(x in str(f) for x in ['venv', '__pycache__', '.git', 'node_modules'])]
82
-
83
- if not py_files:
84
- return {'type': 'python', 'files': 0, 'passed': [], 'issues': ["[!] No Python files found"], 'stats': stats}
85
-
86
- for file_path in py_files[:30]: # Limit
7
+ import re
8
+ import sys
9
+ import stat
10
+
11
+ MAX_FILES = 30
12
+ MAX_BYTES = 1_000_000
13
+ SKIP = {'.git', 'node_modules', 'venv', '.venv', '__pycache__', 'dist', 'build'}
14
+
15
+
16
+ def source_files(root, suffixes):
17
+ """Yield a deterministic sample without following directory or file links."""
18
+ for directory, dirs, files in os.walk(root, followlinks=False):
19
+ dirs[:] = sorted(name for name in dirs if name not in SKIP and not (Path(directory) / name).is_symlink())
20
+ for name in sorted(files):
21
+ path = Path(directory) / name
22
+ if path.suffix in suffixes and not path.name.endswith('.d.ts') and not path.is_symlink():
23
+ yield path
24
+
25
+
26
+ def inventory(project_path, language):
27
+ result = {'type': language, 'files': 0, 'sample_limit': MAX_FILES, 'truncated': False, 'errors': [], 'stats': {}}
28
+ stats = result['stats']
29
+ stats.update({'functions': 0, 'fully_annotated_functions': 0} if language == 'python' else {'explicit_any_text_matches': 0})
30
+ for index, path in enumerate(source_files(project_path, {'.py'} if language == 'python' else {'.ts', '.tsx'})):
31
+ if index == MAX_FILES:
32
+ result['truncated'] = True
33
+ break
87
34
  try:
88
- content = file_path.read_text(encoding='utf-8', errors='ignore')
89
-
90
- # Count Any usage
91
- any_matches = re.findall(r':\s*Any\b', content)
92
- stats['any_count'] += len(any_matches)
93
-
94
- # Find functions with type hints
95
- typed_funcs = re.findall(r'def\s+\w+\s*\([^)]*:[^)]+\)', content)
96
- typed_funcs += re.findall(r'def\s+\w+\s*\([^)]*\)\s*->', content)
97
- stats['typed_functions'] += len(typed_funcs)
98
-
99
- # Find functions without type hints
100
- all_funcs = re.findall(r'def\s+\w+\s*\(', content)
101
- stats['untyped_functions'] += len(all_funcs) - len(typed_funcs)
102
-
103
- except Exception:
104
- continue
105
-
106
- total = stats['typed_functions'] + stats['untyped_functions']
107
-
108
- if total > 0:
109
- typed_ratio = stats['typed_functions'] / total * 100
110
- if typed_ratio >= 70:
111
- passed.append(f"[OK] Type hints coverage: {typed_ratio:.0f}%")
112
- elif typed_ratio >= 40:
113
- issues.append(f"[!] Type hints coverage: {typed_ratio:.0f}%")
114
- else:
115
- issues.append(f"[X] Type hints coverage: {typed_ratio:.0f}% (add type hints)")
116
-
117
- if stats['any_count'] == 0:
118
- passed.append("[OK] No 'Any' types found")
119
- elif stats['any_count'] <= 3:
120
- issues.append(f"[!] {stats['any_count']} 'Any' types found")
121
- else:
122
- issues.append(f"[X] {stats['any_count']} 'Any' types found")
35
+ flags = os.O_RDONLY | getattr(os, 'O_NOFOLLOW', 0) | getattr(os, 'O_NONBLOCK', 0)
36
+ fd = os.open(path, flags)
37
+ with os.fdopen(fd, 'rb') as handle:
38
+ if not stat.S_ISREG(os.fstat(handle.fileno()).st_mode):
39
+ raise ValueError('source is not a regular file')
40
+ raw = handle.read(MAX_BYTES + 1)
41
+ if len(raw) > MAX_BYTES:
42
+ raise ValueError('source exceeds byte limit')
43
+ text = raw.decode('utf-8')
44
+ if language == 'python':
45
+ tree = ast.parse(text)
46
+ for node in ast.walk(tree):
47
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
48
+ stats['functions'] += 1
49
+ args = node.args.posonlyargs + node.args.args + node.args.kwonlyargs
50
+ args += [arg for arg in (node.args.vararg, node.args.kwarg) if arg]
51
+ annotated = node.returns is not None and all(arg.annotation is not None for arg in args)
52
+ stats['fully_annotated_functions'] += int(annotated)
53
+ else:
54
+ # This includes comments/string literals and misses inferred/aliased any.
55
+ stats['explicit_any_text_matches'] += len(re.findall(r':\s*any\b', text))
56
+ result['files'] += 1
57
+ except (OSError, UnicodeError, ValueError, SyntaxError) as error:
58
+ result['errors'].append({'file': str(path.relative_to(project_path)), 'error': str(error)})
59
+ return result
60
+
61
+
62
+ def check_python_coverage(project_path):
63
+ return inventory(project_path, 'python')
64
+
65
+
66
+ def check_typescript_coverage(project_path):
67
+ return inventory(project_path, 'typescript')
123
68
 
124
- passed.append(f"[OK] Analyzed {len(py_files)} Python files")
125
-
126
- return {'type': 'python', 'files': len(py_files), 'passed': passed, 'issues': issues, 'stats': stats}
127
69
 
128
70
  def main():
129
- target = sys.argv[1] if len(sys.argv) > 1 else "."
130
- project_path = Path(target)
131
-
132
- print("\n" + "=" * 60)
133
- print(" TYPE COVERAGE CHECKER")
134
- print("=" * 60 + "\n")
135
-
136
- results = []
137
-
138
- # Check TypeScript
139
- ts_result = check_typescript_coverage(project_path)
140
- if ts_result['files'] > 0:
141
- results.append(ts_result)
142
-
143
- # Check Python
144
- py_result = check_python_coverage(project_path)
145
- if py_result['files'] > 0:
146
- results.append(py_result)
147
-
148
- if not results:
149
- print("[!] No TypeScript or Python files found.")
150
- sys.exit(0)
151
-
152
- # Print results
153
- critical_issues = 0
154
- for result in results:
155
- print(f"\n[{result['type'].upper()}]")
156
- print("-" * 40)
157
- for item in result['passed']:
158
- print(f" {item}")
159
- for item in result['issues']:
160
- print(f" {item}")
161
- if item.startswith("[X]"):
162
- critical_issues += 1
163
-
164
- print("\n" + "=" * 60)
165
- if critical_issues == 0:
166
- print("[OK] TYPE COVERAGE: ACCEPTABLE")
167
- sys.exit(0)
168
- else:
169
- print(f"[X] TYPE COVERAGE: {critical_issues} critical issues")
170
- sys.exit(1)
171
-
172
- if __name__ == "__main__":
173
- main()
71
+ root = Path(sys.argv[1] if len(sys.argv) > 1 else '.').resolve()
72
+ if not root.is_dir():
73
+ print('Project directory does not exist.', file=sys.stderr)
74
+ return 2
75
+ results = [inventory(root, language) for language in ('python', 'typescript')]
76
+ print(json.dumps({'kind': 'annotation-inventory', 'limitation': 'Not type coverage. Annotations do not establish correctness; TypeScript counts are lexical. Run the configured type checker.', 'results': results}, indent=2))
77
+ if any(result['errors'] for result in results):
78
+ return 1
79
+ return 0 if any(result['files'] for result in results) else 2
80
+
81
+
82
+ if __name__ == '__main__':
83
+ sys.exit(main())
@@ -0,0 +1,23 @@
1
+ # Mobile feature delivery
2
+
3
+ ## Inputs
4
+
5
+ Existing stack/version, target OS range, device access, offline requirements and API contract.
6
+
7
+ ## Procedure
8
+
9
+ 1. Use the existing framework and define platform-specific exceptions. Model loading, failed requests, permission denial and offline edits explicitly.
10
+ 2. Implement the shared behavior behind tested adapters. Bound retries and define duplicate/conflict handling before queueing writes for reconnection.
11
+ 3. Run the feature on each available target, checking background/foreground transitions, network loss, keyboard, accessibility and persistent state after restart.
12
+
13
+ ## Worked example
14
+
15
+ An offline note is edited twice and synced after reconnecting. Verify one intended final record, a visible conflict policy and no duplicated submission.
16
+
17
+ ## Verification and handoff
18
+
19
+ Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
20
+
21
+ ## Limitations
22
+
23
+ A cross-platform build does not prove feature parity on untested devices. Store submission and signing remain separate authorized actions.
@@ -0,0 +1,23 @@
1
+ # Cross-platform parity playbook
2
+
3
+ ## Inputs
4
+
5
+ Requested platforms, shared API contract, existing stacks, feature acceptance criteria and available tools.
6
+
7
+ ## Procedure
8
+
9
+ 1. Define behavior as observable scenarios, not a percentage of shared code. Record intentional platform differences before implementation.
10
+ 2. Implement shared contracts first, then platform adapters. Use available tools directly; agent role names in the main guide describe responsibilities and do not guarantee a delegation API exists.
11
+ 3. Maintain a matrix of scenario, platform, observed result and evidence. Check offline conflict handling, permission denial and accessible navigation separately for each target.
12
+
13
+ ## Worked example
14
+
15
+ A saved item must appear on web and mobile after synchronization. Test add, delete, retry and a conflicting edit on both platforms; identify any platform not exercised.
16
+
17
+ ## Verification and handoff
18
+
19
+ Report the actual files or configuration changed, checks performed, observed results and any untested environment. Keep the original inputs and evidence sufficient to reproduce the conclusion.
20
+
21
+ ## Limitations
22
+
23
+ Do not install every framework or manufacture parallel agents. Packaging, store upload and production deployment require the relevant authorization.