opencode-skills-collection 4.0.66 → 4.0.68
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 +18 -1
- package/bundled-skills/anti-slop-design/SKILL.md +393 -0
- package/bundled-skills/antigravity-maintainer-batch-release/SKILL.md +1 -0
- package/bundled-skills/artifact-yylo/SKILL.md +122 -0
- package/bundled-skills/beatra-ai-video-studio/SKILL.md +272 -0
- package/bundled-skills/google-no-code/SKILL.md +136 -0
- package/bundled-skills/idea-evaluator/SKILL.md +75 -0
- package/bundled-skills/idea-evaluator/idea-evaluator-con/SKILL.md +64 -0
- package/bundled-skills/idea-evaluator/idea-evaluator-pro/SKILL.md +64 -0
- package/bundled-skills/ledger-tasks-yylo/SKILL.md +219 -0
- package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package-lock.json +4 -4
- package/bundled-skills/loki-mode/examples/todo-app-generated/backend/package.json +1 -1
- package/bundled-skills/meteora-dlmm-pool-screening/SKILL.md +166 -0
- package/bundled-skills/meteora-dlmm-pool-screening/references/meteora-apis.md +74 -0
- package/bundled-skills/meteora-dlmm-pool-screening/references/meteora-screener.md +352 -0
- package/bundled-skills/plan-ledger-tasks-yylo/SKILL.md +52 -0
- package/bundled-skills/ralph-loop-yylo/SKILL.md +55 -0
- package/bundled-skills/ralph-loop-yylo/references/first_check.md +18 -0
- package/bundled-skills/ralph-loop-yylo/references/implement.md +60 -0
- package/bundled-skills/resumable-implementation-contracts/SKILL.md +254 -0
- package/bundled-skills/understand-project-yylo/SKILL.md +62 -0
- package/bundled-skills/weather-model-data-fetching/SKILL.md +277 -0
- package/bundled-skills/weather-observation-fetching/SKILL.md +246 -0
- package/bundled-skills/wiki-yylo/SKILL.md +114 -0
- package/bundled-skills/workflow-yylo/SKILL.md +107 -0
- package/package.json +1 -1
- package/skills_index.json +422 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# Meteora screener script
|
|
2
|
+
|
|
3
|
+
Embedded copy of the read-only screener. Save the fenced Python block below as
|
|
4
|
+
`screen.py` in a scratch directory and run it with Python 3.10+.
|
|
5
|
+
|
|
6
|
+
```python
|
|
7
|
+
#!/usr/bin/env python3
|
|
8
|
+
"""Rank Meteora DLMM pools from public datapi. Stdlib only. Read-only GET."""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import json
|
|
14
|
+
import sys
|
|
15
|
+
import urllib.error
|
|
16
|
+
import urllib.parse
|
|
17
|
+
import urllib.request
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
DISCOVERY = "https://pool-discovery-api.datapi.meteora.ag"
|
|
21
|
+
DLMM = "https://dlmm.datapi.meteora.ag"
|
|
22
|
+
UA = "Mozilla/5.0 (compatible; etemaro-skill/1.0; +https://etemaro.com)"
|
|
23
|
+
TIMEOUT = 25
|
|
24
|
+
|
|
25
|
+
PRESETS: dict[str, dict[str, Any]] = {
|
|
26
|
+
"volatile": {
|
|
27
|
+
"min_bin": 80,
|
|
28
|
+
"max_bin": 125,
|
|
29
|
+
"min_tvl": 10_000,
|
|
30
|
+
"max_tvl": 150_000,
|
|
31
|
+
"min_fee_tvl": 0.05,
|
|
32
|
+
"min_organic": 60,
|
|
33
|
+
"min_holders": 500,
|
|
34
|
+
"min_volume": 500,
|
|
35
|
+
"hard_warnings": True,
|
|
36
|
+
},
|
|
37
|
+
"stable": {
|
|
38
|
+
"min_bin": 1,
|
|
39
|
+
"max_bin": 50,
|
|
40
|
+
"min_tvl": 100_000,
|
|
41
|
+
"max_tvl": 5_000_000,
|
|
42
|
+
"min_fee_tvl": 0.02,
|
|
43
|
+
"min_organic": 70,
|
|
44
|
+
"min_holders": 2_000,
|
|
45
|
+
"min_volume": 5_000,
|
|
46
|
+
"hard_warnings": True,
|
|
47
|
+
},
|
|
48
|
+
"bluechip": {
|
|
49
|
+
"min_bin": 1,
|
|
50
|
+
"max_bin": 25,
|
|
51
|
+
"min_tvl": 500_000,
|
|
52
|
+
"max_tvl": 10_000_000,
|
|
53
|
+
"min_fee_tvl": 0.01,
|
|
54
|
+
"min_organic": 80,
|
|
55
|
+
"min_holders": 5_000,
|
|
56
|
+
"min_volume": 10_000,
|
|
57
|
+
"hard_warnings": True,
|
|
58
|
+
},
|
|
59
|
+
"loose": {
|
|
60
|
+
"min_bin": None,
|
|
61
|
+
"max_bin": None,
|
|
62
|
+
"min_tvl": 1_000,
|
|
63
|
+
"max_tvl": None,
|
|
64
|
+
"min_fee_tvl": 0.0,
|
|
65
|
+
"min_organic": 0,
|
|
66
|
+
"min_holders": 0,
|
|
67
|
+
"min_volume": 0,
|
|
68
|
+
"hard_warnings": False,
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_json(url: str) -> Any:
|
|
74
|
+
req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json"})
|
|
75
|
+
try:
|
|
76
|
+
with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
|
|
77
|
+
return json.loads(resp.read().decode())
|
|
78
|
+
except urllib.error.HTTPError as exc:
|
|
79
|
+
body = exc.read().decode(errors="replace")[:200]
|
|
80
|
+
raise SystemExit(f"HTTP {exc.code} {url}\n{body}") from exc
|
|
81
|
+
except urllib.error.URLError as exc:
|
|
82
|
+
raise SystemExit(f"network error {url}: {exc.reason}") from exc
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def num(value: Any) -> float | None:
|
|
86
|
+
try:
|
|
87
|
+
n = float(value)
|
|
88
|
+
except (TypeError, ValueError):
|
|
89
|
+
return None
|
|
90
|
+
return n if n == n else None # NaN check
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def bucket(obj: Any, timeframe: str) -> float | None:
|
|
94
|
+
if isinstance(obj, dict):
|
|
95
|
+
return num(obj.get(timeframe))
|
|
96
|
+
return num(obj)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def score(fee_tvl: float, organic: float, volume: float, holders: float) -> float:
|
|
100
|
+
return fee_tvl * 1000 + organic * 10 + volume / 100 + holders / 100
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def discovery_filters(p: dict[str, Any]) -> str:
|
|
104
|
+
parts = ["pool_type=dlmm"]
|
|
105
|
+
if p["hard_warnings"]:
|
|
106
|
+
parts += [
|
|
107
|
+
"base_token_has_critical_warnings=false",
|
|
108
|
+
"quote_token_has_critical_warnings=false",
|
|
109
|
+
"base_token_has_high_single_ownership=false",
|
|
110
|
+
]
|
|
111
|
+
if p["min_tvl"] is not None:
|
|
112
|
+
parts.append(f"tvl>={int(p['min_tvl'])}")
|
|
113
|
+
if p["max_tvl"] is not None:
|
|
114
|
+
parts.append(f"tvl<={int(p['max_tvl'])}")
|
|
115
|
+
if p["min_bin"] is not None:
|
|
116
|
+
parts.append(f"dlmm_bin_step>={int(p['min_bin'])}")
|
|
117
|
+
if p["max_bin"] is not None:
|
|
118
|
+
parts.append(f"dlmm_bin_step<={int(p['max_bin'])}")
|
|
119
|
+
if p["min_fee_tvl"]:
|
|
120
|
+
parts.append(f"fee_active_tvl_ratio>={p['min_fee_tvl']}")
|
|
121
|
+
if p["min_organic"]:
|
|
122
|
+
parts.append(f"base_token_organic_score>={int(p['min_organic'])}")
|
|
123
|
+
if p["min_holders"]:
|
|
124
|
+
parts.append(f"base_token_holders>={int(p['min_holders'])}")
|
|
125
|
+
if p["min_volume"]:
|
|
126
|
+
parts.append(f"volume>={int(p['min_volume'])}")
|
|
127
|
+
return "&&".join(parts)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def reject_reason(row: dict[str, Any], p: dict[str, Any]) -> str | None:
|
|
131
|
+
fee = row.get("fee_tvl")
|
|
132
|
+
vol = row.get("volume")
|
|
133
|
+
if (fee is None or fee <= 0) and (vol is None or vol <= 0):
|
|
134
|
+
return "dead pool (zero volume and fee/TVL)"
|
|
135
|
+
if p["hard_warnings"] and row.get("critical"):
|
|
136
|
+
return "critical token warning"
|
|
137
|
+
bin_step = row.get("bin_step")
|
|
138
|
+
tvl = row.get("tvl")
|
|
139
|
+
organic = row.get("organic")
|
|
140
|
+
holders = row.get("holders")
|
|
141
|
+
if p["min_bin"] is not None and (bin_step is None or bin_step < p["min_bin"]):
|
|
142
|
+
return f"bin_step {bin_step} < {p['min_bin']}"
|
|
143
|
+
if p["max_bin"] is not None and bin_step is not None and bin_step > p["max_bin"]:
|
|
144
|
+
return f"bin_step {bin_step} > {p['max_bin']}"
|
|
145
|
+
if tvl is None or tvl < p["min_tvl"]:
|
|
146
|
+
return f"tvl {tvl} < {p['min_tvl']}"
|
|
147
|
+
if p["max_tvl"] is not None and tvl is not None and tvl > p["max_tvl"]:
|
|
148
|
+
return f"tvl {tvl} > {p['max_tvl']}"
|
|
149
|
+
if fee is None or fee < p["min_fee_tvl"]:
|
|
150
|
+
return f"fee/TVL {fee} < {p['min_fee_tvl']}"
|
|
151
|
+
if vol is None or vol < p["min_volume"]:
|
|
152
|
+
return f"volume {vol} < {p['min_volume']}"
|
|
153
|
+
if organic is not None and organic < p["min_organic"]:
|
|
154
|
+
return f"organic {organic} < {p['min_organic']}"
|
|
155
|
+
if holders is not None and holders < p["min_holders"]:
|
|
156
|
+
return f"holders {holders} < {p['min_holders']}"
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def verdict(row: dict[str, Any], p: dict[str, Any]) -> str:
|
|
161
|
+
if reject_reason(row, p):
|
|
162
|
+
return "skip"
|
|
163
|
+
warnings = row.get("warnings") or []
|
|
164
|
+
unverified = any("NOT_VERIFIED" in str(w) for w in warnings)
|
|
165
|
+
thin = (row.get("volume") or 0) < p["min_volume"] * 2 if p["min_volume"] else False
|
|
166
|
+
no_yield = (row.get("fee_tvl") or 0) <= 0
|
|
167
|
+
if unverified or thin or no_yield:
|
|
168
|
+
return "watch"
|
|
169
|
+
return "pass"
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def from_discovery(raw: dict[str, Any], timeframe: str) -> dict[str, Any]:
|
|
173
|
+
token_x = raw.get("token_x") or {}
|
|
174
|
+
warnings = token_x.get("warnings") or []
|
|
175
|
+
critical = bool(raw.get("base_token_has_critical_warnings")) or any(
|
|
176
|
+
(w.get("severity") if isinstance(w, dict) else None) == "critical" for w in warnings if isinstance(w, dict)
|
|
177
|
+
)
|
|
178
|
+
bin_step = num((raw.get("dlmm_params") or {}).get("bin_step"))
|
|
179
|
+
return {
|
|
180
|
+
"name": raw.get("name"),
|
|
181
|
+
"pool": raw.get("pool_address"),
|
|
182
|
+
"bin_step": bin_step,
|
|
183
|
+
"fee_tvl": num(raw.get("fee_active_tvl_ratio")),
|
|
184
|
+
"tvl": num(raw.get("tvl")),
|
|
185
|
+
"active_tvl": num(raw.get("active_tvl")),
|
|
186
|
+
"volume": num(raw.get("volume")),
|
|
187
|
+
"organic": num(token_x.get("organic_score")),
|
|
188
|
+
"holders": num(raw.get("base_token_holders")),
|
|
189
|
+
"mcap": num(token_x.get("market_cap")),
|
|
190
|
+
"volatility": num(raw.get("volatility")),
|
|
191
|
+
"mint": token_x.get("address"),
|
|
192
|
+
"warnings": warnings,
|
|
193
|
+
"critical": critical,
|
|
194
|
+
"source": "discovery",
|
|
195
|
+
"timeframe": timeframe,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def from_dlmm(raw: dict[str, Any], timeframe: str) -> dict[str, Any]:
|
|
200
|
+
token_x = raw.get("token_x") or {}
|
|
201
|
+
cfg = raw.get("pool_config") or {}
|
|
202
|
+
return {
|
|
203
|
+
"name": raw.get("name"),
|
|
204
|
+
"pool": raw.get("address"),
|
|
205
|
+
"bin_step": num(cfg.get("bin_step")),
|
|
206
|
+
"fee_tvl": bucket(raw.get("fee_tvl_ratio"), timeframe),
|
|
207
|
+
"tvl": num(raw.get("tvl")),
|
|
208
|
+
"active_tvl": num(raw.get("tvl")),
|
|
209
|
+
"volume": bucket(raw.get("volume"), timeframe),
|
|
210
|
+
"organic": None,
|
|
211
|
+
"holders": num(token_x.get("holders")),
|
|
212
|
+
"mcap": num(token_x.get("market_cap")),
|
|
213
|
+
"volatility": None,
|
|
214
|
+
"mint": token_x.get("address"),
|
|
215
|
+
"warnings": [],
|
|
216
|
+
"critical": bool(raw.get("is_blacklisted")),
|
|
217
|
+
"source": "dlmm",
|
|
218
|
+
"timeframe": timeframe,
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def fmt(n: float | None, digits: int = 2) -> str:
|
|
223
|
+
if n is None:
|
|
224
|
+
return "—"
|
|
225
|
+
if abs(n) >= 1_000_000:
|
|
226
|
+
return f"{n / 1_000_000:.{digits}f}M"
|
|
227
|
+
if abs(n) >= 1_000:
|
|
228
|
+
return f"{n / 1_000:.{digits}f}k"
|
|
229
|
+
return f"{n:.{digits}f}"
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def fmt_bin(n: float | None) -> str:
|
|
233
|
+
if n is None:
|
|
234
|
+
return "—"
|
|
235
|
+
return str(int(n)) if float(n).is_integer() else fmt(n, 1)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def print_table(rows: list[dict[str, Any]], rejects: list[tuple[str, str]], meta: dict[str, Any]) -> None:
|
|
239
|
+
print(f"# Meteora DLMM screening")
|
|
240
|
+
print(
|
|
241
|
+
f"Universe: {meta['universe']} Timeframe: {meta['timeframe']} "
|
|
242
|
+
f"Preset: {meta['preset']} Source: {meta['source']}"
|
|
243
|
+
)
|
|
244
|
+
proto = meta.get("protocol") or {}
|
|
245
|
+
if proto:
|
|
246
|
+
print(
|
|
247
|
+
f"Protocol: tvl=${fmt(proto.get('total_tvl'))} "
|
|
248
|
+
f"vol_24h=${fmt(proto.get('volume_24h'))} pools={proto.get('total_pools')}"
|
|
249
|
+
)
|
|
250
|
+
print(f"Fetched: {meta['fetched']} Ranked: {len(rows)} Rejected: {len(rejects)}")
|
|
251
|
+
print()
|
|
252
|
+
print("## Ranked")
|
|
253
|
+
print("| # | name | bin | fee/TVL | tvl | vol | organic | holders | verdict | why |")
|
|
254
|
+
print("|---|---|---|---|---|---|---|---|---|---|")
|
|
255
|
+
for i, row in enumerate(rows, 1):
|
|
256
|
+
why = (
|
|
257
|
+
f"fee/TVL {fmt(row.get('fee_tvl'), 3)}, "
|
|
258
|
+
f"bin {fmt_bin(row.get('bin_step'))}, "
|
|
259
|
+
f"{row.get('pool')}"
|
|
260
|
+
)
|
|
261
|
+
print(
|
|
262
|
+
f"| {i} | {row.get('name') or '?'} | {fmt_bin(row.get('bin_step'))} | "
|
|
263
|
+
f"{fmt(row.get('fee_tvl'), 3)} | {fmt(row.get('tvl'))} | {fmt(row.get('volume'))} | "
|
|
264
|
+
f"{fmt(row.get('organic'), 1)} | {fmt(row.get('holders'), 0)} | "
|
|
265
|
+
f"{row.get('verdict')} | {why} |"
|
|
266
|
+
)
|
|
267
|
+
if not rows:
|
|
268
|
+
print("_no pools passed gates — loosen max TVL or min fee/TVL, or try --preset loose_")
|
|
269
|
+
if rejects:
|
|
270
|
+
print()
|
|
271
|
+
print("## Rejects (sample)")
|
|
272
|
+
for name, reason in rejects[:12]:
|
|
273
|
+
print(f"- {name} — {reason}")
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def main() -> None:
|
|
277
|
+
parser = argparse.ArgumentParser(description="Screen Meteora DLMM pools (read-only).")
|
|
278
|
+
parser.add_argument("--preset", choices=sorted(PRESETS), default="volatile")
|
|
279
|
+
parser.add_argument("--query", help="Token symbol or mint (pair search via DLMM datapi)")
|
|
280
|
+
parser.add_argument("--timeframe", default="30m", choices=["5m", "30m", "1h", "2h", "4h", "12h", "24h"])
|
|
281
|
+
parser.add_argument("--limit", type=int, default=10)
|
|
282
|
+
parser.add_argument("--page-size", type=int, default=50)
|
|
283
|
+
parser.add_argument("--json", action="store_true")
|
|
284
|
+
args = parser.parse_args()
|
|
285
|
+
# Pair search is "which pool for this token", not a trending meme screen.
|
|
286
|
+
if args.query and "--preset" not in sys.argv:
|
|
287
|
+
args.preset = "loose"
|
|
288
|
+
preset = PRESETS[args.preset]
|
|
289
|
+
|
|
290
|
+
protocol = get_json(f"{DLMM}/stats/protocol_metrics")
|
|
291
|
+
|
|
292
|
+
if args.query:
|
|
293
|
+
qs = urllib.parse.urlencode({"query": args.query, "sort_by": "tvl:desc"})
|
|
294
|
+
payload = get_json(f"{DLMM}/pools?{qs}")
|
|
295
|
+
raw_list = payload.get("data") or []
|
|
296
|
+
rows = [from_dlmm(p, args.timeframe) for p in raw_list if isinstance(p, dict)]
|
|
297
|
+
source = "dlmm"
|
|
298
|
+
universe = f"query={args.query}"
|
|
299
|
+
fetched = payload.get("total", len(rows))
|
|
300
|
+
else:
|
|
301
|
+
qs = urllib.parse.urlencode(
|
|
302
|
+
{
|
|
303
|
+
"page_size": args.page_size,
|
|
304
|
+
"timeframe": args.timeframe,
|
|
305
|
+
"category": "trending",
|
|
306
|
+
"filter_by": discovery_filters(preset),
|
|
307
|
+
}
|
|
308
|
+
)
|
|
309
|
+
payload = get_json(f"{DISCOVERY}/pools?{qs}")
|
|
310
|
+
raw_list = payload.get("data") or []
|
|
311
|
+
rows = [from_discovery(p, args.timeframe) for p in raw_list if isinstance(p, dict)]
|
|
312
|
+
source = "discovery"
|
|
313
|
+
universe = "trending"
|
|
314
|
+
fetched = payload.get("total", len(rows))
|
|
315
|
+
|
|
316
|
+
rejects: list[tuple[str, str]] = []
|
|
317
|
+
kept: list[dict[str, Any]] = []
|
|
318
|
+
for row in rows:
|
|
319
|
+
reason = reject_reason(row, preset)
|
|
320
|
+
if reason:
|
|
321
|
+
rejects.append((str(row.get("name") or row.get("pool") or "?"), reason))
|
|
322
|
+
continue
|
|
323
|
+
row["score"] = score(
|
|
324
|
+
row.get("fee_tvl") or 0,
|
|
325
|
+
row.get("organic") or 0,
|
|
326
|
+
row.get("volume") or 0,
|
|
327
|
+
row.get("holders") or 0,
|
|
328
|
+
)
|
|
329
|
+
row["verdict"] = verdict(row, preset)
|
|
330
|
+
kept.append(row)
|
|
331
|
+
|
|
332
|
+
kept.sort(key=lambda r: r.get("score") or 0, reverse=True)
|
|
333
|
+
kept = kept[: max(1, args.limit)]
|
|
334
|
+
|
|
335
|
+
meta = {
|
|
336
|
+
"universe": universe,
|
|
337
|
+
"timeframe": args.timeframe,
|
|
338
|
+
"preset": args.preset,
|
|
339
|
+
"source": source,
|
|
340
|
+
"fetched": fetched,
|
|
341
|
+
"protocol": protocol if isinstance(protocol, dict) else {},
|
|
342
|
+
}
|
|
343
|
+
if args.json:
|
|
344
|
+
json.dump({"meta": meta, "ranked": kept, "rejects": rejects[:20]}, sys.stdout, indent=2)
|
|
345
|
+
sys.stdout.write("\n")
|
|
346
|
+
return
|
|
347
|
+
print_table(kept, rejects, meta)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
if __name__ == "__main__":
|
|
351
|
+
main()
|
|
352
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan-ledger-tasks-yylo
|
|
3
|
+
description: Create a concise Product Development Requirement and one or more implementation-sized
|
|
4
|
+
YYLO Ledger tasks when the user explicitly asks to plan or register work.
|
|
5
|
+
category: project-management
|
|
6
|
+
risk: safe
|
|
7
|
+
source: https://github.com/yylo-dev/yylo-skills
|
|
8
|
+
source_repo: yylo-dev/yylo-skills
|
|
9
|
+
source_type: community
|
|
10
|
+
date_added: '2026-09-19'
|
|
11
|
+
license: MIT
|
|
12
|
+
license_source: https://github.com/yylo-dev/yylo-skills/blob/main/LICENSE
|
|
13
|
+
compatibility: Requires the `yy` CLI with the `ledger` and `artifact` groups installed.
|
|
14
|
+
Planning only - implementation, worktrees, push, deploy and production mutation
|
|
15
|
+
need a separate explicit request.
|
|
16
|
+
argument-hint: '[Required Features] [Constraints] [Acceptance Criteria]'
|
|
17
|
+
enable-shell-directives: true
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Plan Kanban work
|
|
21
|
+
|
|
22
|
+
1. Read the project instructions and relevant product code from the integration or feature worktree. Read existing task/spec metadata through the canonical controller; do not assume `.juno_task/plan.md` exists.
|
|
23
|
+
2. Produce one concise PDR covering the goal, current behavior, scope, exclusions, risks, dependencies, acceptance criteria, and focused tests. Draft it in a fresh external file; do not place it in the product tree or a task body.
|
|
24
|
+
3. Preflight `yy ledger --help` and `yy ledger artifact --help`. Capture the PDR as a local immutable `report` Artifact Record with task/request provenance, then verify its ID, digest, size, retention, retrieval, and history. If the artifact API is unavailable, stop with the external draft intact and request an upgrade; never fall back to product `docs/`, task bodies/responses, new `.juno_task/specs`, or direct store edits.
|
|
25
|
+
4. Split only when pieces can be implemented and validated independently. Concurrent tasks must have explicit path ownership and dependencies.
|
|
26
|
+
5. Create tasks through routed `yy ledger` commands. Put concise durable requirements and acceptance criteria in each task body, record the PDR artifact ID in supported task fields/provenance, and relate follow-ups instead of reopening archived IDs.
|
|
27
|
+
6. Product documentation is only documentation shipped with the product. Never create controller-private tasks, ledger, state, artifacts, objects, specs, or receipts inside a product or feature worktree.
|
|
28
|
+
7. Do not start implementation, create worktrees, push, deploy, or mutate production unless the user separately asks.
|
|
29
|
+
|
|
30
|
+
Use `--id`, not legacy `--ID`, for Kanban mutations. Return the task IDs and a short dependency/order summary.
|
|
31
|
+
|
|
32
|
+
$ARGUMENTS
|
|
33
|
+
|
|
34
|
+
## When to Use
|
|
35
|
+
|
|
36
|
+
- The user explicitly asks to plan or register work in the YYLO Ledger.
|
|
37
|
+
- You need a concise Product Development Requirement (PDR) plus implementation-sized Ledger tasks with dependencies.
|
|
38
|
+
|
|
39
|
+
## Limitations
|
|
40
|
+
|
|
41
|
+
- Planning only: never start implementation, create worktrees, push, deploy, or mutate production from this skill.
|
|
42
|
+
- Requires the installed `yy ledger artifact` API; if unavailable, stop with the external PDR draft intact - never fall back to product `docs/`, task bodies, or direct store edits.
|
|
43
|
+
- Concurrent tasks need explicit path ownership and dependencies; relate follow-ups instead of reopening archived IDs.
|
|
44
|
+
|
|
45
|
+
### Example
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
yy ledger --help
|
|
49
|
+
yy ledger artifact --help
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> Adapted from [yylo-dev/yylo-skills](https://github.com/yylo-dev/yylo-skills) (MIT) - v2.0.1; frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ralph-loop-yylo
|
|
3
|
+
description: Execute exactly one explicitly assigned YYLO Ledger task through the
|
|
4
|
+
Ralph loop to a validated queued commit. Use only when the user explicitly requests
|
|
5
|
+
ralph-loop-yylo.
|
|
6
|
+
category: agent-orchestration
|
|
7
|
+
risk: critical
|
|
8
|
+
source: https://github.com/yylo-dev/yylo-skills
|
|
9
|
+
source_repo: yylo-dev/yylo-skills
|
|
10
|
+
source_type: community
|
|
11
|
+
date_added: '2026-09-19'
|
|
12
|
+
license: MIT
|
|
13
|
+
license_source: https://github.com/yylo-dev/yylo-skills/blob/main/LICENSE
|
|
14
|
+
compatibility: Requires the `yy` CLI, git and bash. Executes one explicitly assigned
|
|
15
|
+
Ledger task in its admitted worktree through `yy task start/finish` to a validated
|
|
16
|
+
queued commit. Never pushes, deploys, merges, or releases.
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# Execute one assigned task in the Ralph loop
|
|
20
|
+
|
|
21
|
+
Read [references/implement.md](references/implement.md) completely and follow it.
|
|
22
|
+
|
|
23
|
+
Stay within the assigned task. Do not select unrelated work, edit `tasks.md`, auto-tag releases, push, deploy, mutate production, or broaden scope because another issue is noticed. Record a bounded related Kanban follow-up when necessary.
|
|
24
|
+
|
|
25
|
+
Keep durable instructions concise and evidence-backed. Status belongs in the task response and runtime receipts, not `AGENTS.md`.
|
|
26
|
+
|
|
27
|
+
Controller checkpoints are best-effort local durability warnings after terminal metadata is durable. They never gate `yy pi`, `yy task`, `yy merge`, product commits, candidates, or releases.
|
|
28
|
+
|
|
29
|
+
## Complete assigned request
|
|
30
|
+
|
|
31
|
+
Treat the following as the complete user-assigned request. Preserve task references and directives literally; resolve them only through the normal agent workflow.
|
|
32
|
+
|
|
33
|
+
$ARGUMENTS
|
|
34
|
+
|
|
35
|
+
## When to Use
|
|
36
|
+
|
|
37
|
+
- The user explicitly requests `ralph-loop-yylo` for one already-assigned YYLO Ledger task.
|
|
38
|
+
- You need to implement exactly that task through the validated loop to a queued, review-ready commit.
|
|
39
|
+
|
|
40
|
+
## Limitations
|
|
41
|
+
|
|
42
|
+
- Exactly one assigned task per run: never select unrelated work, broaden scope, push, deploy, merge, release, or mutate production.
|
|
43
|
+
- Requires `yy task start TASK_ID` admission and `yy task finish TASK_ID` closure; stop after queueing - only the target owner runs `yy merge land`.
|
|
44
|
+
- Docs-only import: the upstream `scripts/kanban.sh` wrapper is intentionally not bundled; `references/` holds the worker contract.
|
|
45
|
+
- Controller checkpoints are best-effort durability warnings, never lifecycle gates.
|
|
46
|
+
|
|
47
|
+
### Example
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
yy task start TASK_ID
|
|
51
|
+
yy task preflight TASK_ID
|
|
52
|
+
yy task finish TASK_ID
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> Adapted from [yylo-dev/yylo-skills](https://github.com/yylo-dev/yylo-skills) (MIT) - v2.0.1; frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance. Docs-only import: `scripts/kanban.sh` runtime not bundled.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
### Check once
|
|
2
|
+
|
|
3
|
+
Before editing, verify the task worktree, clean starting state, and frozen admitted
|
|
4
|
+
path scope. Inspect ignore files only when the assigned task requires an ignore
|
|
5
|
+
rule or the task's validation would otherwise produce untracked generated output.
|
|
6
|
+
|
|
7
|
+
Modify an ignore file only when all of the following are true:
|
|
8
|
+
|
|
9
|
+
- the change is necessary for the assigned task;
|
|
10
|
+
- the exact file is included in the task's admitted paths;
|
|
11
|
+
- existing project conventions support the rule; and
|
|
12
|
+
- the change is included in focused validation and the task commit.
|
|
13
|
+
|
|
14
|
+
Do not create or expand `.gitignore`, `.dockerignore`, `.eslintignore`,
|
|
15
|
+
`.prettierignore`, `.npmignore`, `.terraformignore`, or `.helmignore` merely
|
|
16
|
+
because a related tool is present. If a useful ignore-file change is outside the
|
|
17
|
+
assigned scope, record a bounded related follow-up and continue only when the
|
|
18
|
+
current task remains valid without it.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<!-- GENERATED DESTINATIONS: edit this canonical source, then run `npm run generate:implementation-contract`. -->
|
|
2
|
+
---
|
|
3
|
+
description: Implement exactly one assigned Kanban task in its admitted Bolt product worktree and stop after queueing it.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Bolt implementation worker contract
|
|
7
|
+
|
|
8
|
+
An implementation worker owns one explicitly assigned task. It does not select
|
|
9
|
+
other work, mutate the product target, merge, release, deploy, or clean another
|
|
10
|
+
task's workspace.
|
|
11
|
+
|
|
12
|
+
## 1. Resolve and preserve admission
|
|
13
|
+
|
|
14
|
+
1. Read `AGENTS.md` and the complete assigned task from the canonical controller.
|
|
15
|
+
2. Run `yy task start TASK_ID` unless the handoff already contains the matching
|
|
16
|
+
active Bolt task record. Verify the returned worktree, branch, full target ref,
|
|
17
|
+
and exact base SHA before editing; stop on missing or contradictory evidence.
|
|
18
|
+
3. Work only in that product worktree. Never edit product files in the controller
|
|
19
|
+
or copy controller ledgers, specs, state, or artifacts into a task worktree.
|
|
20
|
+
4. Preserve controller identity and workspace-role checks. Controller checkpoints
|
|
21
|
+
are best-effort local durability warnings after terminal metadata is durable;
|
|
22
|
+
they are not product inputs or lifecycle gates.
|
|
23
|
+
|
|
24
|
+
## 2. Implement
|
|
25
|
+
|
|
26
|
+
1. Edit only requested product paths and preserve project sources of truth.
|
|
27
|
+
2. Use focused affected tests in the edit loop. Other feature worktrees may run
|
|
28
|
+
concurrently; do not wait for or modify them.
|
|
29
|
+
3. Do not launch lifecycle-semantic reviewers from implementation. Semantic
|
|
30
|
+
review and project checks are explicit owner operations outside native task
|
|
31
|
+
delivery; never claim they occurred because a task was queued.
|
|
32
|
+
4. If blocked, record bounded truthful state and stop without claiming success.
|
|
33
|
+
Durable diagnostic output belongs in a verified Ledger Artifact Record when
|
|
34
|
+
the installed API supports it; otherwise preserve an external draft and stop,
|
|
35
|
+
never fall back to product documentation or direct controller-store edits.
|
|
36
|
+
|
|
37
|
+
## 3. Queue and hand off
|
|
38
|
+
|
|
39
|
+
1. Run focused tests, required dangerous-path checks, parity checks, and
|
|
40
|
+
`git diff --check`.
|
|
41
|
+
2. Stage only task-owned paths, commit coherently, and leave the worktree clean.
|
|
42
|
+
3. Run `yy task preflight TASK_ID` before expensive final validation. Repair any
|
|
43
|
+
admission, generated-output, runtime, or closure refusal while the task is
|
|
44
|
+
still `WORKING`.
|
|
45
|
+
4. Run `yy task finish TASK_ID`; it validates the exact preflighted tip and
|
|
46
|
+
records `QUEUED` with its immutable review-ready closure.
|
|
47
|
+
5. Record the commit and bounded response in Kanban. A lifecycle finalizer may
|
|
48
|
+
attempt a controller checkpoint after terminal metadata is durable; checkpoint
|
|
49
|
+
failure remains a warning and must not change the task or merge outcome.
|
|
50
|
+
|
|
51
|
+
Stop after queueing. Read-only delivery observation uses `yy merge status`.
|
|
52
|
+
Only the target owner runs `yy merge land TASK_ID`, which uses native Git and an
|
|
53
|
+
expected-old ref update. If Git integration succeeded but Ledger projection did
|
|
54
|
+
not, recover only with `yy merge project TASK_ID`. Implementation agents do not
|
|
55
|
+
poll, steal authority, discard dirty bytes, or mutate the target.
|
|
56
|
+
|
|
57
|
+
Release-version changes use this same ordinary task/merge lifecycle. Package
|
|
58
|
+
preparation is maintainer-only and outside `yy`. Never create a tag, push,
|
|
59
|
+
publish, deploy, mutate production, restart services, run post-deploy E2E, or
|
|
60
|
+
clean worktrees without separate authority.
|