opencode-skills-collection 3.0.49 → 3.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled-skills/.antigravity-install-manifest.json +27 -1
- package/bundled-skills/ab-test-setup/SKILL.md +14 -0
- package/bundled-skills/apple-notes-search/SKILL.md +122 -0
- package/bundled-skills/astropy/references/coordinates.md +9 -0
- package/bundled-skills/astropy/references/cosmology.md +8 -0
- package/bundled-skills/astropy/references/fits.md +8 -0
- package/bundled-skills/astropy/references/tables.md +8 -0
- package/bundled-skills/astropy/references/time.md +7 -0
- package/bundled-skills/astropy/references/units.md +9 -0
- package/bundled-skills/astropy/references/wcs_and_other_modules.md +9 -0
- package/bundled-skills/browser-extension-builder/SKILL.md +1 -1
- package/bundled-skills/ckw-design/SKILL.md +129 -0
- package/bundled-skills/deterministic-design/SKILL.md +56 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/getting-started.md +1 -1
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +4 -4
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/lint-and-validate/SKILL.md +3 -1
- package/bundled-skills/lookdev/SKILL.md +229 -0
- package/bundled-skills/lookdev-auto/SKILL.md +102 -0
- package/bundled-skills/macos-screen-recorder/SKILL.md +59 -0
- package/bundled-skills/pr-merge-champion/SKILL.md +116 -0
- package/bundled-skills/programmatic-seo/SKILL.md +11 -0
- package/bundled-skills/schema-markup/SKILL.md +11 -0
- package/bundled-skills/screenstudio-alt/SKILL.md +91 -0
- package/bundled-skills/super-code/SKILL.md +209 -0
- package/bundled-skills/super-code/bash/SKILL.md +292 -0
- package/bundled-skills/super-code/c/SKILL.md +263 -0
- package/bundled-skills/super-code/cpp/SKILL.md +271 -0
- package/bundled-skills/super-code/csharp/SKILL.md +276 -0
- package/bundled-skills/super-code/dart/SKILL.md +327 -0
- package/bundled-skills/super-code/elixir/SKILL.md +366 -0
- package/bundled-skills/super-code/go/SKILL.md +234 -0
- package/bundled-skills/super-code/java/SKILL.md +230 -0
- package/bundled-skills/super-code/kotlin/SKILL.md +281 -0
- package/bundled-skills/super-code/php/SKILL.md +316 -0
- package/bundled-skills/super-code/python/SKILL.md +315 -0
- package/bundled-skills/super-code/ruby/SKILL.md +306 -0
- package/bundled-skills/super-code/rust/SKILL.md +289 -0
- package/bundled-skills/super-code/scala/SKILL.md +302 -0
- package/bundled-skills/super-code/swift/SKILL.md +299 -0
- package/bundled-skills/super-code/typescript/SKILL.md +286 -0
- package/bundled-skills/web-media-getter/SKILL.md +119 -0
- package/bundled-skills/youtube-seo-optimizer/SKILL.md +9 -9
- package/package.json +1 -1
- package/skills_index.json +574 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript
|
|
3
|
+
description: "Language-specific super-code guidelines for typescript."
|
|
4
|
+
risk: safe
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-06-16"
|
|
7
|
+
---
|
|
8
|
+
# TypeScript / JavaScript: Idiomatic Efficiency Reference
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
1. [Array & Object Operations](#arrays)
|
|
12
|
+
2. [Destructuring & Spread](#destructuring)
|
|
13
|
+
3. [Async / Promises](#async)
|
|
14
|
+
4. [Functions & Closures](#functions)
|
|
15
|
+
5. [TypeScript Types](#types)
|
|
16
|
+
6. [React (if applicable)](#react)
|
|
17
|
+
7. [Anti-patterns specific to TS/JS](#antipatterns)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Array & Object Operations {#arrays}
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// ❌ Imperative push loop
|
|
25
|
+
const result: string[] = []
|
|
26
|
+
for (const item of items) {
|
|
27
|
+
if (item.active) result.push(item.name.toUpperCase())
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ✅
|
|
31
|
+
const result = items.filter(i => i.active).map(i => i.name.toUpperCase())
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// ❌ Manual reduce for sum
|
|
36
|
+
let total = 0
|
|
37
|
+
for (const o of orders) total += o.amount
|
|
38
|
+
|
|
39
|
+
// ✅
|
|
40
|
+
const total = orders.reduce((sum, o) => sum + o.amount, 0)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
// ❌ Manual object copy + override
|
|
45
|
+
const updated = Object.assign({}, user)
|
|
46
|
+
updated.name = "Alice"
|
|
47
|
+
|
|
48
|
+
// ✅
|
|
49
|
+
const updated = { ...user, name: "Alice" }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// ❌ Existence check before property access
|
|
54
|
+
const city = user.address ? user.address.city : undefined
|
|
55
|
+
|
|
56
|
+
// ✅
|
|
57
|
+
const city = user.address?.city
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 2. Destructuring & Spread {#destructuring}
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// ❌ Separate variable assignments
|
|
66
|
+
const name = user.name
|
|
67
|
+
const age = user.age
|
|
68
|
+
|
|
69
|
+
// ✅
|
|
70
|
+
const { name, age } = user
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// ❌ Index access for array elements
|
|
75
|
+
const first = arr[0]
|
|
76
|
+
const second = arr[1]
|
|
77
|
+
|
|
78
|
+
// ✅
|
|
79
|
+
const [first, second] = arr
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// ❌ Merging arrays with concat
|
|
84
|
+
const merged = a.concat(b).concat(c)
|
|
85
|
+
|
|
86
|
+
// ✅
|
|
87
|
+
const merged = [...a, ...b, ...c]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
// ❌ Omitting a key by delete (mutates)
|
|
92
|
+
const copy = { ...obj }
|
|
93
|
+
delete copy.password
|
|
94
|
+
|
|
95
|
+
// ✅ — destructure to omit
|
|
96
|
+
const { password, ...safe } = obj
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 3. Async / Promises {#async}
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
// ❌ Promise chain when async/await is cleaner
|
|
105
|
+
fetchUser(id)
|
|
106
|
+
.then(user => fetchOrders(user.id))
|
|
107
|
+
.then(orders => process(orders))
|
|
108
|
+
.catch(handleError)
|
|
109
|
+
|
|
110
|
+
// ✅
|
|
111
|
+
try {
|
|
112
|
+
const user = await fetchUser(id)
|
|
113
|
+
const orders = await fetchOrders(user.id)
|
|
114
|
+
process(orders)
|
|
115
|
+
} catch (e) {
|
|
116
|
+
handleError(e)
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// ❌ Sequential awaits for independent operations
|
|
122
|
+
const user = await fetchUser(id)
|
|
123
|
+
const config = await fetchConfig()
|
|
124
|
+
|
|
125
|
+
// ✅ — run in parallel
|
|
126
|
+
const [user, config] = await Promise.all([fetchUser(id), fetchConfig()])
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
// ❌ Wrapping already-async function in new Promise
|
|
131
|
+
const result = await new Promise((resolve) => {
|
|
132
|
+
someAsyncFn().then(resolve)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
// ✅
|
|
136
|
+
const result = await someAsyncFn()
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Don't `await` inside a `.map()` without `Promise.all` — it sequences what should be parallel.**
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 4. Functions & Closures {#functions}
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// ❌ Arrow function with unnecessary block body
|
|
147
|
+
const double = (x: number) => { return x * 2 }
|
|
148
|
+
|
|
149
|
+
// ✅
|
|
150
|
+
const double = (x: number) => x * 2
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// ❌ Default parameter with if-guard
|
|
155
|
+
function greet(name?: string) {
|
|
156
|
+
if (!name) name = "World"
|
|
157
|
+
return `Hello, ${name}`
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ✅
|
|
161
|
+
function greet(name = "World") {
|
|
162
|
+
return `Hello, ${name}`
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// ❌ IIFE for no reason in module scope
|
|
168
|
+
;(function() {
|
|
169
|
+
const x = compute()
|
|
170
|
+
doSomething(x)
|
|
171
|
+
})()
|
|
172
|
+
|
|
173
|
+
// ✅ — just top-level statements in a module
|
|
174
|
+
const x = compute()
|
|
175
|
+
doSomething(x)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 5. TypeScript Types {#types}
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
// ❌ Explicit return type when inference is obvious
|
|
184
|
+
function add(a: number, b: number): number {
|
|
185
|
+
return a + b
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ✅ — let TS infer simple return types
|
|
189
|
+
function add(a: number, b: number) {
|
|
190
|
+
return a + b
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
// ❌ any
|
|
196
|
+
function process(data: any) { ... }
|
|
197
|
+
|
|
198
|
+
// ✅ — use unknown + type guard, or a proper type/generic
|
|
199
|
+
function process<T extends Record<string, unknown>>(data: T) { ... }
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
// ❌ Redundant interface for single-use inline shape
|
|
204
|
+
interface UserNameProps { name: string }
|
|
205
|
+
function UserName({ name }: UserNameProps) { ... }
|
|
206
|
+
|
|
207
|
+
// ✅ — inline for single-use
|
|
208
|
+
function UserName({ name }: { name: string }) { ... }
|
|
209
|
+
// Extract interface when reused in 2+ places
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
// ❌ Type assertion (as) to silence a real type error
|
|
214
|
+
const el = document.getElementById("app") as HTMLDivElement
|
|
215
|
+
el.innerText = "hi" // crashes if el is null
|
|
216
|
+
|
|
217
|
+
// ✅
|
|
218
|
+
const el = document.getElementById("app")
|
|
219
|
+
if (!(el instanceof HTMLDivElement)) throw new Error("Missing #app")
|
|
220
|
+
el.innerText = "hi"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Prefer `type` for unions/intersections/aliases; `interface` for extensible object shapes.**
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 6. React (if applicable) {#react}
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
// ❌ Effect for derived state
|
|
231
|
+
const [doubled, setDoubled] = useState(0)
|
|
232
|
+
useEffect(() => { setDoubled(count * 2) }, [count])
|
|
233
|
+
|
|
234
|
+
// ✅ — compute during render
|
|
235
|
+
const doubled = count * 2
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
// ❌ useCallback everywhere by default
|
|
240
|
+
const handler = useCallback(() => doSomething(id), [id])
|
|
241
|
+
|
|
242
|
+
// ✅ — only when passed to memoized child or used as effect dep
|
|
243
|
+
// Otherwise: const handler = () => doSomething(id)
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
// ❌ Passing object literal as prop (new reference each render)
|
|
248
|
+
<Component config={{ debug: true }} />
|
|
249
|
+
|
|
250
|
+
// ✅
|
|
251
|
+
const config = useMemo(() => ({ debug: true }), [])
|
|
252
|
+
<Component config={config} />
|
|
253
|
+
// Or if truly static: define outside component
|
|
254
|
+
const CONFIG = { debug: true }
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
// ❌ Index as key in list that can reorder/filter
|
|
259
|
+
items.map((item, i) => <Row key={i} {...item} />)
|
|
260
|
+
|
|
261
|
+
// ✅
|
|
262
|
+
items.map(item => <Row key={item.id} {...item} />)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 7. Anti-patterns specific to TS/JS {#antipatterns}
|
|
268
|
+
|
|
269
|
+
| Anti-pattern | Preferred |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `== null` (loose) | `=== null` or `?? / ?.` |
|
|
272
|
+
| `typeof x === "undefined"` | `x === undefined` or `x == null` (when both null/undefined ok) |
|
|
273
|
+
| `!!x` when boolean coercion is implied | `Boolean(x)` for clarity, or just `x` in conditionals |
|
|
274
|
+
| `var` | `const` by default, `let` when reassigned |
|
|
275
|
+
| `for...in` on arrays | `for...of` or array methods |
|
|
276
|
+
| String template literal with no interpolation | plain string `'...'` |
|
|
277
|
+
| `console.log` left in production code | remove or use a logger |
|
|
278
|
+
| `Object.keys(obj).forEach(...)` | `for (const [k, v] of Object.entries(obj))` |
|
|
279
|
+
| Nested ternaries beyond 2 levels | if/else or early return |
|
|
280
|
+
| `try { ... } catch (e) {}` (silent swallow) | log or rethrow |
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
## Limitations
|
|
285
|
+
- These are language-specific guidelines and do not cover overall architectural decisions.
|
|
286
|
+
- Over-compression might reduce readability; apply judgement.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-media-getter
|
|
3
|
+
description: "One query across free image / video / GIF APIs (stock + historical/archival + GIF engines), returning normalized, license-tagged results with optional top-K download + attribution sidecar. The retrieval peer to local semantic search and generative media."
|
|
4
|
+
risk: safe
|
|
5
|
+
source: community
|
|
6
|
+
source_type: community
|
|
7
|
+
source_repo: connerkward/web-media-getter-skill
|
|
8
|
+
date_added: "2026-06-16"
|
|
9
|
+
author: Conner K Ward
|
|
10
|
+
license: MIT
|
|
11
|
+
tags:
|
|
12
|
+
- media
|
|
13
|
+
- images
|
|
14
|
+
- video
|
|
15
|
+
- gif
|
|
16
|
+
- stock
|
|
17
|
+
- archival
|
|
18
|
+
- attribution
|
|
19
|
+
tools:
|
|
20
|
+
- claude-code
|
|
21
|
+
- antigravity
|
|
22
|
+
- cursor
|
|
23
|
+
- gemini-cli
|
|
24
|
+
- codex-cli
|
|
25
|
+
---
|
|
26
|
+
## When to Use
|
|
27
|
+
|
|
28
|
+
Use when a task needs a REAL or ARCHIVAL photo / clip (hero, texture, reference, historical footage) or a reaction / animated GIF, rather than a generated one — fan out across free image/video/GIF sources in one query and download license-tagged results.
|
|
29
|
+
|
|
30
|
+
_Source: [connerkward/web-media-getter-skill](https://github.com/connerkward/web-media-getter-skill) (MIT)._
|
|
31
|
+
|
|
32
|
+
# web-media
|
|
33
|
+
|
|
34
|
+
Query many free image/video sources in one fan-out, get a normalized result list,
|
|
35
|
+
optionally download top-K with an attribution sidecar. Zero-dep stdlib script.
|
|
36
|
+
|
|
37
|
+
**Script:** `webmedia.py` (in this dir). **Keys:** `PEXELS_API_KEY`, `PIXABAY_API_KEY`
|
|
38
|
+
in `central/.env` (optional — the 5 no-key sources work without them).
|
|
39
|
+
|
|
40
|
+
## Sources
|
|
41
|
+
|
|
42
|
+
| Source | Key? | Best for | Media |
|
|
43
|
+
|--------|------|----------|-------|
|
|
44
|
+
| openverse | none | CC web images (Flickr, museums) | image |
|
|
45
|
+
| wikimedia | none | factual / historical / landmark photos | image |
|
|
46
|
+
| internetarchive | none | **historical/archival** images + films | image, video |
|
|
47
|
+
| loc | none | historical US prints/photos | image |
|
|
48
|
+
| nasa | none | space imagery + video | image, video |
|
|
49
|
+
| pexels | free key | modern stock photos + **short video clips** | image, video |
|
|
50
|
+
| pixabay | free key | modern photos/illustrations + **short clips** | image, video |
|
|
51
|
+
| klipy | free key | **GIFs** — recommended (free, unlimited, Tenor drop-in) | gif |
|
|
52
|
+
| giphy | free key | **GIFs** — biggest library (prod key needs approval) | gif |
|
|
53
|
+
|
|
54
|
+
GIF sources fire only with `--type gif`. Keys: `KLIPY_API_KEY`, `GIPHY_API_KEY`
|
|
55
|
+
in `central/.env`. (tenor adapter removed — Google EOL'd the API 2026-06-30.)
|
|
56
|
+
**klipy** is the one to get (free + unlimited);
|
|
57
|
+
its adapter is **unverified — assumes Tenor-compatible** request/response;
|
|
58
|
+
verify against docs.klipy.com when you key it. `webmedia.py "shrug" --type gif --count 6 --json`
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
webmedia.py "1950s street scene" --type image --count 8 --json
|
|
64
|
+
webmedia.py "rocket launch" --type video --source nasa,internetarchive
|
|
65
|
+
webmedia.py "car factory 1930s" --source all --download --out /tmp/cars
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- `--source all` (default) | `nokey` (no-key only) | comma list (`wikimedia,pexels`)
|
|
69
|
+
- `--type image|video` · `--count N` · `--json` · `--download --out DIR`
|
|
70
|
+
- `--download` fetches each result's direct media URL and writes `attribution.json`
|
|
71
|
+
(source, author, license, url, page_url) alongside the files.
|
|
72
|
+
|
|
73
|
+
## Record schema
|
|
74
|
+
|
|
75
|
+
`{source, title, url, thumb, dl, page_url, author, license, w, h, type}` —
|
|
76
|
+
`dl` is the directly-downloadable media URL (None when only a page exists).
|
|
77
|
+
|
|
78
|
+
## The video caveat (important)
|
|
79
|
+
|
|
80
|
+
Archival sources (Internet Archive, Europeana, LoC) host **whole films/documentaries**,
|
|
81
|
+
not single shots. So:
|
|
82
|
+
- **Modern single clip** → `pexels` / `pixabay` (born as short clips, direct MP4). Done.
|
|
83
|
+
- **Historical single shot** → retrieve the IA film here, then extract the shot:
|
|
84
|
+
- **Twelve Labs** Marengo search (free 600 min) — pass the IA public MP4 URL, get a
|
|
85
|
+
timestamped moment for "car on assembly line", clip with ffmpeg. Semantic, cheap.
|
|
86
|
+
- or **PySceneDetect** (free, local) to cut the film into shots, then rank keyframes
|
|
87
|
+
with CLIP via the `muser` skill. Fully offline.
|
|
88
|
+
|
|
89
|
+
## Audio: freesound + audio QA
|
|
90
|
+
|
|
91
|
+
`webmedia.py` is image/video. For **sound effects** (real, CC-licensed) and for
|
|
92
|
+
**judging audio** (since Claude can't hear), two sibling scripts live in
|
|
93
|
+
`central/scripts/`:
|
|
94
|
+
|
|
95
|
+
- **`freesound-fetch.py "<query>" [count] [max_sec] [out_dir]`** — searches freesound.org
|
|
96
|
+
and downloads short hq-mp3 previews. Prints one JSON line per file with
|
|
97
|
+
`license`/`user` for attribution. Key: `FREESOUND_API_KEY` in `central/.env`
|
|
98
|
+
(token-based read; full originals would need OAuth — previews suffice for SFX).
|
|
99
|
+
- **`audio-judge.py <file> "<target>"`** — sends the clip to OpenAI `gpt-audio`
|
|
100
|
+
(audio-native) and returns JSON `{heard, score, matches, suggestion}`, enabling a
|
|
101
|
+
generate/fetch → judge → iterate loop. Auto-sources a real `sk-` `OPENAI_API_KEY`
|
|
102
|
+
from `.env` (ignores a local `lm-studio` stub env var). Pads sub-2s clips so the
|
|
103
|
+
speech-tuned model doesn't refuse. **Caveat:** it reliably *describes* audio and
|
|
104
|
+
filters obvious mismatches, but it is NOT a trustworthy judge of subjective qualities
|
|
105
|
+
like "grating" — it labels nearly any beep "sharp/high-pitched". Use it to cull, not
|
|
106
|
+
to make the final aesthetic call; confirm by ear.
|
|
107
|
+
|
|
108
|
+
## Where this fits
|
|
109
|
+
|
|
110
|
+
This is the **internet-retrieval** capability — peer to `muser` (local semantic search)
|
|
111
|
+
and `fal` (generate). A future `media` router would fan out across all three and rank
|
|
112
|
+
candidates by relevance (CLIP), handing aesthetic spreads to `lookdev`. Don't build that
|
|
113
|
+
router until the model demonstrably mis-routes without it.
|
|
114
|
+
|
|
115
|
+
## Limitations
|
|
116
|
+
|
|
117
|
+
- Results depend on third-party API availability, quotas, credentials, and license metadata quality.
|
|
118
|
+
- License tags and attribution fields must still be reviewed before commercial or public use.
|
|
119
|
+
- Relevance ranking can find plausible assets, but final aesthetic fit, brand safety, and audio suitability require human inspection.
|
|
@@ -133,11 +133,11 @@ How · Why · What · Best · Full · Real · Free · New · Step-by-Step · Com
|
|
|
133
133
|
|
|
134
134
|
## Tags Strategy
|
|
135
135
|
|
|
136
|
-
Use for
|
|
136
|
+
Use for long-form modes (A-D) that include tags. Generate 14-19 tags using this mix. For short-form (E-F), see the Shorts section for the 5-8 tag rule.
|
|
137
137
|
|
|
138
138
|
| Type | Count | Rule |
|
|
139
139
|
|---|---|---|
|
|
140
|
-
| Exact match primary keyword |
|
|
140
|
+
| Exact match primary keyword | 1 | Must match Step 1 target keyword exactly |
|
|
141
141
|
| Broad topic | 3-4 | 1-2 word umbrella terms |
|
|
142
142
|
| Long-tail (3-5 words) | 5-6 | Pulled from Step 1 research |
|
|
143
143
|
| Question-based | 2 | "how to [topic]", "what is [topic]" |
|
|
@@ -311,7 +311,7 @@ Character count: [N]/70
|
|
|
311
311
|
5. [secondary keyword from Step 1 research]
|
|
312
312
|
|
|
313
313
|
⑤ TAGS
|
|
314
|
-
[tag1], [tag2], [tag3] ... [
|
|
314
|
+
[tag1], [tag2], [tag3] ... [tag14-19 total]
|
|
315
315
|
Total character count: [N]/500
|
|
316
316
|
|
|
317
317
|
⑥ HASHTAGS
|
|
@@ -399,7 +399,7 @@ Chapters in description: Yes / No
|
|
|
399
399
|
Links/CTA present: Yes / No
|
|
400
400
|
|
|
401
401
|
TAGS ANALYSIS
|
|
402
|
-
Count: [N] (ideal:
|
|
402
|
+
Count: [N] (ideal: 14-19)
|
|
403
403
|
Tag type coverage: [which of 7 types are missing]
|
|
404
404
|
|
|
405
405
|
HASHTAG ANALYSIS
|
|
@@ -429,7 +429,7 @@ Character count: [N]/70
|
|
|
429
429
|
[Full 3-block description]
|
|
430
430
|
|
|
431
431
|
④ REWRITTEN TAGS
|
|
432
|
-
[
|
|
432
|
+
[14-19 tags across all 7 types]
|
|
433
433
|
|
|
434
434
|
⑤ REWRITTEN HASHTAGS
|
|
435
435
|
#Tag1 #Tag2 #Tag3 #Tag4 #Tag5 [#Tag6 #Tag7 optional]
|
|
@@ -507,7 +507,7 @@ Character count: [N]/70
|
|
|
507
507
|
5. [show name + topic]
|
|
508
508
|
|
|
509
509
|
⑤ TAGS
|
|
510
|
-
[tag1], [tag2] ... [
|
|
510
|
+
[tag1], [tag2] ... [tag14-19 — include show + guest name]
|
|
511
511
|
Total: [N]/500
|
|
512
512
|
|
|
513
513
|
⑥ HASHTAGS
|
|
@@ -605,7 +605,7 @@ Timestamps present: Yes / No
|
|
|
605
605
|
Platform links present: Yes / No
|
|
606
606
|
|
|
607
607
|
TAGS ANALYSIS
|
|
608
|
-
Count: [N] (ideal:
|
|
608
|
+
Count: [N] (ideal: 14-19)
|
|
609
609
|
Show / guest name as tags: Yes / No
|
|
610
610
|
|
|
611
611
|
TOPICS / TIMESTAMPS ANALYSIS
|
|
@@ -628,7 +628,7 @@ Character count: [N]/70
|
|
|
628
628
|
[3-block structure, guest bio in Block 2, platform links in Block 3]
|
|
629
629
|
|
|
630
630
|
④ REWRITTEN TAGS
|
|
631
|
-
[
|
|
631
|
+
[14-19 tags including show + guest name]
|
|
632
632
|
|
|
633
633
|
⑤ REWRITTEN HASHTAGS
|
|
634
634
|
#Tag1 #Tag2 #Tag3 #Tag4 #Tag5 [#Tag6 #Tag7 optional]
|
|
@@ -866,7 +866,7 @@ Then run the Quality Checklist below.
|
|
|
866
866
|
- [ ] Hashtags on final line only
|
|
867
867
|
|
|
868
868
|
### Tags & Hashtags
|
|
869
|
-
- [ ]
|
|
869
|
+
- [ ] 14-19 tags, under 500 chars, all 7 types represented
|
|
870
870
|
- [ ] No hashtag symbols in the tags field
|
|
871
871
|
- [ ] 5-8 hashtags (3-5 for short-form), CamelCase, strongest 3 first
|
|
872
872
|
- [ ] Hashtag set differs from recent uploads
|
package/package.json
CHANGED