@nomadamas/k-skill 0.2.5 → 0.4.0

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 (77) hide show
  1. package/package.json +1 -1
  2. package/skills/bok-ecos-stats/instruction.md +1 -1
  3. package/skills/bunjang-search/references/DISCLAIMER.md +23 -0
  4. package/skills/coupang-product-search/references/DISCLAIMER.md +23 -0
  5. package/skills/daangn-cars-search/references/DISCLAIMER.md +23 -0
  6. package/skills/daangn-jobs-search/references/DISCLAIMER.md +23 -0
  7. package/skills/daangn-realty-search/references/DISCLAIMER.md +23 -0
  8. package/skills/daangn-used-goods-search/references/DISCLAIMER.md +23 -0
  9. package/skills/daishin-report-search/references/DISCLAIMER.md +23 -0
  10. package/skills/daiso-product-search/references/DISCLAIMER.md +23 -0
  11. package/skills/danawa-price-search/references/DISCLAIMER.md +23 -0
  12. package/skills/delivery-tracking/references/DISCLAIMER.md +23 -0
  13. package/skills/express-bus-booking/references/DISCLAIMER.md +23 -0
  14. package/skills/fine-dust-location/skill.json +1 -7
  15. package/skills/flight-ticket-search/references/DISCLAIMER.md +23 -0
  16. package/skills/foresttrip-vacancy/references/DISCLAIMER.md +23 -0
  17. package/skills/intercity-bus-booking/references/DISCLAIMER.md +23 -0
  18. package/skills/job-posting-match/references/DISCLAIMER.md +23 -0
  19. package/skills/jobkorea-talent-search/references/DISCLAIMER.md +23 -0
  20. package/skills/k-skill-setup/skill.json +1 -7
  21. package/skills/kakao-bar-nearby/references/DISCLAIMER.md +15 -0
  22. package/skills/kakao-map/references/DISCLAIMER.md +15 -0
  23. package/skills/kakaotalk-mac/references/DISCLAIMER.md +15 -0
  24. package/skills/kbl-results/references/DISCLAIMER.md +13 -0
  25. package/skills/kbo-results/references/DISCLAIMER.md +13 -0
  26. package/skills/keris-academic-search/references/DISCLAIMER.md +13 -0
  27. package/skills/keris-academic-search/references/TRADEMARK-LEGAL-STATEMENT.md +7 -0
  28. package/skills/kleague-results/references/DISCLAIMER.md +13 -0
  29. package/skills/kopis-performance-search/references/DISCLAIMER.md +13 -0
  30. package/skills/kopis-performance-search/references/TRADEMARK-LEGAL-STATEMENT.md +7 -0
  31. package/skills/kopis-performance-search/skill.json +3 -4
  32. package/skills/korean-cinema-search/references/DISCLAIMER.md +13 -0
  33. package/skills/korean-stock-search/references/DISCLAIMER.md +14 -0
  34. package/skills/korean-stock-search/references/TRADEMARK-LEGAL-STATEMENT.md +7 -0
  35. package/skills/korean-transit-route/references/DISCLAIMER.md +13 -0
  36. package/skills/ktx-booking/instruction.md +38 -221
  37. package/skills/ktx-booking/references/AUTOMATION-LEGAL-STATEMENT.md +10 -0
  38. package/skills/ktx-booking/references/DISCLAIMER.md +14 -0
  39. package/skills/ktx-booking/scripts/ktx_booking.py +176 -1274
  40. package/skills/ktx-booking/scripts/ktx_booking.py.lock +27 -0
  41. package/skills/ktx-booking/scripts/ktx_timetable.py +141 -0
  42. package/skills/ktx-booking/skill.json +3 -11
  43. package/skills/lck-analytics/references/DISCLAIMER.md +13 -0
  44. package/skills/lotto-results/references/DISCLAIMER.md +13 -0
  45. package/skills/market-kurly-search/references/DISCLAIMER.md +13 -0
  46. package/skills/myrealtrip-search/instruction.md +3 -1
  47. package/skills/myrealtrip-search/references/DISCLAIMER.md +13 -0
  48. package/skills/myrealtrip-search/scripts/myrealtrip_mcp.py +30 -8
  49. package/skills/myrealtrip-search/scripts/test_myrealtrip_mcp.py +62 -0
  50. package/skills/naver-ad-performance/references/DISCLAIMER.md +13 -0
  51. package/skills/naver-blog-research/references/DISCLAIMER.md +13 -0
  52. package/skills/naver-news-search/references/DISCLAIMER.md +13 -0
  53. package/skills/naver-shopping-search/references/DISCLAIMER.md +13 -0
  54. package/skills/ohou-today-deal/references/DISCLAIMER.md +13 -0
  55. package/skills/olive-young-search/references/DISCLAIMER.md +13 -0
  56. package/skills/popbill/references/DISCLAIMER.md +13 -0
  57. package/skills/saramin-talent-search/references/DISCLAIMER.md +13 -0
  58. package/skills/seoul-weather-risk/instruction.md +28 -35
  59. package/skills/seoul-weather-risk/scripts/seoul_weather_risk.py +15 -68
  60. package/skills/seoul-weather-risk/skill.json +2 -2
  61. package/skills/srt-booking/instruction.md +48 -154
  62. package/skills/srt-booking/references/AUTOMATION-LEGAL-STATEMENT.md +25 -0
  63. package/skills/srt-booking/references/DISCLAIMER.md +13 -0
  64. package/skills/srt-booking/scripts/srt_booking.py +134 -235
  65. package/skills/srt-booking/scripts/srt_booking.py.lock +207 -0
  66. package/skills/srt-booking/skill.json +3 -15
  67. package/skills/store-longevity-radar/scripts/__pycache__/store_longevity_download.cpython-312.pyc +0 -0
  68. package/skills/ticket-availability/references/DISCLAIMER.md +13 -0
  69. package/skills/{toss-securities → toss-investment}/instruction.md +1 -1
  70. package/skills/toss-investment/references/DISCLAIMER.md +14 -0
  71. package/skills/{toss-securities → toss-investment}/references/TRADEMARK-LEGAL-STATEMENT.md +1 -1
  72. package/skills/{toss-securities → toss-investment}/skill.json +2 -2
  73. package/src/assemble.js +1 -1
  74. package/src/execute.js +13 -3
  75. package/skills/lovebug-report/instruction.md +0 -185
  76. package/skills/lovebug-report/skill.json +0 -9
  77. package/skills/srt-booking/scripts/srt_seats.py +0 -156
@@ -1,156 +0,0 @@
1
- #!/usr/bin/env python3
2
- from __future__ import annotations
3
-
4
- import re
5
- from typing import TypedDict
6
-
7
-
8
- class SrtCar(TypedDict):
9
- car_no: int
10
- car_no_raw: str
11
- room_class: str
12
- available: bool
13
- current: bool
14
-
15
-
16
- class SrtSeat(TypedDict):
17
- seat: str
18
- seat_no: str
19
- available: bool
20
- direction: str
21
- position: str
22
- notes: list[str]
23
-
24
-
25
- CAR_RE = re.compile(
26
- r'<li class="scar-(?P<car>\d+)(?P<class>[^"]*)">(?P<body>.*?)</li>',
27
- re.DOTALL,
28
- )
29
- SEAT_LINK_RE = re.compile(
30
- r"<a[^>]+selectSeatInfo\(this,\s*'(?P<seat_no>[^']+)',\s*'(?P<seat>[^']+)'\)[^>]*>"
31
- r".*?<em>\((?P<detail>[^)]*)\)</em>",
32
- re.DOTALL,
33
- )
34
- SEAT_SPAN_RE = re.compile(
35
- r"<span>\s*(?P<seat>\d+[A-Z])\s*<strong><em>\((?P<detail>[^)]*)\)</em></strong></span>",
36
- re.DOTALL,
37
- )
38
- TAG_RE = re.compile(r"<[^>]+>")
39
-
40
-
41
- def strip_tags(value: str) -> str:
42
- return TAG_RE.sub(" ", value).replace("\xa0", " ").strip()
43
-
44
-
45
- def parse_detail(detail: str) -> tuple[str, str, list[str]]:
46
- parts = [part.strip() for part in detail.split(",")]
47
- direction = next((part for part in parts if part in {"정방향", "역방향"}), "unknown")
48
- position = next((part for part in parts if part in {"창측", "내측", "1인석"}), "unknown")
49
- notes = [part for part in parts if part not in {direction, position} and part]
50
- return direction, position, notes
51
-
52
-
53
- def parse_cars(html: str) -> list[SrtCar]:
54
- cars: list[SrtCar] = []
55
- for match in CAR_RE.finditer(html):
56
- body = match.group("body")
57
- text = strip_tags(body)
58
- room_class = "특실" if "특실" in text else "일반실"
59
- css_class = match.group("class")
60
- has_link = "selectScarInfo" in body
61
- cars.append(
62
- {
63
- "car_no": int(match.group("car")),
64
- "car_no_raw": f"{int(match.group('car')):04d}",
65
- "room_class": room_class,
66
- "available": has_link and "off" not in css_class.split(),
67
- "current": "on" in css_class.split(),
68
- }
69
- )
70
- return cars
71
-
72
-
73
- def parse_seats(html: str) -> list[SrtSeat]:
74
- seats: list[SrtSeat] = []
75
- seen: set[str] = set()
76
- for match in SEAT_LINK_RE.finditer(html):
77
- direction, position, notes = parse_detail(match.group("detail"))
78
- seat = match.group("seat")
79
- seen.add(seat)
80
- seats.append(
81
- {
82
- "seat": seat,
83
- "seat_no": match.group("seat_no"),
84
- "available": True,
85
- "direction": direction,
86
- "position": position,
87
- "notes": notes,
88
- }
89
- )
90
- for match in SEAT_SPAN_RE.finditer(html):
91
- seat = match.group("seat")
92
- if seat in seen:
93
- continue
94
- direction, position, notes = parse_detail(match.group("detail"))
95
- seats.append(
96
- {
97
- "seat": seat,
98
- "seat_no": "",
99
- "available": False,
100
- "direction": direction,
101
- "position": position,
102
- "notes": notes,
103
- }
104
- )
105
- return seats
106
-
107
-
108
- def parse_seat_label(seat_label: str) -> tuple[int | None, str]:
109
- match = re.match(r"^(\d+)([A-Z])$", seat_label)
110
- if match is None:
111
- return None, ""
112
- return int(match.group(1)), match.group(2)
113
-
114
-
115
- def car_center_priority(car: SrtCar, car_numbers: list[int]) -> tuple[float, int]:
116
- if not car_numbers:
117
- return (0.0, car["car_no"])
118
- center = (min(car_numbers) + max(car_numbers)) / 2
119
- return (abs(car["car_no"] - center), car["car_no"])
120
-
121
-
122
- def sort_cars_for_booking(cars: list[SrtCar], priority: str = "center") -> list[SrtCar]:
123
- match priority:
124
- case "center":
125
- car_numbers = [car["car_no"] for car in cars]
126
- return sorted(cars, key=lambda car: car_center_priority(car, car_numbers))
127
- case "low":
128
- return sorted(cars, key=lambda car: car["car_no"])
129
- case "high":
130
- return sorted(cars, key=lambda car: car["car_no"], reverse=True)
131
- case _:
132
- raise ValueError(f"unsupported car priority: {priority}")
133
-
134
-
135
- def seat_preference_key(seat: SrtSeat, priority: str = "forward-window") -> tuple[int, int, int, str]:
136
- row, column = parse_seat_label(seat["seat"])
137
- forward_rank = 0 if seat["direction"] == "정방향" else 1
138
- window_rank = 0 if seat["position"] in {"창측", "1인석"} else 1
139
- row_rank = 999 if row is None else row
140
- match priority:
141
- case "forward-window":
142
- return (forward_rank, window_rank, row_rank, column)
143
- case "window-forward":
144
- return (window_rank, forward_rank, row_rank, column)
145
- case "row-low":
146
- return (row_rank, forward_rank, window_rank, column)
147
- case _:
148
- raise ValueError(f"unsupported seat priority: {priority}")
149
-
150
-
151
- def sort_seats_for_booking(seats: list[SrtSeat], priority: str = "forward-window") -> list[SrtSeat]:
152
- return sorted(seats, key=lambda seat: seat_preference_key(seat, priority))
153
-
154
-
155
- sort_cars = sort_cars_for_booking
156
- sort_seats = sort_seats_for_booking