@nomadamas/k-skill 0.1.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 (350) hide show
  1. package/bin/k-skill.js +60 -0
  2. package/package.json +37 -0
  3. package/skills/assembly-bill-vote-search/instruction.md +111 -0
  4. package/skills/assembly-bill-vote-search/skill.json +10 -0
  5. package/skills/biz-health-check/instruction.md +69 -0
  6. package/skills/biz-health-check/scripts/biz_health_check.py +163 -0
  7. package/skills/biz-health-check/skill.json +10 -0
  8. package/skills/bok-ecos-stats/instruction.md +95 -0
  9. package/skills/bok-ecos-stats/scripts/bok_ecos.py +302 -0
  10. package/skills/bok-ecos-stats/skill.json +10 -0
  11. package/skills/building-register-search/instruction.md +69 -0
  12. package/skills/building-register-search/scripts/building_register.py +309 -0
  13. package/skills/building-register-search/scripts/building_register_xml.py +32 -0
  14. package/skills/building-register-search/skill.json +9 -0
  15. package/skills/bunjang-search/instruction.md +154 -0
  16. package/skills/bunjang-search/skill.json +10 -0
  17. package/skills/catchtable-sniper/instruction.md +270 -0
  18. package/skills/catchtable-sniper/skill.json +9 -0
  19. package/skills/cheap-gas-nearby/instruction.md +107 -0
  20. package/skills/cheap-gas-nearby/skill.json +10 -0
  21. package/skills/corporate-registration-consulting/instruction.md +117 -0
  22. package/skills/corporate-registration-consulting/scripts/fill_official_hwp.py +106 -0
  23. package/skills/corporate-registration-consulting/skill.json +8 -0
  24. package/skills/coupang-product-search/instruction.md +219 -0
  25. package/skills/coupang-product-search/scripts/coupang_partners_mcp.py +146 -0
  26. package/skills/coupang-product-search/skill.json +10 -0
  27. package/skills/court-auction-notice-search/instruction.md +201 -0
  28. package/skills/court-auction-notice-search/skill.json +9 -0
  29. package/skills/court-payment-order-assistant/instruction.md +120 -0
  30. package/skills/court-payment-order-assistant/skill.json +10 -0
  31. package/skills/d2b-notice-search/instruction.md +117 -0
  32. package/skills/d2b-notice-search/skill.json +10 -0
  33. package/skills/daangn-cars-search/instruction.md +91 -0
  34. package/skills/daangn-cars-search/scripts/daangn_cars.py +72 -0
  35. package/skills/daangn-cars-search/skill.json +9 -0
  36. package/skills/daangn-jobs-search/instruction.md +90 -0
  37. package/skills/daangn-jobs-search/scripts/daangn_jobs.py +98 -0
  38. package/skills/daangn-jobs-search/skill.json +9 -0
  39. package/skills/daangn-realty-search/instruction.md +114 -0
  40. package/skills/daangn-realty-search/scripts/daangn_detail_ld.py +76 -0
  41. package/skills/daangn-realty-search/scripts/daangn_realty.py +216 -0
  42. package/skills/daangn-realty-search/scripts/daangn_relay_store.py +174 -0
  43. package/skills/daangn-realty-search/skill.json +8 -0
  44. package/skills/daangn-used-goods-search/instruction.md +90 -0
  45. package/skills/daangn-used-goods-search/scripts/daangn_used_goods.py +80 -0
  46. package/skills/daangn-used-goods-search/skill.json +9 -0
  47. package/skills/daishin-report-search/instruction.md +138 -0
  48. package/skills/daishin-report-search/skill.json +10 -0
  49. package/skills/daiso-product-search/instruction.md +172 -0
  50. package/skills/daiso-product-search/skill.json +8 -0
  51. package/skills/danawa-price-search/instruction.md +183 -0
  52. package/skills/danawa-price-search/scripts/danawa_search.py +354 -0
  53. package/skills/danawa-price-search/skill.json +8 -0
  54. package/skills/delivery-tracking/instruction.md +358 -0
  55. package/skills/delivery-tracking/skill.json +8 -0
  56. package/skills/donation-place-search/instruction.md +129 -0
  57. package/skills/donation-place-search/skill.json +9 -0
  58. package/skills/emergency-room-beds/instruction.md +82 -0
  59. package/skills/emergency-room-beds/skill.json +8 -0
  60. package/skills/ev-charger-nearby/instruction.md +80 -0
  61. package/skills/ev-charger-nearby/scripts/ev_charger.py +222 -0
  62. package/skills/ev-charger-nearby/skill.json +10 -0
  63. package/skills/ev-subsidy-status/instruction.md +165 -0
  64. package/skills/ev-subsidy-status/skill.json +10 -0
  65. package/skills/express-bus-booking/instruction.md +207 -0
  66. package/skills/express-bus-booking/references/kobus-http-flow.md +159 -0
  67. package/skills/express-bus-booking/scripts/kobus_express_booking.py +243 -0
  68. package/skills/express-bus-booking/skill.json +8 -0
  69. package/skills/fine-dust-location/instruction.md +89 -0
  70. package/skills/fine-dust-location/skill.json +9 -0
  71. package/skills/flight-ticket-search/instruction.md +237 -0
  72. package/skills/flight-ticket-search/scripts/flight_ticket_search.py +501 -0
  73. package/skills/flight-ticket-search/skill.json +9 -0
  74. package/skills/foresttrip-vacancy/instruction.md +167 -0
  75. package/skills/foresttrip-vacancy/scripts/run_foresttrip_vacancy.py +549 -0
  76. package/skills/foresttrip-vacancy/skill.json +10 -0
  77. package/skills/fsc-corporate-info/instruction.md +57 -0
  78. package/skills/fsc-corporate-info/scripts/fsc_corporate_info.py +113 -0
  79. package/skills/fsc-corporate-info/skill.json +10 -0
  80. package/skills/g2b-order-plan-search/instruction.md +131 -0
  81. package/skills/g2b-order-plan-search/scripts/g2b_order_plan.py +158 -0
  82. package/skills/g2b-order-plan-search/skill.json +10 -0
  83. package/skills/g2b-sanctioned-supplier/instruction.md +61 -0
  84. package/skills/g2b-sanctioned-supplier/scripts/g2b_sanctioned_supplier.py +114 -0
  85. package/skills/g2b-sanctioned-supplier/skill.json +10 -0
  86. package/skills/gangnamunni-clinic-search/instruction.md +113 -0
  87. package/skills/gangnamunni-clinic-search/skill.json +9 -0
  88. package/skills/geeknews-search/instruction.md +69 -0
  89. package/skills/geeknews-search/scripts/geeknews_search.py +296 -0
  90. package/skills/geeknews-search/skill.json +8 -0
  91. package/skills/gongsijiga-search/instruction.md +128 -0
  92. package/skills/gongsijiga-search/skill.json +9 -0
  93. package/skills/gov-overseas-trip-report/instruction.md +488 -0
  94. package/skills/gov-overseas-trip-report/scripts/gov_overseas_trip_report.py +1206 -0
  95. package/skills/gov-overseas-trip-report/skill.json +9 -0
  96. package/skills/han-river-water-level/instruction.md +83 -0
  97. package/skills/han-river-water-level/skill.json +10 -0
  98. package/skills/highway-traffic-status/instruction.md +88 -0
  99. package/skills/highway-traffic-status/scripts/highway_traffic.py +315 -0
  100. package/skills/highway-traffic-status/skill.json +11 -0
  101. package/skills/hipass-receipt/instruction.md +97 -0
  102. package/skills/hipass-receipt/skill.json +10 -0
  103. package/skills/hola-poke-yeoksam/instruction.md +247 -0
  104. package/skills/hola-poke-yeoksam/skill.json +8 -0
  105. package/skills/household-waste-info/instruction.md +117 -0
  106. package/skills/household-waste-info/skill.json +10 -0
  107. package/skills/housing-official-price/instruction.md +177 -0
  108. package/skills/housing-official-price/skill.json +10 -0
  109. package/skills/hwp/instruction.md +206 -0
  110. package/skills/hwp/skill.json +8 -0
  111. package/skills/intercity-bus-booking/instruction.md +189 -0
  112. package/skills/intercity-bus-booking/references/tmoney-intercity-http-flow.md +126 -0
  113. package/skills/intercity-bus-booking/scripts/intercity_bus_search.py +381 -0
  114. package/skills/intercity-bus-booking/skill.json +8 -0
  115. package/skills/iros-registry-automation/instruction.md +229 -0
  116. package/skills/iros-registry-automation/scripts/iros_pdf_summary.py +249 -0
  117. package/skills/iros-registry-automation/scripts/upstream.pin +1 -0
  118. package/skills/iros-registry-automation/skill.json +9 -0
  119. package/skills/job-posting-match/instruction.md +130 -0
  120. package/skills/job-posting-match/scripts/job_posting_match.py +396 -0
  121. package/skills/job-posting-match/scripts/test_job_posting_match.py +54 -0
  122. package/skills/job-posting-match/skill.json +8 -0
  123. package/skills/jobkorea-talent-search/instruction.md +118 -0
  124. package/skills/jobkorea-talent-search/scripts/jobkorea_talent_models.py +27 -0
  125. package/skills/jobkorea-talent-search/scripts/jobkorea_talent_parse.py +186 -0
  126. package/skills/jobkorea-talent-search/scripts/jobkorea_talent_search.py +94 -0
  127. package/skills/jobkorea-talent-search/scripts/jobkorea_talent_search_condition.py +136 -0
  128. package/skills/jobkorea-talent-search/scripts/test_jobkorea_talent_search.py +76 -0
  129. package/skills/jobkorea-talent-search/skill.json +9 -0
  130. package/skills/joseon-sillok-search/instruction.md +76 -0
  131. package/skills/joseon-sillok-search/scripts/sillok_search.py +552 -0
  132. package/skills/joseon-sillok-search/skill.json +8 -0
  133. package/skills/k-dart/instruction.md +406 -0
  134. package/skills/k-dart/skill.json +8 -0
  135. package/skills/k-schoollunch-menu/instruction.md +109 -0
  136. package/skills/k-schoollunch-menu/skill.json +9 -0
  137. package/skills/k-skill-cleaner/instruction.md +80 -0
  138. package/skills/k-skill-cleaner/scripts/k_skill_cleaner.py +410 -0
  139. package/skills/k-skill-cleaner/skill.json +8 -0
  140. package/skills/k-skill-setup/instruction.md +253 -0
  141. package/skills/k-skill-setup/skill.json +11 -0
  142. package/skills/kakao-bar-nearby/instruction.md +76 -0
  143. package/skills/kakao-bar-nearby/skill.json +8 -0
  144. package/skills/kakao-map/instruction.md +176 -0
  145. package/skills/kakao-map/skill.json +10 -0
  146. package/skills/kakaotalk-mac/instruction.md +189 -0
  147. package/skills/kakaotalk-mac/skill.json +8 -0
  148. package/skills/kbl-results/instruction.md +89 -0
  149. package/skills/kbl-results/skill.json +9 -0
  150. package/skills/kbo-results/instruction.md +82 -0
  151. package/skills/kbo-results/skill.json +8 -0
  152. package/skills/keris-academic-search/instruction.md +81 -0
  153. package/skills/keris-academic-search/scripts/keris_academic.py +210 -0
  154. package/skills/keris-academic-search/skill.json +10 -0
  155. package/skills/kleague-results/instruction.md +92 -0
  156. package/skills/kleague-results/skill.json +8 -0
  157. package/skills/kopis-performance-search/instruction.md +109 -0
  158. package/skills/kopis-performance-search/skill.json +10 -0
  159. package/skills/korea-weather/instruction.md +93 -0
  160. package/skills/korea-weather/skill.json +10 -0
  161. package/skills/korean-character-count/instruction.md +87 -0
  162. package/skills/korean-character-count/scripts/korean_character_count.js +268 -0
  163. package/skills/korean-character-count/skill.json +8 -0
  164. package/skills/korean-cinema-search/instruction.md +177 -0
  165. package/skills/korean-cinema-search/skill.json +8 -0
  166. package/skills/korean-heritage-search/instruction.md +106 -0
  167. package/skills/korean-heritage-search/scripts/korean_heritage_search.py +321 -0
  168. package/skills/korean-heritage-search/skill.json +8 -0
  169. package/skills/korean-holiday-calendar/instruction.md +97 -0
  170. package/skills/korean-holiday-calendar/skill.json +9 -0
  171. package/skills/korean-humanizer/instruction.md +389 -0
  172. package/skills/korean-humanizer/references/ai-tell-taxonomy.md +147 -0
  173. package/skills/korean-humanizer/skill.json +8 -0
  174. package/skills/korean-jangbu-for/instruction.md +133 -0
  175. package/skills/korean-jangbu-for/scripts/install.sh +237 -0
  176. package/skills/korean-jangbu-for/scripts/upstream.pin +1 -0
  177. package/skills/korean-jangbu-for/skill.json +8 -0
  178. package/skills/korean-law-search/instruction.md +126 -0
  179. package/skills/korean-law-search/skill.json +10 -0
  180. package/skills/korean-marathon-schedule/instruction.md +111 -0
  181. package/skills/korean-marathon-schedule/skill.json +9 -0
  182. package/skills/korean-middle-korean/instruction.md +79 -0
  183. package/skills/korean-middle-korean/scripts/korean_middle_korean.js +214 -0
  184. package/skills/korean-middle-korean/skill.json +8 -0
  185. package/skills/korean-patent-search/instruction.md +79 -0
  186. package/skills/korean-patent-search/scripts/patent_search.py +409 -0
  187. package/skills/korean-patent-search/skill.json +9 -0
  188. package/skills/korean-privacy-terms/instruction.md +128 -0
  189. package/skills/korean-privacy-terms/scripts/install.sh +108 -0
  190. package/skills/korean-privacy-terms/scripts/upstream.pin +1 -0
  191. package/skills/korean-privacy-terms/skill.json +8 -0
  192. package/skills/korean-scholarship-search/instruction.md +317 -0
  193. package/skills/korean-scholarship-search/references/report-format.md +40 -0
  194. package/skills/korean-scholarship-search/references/school-discovery.md +61 -0
  195. package/skills/korean-scholarship-search/references/search-clues.md +58 -0
  196. package/skills/korean-scholarship-search/references/source-patterns.md +67 -0
  197. package/skills/korean-scholarship-search/scripts/scholarship_filter.py +811 -0
  198. package/skills/korean-scholarship-search/scripts/test_scholarship_filter.py +224 -0
  199. package/skills/korean-scholarship-search/scripts/university_search_plan.py +148 -0
  200. package/skills/korean-scholarship-search/skill.json +8 -0
  201. package/skills/korean-slang-writing/instruction.md +181 -0
  202. package/skills/korean-slang-writing/scripts/_slang_http.py +91 -0
  203. package/skills/korean-slang-writing/scripts/slang_lookup.py +291 -0
  204. package/skills/korean-slang-writing/scripts/slang_search.py +284 -0
  205. package/skills/korean-slang-writing/skill.json +8 -0
  206. package/skills/korean-spell-check/instruction.md +105 -0
  207. package/skills/korean-spell-check/scripts/korean_spell_check.py +523 -0
  208. package/skills/korean-spell-check/skill.json +9 -0
  209. package/skills/korean-stock-search/instruction.md +194 -0
  210. package/skills/korean-stock-search/skill.json +10 -0
  211. package/skills/korean-transit-route/instruction.md +113 -0
  212. package/skills/korean-transit-route/skill.json +10 -0
  213. package/skills/kosis-stats/instruction.md +232 -0
  214. package/skills/kosis-stats/references/kosis-openapi-guide.md +171 -0
  215. package/skills/kosis-stats/scripts/run_kosis_stats.py +896 -0
  216. package/skills/kosis-stats/skill.json +9 -0
  217. package/skills/kr-whois-lookup/instruction.md +107 -0
  218. package/skills/kr-whois-lookup/skill.json +10 -0
  219. package/skills/kstartup-search/instruction.md +186 -0
  220. package/skills/kstartup-search/scripts/run_kstartup.py +424 -0
  221. package/skills/kstartup-search/skill.json +11 -0
  222. package/skills/ktx-booking/instruction.md +244 -0
  223. package/skills/ktx-booking/skill.json +10 -0
  224. package/skills/lck-analytics/instruction.md +192 -0
  225. package/skills/lck-analytics/scripts/_lib.js +103 -0
  226. package/skills/lck-analytics/scripts/analyze-live-game.js +52 -0
  227. package/skills/lck-analytics/scripts/build-match-report.js +44 -0
  228. package/skills/lck-analytics/scripts/sync-oracle.js +50 -0
  229. package/skills/lck-analytics/skill.json +9 -0
  230. package/skills/lh-notice-search/instruction.md +206 -0
  231. package/skills/lh-notice-search/skill.json +10 -0
  232. package/skills/library-book-search/instruction.md +139 -0
  233. package/skills/library-book-search/skill.json +9 -0
  234. package/skills/local-election-candidate-search/instruction.md +77 -0
  235. package/skills/local-election-candidate-search/skill.json +8 -0
  236. package/skills/localdata-business-status/instruction.md +64 -0
  237. package/skills/localdata-business-status/scripts/localdata_business_status.py +206 -0
  238. package/skills/localdata-business-status/skill.json +8 -0
  239. package/skills/lotto-results/instruction.md +80 -0
  240. package/skills/lotto-results/skill.json +8 -0
  241. package/skills/lovebug-report/instruction.md +185 -0
  242. package/skills/lovebug-report/skill.json +9 -0
  243. package/skills/market-kurly-search/instruction.md +125 -0
  244. package/skills/market-kurly-search/skill.json +8 -0
  245. package/skills/mfds-drug-safety/instruction.md +86 -0
  246. package/skills/mfds-drug-safety/scripts/mfds_drug_safety.py +184 -0
  247. package/skills/mfds-drug-safety/skill.json +10 -0
  248. package/skills/mfds-food-safety/instruction.md +126 -0
  249. package/skills/mfds-food-safety/scripts/mfds_food_safety.py +281 -0
  250. package/skills/mfds-food-safety/skill.json +10 -0
  251. package/skills/myrealtrip-search/instruction.md +239 -0
  252. package/skills/myrealtrip-search/scripts/myrealtrip_mcp.py +194 -0
  253. package/skills/myrealtrip-search/scripts/test_myrealtrip_mcp.py +99 -0
  254. package/skills/myrealtrip-search/skill.json +9 -0
  255. package/skills/naming-house/instruction.md +146 -0
  256. package/skills/naming-house/skill.json +8 -0
  257. package/skills/national-pension-workplace/instruction.md +64 -0
  258. package/skills/national-pension-workplace/scripts/national_pension_workplace.py +113 -0
  259. package/skills/national-pension-workplace/skill.json +10 -0
  260. package/skills/naver-ad-performance/instruction.md +108 -0
  261. package/skills/naver-ad-performance/scripts/naver_ad_performance.py +240 -0
  262. package/skills/naver-ad-performance/skill.json +9 -0
  263. package/skills/naver-blog-research/instruction.md +128 -0
  264. package/skills/naver-blog-research/scripts/_naver_http.py +58 -0
  265. package/skills/naver-blog-research/scripts/naver_download_images.py +233 -0
  266. package/skills/naver-blog-research/scripts/naver_read.py +256 -0
  267. package/skills/naver-blog-research/scripts/naver_search.py +192 -0
  268. package/skills/naver-blog-research/skill.json +8 -0
  269. package/skills/naver-news-search/instruction.md +103 -0
  270. package/skills/naver-news-search/skill.json +10 -0
  271. package/skills/naver-shopping-search/instruction.md +94 -0
  272. package/skills/naver-shopping-search/skill.json +11 -0
  273. package/skills/nhis-care-checkup-search/instruction.md +116 -0
  274. package/skills/nhis-care-checkup-search/skill.json +10 -0
  275. package/skills/nts-business-registration/instruction.md +115 -0
  276. package/skills/nts-business-registration/scripts/nts_business_registration.py +215 -0
  277. package/skills/nts-business-registration/skill.json +10 -0
  278. package/skills/nts-tax-delinquency/instruction.md +54 -0
  279. package/skills/nts-tax-delinquency/scripts/nts_tax_delinquency.py +150 -0
  280. package/skills/nts-tax-delinquency/skill.json +8 -0
  281. package/skills/ohou-today-deal/instruction.md +182 -0
  282. package/skills/ohou-today-deal/scripts/ohou_today_deal.py +369 -0
  283. package/skills/ohou-today-deal/skill.json +9 -0
  284. package/skills/olive-young-search/instruction.md +154 -0
  285. package/skills/olive-young-search/skill.json +8 -0
  286. package/skills/parking-lot-search/instruction.md +96 -0
  287. package/skills/parking-lot-search/skill.json +9 -0
  288. package/skills/popbill/instruction.md +146 -0
  289. package/skills/popbill/scripts/popbill_cli.py +284 -0
  290. package/skills/popbill/scripts/popbill_registry.py +54 -0
  291. package/skills/popbill/scripts/popbill_safety.py +37 -0
  292. package/skills/popbill/scripts/popbill_templates.py +71 -0
  293. package/skills/popbill/skill.json +9 -0
  294. package/skills/public-restroom-nearby/instruction.md +89 -0
  295. package/skills/public-restroom-nearby/skill.json +9 -0
  296. package/skills/real-estate-search/instruction.md +172 -0
  297. package/skills/real-estate-search/skill.json +10 -0
  298. package/skills/rhwp-advanced/instruction.md +145 -0
  299. package/skills/rhwp-advanced/skill.json +8 -0
  300. package/skills/rhwp-edit/instruction.md +153 -0
  301. package/skills/rhwp-edit/skill.json +8 -0
  302. package/skills/s2b-notice-search/instruction.md +66 -0
  303. package/skills/s2b-notice-search/skill.json +9 -0
  304. package/skills/saju-fortune/instruction.md +177 -0
  305. package/skills/saju-fortune/skill.json +8 -0
  306. package/skills/saramin-talent-search/instruction.md +119 -0
  307. package/skills/saramin-talent-search/skill.json +9 -0
  308. package/skills/seoul-bike/instruction.md +83 -0
  309. package/skills/seoul-bike/scripts/seoul_bike.py +247 -0
  310. package/skills/seoul-bike/skill.json +10 -0
  311. package/skills/seoul-density/instruction.md +109 -0
  312. package/skills/seoul-density/scripts/seoul_density.py +271 -0
  313. package/skills/seoul-density/skill.json +10 -0
  314. package/skills/seoul-subway-arrival/instruction.md +85 -0
  315. package/skills/seoul-subway-arrival/skill.json +9 -0
  316. package/skills/sh-notice-search/instruction.md +150 -0
  317. package/skills/sh-notice-search/skill.json +9 -0
  318. package/skills/srt-booking/instruction.md +181 -0
  319. package/skills/srt-booking/scripts/srt_booking.py +272 -0
  320. package/skills/srt-booking/scripts/srt_seats.py +156 -0
  321. package/skills/srt-booking/skill.json +20 -0
  322. package/skills/subway-lost-property/instruction.md +93 -0
  323. package/skills/subway-lost-property/scripts/subway_lost_property.py +244 -0
  324. package/skills/subway-lost-property/skill.json +8 -0
  325. package/skills/ticket-availability/instruction.md +175 -0
  326. package/skills/ticket-availability/scripts/ticket_availability.py +430 -0
  327. package/skills/ticket-availability/skill.json +9 -0
  328. package/skills/toss-securities/instruction.md +116 -0
  329. package/skills/toss-securities/skill.json +9 -0
  330. package/skills/used-car-price-search/instruction.md +109 -0
  331. package/skills/used-car-price-search/skill.json +8 -0
  332. package/skills/yebigun-training/instruction.md +177 -0
  333. package/skills/yebigun-training/skill.json +9 -0
  334. package/skills/zipcode-search/instruction.md +159 -0
  335. package/skills/zipcode-search/scripts/zipcode_search.py +150 -0
  336. package/skills/zipcode-search/skill.json +8 -0
  337. package/src/assemble.js +134 -0
  338. package/src/detect.js +18 -0
  339. package/templates/action-account.md +4 -0
  340. package/templates/action-booking.md +5 -0
  341. package/templates/action-commerce.md +5 -0
  342. package/templates/action-communication.md +5 -0
  343. package/templates/action-submission.md +5 -0
  344. package/templates/browser.md +4 -0
  345. package/templates/core.md +5 -0
  346. package/templates/hard-boundary.md +3 -0
  347. package/templates/local.md +2 -0
  348. package/templates/lookup.md +2 -0
  349. package/templates/proxy.md +2 -0
  350. package/templates/vault.md +4 -0
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env python3
2
+ """등기부등본(등기사항증명서) PDF → 사실 요약 (판단 없음).
3
+
4
+ iros-registry-automation 스킬의 **발급 후 단계** 전용. 사용자가 직접 로그인·결제해
5
+ 받은 PDF에서 근저당·가압류·소유권 변동 등 핵심 항목을 "PDF에 이렇게 적혀 있다"는
6
+ 사실만 뽑아 사람이 읽기 쉬운 요약으로 만든다.
7
+
8
+ 지켜야 할 것 (기존 스킬 hard limit 승계):
9
+ - 로그인/결제는 사람이 직접 — 이 스크립트는 발급 후에만 관여한다.
10
+ - **법률 자문·권리관계 해석·안전/위험 판단을 하지 않는다.** 사실 추출까지만.
11
+ - 개인정보: 이 스크립트는 **어디에도 전송하지 않는다**(로컬 처리 전용). 주민등록번호는
12
+ 마스킹한다. 요약 결과는 저장소·PR·로그에 남기지 말고 $workdir/output 등 비공개 폴더에만 둔다.
13
+
14
+ 입력:
15
+ - PDF 경로 → 로컬 텍스트 추출(pdfplumber → pypdf). 텍스트 레이어가 있는 등기 PDF에 적합.
16
+ - 이미 변환된 텍스트/마크다운(`--from-text`) → 스캔 PDF를 사용자가 self-host 변환기
17
+ (예: marker, https://github.com/NomaDamas/marker-api-server)로 변환한 결과를 그대로 요약.
18
+ ※ marker는 로컬에서 사용자가 직접 실행하며, 이 스크립트가 원격으로 PDF를 보내지 않는다.
19
+
20
+ 사용 예:
21
+ python iros_pdf_summary.py "$workdir/downloads/등기.pdf" --out "$workdir/output"
22
+ python iros_pdf_summary.py 변환결과.md --from-text
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import argparse
27
+ import json
28
+ import re
29
+ import sys
30
+ from pathlib import Path
31
+
32
+ # ── 개인정보 마스킹 ──────────────────────────────────────────────
33
+ RRN_RE = re.compile(r"\b\d{6}[-\s]?[1-4]\d{6}\b") # 주민등록번호
34
+
35
+
36
+ def mask_pii(text: str) -> str:
37
+ """주민등록번호를 마스킹한다. 요약/로그 어디서도 원문 노출 금지."""
38
+ return RRN_RE.sub("******-*******", text)
39
+
40
+
41
+ # ── 텍스트 추출 (로컬 전용, 무전송) ──────────────────────────────
42
+ def extract_text_from_pdf(pdf_path: Path) -> str:
43
+ """PDF에서 텍스트 레이어를 로컬로 추출. 네트워크 사용 없음."""
44
+ try:
45
+ import pdfplumber # 표(근저당 목록) 추출에 유리
46
+ with pdfplumber.open(str(pdf_path)) as pdf:
47
+ return "\n".join((page.extract_text() or "") for page in pdf.pages)
48
+ except ImportError:
49
+ pass
50
+ try:
51
+ from pypdf import PdfReader
52
+ reader = PdfReader(str(pdf_path))
53
+ return "\n".join((page.extract_text() or "") for page in reader.pages)
54
+ except ImportError:
55
+ raise SystemExit(
56
+ "PDF 텍스트 추출 라이브러리가 없습니다. `pip install pypdf`(권장) 또는 "
57
+ "`pip install pdfplumber` 후 다시 실행하세요.\n"
58
+ "스캔(이미지) PDF라면, 로컬에 self-host한 변환기(예: marker)로 먼저 "
59
+ "텍스트/마크다운으로 바꾼 뒤 `--from-text <파일>`로 요약하세요."
60
+ )
61
+
62
+
63
+ def load_input_text(input_path: Path, from_text: bool) -> str:
64
+ """입력을 텍스트로 로드. PDF면 로컬 추출, 아니면(또는 --from-text) 파일을 그대로 읽는다."""
65
+ is_pdf = input_path.suffix.lower() == ".pdf"
66
+ if is_pdf and not from_text:
67
+ return extract_text_from_pdf(input_path)
68
+ return input_path.read_text(encoding="utf-8", errors="replace")
69
+
70
+
71
+ # ── 파싱 헬퍼 ────────────────────────────────────────────────────
72
+ DATE_RE = re.compile(r"(\d{4})\s*년\s*(\d{1,2})\s*월\s*(\d{1,2})\s*일")
73
+ AMOUNT_RE = re.compile(r"채권최고액\s*금?\s*([\d,]+)\s*원")
74
+
75
+
76
+ def _iso_date(m: "re.Match") -> str:
77
+ return f"{int(m.group(1)):04d}-{int(m.group(2)):02d}-{int(m.group(3)):02d}"
78
+
79
+
80
+ def detect_doc_type(text: str) -> str:
81
+ """부동산 / 법인 / 불명. 사실 판별(구조 마커 기반)."""
82
+ real = any(k in text for k in ("표제부", "표 제 부", "집합건물", "【갑구】", "【 갑 구 】", "갑 구", "을 구"))
83
+ corp = any(k in text for k in ("법인등기", "상 호", "임원에 관한 사항", "본 점", "발행할 주식"))
84
+ if real and not corp:
85
+ return "부동산"
86
+ if corp and not real:
87
+ return "법인"
88
+ if real:
89
+ return "부동산"
90
+ if corp:
91
+ return "법인"
92
+ return "불명"
93
+
94
+
95
+ def find_issued_at(text: str) -> str | None:
96
+ """열람/발급 일시 (사실). 없으면 None."""
97
+ for label in ("열람일시", "발급일시", "출력일시", "발행일시"):
98
+ idx = text.find(label)
99
+ if idx != -1:
100
+ m = DATE_RE.search(text[idx:idx + 60])
101
+ if m:
102
+ return _iso_date(m)
103
+ return None
104
+
105
+
106
+ def count_owner_changes(text: str) -> int:
107
+ """갑구 소유권이전 등기 건수 (소유자 변동 건수, 사실). 청구권가등기는 제외."""
108
+ return len(re.findall(r"소유권이전(?!청구권)", text))
109
+
110
+
111
+ def _section(text: str, start_markers, end_markers) -> str:
112
+ """지정 구간 텍스트만 잘라낸다(없으면 전체)."""
113
+ lo = -1
114
+ for mk in start_markers:
115
+ i = text.find(mk)
116
+ if i != -1:
117
+ lo = i
118
+ break
119
+ if lo == -1:
120
+ return text
121
+ hi = len(text)
122
+ for mk in end_markers:
123
+ j = text.find(mk, lo + 1)
124
+ if j != -1:
125
+ hi = min(hi, j)
126
+ return text[lo:hi]
127
+
128
+
129
+ def extract_mortgages(text: str) -> list:
130
+ """근저당권 목록: 채권최고액·설정일·말소여부 (사실 나열, 판단 없음).
131
+
132
+ 을구 구간에서 '근저당권설정'마다 인접 채권최고액·접수일을 뽑고,
133
+ 'N번근저당권설정등기말소'로 언급된 순위번호는 말소로 표시한다.
134
+ 구조가 흐트러진 추출 텍스트에선 누락될 수 있어 원문 대조를 권한다.
135
+ """
136
+ eul = _section(text, ("【을구】", "【 을 구 】", "을 구", "을 구"),
137
+ ("【갑구】", "【표제부】"))
138
+ # 말소된 순위번호 수집
139
+ canceled_ranks = set(int(n) for n in re.findall(r"(\d+)\s*번\s*근저당권설정(?:등기)?\s*말소", text))
140
+
141
+ mortgages = []
142
+ for m in re.finditer(r"근저당권설정(?!등기말소|\s*등기\s*말소)", eul):
143
+ window = eul[m.start(): m.start() + 500]
144
+ amt_m = AMOUNT_RE.search(window)
145
+ date_m = DATE_RE.search(window)
146
+ # 순위번호: '근저당권설정' 직전의 숫자(줄 시작 순위)
147
+ before = eul[max(0, m.start() - 40): m.start()]
148
+ rank_m = re.search(r"(\d+)\D*$", before)
149
+ rank = int(rank_m.group(1)) if rank_m else None
150
+ amount_won = int(amt_m.group(1).replace(",", "")) if amt_m else None
151
+ mortgages.append({
152
+ "rank": rank,
153
+ "amount_won": amount_won,
154
+ "amount_text": (f"채권최고액 금 {amt_m.group(1)}원" if amt_m else None),
155
+ "registered_date": (_iso_date(date_m) if date_m else None),
156
+ "canceled": (rank in canceled_ranks) if rank is not None else False,
157
+ })
158
+ return mortgages
159
+
160
+
161
+ def count_encumbrances(text: str) -> dict:
162
+ """가압류·가처분·압류·경매개시결정 언급 건수 (사실)."""
163
+ return {
164
+ "가압류": len(re.findall(r"가압류", text)),
165
+ "가처분": len(re.findall(r"가처분", text)),
166
+ "압류": len(re.findall(r"(?<!가)압류", text)), # '가압류'의 압류 중복 제외
167
+ "경매개시결정": len(re.findall(r"경매개시결정", text)),
168
+ }
169
+
170
+
171
+ # ── 요약 (테스트 대상 순수 함수) ─────────────────────────────────
172
+ def summarize_registry(text: str, source: str = "local-pdf") -> dict:
173
+ """등기부 텍스트 → 사실 요약 dict. 판단·해석 없음. PII(주민번호)는 마스킹된 텍스트 전제."""
174
+ text = mask_pii(text)
175
+ mortgages = extract_mortgages(text)
176
+ active = sum(1 for x in mortgages if not x["canceled"])
177
+ return {
178
+ "doc_type": detect_doc_type(text),
179
+ "issued_at": find_issued_at(text),
180
+ "owner_change_count": count_owner_changes(text),
181
+ "mortgages": mortgages,
182
+ "mortgage_count": len(mortgages),
183
+ "active_mortgage_count": active,
184
+ "canceled_mortgage_count": len(mortgages) - active,
185
+ "encumbrances": count_encumbrances(text),
186
+ "source": source,
187
+ "notes": [
188
+ "PDF 텍스트에서 자동 추출한 사실입니다. 판단·법률자문이 아니며, 원문과 대조하세요.",
189
+ "말소 여부·순위번호는 추출 텍스트 구조에 따라 부정확할 수 있습니다.",
190
+ ],
191
+ }
192
+
193
+
194
+ # ── 사람이 읽는 요약 (사실만) ────────────────────────────────────
195
+ def render_markdown(summary: dict) -> str:
196
+ lines = ["# 등기부등본 요약 (사실 추출 · 판단 없음)", ""]
197
+ lines.append(f"- 종류: {summary['doc_type']}")
198
+ lines.append(f"- 열람/발급 일시: {summary['issued_at'] or '미상'}")
199
+ lines.append(f"- 소유권 변동(소유권이전) 건수: {summary['owner_change_count']}건")
200
+ lines.append(f"- 근저당권: 총 {summary['mortgage_count']}건 "
201
+ f"(유효 {summary['active_mortgage_count']} / 말소 {summary['canceled_mortgage_count']})")
202
+ for i, mo in enumerate(summary["mortgages"], 1):
203
+ amt = f"{mo['amount_won']:,}원" if mo["amount_won"] else "금액 미상"
204
+ state = "말소" if mo["canceled"] else "유효"
205
+ rank = f"순위 {mo['rank']}" if mo["rank"] else "순위 미상"
206
+ lines.append(f" {i}. {rank} · 채권최고액 {amt} · 설정일 {mo['registered_date'] or '미상'} · {state}")
207
+ enc = summary["encumbrances"]
208
+ enc_str = ", ".join(f"{k} {v}건" for k, v in enc.items() if v) or "없음(텍스트 기준)"
209
+ lines.append(f"- 가압류·가처분·압류 등: {enc_str}")
210
+ lines.append("")
211
+ for n in summary["notes"]:
212
+ lines.append(f"> {n}")
213
+ return "\n".join(lines) + "\n"
214
+
215
+
216
+ def main(argv=None):
217
+ ap = argparse.ArgumentParser(description="등기부등본 PDF → 사실 요약(판단 없음)")
218
+ ap.add_argument("input", help="등기부 PDF 경로 또는 (--from-text 시) 텍스트/마크다운 파일")
219
+ ap.add_argument("--from-text", action="store_true",
220
+ help="입력을 이미 텍스트/마크다운으로 취급(스캔 PDF를 로컬 변환기로 바꾼 결과 등)")
221
+ ap.add_argument("--out", help="요약 저장 폴더($workdir/output 권장). 없으면 표준출력만.")
222
+ ap.add_argument("--json", action="store_true", help="표준출력을 JSON으로")
223
+ args = ap.parse_args(argv)
224
+
225
+ input_path = Path(args.input)
226
+ if not input_path.exists():
227
+ raise SystemExit(f"입력 파일이 없습니다: {input_path}")
228
+
229
+ text = load_input_text(input_path, args.from_text)
230
+ source = "text-file" if (args.from_text or input_path.suffix.lower() != ".pdf") else "local-pdf"
231
+ summary = summarize_registry(text, source=source)
232
+
233
+ if args.json:
234
+ print(json.dumps(summary, ensure_ascii=False, indent=2))
235
+ else:
236
+ print(render_markdown(summary))
237
+
238
+ if args.out:
239
+ out_dir = Path(args.out)
240
+ out_dir.mkdir(parents=True, exist_ok=True)
241
+ (out_dir / "registry-summary.json").write_text(
242
+ json.dumps(summary, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
243
+ (out_dir / "registry-summary.md").write_text(render_markdown(summary), encoding="utf-8")
244
+ print(f"\n[저장] {out_dir}/registry-summary.(json|md) ※ 개인정보 포함 가능 — 저장소/PR에 커밋 금지",
245
+ file=sys.stderr)
246
+
247
+
248
+ if __name__ == "__main__":
249
+ main()
@@ -0,0 +1 @@
1
+ 7c6924b2ff88d693a12556659188cb91041e5097
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "iros-registry-automation",
3
+ "description": "인터넷등기소(IROS)에서 법인/부동산 등기부등본(등기사항증명서) 발급을 준비하고, 사용자가 직접 로그인·결제한 브라우저 흐름 안에서 장바구니·열람·저장을 안전하게 보조한다. 돌쇠에서는 가능한 가장 가까운 합법적 공식 단계까지 준비한다.",
4
+ "profiles": [
5
+ "browser",
6
+ "hard-boundary"
7
+ ],
8
+ "frontmatter": "name: iros-registry-automation\ndescription: 인터넷등기소(IROS)에서 법인/부동산 등기부등본(등기사항증명서) 발급을 준비하고, 사용자가 직접 로그인·결제한 브라우저 흐름 안에서 장바구니·열람·저장을 안전하게 보조한다. 돌쇠에서는 가능한 가장 가까운 합법적 공식 단계까지 준비한다.\nlicense: MIT\nmetadata:\n category: legal-documents\n locale: ko-KR\n phase: v1"
9
+ }
@@ -0,0 +1,130 @@
1
+ # job-posting-match
2
+
3
+ ## What this skill does
4
+
5
+ `job-posting-match`는 구직자가 제공한 이력서/경력요약, 희망 직무, 지역, 제외 조건을 바탕으로 잡코리아와 사람인의 공개 채용공고 검색 결과를 조회하고, 공고별 적합도·추천 이유·주의점·지원 전략을 정리한다.
6
+
7
+ 기존 `jobkorea-talent-search`, `saramin-talent-search`가 채용담당자 관점의 인재검색이라면, 이 스킬은 구직자 관점의 공고 매칭이다. 개발자 전용이 아니며 마케팅, 영업, 운영, 디자인, 기획, 회계, 인사 등 모든 직무에 role-adaptive하게 적용한다.
8
+
9
+ ## When to use
10
+
11
+ - 사용자가 “내 이력서에 맞는 공고를 찾아줘”, “지원할 만한 잡코리아/사람인 공고를 추천해줘”라고 요청한다.
12
+ - 이력서/경력기술서/자기소개서 요약에서 직무·스킬·산업 키워드를 뽑아 공개 채용공고를 검색해야 한다.
13
+ - 공고 링크 목록만이 아니라 적합도, 추천 이유, 주의점, 지원 전략이 필요하다.
14
+
15
+ ## Hard boundaries
16
+
17
+ Allowed:
18
+ - 사용자가 제공한 이력서/경력요약 텍스트 읽기
19
+ - 잡코리아·사람인 공개 채용공고 검색 결과 조회
20
+ - 공고 제목/회사/목록 요약/공개 상세 링크 기반 매칭 점수화
21
+ - 지원 우선순위, 이력서 보완 포인트, 자기소개서 방향 제안
22
+
23
+ Never do without explicit user handoff/confirmation:
24
+ - 입사지원 버튼 클릭, 지원서 제출, 개인정보 입력
25
+ - 로그인, 스크랩/관심공고 저장, 메시지 발송, 파일 업로드
26
+ - 비밀번호, OTP, 인증번호, 세션 쿠키 요청/저장
27
+ - 주민등록번호, 상세 주소, 연락처 등 민감정보 장기 저장 또는 대량 수집
28
+
29
+ The result is a recommendation aid, not a guarantee of hiring or interview success. Salary, deadline, employment type, and detailed requirements must be checked on the original posting before applying.
30
+
31
+ ## Site-dependent access path
32
+
33
+ v1 uses public, no-login search result pages only:
34
+
35
+ - JobKorea: `https://www.jobkorea.co.kr/Search/?stext=<검색어>`
36
+ - Result links are public anchors like `/Recruit/GI_Read/<id>`.
37
+ - Modern JobKorea pages may include Next.js data and repeated anchors; dedupe by posting id.
38
+ - Saramin: `https://www.saramin.co.kr/zf_user/search/recruit?searchword=<검색어>`
39
+ - Result cards contain `rec_idx` links such as `/zf_user/jobs/relay/view?...&rec_idx=<id>`.
40
+ - Dedupe by `rec_idx`.
41
+
42
+ No proxy is used because both surfaces are public and do not require an API key.
43
+
44
+ ## Inputs
45
+
46
+ Extract or ask only if missing and necessary:
47
+
48
+ - resume_text: 이력서, 경력기술서, 자기소개서, 포트폴리오 요약
49
+ - desired_role: 희망 직무/포지션
50
+ - must_have / nice_to_have: 필수·우대 스킬, 도구, 산업 경험
51
+ - desired_location: 희망 지역
52
+ - career_years: 경력 연차
53
+ - negative_keywords: 피하고 싶은 직무/산업/조건
54
+ - limit: 추천받을 공고 수
55
+
56
+ Do not block on missing fields when a reasonable first search is possible. If the user gives only a resume, infer search queries from role/tool/industry terms.
57
+
58
+ ## Workflow
59
+
60
+ 1. Normalize the user input.
61
+ - Remove or ignore unnecessary personal identifiers such as phone, email, exact address if they are not needed for matching.
62
+ - Extract role terms, tools/skills, industry/domain, years of experience, desired locations, negative keywords.
63
+
64
+ 2. Build 1-3 focused search queries.
65
+ - Prefer role + key tool: `퍼포먼스 마케터 GA4 Meta Ads`.
66
+ - Add role + domain when useful: `커머스 퍼포먼스 마케터`.
67
+ - Avoid one huge query that over-filters results.
68
+
69
+ 3. Run both public sources by default:
70
+
71
+ ```bash
72
+ python3 job-posting-match/scripts/job_posting_match.py --resume-text "퍼포먼스 마케터 5년. GA4, Google Ads, Meta Ads, SQL, 커머스 경험. 서울 희망." --location 서울 --negative 보험영업 --limit 10
73
+ ```
74
+
75
+ Use explicit keywords when the user already knows target roles:
76
+
77
+ ```bash
78
+ python3 job-posting-match/scripts/job_posting_match.py --resume-file /path/to/resume.txt --keyword "CRM 마케터 Braze" --keyword "그로스 마케터 SQL" --location 서울 --json
79
+ ```
80
+
81
+ 4. Score postings conservatively.
82
+ - Match role keywords, tools/skills, industry/domain, location, and career hints.
83
+ - Penalize explicit negative keywords such as `보험영업`, `대출영업`, `텔레마케팅`.
84
+ - Treat list-page summaries as low/medium confidence; do not invent requirements not visible in the source text.
85
+
86
+ 5. Return a Korean shortlist.
87
+ - Include source, company, direct URL, score, reasons, cautions, matched keywords, and support strategy.
88
+ - Tell the user to verify deadline/salary/employment type on the original posting.
89
+
90
+ ## Output shape
91
+
92
+ ```text
93
+ 이력서 기반 채용공고 추천
94
+
95
+ 검색 조건
96
+ - 이력서 요약: ...
97
+ - 생성 검색어: ...
98
+ - 희망 지역/제외 조건: ...
99
+ - 조회 소스: 잡코리아, 사람인
100
+
101
+ 추천 공고 Top N
102
+ 1. [사람인] 회사명 - 공고 제목
103
+ - 점수: 87/100
104
+ - URL: ...
105
+ - 추천 이유: 직무 키워드, GA4/SQL, 커머스 경험 일치
106
+ - 주의점: 연봉은 목록에서 확인 안 됨, 상세 공고 확인 필요
107
+ - 지원 전략: 이력서 상단 요약에 ... 경험을 먼저 강조
108
+
109
+ 제외/주의 후보
110
+ - ...
111
+
112
+ 검색 한계
113
+ - 공개 검색 결과 요약 기반이며 상세 요건은 원문 확인 필요
114
+ - 로그인, 지원, 스크랩, 개인정보 입력은 수행하지 않음
115
+ ```
116
+
117
+ ## Failure modes
118
+
119
+ - Empty results: broaden query, remove tools, search role only, or try alternate role names.
120
+ - Blocked or login wall: stop and report which source failed; continue with the other public source if possible.
121
+ - UI changed: rediscover the public search result structure before changing selectors.
122
+ - Too many irrelevant postings: add negative keywords and tighter role/domain terms.
123
+ - Personal data in resume: use it only for the current matching task; do not store it.
124
+
125
+ ## Done when
126
+
127
+ - At least one source was queried, or the reason both sources failed is reported.
128
+ - Recommended postings include direct original URLs.
129
+ - Each recommendation has score, reason, caution or verification note, and support strategy.
130
+ - The response states that applying/submitting is not automated.