opencode-skills-collection 3.1.14 → 3.1.16

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 (164) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +36 -1
  2. package/bundled-skills/007/scripts/full_audit.py +34 -22
  3. package/bundled-skills/007/scripts/quick_scan.py +24 -15
  4. package/bundled-skills/007/scripts/scanners/dependency_scanner.py +31 -19
  5. package/bundled-skills/007/scripts/scanners/injection_scanner.py +24 -14
  6. package/bundled-skills/007/scripts/scanners/secrets_scanner.py +24 -14
  7. package/bundled-skills/007/scripts/score_calculator.py +25 -13
  8. package/bundled-skills/2slides-ppt-generator/scripts/download_slides_pages_voices.py +15 -1
  9. package/bundled-skills/aegisops-ai/SKILL.md +1 -1
  10. package/bundled-skills/agent-self-scheduling/SKILL.md +88 -0
  11. package/bundled-skills/alpha-vantage/SKILL.md +3 -1
  12. package/bundled-skills/anti-sleep/SKILL.md +90 -0
  13. package/bundled-skills/api-security-best-practices/SKILL.md +1 -1
  14. package/bundled-skills/app-store-optimization/SKILL.md +7 -0
  15. package/bundled-skills/audio-transcriber/scripts/transcribe.py +17 -4
  16. package/bundled-skills/azure-mgmt-botservice-py/SKILL.md +2 -1
  17. package/bundled-skills/azure-resource-manager-mysql-dotnet/SKILL.md +2 -1
  18. package/bundled-skills/azure-resource-manager-postgresql-dotnet/SKILL.md +2 -1
  19. package/bundled-skills/azure-resource-manager-sql-dotnet/SKILL.md +2 -1
  20. package/bundled-skills/biopython/SKILL.md +2 -1
  21. package/bundled-skills/brain-to-docs/SKILL.md +54 -0
  22. package/bundled-skills/browser-harness/SKILL.md +220 -0
  23. package/bundled-skills/browser-harness/references/install.md +132 -0
  24. package/bundled-skills/bumblebee/scripts/render_report.py +16 -3
  25. package/bundled-skills/bun-development/SKILL.md +1 -1
  26. package/bundled-skills/cc-skill-security-review/SKILL.md +2 -2
  27. package/bundled-skills/claude-monitor/scripts/monitor.py +15 -2
  28. package/bundled-skills/cmux/SKILL.md +250 -0
  29. package/bundled-skills/code-polish/SKILL.md +192 -0
  30. package/bundled-skills/code-review-checklist/SKILL.md +1 -1
  31. package/bundled-skills/codex-subagent/SKILL.md +117 -0
  32. package/bundled-skills/competitor-analysis/scripts/capture_screenshots.mjs +24 -3
  33. package/bundled-skills/competitor-analysis/scripts/compile_report.mjs +13 -2
  34. package/bundled-skills/competitor-analysis/scripts/extract_vs_names.mjs +23 -2
  35. package/bundled-skills/competitor-analysis/scripts/gate_candidates.mjs +21 -0
  36. package/bundled-skills/competitor-analysis/scripts/list_urls.mjs +23 -2
  37. package/bundled-skills/competitor-analysis/scripts/merge_partials.mjs +24 -3
  38. package/bundled-skills/container-security-hardening/SKILL.md +1 -1
  39. package/bundled-skills/content-creator/scripts/brand_voice_analyzer.py +15 -1
  40. package/bundled-skills/content-creator/scripts/seo_optimizer.py +15 -1
  41. package/bundled-skills/context-kit/SKILL.md +135 -0
  42. package/bundled-skills/cyber-audit/SKILL.md +138 -0
  43. package/bundled-skills/deepapi/SKILL.md +649 -0
  44. package/bundled-skills/delegating-to-agents/SKILL.md +64 -0
  45. package/bundled-skills/developer-signup-flow/SKILL.md +1 -1
  46. package/bundled-skills/diary/scripts/fetch_diaries.py +14 -1
  47. package/bundled-skills/diary/scripts/prepare_context.py +15 -2
  48. package/bundled-skills/diary/scripts/sync_to_notion.py +14 -1
  49. package/bundled-skills/dispatch/SKILL.md +19 -7
  50. package/bundled-skills/distribute-skill-to-all-agents/SKILL.md +85 -0
  51. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  52. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  53. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  54. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  55. package/bundled-skills/docs/users/bundles.md +1 -1
  56. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  57. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  58. package/bundled-skills/docs/users/getting-started.md +1 -1
  59. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  60. package/bundled-skills/docs/users/usage.md +4 -4
  61. package/bundled-skills/docs/users/visual-guide.md +4 -4
  62. package/bundled-skills/docx-official/ooxml/scripts/pack.py +30 -3
  63. package/bundled-skills/docx-official/ooxml/scripts/unpack.py +16 -3
  64. package/bundled-skills/drizzle-migration-conflict/scripts/check_drizzle_migrations.py +27 -17
  65. package/bundled-skills/ecl-harness-engineer/agents/creator-config.md +17 -3
  66. package/bundled-skills/ecl-harness-engineer/references/environment-detection-guide.md +9 -5
  67. package/bundled-skills/effective-agent-skills/SKILL.md +333 -0
  68. package/bundled-skills/electron-development/SKILL.md +6 -2
  69. package/bundled-skills/environment-setup-guide/SKILL.md +2 -5
  70. package/bundled-skills/expo-ui/scripts/list-components.js +5 -1
  71. package/bundled-skills/fable-safe-prompt/SKILL.md +79 -0
  72. package/bundled-skills/folder-specific-claude-and-agents-md/SKILL.md +96 -0
  73. package/bundled-skills/frontend-slides/scripts/extract-pptx.py +18 -4
  74. package/bundled-skills/gcp-cloud-run/SKILL.md +2 -1
  75. package/bundled-skills/gemini-api-integration/SKILL.md +3 -1
  76. package/bundled-skills/gemini-live-api-dev/SKILL.md +2 -1
  77. package/bundled-skills/gemini-omni-flash-api/scripts/video/generate_video.py +49 -14
  78. package/bundled-skills/goal-loop/SKILL.md +175 -0
  79. package/bundled-skills/hugging-face-evaluation/SKILL.md +1 -1
  80. package/bundled-skills/hugging-face-jobs/SKILL.md +1 -1
  81. package/bundled-skills/hugging-face-jobs/scripts/finepdfs-stats.py +14 -1
  82. package/bundled-skills/hugging-face-model-trainer/scripts/convert_to_gguf.py +10 -1
  83. package/bundled-skills/hugo-to-markdown/scripts/inventory_hugo_rules.py +14 -1
  84. package/bundled-skills/image-generator/SKILL.md +3 -1
  85. package/bundled-skills/instagram/scripts/export.py +18 -7
  86. package/bundled-skills/interview-style-doc-building/SKILL.md +86 -0
  87. package/bundled-skills/junta-leiloeiros/scripts/export.py +19 -10
  88. package/bundled-skills/landing-page-generator/scripts/landing_page_scaffolder.py +15 -1
  89. package/bundled-skills/linear-claude-skill/SKILL.md +4 -2
  90. package/bundled-skills/linkedin-post-writer/SKILL.md +159 -0
  91. package/bundled-skills/linkedin-post-writer/references/hook-formulas.md +482 -0
  92. package/bundled-skills/llm-council/SKILL.md +4 -2
  93. package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package-lock.json +5 -6
  94. package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package.json +2 -3
  95. package/bundled-skills/markdown-rendering/SKILL.md +72 -0
  96. package/bundled-skills/matematico-tao/scripts/complexity_analyzer.py +14 -1
  97. package/bundled-skills/matematico-tao/scripts/dependency_graph.py +15 -2
  98. package/bundled-skills/mobile-design/scripts/mobile_audit.py +20 -6
  99. package/bundled-skills/monte-carlo-validation-notebook/scripts/resolve_dbt_schema.py +15 -2
  100. package/bundled-skills/multi-agent-architect/SKILL.md +1 -1
  101. package/bundled-skills/odoo-rpc-api/SKILL.md +2 -1
  102. package/bundled-skills/pci-compliance/SKILL.md +3 -1
  103. package/bundled-skills/pdf-official/scripts/create_validation_image.py +17 -3
  104. package/bundled-skills/pdf-official/scripts/extract_form_field_info.py +1 -1
  105. package/bundled-skills/personal-tool-builder/SKILL.md +1 -1
  106. package/bundled-skills/pi-custom-model/SKILL.md +68 -0
  107. package/bundled-skills/pi-web-search/SKILL.md +74 -0
  108. package/bundled-skills/playwright-skill/run.js +19 -1
  109. package/bundled-skills/pptx-official/ooxml/scripts/pack.py +30 -3
  110. package/bundled-skills/pptx-official/ooxml/scripts/unpack.py +16 -3
  111. package/bundled-skills/pptx-official/scripts/inventory.py +17 -4
  112. package/bundled-skills/pptx-official/scripts/rearrange.py +15 -2
  113. package/bundled-skills/pptx-official/scripts/replace.py +16 -3
  114. package/bundled-skills/product-manager-toolkit/scripts/customer_interview_analyzer.py +15 -1
  115. package/bundled-skills/production-code-audit/SKILL.md +1 -1
  116. package/bundled-skills/push-skill-to-github/SKILL.md +61 -0
  117. package/bundled-skills/rclone-cli/references/commands/rclone_completion_powershell.md +3 -2
  118. package/bundled-skills/read-all-adrs/SKILL.md +35 -0
  119. package/bundled-skills/remote-gpu-trainer/scripts/verify_local.py +14 -1
  120. package/bundled-skills/research-prompt/SKILL.md +63 -0
  121. package/bundled-skills/run-deep-swe/SKILL.md +120 -0
  122. package/bundled-skills/senior-architect/scripts/architecture_diagram_generator.py +15 -2
  123. package/bundled-skills/senior-architect/scripts/dependency_analyzer.py +15 -2
  124. package/bundled-skills/senior-architect/scripts/project_architect.py +15 -2
  125. package/bundled-skills/senior-frontend/scripts/bundle_analyzer.py +14 -1
  126. package/bundled-skills/senior-frontend/scripts/frontend_scaffolder.py +14 -1
  127. package/bundled-skills/senior-fullstack/scripts/code_quality_analyzer.py +15 -2
  128. package/bundled-skills/senior-fullstack/scripts/fullstack_scaffolder.py +15 -2
  129. package/bundled-skills/senior-fullstack/scripts/project_scaffolder.py +15 -2
  130. package/bundled-skills/setup-help/SKILL.md +50 -0
  131. package/bundled-skills/shodan-reconnaissance/SKILL.md +2 -1
  132. package/bundled-skills/short/SKILL.md +28 -0
  133. package/bundled-skills/skill-creator/scripts/init_skill.py +15 -2
  134. package/bundled-skills/skill-creator/scripts/package_skill.py +29 -12
  135. package/bundled-skills/skill-creator/scripts/quick_validate.py +14 -2
  136. package/bundled-skills/skill-creator-ms/SKILL.md +1 -1
  137. package/bundled-skills/skill-installer/scripts/install_skill.py +42 -8
  138. package/bundled-skills/skill-installer/scripts/package_skill.py +29 -17
  139. package/bundled-skills/skill-installer/scripts/validate_skill.py +37 -22
  140. package/bundled-skills/stripe-integration/SKILL.md +7 -3
  141. package/bundled-skills/swiftui-expert-skill/scripts/instruments_parser/xctrace.py +7 -1
  142. package/bundled-skills/swiftui-expert-skill/scripts/instruments_parser/xml_utils.py +7 -1
  143. package/bundled-skills/taisly-social-media-posting/SKILL.md +79 -0
  144. package/bundled-skills/technical-tutorials/SKILL.md +1 -1
  145. package/bundled-skills/telegram/scripts/setup_project.py +17 -2
  146. package/bundled-skills/time-ledger/SKILL.md +118 -0
  147. package/bundled-skills/trading-ledger/SKILL.md +121 -0
  148. package/bundled-skills/videodb/scripts/ws_listener.py +17 -4
  149. package/bundled-skills/voice-ai-development/SKILL.md +2 -1
  150. package/bundled-skills/vps-server-management/SKILL.md +72 -0
  151. package/bundled-skills/weaviate/scripts/weaviate_conn.py +20 -18
  152. package/bundled-skills/wgm/SKILL.md +137 -0
  153. package/bundled-skills/whatsapp-cloud-api/scripts/setup_project.py +16 -1
  154. package/bundled-skills/workorai/SKILL.md +137 -0
  155. package/bundled-skills/wp-site-health-auditor/SKILL.md +341 -0
  156. package/bundled-skills/wp-site-health-auditor/references/catalog.md +135 -0
  157. package/bundled-skills/writing-skills/render-graphs.js +13 -2
  158. package/bundled-skills/x-twitter-scraper/SKILL.md +3 -1
  159. package/bundled-skills/youtube-notetaker/scripts/serve.py +41 -31
  160. package/bundled-skills/youtube-notetaker/scripts/vtt_to_transcript.py +16 -2
  161. package/bundled-skills/youtube-notetaker/scripts/write_library_item.py +15 -1
  162. package/bundled-skills/youtube-transcript/SKILL.md +120 -0
  163. package/package.json +5 -1
  164. package/skills_index.json +786 -6
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: folder-specific-claude-and-agents-md
3
+ description: "Create folder-scoped CLAUDE.md and AGENTS.md guidance for future agents working in that area."
4
+ category: development
5
+ risk: critical
6
+ source: community
7
+ source_repo: davidondrej/skills
8
+ source_type: community
9
+ date_added: "2026-07-07"
10
+ author: davidondrej
11
+ tags: [agents-md, claude-md, documentation]
12
+ tools: [claude, codex]
13
+ license: "MIT"
14
+ license_source: "https://github.com/davidondrej/skills/blob/main/LICENSE"
15
+ user-invocable: true
16
+ ---
17
+
18
+ # Folder CLAUDE.md Creation
19
+
20
+ ## When to Use
21
+
22
+ - Use when the user asks for folder-specific agent instructions or local context files.
23
+ - Use when a subdirectory needs a CLAUDE.md and AGENTS.md handoff for future agents.
24
+
25
+ Generate a focused `CLAUDE.md` inside a target folder, plus an `AGENTS.md` symlink pointing at it. The file gives any future agent (Claude Code, Codex, etc.) the folder-specific context the global `CLAUDE.md` doesn't cover.
26
+
27
+ Background reference: `library/claude-code/claude-and-agents-md.md`.
28
+
29
+ ## Process
30
+
31
+ ### Step 1: Confirm the target folder + sanity-check it deserves a file
32
+ Ask the user which folder. Use absolute path under `~/Documents/code/workspace/`.
33
+
34
+ **Only create a file if the folder has context needed across multiple sessions** — active evolving work, specific conventions, ongoing decisions. A folder of static reference files does NOT need one (agents can read on demand). If unsure, ask the user.
35
+
36
+ ### Step 2: Read every file in the folder IN FULL
37
+ - Use `ls -la` first to enumerate files and subfolders.
38
+ - Read every markdown, config, and key source file.
39
+ - For large tldraw/Vite subprojects: read `package.json`, `src/App.tsx`, one representative module file, and the folder's own `module-details.md`-style files.
40
+ - Do NOT skim. Do NOT skip. The user's later edits depend on you having full context.
41
+
42
+ ### Step 3: Draft a bullet list of candidate content
43
+ Before writing the file, give the user a bullet list grouped by section — let them react first. Candidate sections (skip any that don't apply):
44
+
45
+ - **Product / Purpose** — what this folder/project is, current state, key metrics
46
+ - **Avatar / Audience** — who it's for (if applicable)
47
+ - **Essential Files** — one-line role for each important file, including cross-folder references (use `@path/file.md` import syntax)
48
+ - **Constraints (MUST NOT)** — explicit hard negatives. Highest-ROI content in the file.
49
+ - **Conventions** — the user's lingo, status emojis (✅ 🟡), naming patterns, "usually do" patterns
50
+ - **Locked Decisions** — things agreed + dated, must not re-litigate
51
+ - **Context** — history, authority, credibility that frames the work
52
+ - **How to work with the user** — collaboration style for this specific folder
53
+ - **Marketing Angles / Positioning** — if public-facing
54
+ - **Top Insights** — 3-5 most glaring signals from research (if research exists)
55
+
56
+ ### Step 4: Iterate with the user
57
+ - Keep answers short. The user will edit directly in the IDE.
58
+ - When they edit the file, RE-READ it and flag: contradictions, typos, missing rules, wrong categorization.
59
+ - Do not revert their edits unless asked.
60
+
61
+ ### Step 5: Write the file
62
+ - Path: `<folder>/CLAUDE.md`
63
+ - Start with a one-line header explaining the file's purpose.
64
+ - **Subdir file marker:** if this is a subdirectory file (parent folder already has its own CLAUDE.md), open with `Apply root CLAUDE.md first, then this file.`
65
+ - Use `##` section headers matching the sections the user approved.
66
+ - Bullets over prose. Short bullets.
67
+ - **Cross-folder references:** use `@relative/path/file.md` import syntax, not prose mentions.
68
+ - **Heavy reference docs:** annotate with `**Read when:**` triggers (e.g. "Read when: writing offer copy"). Prevents loading every session.
69
+
70
+ ### Step 6: Create the AGENTS.md symlink
71
+ ```
72
+ cd <folder> && ln -s CLAUDE.md AGENTS.md
73
+ ```
74
+ Verify with `ls -la CLAUDE.md AGENTS.md`.
75
+
76
+ ### Step 7: Commit only when asked
77
+ Do NOT stage or push unless the user says to. When they do: `git add -A`, commit with a `Day N:` style message, push.
78
+
79
+ ## Rules
80
+
81
+ - **Never invent content.** Every bullet must trace back to something you read in the folder or something the user said. No generic boilerplate.
82
+ - **Brevity wins.** The user edits aggressively to make things shorter. Start tight.
83
+ - **Folder-scoped only.** Don't duplicate the global `CLAUDE.md` (personality, dates, ports, etc.). Only include what's specific to this folder.
84
+ - **No file trees, no directory dumps, no stack details the code already shows.** Anything an agent can derive from `ls` or `grep` rots fast and wastes tokens. Pin decisions, rules, and context — not structure.
85
+ - **Constraints vs Conventions.** Hard "MUST NOT" rules go in Constraints (explicit negatives). "Usually do X" patterns go in Conventions. Splitting these improves adherence.
86
+ - **No absolute ALWAYS/NEVER without explicit exceptions.** Edge cases make absolute rules get ignored. "Never commit secrets EXCEPT `.env.example`" beats "never commit secrets."
87
+ - **Never summarize or auto-shorten the file.** Context collapse degrades it. Grow deliberately, prune manually. If the user asks to trim, do it by hand.
88
+ - **Maintenance loop.** When the user corrects the agent on something this file should have prevented, add the rule to the file immediately. Don't wait.
89
+ - **No emojis unless the user uses them** (status markers ✅ 🟡 are the exception — they're already conventions).
90
+ - **Symlink, not copy.** `AGENTS.md` must be a symlink so edits stay in sync.
91
+ - **Flag gaps honestly.** If the user's edits introduce contradictions (e.g. "sell X" in one section and "never sell X" in another), call it out before they ask.
92
+
93
+ ## Limitations
94
+
95
+ - Adapted from `davidondrej/skills`; verify local paths, tools, credentials, and agent features before acting.
96
+ - For commands, remote access, scheduling, browser automation, or file-changing workflows, get explicit user approval and confirm the target environment first.
@@ -13,6 +13,20 @@ import json
13
13
  import os
14
14
  import sys
15
15
  from pptx import Presentation
16
+ from pathlib import Path
17
+
18
+
19
+ def safe_user_path(path_value, base_dir="."):
20
+ """Resolve a CLI path under the current workspace."""
21
+ if base_dir != ".":
22
+ raise ValueError("Custom base directories are not supported for CLI paths")
23
+ base_path = Path.cwd().resolve()
24
+ resolved_path = Path(path_value).expanduser().resolve()
25
+ try:
26
+ resolved_path.relative_to(base_path)
27
+ except ValueError as exc:
28
+ raise ValueError(f"Path escapes allowed directory: {path_value}") from exc
29
+ return resolved_path
16
30
 
17
31
 
18
32
  def extract_pptx(file_path, output_dir="."):
@@ -54,7 +68,7 @@ def extract_pptx(file_path, output_dir="."):
54
68
  image_name = f"slide{slide_num + 1}_img{len(slide_data['images']) + 1}.{image_ext}"
55
69
  image_path = os.path.join(assets_dir, image_name)
56
70
 
57
- with open(image_path, "wb") as f:
71
+ with safe_user_path(image_path).open("wb") as f:
58
72
  f.write(image_bytes)
59
73
 
60
74
  slide_data["images"].append(
@@ -81,14 +95,14 @@ if __name__ == "__main__":
81
95
  sys.exit(1)
82
96
 
83
97
  input_file = sys.argv[1]
84
- output_dir = sys.argv[2] if len(sys.argv) > 2 else "."
98
+ output_dir = safe_user_path(sys.argv[2]) if len(sys.argv) > 2 else "."
85
99
 
86
100
  slides = extract_pptx(input_file, output_dir)
87
101
 
88
102
  # Write extracted data as JSON
89
103
  output_path = os.path.join(output_dir, "extracted-slides.json")
90
- with open(output_path, "w") as f:
91
- json.dump(slides, f, indent=2)
104
+ with safe_user_path(output_path).open("w") as f:
105
+ f.write(json.dumps(slides, indent=2))
92
106
 
93
107
  print(f"Extracted {len(slides)} slides to {output_path}")
94
108
  for s in slides:
@@ -948,6 +948,7 @@ cloud-sql-python-connector[pg8000]
948
948
  ```
949
949
 
950
950
  ```python
951
+ import os
951
952
  from google.cloud.sql.connector import Connector
952
953
  import sqlalchemy
953
954
 
@@ -958,7 +959,7 @@ def getconn():
958
959
  "project:region:instance",
959
960
  "pg8000",
960
961
  user="user",
961
- password="password",
962
+ password=os.environ["DB_PASSWORD"],
962
963
  db="database"
963
964
  )
964
965
 
@@ -37,7 +37,9 @@ pip install google-generativeai
37
37
 
38
38
  Set your API key securely:
39
39
  ```bash
40
- export GEMINI_API_KEY="your-api-key-here"
40
+ read -rsp "Gemini API key: " GEMINI_API_KEY
41
+ echo
42
+ export GEMINI_API_KEY
41
43
  ```
42
44
 
43
45
  ### 2. Basic Text Generation
@@ -85,9 +85,10 @@ To streamline real-time audio/video app development, use a third-party integrati
85
85
  #### Python
86
86
 
87
87
  ```python
88
+ import os
88
89
  from google import genai
89
90
 
90
- client = genai.Client(api_key="YOUR_API_KEY")
91
+ client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
91
92
  ```
92
93
 
93
94
  #### JavaScript
@@ -15,12 +15,27 @@ import sys
15
15
  import time
16
16
  import urllib.request
17
17
  import urllib.error
18
+ import urllib.parse
18
19
  import uuid
19
20
  from google import genai
20
21
 
21
22
  # Load local upload helper logic inline to prevent dependency issues
22
23
  sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
23
24
  from upload_file import upload_file, wait_for_active
25
+ from pathlib import Path
26
+
27
+
28
+ def safe_user_path(path_value, base_dir="."):
29
+ """Resolve a CLI path under the current workspace."""
30
+ if base_dir != ".":
31
+ raise ValueError("Custom base directories are not supported for CLI paths")
32
+ base_path = Path.cwd().resolve()
33
+ resolved_path = Path(path_value).expanduser().resolve()
34
+ try:
35
+ resolved_path.relative_to(base_path)
36
+ except ValueError as exc:
37
+ raise ValueError(f"Path escapes allowed directory: {path_value}") from exc
38
+ return resolved_path
24
39
 
25
40
  def get_api_key(args):
26
41
  """Retrieves API key from command args or environment."""
@@ -28,22 +43,43 @@ def get_api_key(args):
28
43
  return args.api_key
29
44
  return os.environ.get("GEMINI_API_KEY")
30
45
 
46
+ FILE_ID_RE = re.compile(r'^[A-Za-z0-9_-]+$')
47
+
48
+
49
+ def extract_file_id(uri):
50
+ """Returns a Gemini File API id from a local reference or trusted API URL."""
51
+ if not uri:
52
+ return None
53
+ if uri.startswith("files/"):
54
+ file_id = uri.removeprefix("files/")
55
+ return file_id if FILE_ID_RE.fullmatch(file_id) else None
56
+
57
+ parsed = urllib.parse.urlparse(uri)
58
+ if parsed.scheme != "https" or parsed.netloc != "generativelanguage.googleapis.com":
59
+ return None
60
+ path_match = re.fullmatch(r'/files/([A-Za-z0-9_-]+)', parsed.path)
61
+ return path_match.group(1) if path_match else None
62
+
63
+
31
64
  def is_file_uri(uri):
32
65
  """Returns True if the string is a standard Gemini File URI."""
33
- if not uri:
34
- return False
35
- return "files/" in uri and ("generativelanguage.googleapis.com" in uri or uri.startswith("files/"))
66
+ return extract_file_id(uri) is not None
36
67
 
37
68
  def normalize_file_uri(uri):
38
69
  """Normalizes any File API URI/reference to the standard https://generativelanguage.googleapis.com/files/{id} format."""
39
- if not uri:
40
- return None
41
- match = re.search(r'files/([a-zA-Z0-9]+)', uri)
42
- if match:
43
- file_id = match.group(1)
70
+ file_id = extract_file_id(uri)
71
+ if file_id:
44
72
  return f"https://generativelanguage.googleapis.com/files/{file_id}"
45
73
  return uri
46
74
 
75
+
76
+ def media_download_url(file_uri):
77
+ """Build a media URL only for validated Gemini File API references."""
78
+ file_id = extract_file_id(file_uri)
79
+ if not file_id:
80
+ raise ValueError("Generated video URI must be a Gemini File API reference.")
81
+ return f"https://generativelanguage.googleapis.com/files/{file_id}?alt=media"
82
+
47
83
  def slugify(text):
48
84
  """Converts a text prompt into a safe, descriptive filename slug."""
49
85
  text = text.lower()
@@ -144,7 +180,7 @@ def resolve_or_upload_asset(asset_path, mime_type, api_key, strip_audio=False):
144
180
  # Clean up temporary stripped file if we created one
145
181
  if temp_stripped_path and os.path.exists(temp_stripped_path):
146
182
  try:
147
- os.remove(temp_stripped_path)
183
+ safe_user_path(temp_stripped_path).unlink()
148
184
  print(f"Cleaned up temporary video file: {temp_stripped_path}")
149
185
  except Exception as e:
150
186
  print(f"Warning: Failed to remove temporary file {temp_stripped_path}: {e}", file=sys.stderr)
@@ -157,8 +193,7 @@ def resolve_or_upload_asset(asset_path, mime_type, api_key, strip_audio=False):
157
193
 
158
194
  def download_video_file(file_uri, output_path, api_key):
159
195
  """Downloads generated video file from URI using alt=media standard in a memory-safe, chunked manner."""
160
- separator = "&" if "?" in file_uri else "?"
161
- download_url = f"{file_uri}{separator}alt=media"
196
+ download_url = media_download_url(file_uri)
162
197
 
163
198
  print(f"Downloading video from {file_uri} to {output_path} in chunked mode...")
164
199
  req = urllib.request.Request(download_url)
@@ -170,7 +205,7 @@ def download_video_file(file_uri, output_path, api_key):
170
205
  if parent_dir:
171
206
  os.makedirs(parent_dir, exist_ok=True)
172
207
 
173
- with open(output_path, "wb") as f:
208
+ with safe_user_path(output_path).open("wb") as f:
174
209
  while True:
175
210
  chunk = resp.read(8192)
176
211
  if not chunk:
@@ -343,7 +378,7 @@ def main():
343
378
  print(f"Error: Batch JSON file '{args.batch}' not found.", file=sys.stderr)
344
379
  sys.exit(1)
345
380
  try:
346
- with open(args.batch, "r", encoding="utf-8") as f:
381
+ with safe_user_path(args.batch).open("r", encoding="utf-8") as f:
347
382
  jobs = json.load(f)
348
383
  if not isinstance(jobs, list):
349
384
  print("Error: Batch JSON file must contain a list/array of job objects.", file=sys.stderr)
@@ -361,7 +396,7 @@ def main():
361
396
  sys.exit(1)
362
397
 
363
398
  jobs = []
364
- with open(args.prompts_file, "r", encoding="utf-8") as f:
399
+ with safe_user_path(args.prompts_file).open("r", encoding="utf-8") as f:
365
400
  for line in f:
366
401
  line = line.strip()
367
402
  if line and not line.startswith("#"):
@@ -0,0 +1,175 @@
1
+ ---
2
+ name: goal-loop
3
+ description: "Draft and explain persistent goal-loop prompts for long-running agent work with clear stop conditions."
4
+ category: agent-orchestration
5
+ risk: safe
6
+ source: community
7
+ source_repo: davidondrej/skills
8
+ source_type: community
9
+ date_added: "2026-07-07"
10
+ author: davidondrej
11
+ tags: [goals, autonomy, planning]
12
+ tools: [claude, codex]
13
+ license: "MIT"
14
+ license_source: "https://github.com/davidondrej/skills/blob/main/LICENSE"
15
+ ---
16
+
17
+ # Agent `/goal` Loop
18
+
19
+ ## What `/goal` is
20
+
21
+ `/goal` is a slash command that turns an agent prompt into a **persistent agent** looping `plan → act → test → review → iterate` until a stop condition is met, the user pauses, or the token budget runs out. Internally called the "Ralph loop."
22
+
23
+ Agents with the `/goal` feature right now: **Codex, Claude Code, and Hermes Agent**.
24
+
25
+ Key difference from a normal prompt: when a turn ends but the goal isn't met, the agent **auto-continues** instead of waiting for input.
26
+
27
+ **Lifecycle states:** `pursuing`, `paused`, `achieved`, `unmet`, `budget-limited`.
28
+
29
+ When monitoring a running `/goal`, every check should include a one-line update to the user: what the agent is doing and whether it is on track. Keep it extremely concise.
30
+
31
+ **Not:** a budget command, a safety boundary, "run forever", or a replacement for `/plan`. It's a contract enforcer with a verification loop.
32
+
33
+ ## Requirements
34
+
35
+ - An agent with the `/goal` feature — right now: Codex, Claude Code, or Hermes Agent
36
+ - The goals feature enabled in the agent's config
37
+ - **Subscription auth** — API-key auth does **not** work. A pro-tier plan is the realistic minimum for long runs.
38
+
39
+ ## When to Use it
40
+
41
+ Use only when **all three** are true:
42
+ 1. Task is >30 min of mechanical work.
43
+ 2. There's a **verifiable stop condition** (tests pass, coverage hit, eval ≥ X, build green).
44
+ 3. Repo is agent-ready (working build, decent tests, `AGENTS.md` present).
45
+
46
+ Fits: migrations, coverage lifts, TDD feature builds, refactors with contract tests, prompt/eval optimization, deploy retry loops, bug-repro-then-fix.
47
+
48
+ Bad fits: exploratory work, vague "improve this", anything without a "done" definition, prod credentials, destructive shared-infra ops.
49
+
50
+ ## The 5-part contract (every goal needs this)
51
+
52
+ 1. **Objective** — one sentence, one concrete outcome.
53
+ 2. **Constraints** — what must NOT change (public API, files, libs, conventions).
54
+ 3. **Validation command** — the exact shell command that proves progress (`pytest -q`, `pnpm test`, etc.).
55
+ 4. **Stop condition** — verifiable: "Stop when X passes" OR "when further changes need human/product input."
56
+ 5. **Documentation** — one sentence instructing the agent to write concise, targeted docs for every change, either creating new `.md` files or updating existing ones.
57
+
58
+ Plus: tell the agent what to read first, ask it to work in checkpoints with a short progress log.
59
+
60
+ ## Writing a goal (the core deliverable)
61
+
62
+ When the user wants a quick `/goal` instruction, produce a structured markdown block with one line per contract item (proper newlines, not flowing prose). **Do not prefix the output with `/goal`** — the user adds the slash command themselves in the composer. Emit only the contract body. Template:
63
+
64
+ ```
65
+ **Objective:** <one-sentence objective>
66
+ **Read first:** <files/PLAN.md/issue>
67
+ **Constraints:** <what not to change, libs, conventions>
68
+ **Validate:** `<exact command>` after each change
69
+ **Document:** Write concise, targeted documentation for all changes — create new `.md` files or update existing docs as needed.
70
+ **Checkpoints:** work in checkpoints and log progress briefly
71
+ **Stop when:** <verifiable condition>, OR when further changes require human/product input
72
+ ```
73
+
74
+ ### Example (migration)
75
+
76
+ ```
77
+ **Objective:** Migrate this project from Pydantic v1 to v2.
78
+ **Read first:** pyproject.toml, src/, tests/
79
+ **Constraints:** no public API changes; keep imports backwards-compatible via shims if needed; no new dependencies
80
+ **Validate:** `pytest -q` after each change
81
+ **Checkpoints:** work in checkpoints; log progress briefly
82
+ **Stop when:** full suite passes with zero deprecation warnings, OR when a change requires architecture decisions
83
+ ```
84
+
85
+ ### Example (coverage lift)
86
+
87
+ ```
88
+ **Objective:** Raise coverage in src/auth/ from ~38% to ≥75%.
89
+ **Read first:** src/auth/, tests/auth/, AGENTS.md
90
+ **Constraints:** no new deps; mirror existing test style; do not modify production code unless strictly required for testability
91
+ **Validate:** `pytest --cov=src/auth --cov-report=term-missing`
92
+ **Checkpoints:** work in checkpoints; log coverage delta each one
93
+ **Stop when:** coverage ≥75% AND all tests pass, OR when uncovered code needs design changes
94
+ ```
95
+
96
+ ### Writing rules
97
+ - **One objective, one stop condition.** Not a backlog.
98
+ - **Documentation is mandatory.** Every `/goal` prompt must include a single sentence committing the agent to concise, targeted docs — new `.md` files or focused updates to existing docs.
99
+ - **Never instruct the agent to create new ADRs** — ADRs require the user's explicit approval, so goal prompts must not pre-approve or encourage them.
100
+ - **Forbid reward-hacking explicitly:** "Do not delete, skip, weaken, or narrow tests to make the goal pass." Otherwise the agent may game the stop condition.
101
+ - **4,000-char limit** on the objective. If longer, put detail in a file (`PLAN.md`/`GOAL_BRIEF.md`) and make the goal point to it — keep the goal itself compact.
102
+ - Use **literal strings** for paths, commands, issue numbers — exact.
103
+ - Forbid scope creep explicitly: "Do not refactor unrelated code. Do not add dependencies."
104
+ - Tell the agent when to pause: "If <condition>, pause and ask before proceeding."
105
+ - Short, vague goals burn tokens for no extra value vs. a normal prompt.
106
+
107
+ ### Meta-prompting trick (highest-leverage)
108
+
109
+ Hand-written goals under-specify. Ask a second AI session (Claude with the codebase loaded, ChatGPT with project connected, or a separate agent thread in the same dir) to: (1) inspect the codebase, (2) surface hidden assumptions/constraints/edge cases, (3) emit a structured `/goal` markdown block using the 4-part contract. Paste that into the agent. Order-of-magnitude better runs.
110
+
111
+ Claude Code cmux note: after Claude finishes, it may prefill a predicted next user message; that draft is Claude, not the user speaking.
112
+
113
+ ### Self-goal setting
114
+
115
+ The agent can now write and set its own goal natively (the `create_goal` tool). Instead of crafting the contract yourself, give it your high-level intent and tell it to set the goal: "Inspect this repo, then write yourself a `/goal` with a verifiable stop condition and pursue it." It's the meta-prompting trick done inline — the agent turns your intent into the contract. Still give it the same raw materials (files to read, constraints, the validation command) so the goal it writes is grounded. Add: "ask clarifying questions before committing if the intent is underspecified" — catches ambiguity up front and prevents the self-set goal from drifting.
116
+
117
+ ## Launching
118
+
119
+ 1. `cd <repo>` (goals run scoped to the working directory).
120
+ 2. Launch the agent bare (opens the TUI). **Not** exec/headless mode — `/goal` is a TUI slash command only.
121
+ 3. Sign in with subscription auth (not an API key).
122
+ 4. Type `/goal <your contract>` in the composer, Enter.
123
+ 5. Walk away.
124
+
125
+ ## Controlling a running goal
126
+
127
+ | Command | Effect |
128
+ |---|---|
129
+ | `/goal` (alone) | Status: current checkpoint, what's verified, what remains, blockers |
130
+ | `/goal pause` | Freeze |
131
+ | `/goal resume` | Unfreeze (paused goals never auto-resume) |
132
+ | `/goal clear` | Kill the goal |
133
+ | `/goal <new>` | Replace the current goal |
134
+ | Ctrl+C / any typed message | Auto-pauses; user input always wins priority |
135
+
136
+ Resuming across sessions: goal state is persisted server-side. `cd` back into the repo, launch the agent, `/goal` for status, `/goal resume`.
137
+
138
+ Budget-limited state: the agent doesn't stop abruptly — it summarizes, notes what's left, saves state. `/goal resume` works after budget refresh or upgrade.
139
+
140
+ ## When a goal drifts
141
+
142
+ - **Minor drift:** just type a correction in the composer (auto-pauses, folds it in, resumes).
143
+ - **Loose objective:** `/goal pause`, read status, then `/goal <tighter version>` — replaces the contract. Don't pile instructions on a vague goal.
144
+ - **Bad mess:** `/goal clear`, `git status` or `git stash`, rewrite with the meta-prompting trick, restart.
145
+
146
+ Don't let a drifting goal keep running "to see where it goes." Tokens burn, diffs compound.
147
+
148
+ ## Operational tips
149
+
150
+ - Inspect status periodically with bare `/goal`.
151
+ - **Always review the diff** before merging — long autonomy means more code to validate, not less. Human oversight becomes more critical, not optional.
152
+ - Keep approvals/sandboxing tight; default permissions are correct.
153
+ - First run: pick a 30-min scoped task so you learn how `/goal` actually stops before trusting it overnight.
154
+ - Bake recurring policy into `AGENTS.md` so every goal inherits it without restating: adversarial self-review before declaring done, an extra QA pass even when tests pass, and the standard validation command. Saves repeating it in each goal paragraph.
155
+
156
+ ## Troubleshooting
157
+
158
+ | Symptom | Fix |
159
+ |---|---|
160
+ | `/goal` missing from slash popup | Update the agent to a version that supports `/goal` |
161
+ | Feature flag on but command missing | Quit and restart the agent fully |
162
+ | Typed `/goals` | It's singular: `/goal` |
163
+ | Doesn't activate | Sign out, sign back in with subscription auth (not API key) |
164
+ | Stopped with progress summary | Budget-limited — `/goal resume` after refresh, or tighten scope |
165
+ | `/goal resume` says no active goal | Terminal state or cleared — start fresh with `/goal <new>` |
166
+ | Goal looks active but won't auto-continue | Stuck in Plan mode — plan-only work doesn't trigger continuation. Draft the plan, then switch to Goal execution |
167
+
168
+ ## Mental model
169
+
170
+ `/goal` is a **contract enforcer with a verification loop**, not a "run forever" button. The shift: stop writing prompts, start writing **specifications with stop conditions**. Spend the time upfront defining "done"; the run takes care of itself.
171
+
172
+ ## Limitations
173
+
174
+ - Adapted from `davidondrej/skills`; verify local paths, tools, credentials, and agent features before acting.
175
+ - For commands, remote access, scheduling, browser automation, or file-changing workflows, get explicit user approval and confirm the target environment first.
@@ -192,7 +192,7 @@ Fetch benchmark scores from Artificial Analysis API and add them to a model card
192
192
 
193
193
  **Basic Usage:**
194
194
  ```bash
195
- AA_API_KEY="your-api-key" uv run scripts/evaluation_manager.py import-aa \
195
+ env "AA_API_KEY=${AA_API_KEY:?set AA_API_KEY first}" uv run scripts/evaluation_manager.py import-aa \
196
196
  --creator-slug "anthropic" \
197
197
  --model-name "claude-sonnet-4" \
198
198
  --repo-id "username/model-name"
@@ -830,7 +830,7 @@ webhook = create_webhook(
830
830
  {"type": "org", "name": "your-org-name"}
831
831
  ],
832
832
  domains=["repo", "discussion"],
833
- secret="your-secret"
833
+ secret=os.environ["HF_WEBHOOK_SECRET"]
834
834
  )
835
835
  ```
836
836
 
@@ -42,6 +42,19 @@ import sys
42
42
  import time
43
43
  from pathlib import Path
44
44
 
45
+
46
+ def safe_user_path(path_value, base_dir="."):
47
+ """Resolve a CLI path under the current workspace."""
48
+ if base_dir != ".":
49
+ raise ValueError("Custom base directories are not supported for CLI paths")
50
+ base_path = Path.cwd().resolve()
51
+ resolved_path = Path(path_value).expanduser().resolve()
52
+ try:
53
+ resolved_path.relative_to(base_path)
54
+ except ValueError as exc:
55
+ raise ValueError(f"Path escapes allowed directory: {path_value}") from exc
56
+ return resolved_path
57
+
45
58
  import polars as pl
46
59
  from ascii_graph import Pyasciigraph
47
60
  from datasets import Dataset
@@ -401,7 +414,7 @@ def main():
401
414
  print("The 'text' column is never loaded, making this very fast.\n")
402
415
 
403
416
  # Create output directory
404
- output_dir = Path(args.output_dir)
417
+ output_dir = safe_user_path(args.output_dir)
405
418
  output_dir.mkdir(parents=True, exist_ok=True)
406
419
 
407
420
  # Single scan: compute temporal stats
@@ -84,6 +84,7 @@ def run_command(cmd, description):
84
84
  cmd,
85
85
  check=True,
86
86
  capture_output=True,
87
+ shell=False,
87
88
  text=True
88
89
  )
89
90
  if result.stdout:
@@ -114,6 +115,14 @@ def require_hf_repo_id(value, name):
114
115
  sys.exit(1)
115
116
 
116
117
 
118
+ def safe_filename_component(value, name):
119
+ """Allow repo-name text only where it becomes a local filename component."""
120
+ if not re.fullmatch(r"[A-Za-z0-9._-]{1,96}", value):
121
+ print(f" Invalid {name}: {value!r}. Use letters, numbers, dots, dashes, or underscores.", file=sys.stderr)
122
+ sys.exit(1)
123
+ return value
124
+
125
+
117
126
  def env_flag(name):
118
127
  return os.environ.get(name, "").strip().lower() in {"1", "true", "yes", "on"}
119
128
 
@@ -230,7 +239,7 @@ gguf_output_dir = "/tmp/gguf_output"
230
239
  os.makedirs(gguf_output_dir, exist_ok=True)
231
240
 
232
241
  convert_script = "/tmp/llama.cpp/convert_hf_to_gguf.py"
233
- model_name = ADAPTER_MODEL.split('/')[-1]
242
+ model_name = safe_filename_component(ADAPTER_MODEL.split('/')[-1], "ADAPTER_MODEL repo name")
234
243
  gguf_file = f"{gguf_output_dir}/{model_name}-f16.gguf"
235
244
 
236
245
  print(f" Running conversion...")
@@ -6,6 +6,19 @@ import re
6
6
  from collections import Counter, defaultdict
7
7
  from pathlib import Path
8
8
 
9
+
10
+ def safe_user_path(path_value, base_dir="."):
11
+ """Resolve a CLI path under the current workspace."""
12
+ if base_dir != ".":
13
+ raise ValueError("Custom base directories are not supported for CLI paths")
14
+ base_path = Path.cwd().resolve()
15
+ resolved_path = Path(path_value).expanduser().resolve()
16
+ try:
17
+ resolved_path.relative_to(base_path)
18
+ except ValueError as exc:
19
+ raise ValueError(f"Path escapes allowed directory: {path_value}") from exc
20
+ return resolved_path
21
+
9
22
  try:
10
23
  import tomllib
11
24
  except ModuleNotFoundError: # pragma: no cover
@@ -177,7 +190,7 @@ def main():
177
190
 
178
191
  payload = json.dumps(result, indent=2, sort_keys=True)
179
192
  if args.output:
180
- output = Path(args.output)
193
+ output = safe_user_path(args.output)
181
194
  output.parent.mkdir(parents=True, exist_ok=True)
182
195
  output.write_text(payload + "\n", encoding="utf-8")
183
196
  else:
@@ -39,7 +39,9 @@ Before using this skill, the user must set the `GEMINI_API_KEY` environment vari
39
39
  1. Get a free API key from [Google AI Studio](https://aistudio.google.com/)
40
40
  2. Export the key in your shell profile (`~/.zshrc`, `~/.bashrc`, etc.):
41
41
  ```bash
42
- export GEMINI_API_KEY="your_api_key_here"
42
+ read -rsp "Gemini API key: " GEMINI_API_KEY
43
+ echo
44
+ export GEMINI_API_KEY
43
45
  ```
44
46
  3. Restart your terminal or run `source ~/.zshrc` (or `~/.bashrc`)
45
47