@elizaos/skills 2.0.0-alpha.43 → 2.0.0-alpha.430

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 (154) hide show
  1. package/README.md +4 -0
  2. package/dist/formatter.d.ts.map +1 -1
  3. package/dist/formatter.js +3 -3
  4. package/dist/frontmatter.d.ts +13 -1
  5. package/dist/frontmatter.d.ts.map +1 -1
  6. package/dist/frontmatter.js +51 -1
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -2
  10. package/dist/loader.d.ts.map +1 -1
  11. package/dist/loader.js +10 -3
  12. package/dist/resolver.d.ts +17 -0
  13. package/dist/resolver.d.ts.map +1 -1
  14. package/dist/resolver.js +54 -1
  15. package/dist/types.d.ts +38 -1
  16. package/dist/types.d.ts.map +1 -1
  17. package/package.json +7 -6
  18. package/skills/apple-reminders/SKILL.md +1 -1
  19. package/skills/blucli/SKILL.md +1 -1
  20. package/skills/bluebubbles/SKILL.md +1 -1
  21. package/skills/camsnap/SKILL.md +1 -1
  22. package/skills/canvas/SKILL.md +6 -6
  23. package/skills/coding-agent/SKILL.md +2 -2
  24. package/skills/eliza-app-development/SKILL.md +62 -0
  25. package/skills/eliza-app-development/references/repo-map.md +70 -0
  26. package/skills/eliza-app-development/references/runtime-and-cloud.md +61 -0
  27. package/skills/eliza-cloud/SKILL.md +39 -0
  28. package/skills/eliza-cloud/references/apps-and-containers.md +73 -0
  29. package/skills/eliza-cloud/references/cloud-backend-and-monetization.md +99 -0
  30. package/skills/elizaos/SKILL.md +27 -0
  31. package/skills/elizaos/references/core-abstractions.md +101 -0
  32. package/skills/elizaos/references/plugin-development.md +74 -0
  33. package/skills/github/SKILL.md +1 -1
  34. package/skills/imsg/SKILL.md +1 -1
  35. package/skills/nano-banana-pro/SKILL.md +1 -1
  36. package/skills/nano-pdf/SKILL.md +1 -1
  37. package/skills/notion/SKILL.md +1 -1
  38. package/skills/obsidian/SKILL.md +1 -1
  39. package/skills/ordercli/SKILL.md +1 -1
  40. package/skills/skill-creator/SKILL.md +1 -1
  41. package/skills/slack/SKILL.md +1 -1
  42. package/skills/spotify-player/SKILL.md +1 -1
  43. package/skills/tmux/SKILL.md +1 -1
  44. package/skills/trello/SKILL.md +1 -1
  45. package/skills/wacli/SKILL.md +1 -1
  46. package/skills/weather/SKILL.md +1 -1
  47. package/skills/yara-authoring/SKILL.md +111 -0
  48. package/skills/bear-notes/SKILL.md +0 -107
  49. package/skills/bird/SKILL.md +0 -224
  50. package/skills/blogwatcher/SKILL.md +0 -69
  51. package/skills/clawhub/SKILL.md +0 -77
  52. package/skills/eightctl/SKILL.md +0 -50
  53. package/skills/food-order/SKILL.md +0 -48
  54. package/skills/gemini/SKILL.md +0 -43
  55. package/skills/gifgrep/SKILL.md +0 -79
  56. package/skills/gog/SKILL.md +0 -116
  57. package/skills/goplaces/SKILL.md +0 -52
  58. package/skills/himalaya/SKILL.md +0 -257
  59. package/skills/himalaya/references/configuration.md +0 -184
  60. package/skills/himalaya/references/message-composition.md +0 -199
  61. package/skills/local-places/SERVER_README.md +0 -101
  62. package/skills/local-places/SKILL.md +0 -102
  63. package/skills/local-places/pyproject.toml +0 -21
  64. package/skills/local-places/src/local_places/__init__.py +0 -2
  65. package/skills/local-places/src/local_places/google_places.py +0 -314
  66. package/skills/local-places/src/local_places/main.py +0 -65
  67. package/skills/local-places/src/local_places/schemas.py +0 -107
  68. package/skills/mcporter/SKILL.md +0 -61
  69. package/skills/model-usage/SKILL.md +0 -69
  70. package/skills/model-usage/references/codexbar-cli.md +0 -33
  71. package/skills/model-usage/scripts/model_usage.py +0 -310
  72. package/skills/openai-image-gen/SKILL.md +0 -89
  73. package/skills/openai-image-gen/scripts/gen.py +0 -240
  74. package/skills/openai-whisper/SKILL.md +0 -38
  75. package/skills/openai-whisper-api/SKILL.md +0 -52
  76. package/skills/openai-whisper-api/scripts/transcribe.sh +0 -85
  77. package/skills/openhue/SKILL.md +0 -51
  78. package/skills/oracle/SKILL.md +0 -125
  79. package/skills/peekaboo/SKILL.md +0 -190
  80. package/skills/sag/SKILL.md +0 -87
  81. package/skills/session-logs/SKILL.md +0 -115
  82. package/skills/sharp-edges/.claude-plugin/plugin.json +0 -10
  83. package/skills/sharp-edges/README.md +0 -48
  84. package/skills/sharp-edges/SKILL.md +0 -292
  85. package/skills/sharp-edges/skills/sharp-edges/SKILL.md +0 -292
  86. package/skills/sharp-edges/skills/sharp-edges/references/auth-patterns.md +0 -252
  87. package/skills/sharp-edges/skills/sharp-edges/references/case-studies.md +0 -274
  88. package/skills/sharp-edges/skills/sharp-edges/references/config-patterns.md +0 -333
  89. package/skills/sharp-edges/skills/sharp-edges/references/crypto-apis.md +0 -190
  90. package/skills/sharp-edges/skills/sharp-edges/references/lang-c.md +0 -205
  91. package/skills/sharp-edges/skills/sharp-edges/references/lang-csharp.md +0 -285
  92. package/skills/sharp-edges/skills/sharp-edges/references/lang-go.md +0 -270
  93. package/skills/sharp-edges/skills/sharp-edges/references/lang-java.md +0 -263
  94. package/skills/sharp-edges/skills/sharp-edges/references/lang-javascript.md +0 -269
  95. package/skills/sharp-edges/skills/sharp-edges/references/lang-kotlin.md +0 -265
  96. package/skills/sharp-edges/skills/sharp-edges/references/lang-php.md +0 -245
  97. package/skills/sharp-edges/skills/sharp-edges/references/lang-python.md +0 -274
  98. package/skills/sharp-edges/skills/sharp-edges/references/lang-ruby.md +0 -273
  99. package/skills/sharp-edges/skills/sharp-edges/references/lang-rust.md +0 -272
  100. package/skills/sharp-edges/skills/sharp-edges/references/lang-swift.md +0 -287
  101. package/skills/sharp-edges/skills/sharp-edges/references/language-specific.md +0 -588
  102. package/skills/sherpa-onnx-tts/SKILL.md +0 -103
  103. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +0 -178
  104. package/skills/songsee/SKILL.md +0 -49
  105. package/skills/sonoscli/SKILL.md +0 -46
  106. package/skills/spec-to-code-compliance/.claude-plugin/plugin.json +0 -10
  107. package/skills/spec-to-code-compliance/README.md +0 -67
  108. package/skills/spec-to-code-compliance/SKILL.md +0 -349
  109. package/skills/spec-to-code-compliance/commands/spec-compliance.md +0 -22
  110. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/SKILL.md +0 -349
  111. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/COMPLETENESS_CHECKLIST.md +0 -69
  112. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/IR_EXAMPLES.md +0 -417
  113. package/skills/spec-to-code-compliance/skills/spec-to-code-compliance/resources/OUTPUT_REQUIREMENTS.md +0 -105
  114. package/skills/static-analysis/.claude-plugin/plugin.json +0 -8
  115. package/skills/static-analysis/README.md +0 -59
  116. package/skills/static-analysis/SKILL.md +0 -91
  117. package/skills/static-analysis/skills/codeql/SKILL.md +0 -315
  118. package/skills/static-analysis/skills/sarif-parsing/SKILL.md +0 -479
  119. package/skills/static-analysis/skills/sarif-parsing/resources/jq-queries.md +0 -162
  120. package/skills/static-analysis/skills/sarif-parsing/resources/sarif_helpers.py +0 -331
  121. package/skills/static-analysis/skills/semgrep/SKILL.md +0 -337
  122. package/skills/summarize/SKILL.md +0 -87
  123. package/skills/testing-handbook-skills/.claude-plugin/plugin.json +0 -8
  124. package/skills/testing-handbook-skills/README.md +0 -241
  125. package/skills/testing-handbook-skills/SKILL.md +0 -104
  126. package/skills/testing-handbook-skills/scripts/pyproject.toml +0 -8
  127. package/skills/testing-handbook-skills/scripts/validate-skills.py +0 -657
  128. package/skills/testing-handbook-skills/skills/address-sanitizer/SKILL.md +0 -341
  129. package/skills/testing-handbook-skills/skills/aflpp/SKILL.md +0 -640
  130. package/skills/testing-handbook-skills/skills/atheris/SKILL.md +0 -515
  131. package/skills/testing-handbook-skills/skills/cargo-fuzz/SKILL.md +0 -454
  132. package/skills/testing-handbook-skills/skills/codeql/SKILL.md +0 -549
  133. package/skills/testing-handbook-skills/skills/constant-time-testing/SKILL.md +0 -507
  134. package/skills/testing-handbook-skills/skills/coverage-analysis/SKILL.md +0 -607
  135. package/skills/testing-handbook-skills/skills/fuzzing-dictionary/SKILL.md +0 -297
  136. package/skills/testing-handbook-skills/skills/fuzzing-obstacles/SKILL.md +0 -426
  137. package/skills/testing-handbook-skills/skills/harness-writing/SKILL.md +0 -614
  138. package/skills/testing-handbook-skills/skills/libafl/SKILL.md +0 -625
  139. package/skills/testing-handbook-skills/skills/libfuzzer/SKILL.md +0 -795
  140. package/skills/testing-handbook-skills/skills/ossfuzz/SKILL.md +0 -426
  141. package/skills/testing-handbook-skills/skills/ruzzy/SKILL.md +0 -443
  142. package/skills/testing-handbook-skills/skills/semgrep/SKILL.md +0 -601
  143. package/skills/testing-handbook-skills/skills/testing-handbook-generator/SKILL.md +0 -372
  144. package/skills/testing-handbook-skills/skills/testing-handbook-generator/agent-prompt.md +0 -280
  145. package/skills/testing-handbook-skills/skills/testing-handbook-generator/discovery.md +0 -452
  146. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/domain-skill.md +0 -504
  147. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/fuzzer-skill.md +0 -454
  148. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/technique-skill.md +0 -527
  149. package/skills/testing-handbook-skills/skills/testing-handbook-generator/templates/tool-skill.md +0 -366
  150. package/skills/testing-handbook-skills/skills/testing-handbook-generator/testing.md +0 -482
  151. package/skills/testing-handbook-skills/skills/wycheproof/SKILL.md +0 -533
  152. package/skills/video-frames/SKILL.md +0 -46
  153. package/skills/video-frames/scripts/frame.sh +0 -81
  154. package/skills/voice-call/SKILL.md +0 -45
@@ -1,310 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Summarize CodexBar local cost usage by model.
4
-
5
- Defaults to current model (most recent daily entry), or list all models.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import argparse
11
- import json
12
- import os
13
- import subprocess
14
- import sys
15
- from dataclasses import dataclass
16
- from datetime import date, datetime, timedelta
17
- from typing import Any, Dict, Iterable, List, Optional, Tuple
18
-
19
-
20
- def eprint(msg: str) -> None:
21
- print(msg, file=sys.stderr)
22
-
23
-
24
- def run_codexbar_cost(provider: str) -> List[Dict[str, Any]]:
25
- cmd = ["codexbar", "cost", "--format", "json", "--provider", provider]
26
- try:
27
- output = subprocess.check_output(cmd, text=True)
28
- except FileNotFoundError:
29
- raise RuntimeError("codexbar not found on PATH. Install CodexBar CLI first.")
30
- except subprocess.CalledProcessError as exc:
31
- raise RuntimeError(f"codexbar cost failed (exit {exc.returncode}).")
32
- try:
33
- payload = json.loads(output)
34
- except json.JSONDecodeError as exc:
35
- raise RuntimeError(f"Failed to parse codexbar JSON output: {exc}")
36
- if not isinstance(payload, list):
37
- raise RuntimeError("Expected codexbar cost JSON array.")
38
- return payload
39
-
40
-
41
- def load_payload(input_path: Optional[str], provider: str) -> Dict[str, Any]:
42
- if input_path:
43
- if input_path == "-":
44
- raw = sys.stdin.read()
45
- else:
46
- with open(input_path, "r", encoding="utf-8") as handle:
47
- raw = handle.read()
48
- data = json.loads(raw)
49
- else:
50
- data = run_codexbar_cost(provider)
51
-
52
- if isinstance(data, dict):
53
- return data
54
-
55
- if isinstance(data, list):
56
- for entry in data:
57
- if isinstance(entry, dict) and entry.get("provider") == provider:
58
- return entry
59
- raise RuntimeError(f"Provider '{provider}' not found in codexbar payload.")
60
-
61
- raise RuntimeError("Unsupported JSON input format.")
62
-
63
-
64
- @dataclass
65
- class ModelCost:
66
- model: str
67
- cost: float
68
-
69
-
70
- def parse_daily_entries(payload: Dict[str, Any]) -> List[Dict[str, Any]]:
71
- daily = payload.get("daily")
72
- if not daily:
73
- return []
74
- if not isinstance(daily, list):
75
- return []
76
- return [entry for entry in daily if isinstance(entry, dict)]
77
-
78
-
79
- def parse_date(value: str) -> Optional[date]:
80
- try:
81
- return datetime.strptime(value, "%Y-%m-%d").date()
82
- except Exception:
83
- return None
84
-
85
-
86
- def filter_by_days(entries: List[Dict[str, Any]], days: Optional[int]) -> List[Dict[str, Any]]:
87
- if not days:
88
- return entries
89
- cutoff = date.today() - timedelta(days=days - 1)
90
- filtered: List[Dict[str, Any]] = []
91
- for entry in entries:
92
- day = entry.get("date")
93
- if not isinstance(day, str):
94
- continue
95
- parsed = parse_date(day)
96
- if parsed and parsed >= cutoff:
97
- filtered.append(entry)
98
- return filtered
99
-
100
-
101
- def aggregate_costs(entries: Iterable[Dict[str, Any]]) -> Dict[str, float]:
102
- totals: Dict[str, float] = {}
103
- for entry in entries:
104
- breakdowns = entry.get("modelBreakdowns")
105
- if not breakdowns:
106
- continue
107
- if not isinstance(breakdowns, list):
108
- continue
109
- for item in breakdowns:
110
- if not isinstance(item, dict):
111
- continue
112
- model = item.get("modelName")
113
- cost = item.get("cost")
114
- if not isinstance(model, str):
115
- continue
116
- if not isinstance(cost, (int, float)):
117
- continue
118
- totals[model] = totals.get(model, 0.0) + float(cost)
119
- return totals
120
-
121
-
122
- def pick_current_model(entries: List[Dict[str, Any]]) -> Tuple[Optional[str], Optional[str]]:
123
- if not entries:
124
- return None, None
125
- sorted_entries = sorted(
126
- entries,
127
- key=lambda entry: entry.get("date") or "",
128
- )
129
- for entry in reversed(sorted_entries):
130
- breakdowns = entry.get("modelBreakdowns")
131
- if isinstance(breakdowns, list) and breakdowns:
132
- scored: List[ModelCost] = []
133
- for item in breakdowns:
134
- if not isinstance(item, dict):
135
- continue
136
- model = item.get("modelName")
137
- cost = item.get("cost")
138
- if isinstance(model, str) and isinstance(cost, (int, float)):
139
- scored.append(ModelCost(model=model, cost=float(cost)))
140
- if scored:
141
- scored.sort(key=lambda item: item.cost, reverse=True)
142
- return scored[0].model, entry.get("date") if isinstance(entry.get("date"), str) else None
143
- models_used = entry.get("modelsUsed")
144
- if isinstance(models_used, list) and models_used:
145
- last = models_used[-1]
146
- if isinstance(last, str):
147
- return last, entry.get("date") if isinstance(entry.get("date"), str) else None
148
- return None, None
149
-
150
-
151
- def usd(value: Optional[float]) -> str:
152
- if value is None:
153
- return "—"
154
- return f"${value:,.2f}"
155
-
156
-
157
- def latest_day_cost(entries: List[Dict[str, Any]], model: str) -> Tuple[Optional[str], Optional[float]]:
158
- if not entries:
159
- return None, None
160
- sorted_entries = sorted(
161
- entries,
162
- key=lambda entry: entry.get("date") or "",
163
- )
164
- for entry in reversed(sorted_entries):
165
- breakdowns = entry.get("modelBreakdowns")
166
- if not isinstance(breakdowns, list):
167
- continue
168
- for item in breakdowns:
169
- if not isinstance(item, dict):
170
- continue
171
- if item.get("modelName") == model:
172
- cost = item.get("cost") if isinstance(item.get("cost"), (int, float)) else None
173
- day = entry.get("date") if isinstance(entry.get("date"), str) else None
174
- return day, float(cost) if cost is not None else None
175
- return None, None
176
-
177
-
178
- def render_text_current(
179
- provider: str,
180
- model: str,
181
- latest_date: Optional[str],
182
- total_cost: Optional[float],
183
- latest_cost: Optional[float],
184
- latest_cost_date: Optional[str],
185
- entry_count: int,
186
- ) -> str:
187
- lines = [f"Provider: {provider}", f"Current model: {model}"]
188
- if latest_date:
189
- lines.append(f"Latest model date: {latest_date}")
190
- lines.append(f"Total cost (rows): {usd(total_cost)}")
191
- if latest_cost_date:
192
- lines.append(f"Latest day cost: {usd(latest_cost)} ({latest_cost_date})")
193
- lines.append(f"Daily rows: {entry_count}")
194
- return "\n".join(lines)
195
-
196
-
197
- def render_text_all(provider: str, totals: Dict[str, float]) -> str:
198
- lines = [f"Provider: {provider}", "Models:"]
199
- for model, cost in sorted(totals.items(), key=lambda item: item[1], reverse=True):
200
- lines.append(f"- {model}: {usd(cost)}")
201
- return "\n".join(lines)
202
-
203
-
204
- def build_json_current(
205
- provider: str,
206
- model: str,
207
- latest_date: Optional[str],
208
- total_cost: Optional[float],
209
- latest_cost: Optional[float],
210
- latest_cost_date: Optional[str],
211
- entry_count: int,
212
- ) -> Dict[str, Any]:
213
- return {
214
- "provider": provider,
215
- "mode": "current",
216
- "model": model,
217
- "latestModelDate": latest_date,
218
- "totalCostUSD": total_cost,
219
- "latestDayCostUSD": latest_cost,
220
- "latestDayCostDate": latest_cost_date,
221
- "dailyRowCount": entry_count,
222
- }
223
-
224
-
225
- def build_json_all(provider: str, totals: Dict[str, float]) -> Dict[str, Any]:
226
- return {
227
- "provider": provider,
228
- "mode": "all",
229
- "models": [
230
- {"model": model, "totalCostUSD": cost}
231
- for model, cost in sorted(totals.items(), key=lambda item: item[1], reverse=True)
232
- ],
233
- }
234
-
235
-
236
- def main() -> int:
237
- parser = argparse.ArgumentParser(description="Summarize CodexBar model usage from local cost logs.")
238
- parser.add_argument("--provider", choices=["codex", "claude"], default="codex")
239
- parser.add_argument("--mode", choices=["current", "all"], default="current")
240
- parser.add_argument("--model", help="Explicit model name to report instead of auto-current.")
241
- parser.add_argument("--input", help="Path to codexbar cost JSON (or '-' for stdin).")
242
- parser.add_argument("--days", type=int, help="Limit to last N days (based on daily rows).")
243
- parser.add_argument("--format", choices=["text", "json"], default="text")
244
- parser.add_argument("--pretty", action="store_true", help="Pretty-print JSON output.")
245
-
246
- args = parser.parse_args()
247
-
248
- try:
249
- payload = load_payload(args.input, args.provider)
250
- except Exception as exc:
251
- eprint(str(exc))
252
- return 1
253
-
254
- entries = parse_daily_entries(payload)
255
- entries = filter_by_days(entries, args.days)
256
-
257
- if args.mode == "current":
258
- model = args.model
259
- latest_date = None
260
- if not model:
261
- model, latest_date = pick_current_model(entries)
262
- if not model:
263
- eprint("No model data found in codexbar cost payload.")
264
- return 2
265
- totals = aggregate_costs(entries)
266
- total_cost = totals.get(model)
267
- latest_cost_date, latest_cost = latest_day_cost(entries, model)
268
-
269
- if args.format == "json":
270
- payload_out = build_json_current(
271
- provider=args.provider,
272
- model=model,
273
- latest_date=latest_date,
274
- total_cost=total_cost,
275
- latest_cost=latest_cost,
276
- latest_cost_date=latest_cost_date,
277
- entry_count=len(entries),
278
- )
279
- indent = 2 if args.pretty else None
280
- print(json.dumps(payload_out, indent=indent, sort_keys=args.pretty))
281
- else:
282
- print(
283
- render_text_current(
284
- provider=args.provider,
285
- model=model,
286
- latest_date=latest_date,
287
- total_cost=total_cost,
288
- latest_cost=latest_cost,
289
- latest_cost_date=latest_cost_date,
290
- entry_count=len(entries),
291
- )
292
- )
293
- return 0
294
-
295
- totals = aggregate_costs(entries)
296
- if not totals:
297
- eprint("No model breakdowns found in codexbar cost payload.")
298
- return 2
299
-
300
- if args.format == "json":
301
- payload_out = build_json_all(provider=args.provider, totals=totals)
302
- indent = 2 if args.pretty else None
303
- print(json.dumps(payload_out, indent=indent, sort_keys=args.pretty))
304
- else:
305
- print(render_text_all(provider=args.provider, totals=totals))
306
- return 0
307
-
308
-
309
- if __name__ == "__main__":
310
- raise SystemExit(main())
@@ -1,89 +0,0 @@
1
- ---
2
- name: openai-image-gen
3
- description: Batch-generate images via OpenAI Images API. Random prompt sampler + `index.html` gallery.
4
- homepage: https://platform.openai.com/docs/api-reference/images
5
- metadata:
6
- {
7
- "otto":
8
- {
9
- "emoji": "🖼️",
10
- "requires": { "bins": ["python3"], "env": ["OPENAI_API_KEY"] },
11
- "primaryEnv": "OPENAI_API_KEY",
12
- "install":
13
- [
14
- {
15
- "id": "python-brew",
16
- "kind": "brew",
17
- "formula": "python",
18
- "bins": ["python3"],
19
- "label": "Install Python (brew)",
20
- },
21
- ],
22
- },
23
- }
24
- ---
25
-
26
- # OpenAI Image Gen
27
-
28
- Generate a handful of “random but structured” prompts and render them via the OpenAI Images API.
29
-
30
- ## Run
31
-
32
- ```bash
33
- python3 {baseDir}/scripts/gen.py
34
- open ~/Projects/tmp/openai-image-gen-*/index.html # if ~/Projects/tmp exists; else ./tmp/...
35
- ```
36
-
37
- Useful flags:
38
-
39
- ```bash
40
- # GPT image models with various options
41
- python3 {baseDir}/scripts/gen.py --count 16 --model gpt-image-1
42
- python3 {baseDir}/scripts/gen.py --prompt "ultra-detailed studio photo of a futuristic cityscape" --count 4
43
- python3 {baseDir}/scripts/gen.py --size 1536x1024 --quality high --out-dir ./out/images
44
- python3 {baseDir}/scripts/gen.py --model gpt-image-1.5 --background transparent --output-format webp
45
-
46
- # DALL-E 3 (note: count is automatically limited to 1)
47
- python3 {baseDir}/scripts/gen.py --model dall-e-3 --quality hd --size 1792x1024 --style vivid
48
- python3 {baseDir}/scripts/gen.py --model dall-e-3 --style natural --prompt "serene mountain landscape"
49
-
50
- # DALL-E 2
51
- python3 {baseDir}/scripts/gen.py --model dall-e-2 --size 512x512 --count 4
52
- ```
53
-
54
- ## Model-Specific Parameters
55
-
56
- Different models support different parameter values. The script automatically selects appropriate defaults based on the model.
57
-
58
- ### Size
59
-
60
- - **GPT image models** (`gpt-image-1`, `gpt-image-1-mini`, `gpt-image-1.5`): `1024x1024`, `1536x1024` (landscape), `1024x1536` (portrait), or `auto`
61
- - Default: `1024x1024`
62
- - **dall-e-3**: `1024x1024`, `1792x1024`, or `1024x1792`
63
- - Default: `1024x1024`
64
- - **dall-e-2**: `256x256`, `512x512`, or `1024x1024`
65
- - Default: `1024x1024`
66
-
67
- ### Quality
68
-
69
- - **GPT image models**: `auto`, `high`, `medium`, or `low`
70
- - Default: `high`
71
- - **dall-e-3**: `hd` or `standard`
72
- - Default: `standard`
73
- - **dall-e-2**: `standard` only
74
- - Default: `standard`
75
-
76
- ### Other Notable Differences
77
-
78
- - **dall-e-3** only supports generating 1 image at a time (`n=1`). The script automatically limits count to 1 when using this model.
79
- - **GPT image models** support additional parameters:
80
- - `--background`: `transparent`, `opaque`, or `auto` (default)
81
- - `--output-format`: `png` (default), `jpeg`, or `webp`
82
- - Note: `stream` and `moderation` are available via API but not yet implemented in this script
83
- - **dall-e-3** has a `--style` parameter: `vivid` (hyper-real, dramatic) or `natural` (more natural looking)
84
-
85
- ## Output
86
-
87
- - `*.png`, `*.jpeg`, or `*.webp` images (output format depends on model + `--output-format`)
88
- - `prompts.json` (prompt → file mapping)
89
- - `index.html` (thumbnail gallery)
@@ -1,240 +0,0 @@
1
- #!/usr/bin/env python3
2
- import argparse
3
- import base64
4
- import datetime as dt
5
- import json
6
- import os
7
- import random
8
- import re
9
- import sys
10
- import urllib.error
11
- import urllib.request
12
- from pathlib import Path
13
-
14
-
15
- def slugify(text: str) -> str:
16
- text = text.lower().strip()
17
- text = re.sub(r"[^a-z0-9]+", "-", text)
18
- text = re.sub(r"-{2,}", "-", text).strip("-")
19
- return text or "image"
20
-
21
-
22
- def default_out_dir() -> Path:
23
- now = dt.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
24
- preferred = Path.home() / "Projects" / "tmp"
25
- base = preferred if preferred.is_dir() else Path("./tmp")
26
- base.mkdir(parents=True, exist_ok=True)
27
- return base / f"openai-image-gen-{now}"
28
-
29
-
30
- def pick_prompts(count: int) -> list[str]:
31
- subjects = [
32
- "a futuristic cityscape",
33
- "a brutalist lighthouse",
34
- "a cozy reading nook",
35
- "a cyberpunk noodle shop",
36
- "a Vienna street at dusk",
37
- "a minimalist product photo",
38
- "a surreal underwater library",
39
- ]
40
- styles = [
41
- "ultra-detailed studio photo",
42
- "35mm film still",
43
- "isometric illustration",
44
- "editorial photography",
45
- "soft watercolor",
46
- "architectural render",
47
- "high-contrast monochrome",
48
- ]
49
- lighting = [
50
- "golden hour",
51
- "overcast soft light",
52
- "neon lighting",
53
- "dramatic rim light",
54
- "candlelight",
55
- "foggy atmosphere",
56
- ]
57
- prompts: list[str] = []
58
- for _ in range(count):
59
- prompts.append(
60
- f"{random.choice(styles)} of {random.choice(subjects)}, {random.choice(lighting)}"
61
- )
62
- return prompts
63
-
64
-
65
- def get_model_defaults(model: str) -> tuple[str, str]:
66
- """Return (default_size, default_quality) for the given model."""
67
- if model == "dall-e-2":
68
- # quality will be ignored
69
- return ("1024x1024", "standard")
70
- elif model == "dall-e-3":
71
- return ("1024x1024", "standard")
72
- else:
73
- # GPT image or future models
74
- return ("1024x1024", "high")
75
-
76
-
77
- def request_images(
78
- api_key: str,
79
- prompt: str,
80
- model: str,
81
- size: str,
82
- quality: str,
83
- background: str = "",
84
- output_format: str = "",
85
- style: str = "",
86
- ) -> dict:
87
- url = "https://api.openai.com/v1/images/generations"
88
- args = {
89
- "model": model,
90
- "prompt": prompt,
91
- "size": size,
92
- "n": 1,
93
- }
94
-
95
- # Quality parameter - dall-e-2 doesn't accept this parameter
96
- if model != "dall-e-2":
97
- args["quality"] = quality
98
-
99
- # Note: response_format no longer supported by OpenAI Images API
100
- # dall-e models now return URLs by default
101
-
102
- if model.startswith("gpt-image"):
103
- if background:
104
- args["background"] = background
105
- if output_format:
106
- args["output_format"] = output_format
107
-
108
- if model == "dall-e-3" and style:
109
- args["style"] = style
110
-
111
- body = json.dumps(args).encode("utf-8")
112
- req = urllib.request.Request(
113
- url,
114
- method="POST",
115
- headers={
116
- "Authorization": f"Bearer {api_key}",
117
- "Content-Type": "application/json",
118
- },
119
- data=body,
120
- )
121
- try:
122
- with urllib.request.urlopen(req, timeout=300) as resp:
123
- return json.loads(resp.read().decode("utf-8"))
124
- except urllib.error.HTTPError as e:
125
- payload = e.read().decode("utf-8", errors="replace")
126
- raise RuntimeError(f"OpenAI Images API failed ({e.code}): {payload}") from e
127
-
128
-
129
- def write_gallery(out_dir: Path, items: list[dict]) -> None:
130
- thumbs = "\n".join(
131
- [
132
- f"""
133
- <figure>
134
- <a href="{it["file"]}"><img src="{it["file"]}" loading="lazy" /></a>
135
- <figcaption>{it["prompt"]}</figcaption>
136
- </figure>
137
- """.strip()
138
- for it in items
139
- ]
140
- )
141
- html = f"""<!doctype html>
142
- <meta charset="utf-8" />
143
- <title>openai-image-gen</title>
144
- <style>
145
- :root {{ color-scheme: dark; }}
146
- body {{ margin: 24px; font: 14px/1.4 ui-sans-serif, system-ui; background: #0b0f14; color: #e8edf2; }}
147
- h1 {{ font-size: 18px; margin: 0 0 16px; }}
148
- .grid {{ display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }}
149
- figure {{ margin: 0; padding: 12px; border: 1px solid #1e2a36; border-radius: 14px; background: #0f1620; }}
150
- img {{ width: 100%; height: auto; border-radius: 10px; display: block; }}
151
- figcaption {{ margin-top: 10px; color: #b7c2cc; }}
152
- code {{ color: #9cd1ff; }}
153
- </style>
154
- <h1>openai-image-gen</h1>
155
- <p>Output: <code>{out_dir.as_posix()}</code></p>
156
- <div class="grid">
157
- {thumbs}
158
- </div>
159
- """
160
- (out_dir / "index.html").write_text(html, encoding="utf-8")
161
-
162
-
163
- def main() -> int:
164
- ap = argparse.ArgumentParser(description="Generate images via OpenAI Images API.")
165
- ap.add_argument("--prompt", help="Single prompt. If omitted, random prompts are generated.")
166
- ap.add_argument("--count", type=int, default=8, help="How many images to generate.")
167
- ap.add_argument("--model", default="gpt-image-1", help="Image model id.")
168
- ap.add_argument("--size", default="", help="Image size (e.g. 1024x1024, 1536x1024). Defaults based on model if not specified.")
169
- ap.add_argument("--quality", default="", help="Image quality (e.g. high, standard). Defaults based on model if not specified.")
170
- ap.add_argument("--background", default="", help="Background transparency (GPT models only): transparent, opaque, or auto.")
171
- ap.add_argument("--output-format", default="", help="Output format (GPT models only): png, jpeg, or webp.")
172
- ap.add_argument("--style", default="", help="Image style (dall-e-3 only): vivid or natural.")
173
- ap.add_argument("--out-dir", default="", help="Output directory (default: ./tmp/openai-image-gen-<ts>).")
174
- args = ap.parse_args()
175
-
176
- api_key = (os.environ.get("OPENAI_API_KEY") or "").strip()
177
- if not api_key:
178
- print("Missing OPENAI_API_KEY", file=sys.stderr)
179
- return 2
180
-
181
- # Apply model-specific defaults if not specified
182
- default_size, default_quality = get_model_defaults(args.model)
183
- size = args.size or default_size
184
- quality = args.quality or default_quality
185
-
186
- count = args.count
187
- if args.model == "dall-e-3" and count > 1:
188
- print(f"Warning: dall-e-3 only supports generating 1 image at a time. Reducing count from {count} to 1.", file=sys.stderr)
189
- count = 1
190
-
191
- out_dir = Path(args.out_dir).expanduser() if args.out_dir else default_out_dir()
192
- out_dir.mkdir(parents=True, exist_ok=True)
193
-
194
- prompts = [args.prompt] * count if args.prompt else pick_prompts(count)
195
-
196
- # Determine file extension based on output format
197
- if args.model.startswith("gpt-image") and args.output_format:
198
- file_ext = args.output_format
199
- else:
200
- file_ext = "png"
201
-
202
- items: list[dict] = []
203
- for idx, prompt in enumerate(prompts, start=1):
204
- print(f"[{idx}/{len(prompts)}] {prompt}")
205
- res = request_images(
206
- api_key,
207
- prompt,
208
- args.model,
209
- size,
210
- quality,
211
- args.background,
212
- args.output_format,
213
- args.style,
214
- )
215
- data = res.get("data", [{}])[0]
216
- image_b64 = data.get("b64_json")
217
- image_url = data.get("url")
218
- if not image_b64 and not image_url:
219
- raise RuntimeError(f"Unexpected response: {json.dumps(res)[:400]}")
220
-
221
- filename = f"{idx:03d}-{slugify(prompt)[:40]}.{file_ext}"
222
- filepath = out_dir / filename
223
- if image_b64:
224
- filepath.write_bytes(base64.b64decode(image_b64))
225
- else:
226
- try:
227
- urllib.request.urlretrieve(image_url, filepath)
228
- except urllib.error.URLError as e:
229
- raise RuntimeError(f"Failed to download image from {image_url}: {e}") from e
230
-
231
- items.append({"prompt": prompt, "file": filename})
232
-
233
- (out_dir / "prompts.json").write_text(json.dumps(items, indent=2), encoding="utf-8")
234
- write_gallery(out_dir, items)
235
- print(f"\nWrote: {(out_dir / 'index.html').as_posix()}")
236
- return 0
237
-
238
-
239
- if __name__ == "__main__":
240
- raise SystemExit(main())
@@ -1,38 +0,0 @@
1
- ---
2
- name: openai-whisper
3
- description: Local speech-to-text with the Whisper CLI (no API key).
4
- homepage: https://openai.com/research/whisper
5
- metadata:
6
- {
7
- "otto":
8
- {
9
- "emoji": "🎙️",
10
- "requires": { "bins": ["whisper"] },
11
- "install":
12
- [
13
- {
14
- "id": "brew",
15
- "kind": "brew",
16
- "formula": "openai-whisper",
17
- "bins": ["whisper"],
18
- "label": "Install OpenAI Whisper (brew)",
19
- },
20
- ],
21
- },
22
- }
23
- ---
24
-
25
- # Whisper (CLI)
26
-
27
- Use `whisper` to transcribe audio locally.
28
-
29
- Quick start
30
-
31
- - `whisper /path/audio.mp3 --model medium --output_format txt --output_dir .`
32
- - `whisper /path/audio.m4a --task translate --output_format srt`
33
-
34
- Notes
35
-
36
- - Models download to `~/.cache/whisper` on first run.
37
- - `--model` defaults to `turbo` on this install.
38
- - Use smaller models for speed, larger for accuracy.