@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
package/bin/k-skill.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const { assemble, bundledFiles, listSkills } = require("../src/assemble");
5
+ const { detectRuntime } = require("../src/detect");
6
+
7
+ function usage() {
8
+ return [
9
+ "Usage: k-skill <command> [skill]",
10
+ "",
11
+ "Commands:",
12
+ " instruct <skill> Print runtime-aware assembled instructions for a skill",
13
+ " files <skill> Print local paths of the skill's bundled helper files",
14
+ " list List bundled skills",
15
+ "",
16
+ "Runtime detection: DOLSHOI_ACTION_BROKER_URL enables Dolshoi mode;",
17
+ "CLOAKBROWSER_PEEK_TOKEN marks CloakBrowser availability.",
18
+ ].join("\n");
19
+ }
20
+
21
+ function main() {
22
+ const [command, skillName] = process.argv.slice(2);
23
+
24
+ if (!command || command === "--help" || command === "-h") {
25
+ console.log(usage());
26
+ return 0;
27
+ }
28
+
29
+ if (command === "list") {
30
+ for (const name of listSkills()) console.log(name);
31
+ return 0;
32
+ }
33
+
34
+ if (command === "instruct" || command === "files") {
35
+ if (!skillName) {
36
+ console.error(`error: "${command}" requires a skill name\n\n${usage()}`);
37
+ return 1;
38
+ }
39
+
40
+ try {
41
+ if (command === "instruct") {
42
+ process.stdout.write(assemble(skillName, detectRuntime()));
43
+ } else {
44
+ for (const filePath of bundledFiles(skillName)) console.log(filePath);
45
+ }
46
+ return 0;
47
+ } catch (error) {
48
+ if (error.code === "EUNKNOWNSKILL") {
49
+ console.error(`error: ${error.message}`);
50
+ return 1;
51
+ }
52
+ throw error;
53
+ }
54
+ }
55
+
56
+ console.error(`error: unknown command "${command}"\n\n${usage()}`);
57
+ return 1;
58
+ }
59
+
60
+ process.exitCode = main();
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@nomadamas/k-skill",
3
+ "version": "0.1.0",
4
+ "description": "k-skill unified CLI: assembles runtime-aware skill instructions and ships bundled helper files",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "k-skill": "bin/k-skill.js"
8
+ },
9
+ "main": "src/assemble.js",
10
+ "files": [
11
+ "bin",
12
+ "src",
13
+ "templates",
14
+ "skills",
15
+ "README.md"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/NomaDamas/k-skill.git"
26
+ },
27
+ "keywords": [
28
+ "k-skill",
29
+ "korea",
30
+ "agent-skills",
31
+ "cli"
32
+ ],
33
+ "scripts": {
34
+ "lint": "node --check bin/k-skill.js && node --check src/assemble.js && node --check src/detect.js && node --check test/cli.test.js",
35
+ "test": "node --test"
36
+ }
37
+ }
@@ -0,0 +1,111 @@
1
+ # Assembly Bill Vote Search
2
+
3
+ ## What this skill does
4
+
5
+ 열린국회정보 Open API `https://open.assembly.go.kr/portal/openapi` 를 `k-skill-proxy` 경유로 호출한다.
6
+
7
+ 지원 endpoint:
8
+
9
+ - `GET /v1/assembly/bills` → `ALLBILLV2` 의안정보 통합 API
10
+ - `GET /v1/assembly/bill-detail` → `BILLINFODETAIL` 의안 상세정보
11
+ - `GET /v1/assembly/votes` → `nojepdqqaweusdfbi` 국회의원 본회의 표결정보
12
+
13
+ ## When to use
14
+
15
+ - "간호법 의안 검색해줘"
16
+ - "BILL_ID로 의안 상세 보여줘"
17
+ - "21대 국회 특정 의안 표결에서 의원별 찬반 알려줘"
18
+
19
+ ## Prerequisites
20
+
21
+ - 인터넷 연결
22
+ - hosted/self-host `k-skill-proxy`의 `/v1/assembly/*` route 접근 가능
23
+
24
+ ## Credential requirements
25
+
26
+ - 사용자 측 필수 시크릿 없음.
27
+ - `KSKILL_PROXY_BASE_URL` — self-host·별도 프록시를 쓸 때만 설정. 비우면 기본 hosted `https://k-skill-proxy.nomadamas.org` 를 사용한다.
28
+ - `ASSEMBLY_API_KEY` 또는 `KSKILL_ASSEMBLY_API_KEY` 는 프록시 운영 서버 환경에만 둔다.
29
+
30
+ 키 발급: <https://open.assembly.go.kr/portal/openapi/openApiActKeyIssPage.do>
31
+
32
+ ## Inputs
33
+
34
+ 의안 검색:
35
+
36
+ - `query`/`q`/`billName` → `BILL_NM`
37
+ - `billId`, `billNo`, `billKind`, `committeeName`, `proposalDate`, `result`
38
+ - `eraco`/`ageLabel` → `ERACO`, 기본 `제21대`
39
+ - `page`/`pIndex`, `limit`/`pSize`
40
+
41
+ 의안 상세:
42
+
43
+ - `billId` 필수
44
+
45
+ 표결 조회:
46
+
47
+ - `age` 필수 (`21` 등 숫자)
48
+ - `billId` 필수
49
+ - `memberName`, `party`, `memberNo`, `voteDate`, `billNo`, `billName`, `committee`, `voteResult`
50
+ - `page`/`pIndex`, `limit`/`pSize`
51
+
52
+ ## Workflow
53
+
54
+ ### 1. Search bills first
55
+
56
+ ```bash
57
+ BASE="${KSKILL_PROXY_BASE_URL:-https://k-skill-proxy.nomadamas.org}"
58
+ curl -fsS --get "$BASE/v1/assembly/bills" \
59
+ --data-urlencode "query=간호법" \
60
+ --data-urlencode "eraco=제21대" \
61
+ --data-urlencode "limit=10"
62
+ ```
63
+
64
+ ### 2. Fetch bill detail
65
+
66
+ ```bash
67
+ curl -fsS --get "$BASE/v1/assembly/bill-detail" \
68
+ --data-urlencode "billId=PRC_N2D0H0W9P2S3Z1Q2X0L8W4B1G8E3F4"
69
+ ```
70
+
71
+ ### 3. Fetch plenary votes
72
+
73
+ ```bash
74
+ curl -fsS --get "$BASE/v1/assembly/votes" \
75
+ --data-urlencode "age=21" \
76
+ --data-urlencode "billId=PRC_N2D0H0W9P2S3Z1Q2X0L8W4B1G8E3F4" \
77
+ --data-urlencode "limit=100"
78
+ ```
79
+
80
+ ## Failure modes
81
+
82
+ - `400 bad_request`: 필수 `billId`/`age` 누락, 페이지 크기 초과, 잘못된 숫자 형식.
83
+ - `503 upstream_not_configured`: 프록시 서버에 `ASSEMBLY_API_KEY`/`KSKILL_ASSEMBLY_API_KEY` 없음.
84
+ - 열린국회정보 `RESULT.CODE`:
85
+ - `ERROR-290`: 키 누락/오류
86
+ - `ERROR-300`: 필수 파라미터 누락
87
+ - `ERROR-337`: 일일 트래픽 초과
88
+ - `INFO-200`: 결과 없음
89
+ - 빈 결과: 대수(`ERACO`/`age`), 의안명, 의안번호, BILL_ID를 다시 확인한다.
90
+
91
+ ## Done when
92
+
93
+ - 먼저 의안 검색으로 `BILL_ID`를 확정했다.
94
+ - 상세 또는 표결 조회 결과에 `BILL_ID`, 국회 대수, endpoint를 함께 적었다.
95
+ - 표결 요약은 찬성/반대/기권 등 upstream 원문 분류를 임의 변경하지 않았다.
96
+
97
+ ## Maintainer review notes
98
+
99
+ 키 없이 가능한 검증:
100
+
101
+ - `./scripts/validate-skills.sh`
102
+ - `node --test packages/k-skill-proxy/test/server.test.js`
103
+ - `curl -i --get "$KSKILL_PROXY_BASE_URL/v1/assembly/bills" --data-urlencode "query=간호법"` (키 미설정이면 503 확인)
104
+
105
+ Live smoke는 hosted/self-host proxy에 `ASSEMBLY_API_KEY`가 설정된 뒤 수행한다.
106
+
107
+ ## Safety notes
108
+
109
+ - 조회 전용 스킬이다.
110
+ - 정치적 평가·추천을 자동 생성하지 않고, 공식 원천의 의안·표결 사실을 요약한다.
111
+ - 인증키는 프록시 서버에서만 다루며 repo/GitHub Actions/public docs에 저장하지 않는다.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "assembly-bill-vote-search",
3
+ "description": "열린국회정보 Open API를 k-skill-proxy 경유로 호출해 의안 검색·상세와 국회의원 본회의 표결정보를 조회한다. 조회 전용.",
4
+ "profiles": [
5
+ "proxy",
6
+ "vault",
7
+ "lookup"
8
+ ],
9
+ "frontmatter": "name: assembly-bill-vote-search\ndescription: 열린국회정보 Open API를 k-skill-proxy 경유로 호출해 의안 검색·상세와 국회의원 본회의 표결정보를 조회한다. 조회 전용.\nlicense: MIT\nmetadata:\n category: civic\n locale: ko-KR\n phase: v1"
10
+ }
@@ -0,0 +1,69 @@
1
+ # 사업자 실사 복합 조회 (biz-health-check)
2
+
3
+ ## What this skill does
4
+
5
+ 사업자등록번호(+상호/지역)를 입력하면 무료 공공 데이터 6종을 한 번에 교차 조회해 실사 리포트 한 장을 만든다. 같은 레포의 단품 스킬 helper를 그대로 재사용한다(단일 진실원천).
6
+
7
+ | 섹션 | 데이터 | 단품 스킬 | 경로 |
8
+ |---|---|---|---|
9
+ | 국세청 상태 | 계속/휴업/폐업·과세유형 | `nts-business-registration` | proxy |
10
+ | 국민연금 | 가입자수·당월 고지금액·월별 | `national-pension-workplace` | proxy |
11
+ | 체납 명단 | 고액·상습체납자 명단공개 대조 | `nts-tax-delinquency` | 직접(무인증) |
12
+ | 금융위 | 대표자·설립일·업종 법인개요 | `fsc-corporate-info` | proxy |
13
+ | 부정당제재 | 조회시점 유효 제재 | `g2b-sanctioned-supplier` | proxy |
14
+ | 인허가 영업상태 | 동네 사업장(208업종) 영업/폐업·업력 | `localdata-business-status` | 직접(무인증) |
15
+
16
+ 공시 유무는 기존 `k-dart` 스킬을 함께 쓰면 된다.
17
+
18
+ ## Design principles
19
+
20
+ - **점수·등급·"위험" 같은 해석 라벨을 산출하지 않는다.** 각 항목의 사실 + 출처 + 조회시각만 병렬한다. 판단은 사용자 몫이다.
21
+ - 한 항목 조회가 실패해도 전체를 막지 않고 그 항목만 정직하게 강등한다(`unavailable` + 사유).
22
+ - 단품 helper를 찾지 못하면(개별 설치 등) 해당 섹션만 건너뛰고 나머지를 진행한다.
23
+
24
+ ## When to use
25
+
26
+ - "이 사업자(거래처/의뢰인) 실제 문제 없는지 한 번에 확인해줘"
27
+ - "○○○-○○-○○○○○ 살아있는 회사야? 직원은 좀 있고, 체납·입찰 제재 이력은 없어?"
28
+
29
+ ## Prerequisites
30
+
31
+ - 인터넷 연결, `python3`
32
+ - 같은 레포의 단품 스킬 6종(이 복합이 helper를 재사용)
33
+ - proxy 섹션을 켜려면 hosted/self-host `k-skill-proxy` 접근 가능
34
+
35
+ ## Credential requirements
36
+
37
+ - 사용자 측 필수 시크릿 없음.
38
+ - proxy 섹션(국세청 상태·국민연금·금융위·부정당)은 운영 서버의 `DATA_GO_KR_API_KEY`로 동작한다. 활용신청 항목은 각 단품 스킬 문서를 따른다.
39
+ - 무인증 섹션(체납·인허가)은 키 없이 사용자 머신에서 직접 동작한다.
40
+
41
+ ## Inputs
42
+
43
+ - `b_no`: 사업자등록번호 10자리(하이픈 허용) — 상태조회·부정당제재에 필요
44
+ - `--name`: 상호·법인명 — 국민연금·금융위·체납·인허가에 필요
45
+ - `--region`: 시군구 — 인허가(동네 사업장) 조회에 필요 (예: `제주제주시`)
46
+ - `--industry`: 인허가 업종(여러 번 지정 가능). 생략 시 음식점·카페·숙박
47
+
48
+ ## CLI examples
49
+
50
+ ```bash
51
+ python3 biz-health-check/scripts/biz_health_check.py 124-81-00998 --name "삼성전자"
52
+
53
+ # 동네 사업장까지 포함
54
+ python3 biz-health-check/scripts/biz_health_check.py --name "호텔샬롬" --region 제주제주시 --industry 숙박업
55
+ ```
56
+
57
+ ## Output
58
+
59
+ - `sections`: 6개 섹션 각각의 `data`(단품 응답 원문) 또는 `status: unavailable` + `note`
60
+ - 입력에 따라 일부 섹션은 생략된다(예: `--name` 없으면 국민연금/금융위/체납 생략).
61
+
62
+ ## Failure modes
63
+
64
+ - 섹션별 강등은 리포트에 그대로 남는다(전체 실패가 아니다).
65
+ - proxy 섹션이 `503/502`면 운영 서버 키·활용신청 문제 — 각 단품 스킬 문서 참고.
66
+
67
+ ## Official surfaces
68
+
69
+ - 각 단품 스킬 문서(`docs/features/<skill>.md`)의 공식 출처를 따른다.
@@ -0,0 +1,163 @@
1
+ """Business due-diligence composite — runs the sibling k-skill providers at once.
2
+
3
+ 사업자등록번호(+상호/지역) 하나로 "이 사업자, 실제 문제 없나"를 무료 공공 데이터로
4
+ 교차 조회해 실사 리포트 한 장을 만든다. 점수·등급·"위험" 라벨을 만들지 않고,
5
+ 각 항목의 사실 + 출처 + 조회시각만 병렬한다. 판단은 사용자 몫이다.
6
+
7
+ 이 복합 스킬은 같은 레포의 단품 스킬 helper들을 그대로 재사용한다(단일 진실원천):
8
+
9
+ - nts-business-registration 상태조회 (k-skill-proxy)
10
+ - national-pension-workplace 국민연금 사업장 (k-skill-proxy)
11
+ - fsc-corporate-info 금융위 법인개요 (k-skill-proxy)
12
+ - g2b-sanctioned-supplier 부정당제재 (k-skill-proxy)
13
+ - nts-tax-delinquency 체납 명단 (무인증 직접)
14
+ - localdata-business-status 인허가 영업상태 (무인증 직접, --region 필요)
15
+
16
+ 단품 helper를 찾지 못하면 해당 항목만 정직하게 강등하고 나머지는 계속 진행한다.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import argparse
22
+ import datetime as dt
23
+ import importlib.util
24
+ import json
25
+ import pathlib
26
+ import re
27
+ import sys
28
+ from typing import Any, Callable
29
+
30
+ KST = dt.timezone(dt.timedelta(hours=9))
31
+ PROXY_DOWN_MSG = "설정된 k-skill-proxy 서버가 응답하지 않습니다. 잠시 후 재시도하거나 운영자에게 문의하세요."
32
+ PROXY_KEY_NOT_CONFIGURED_MSG = "k-skill-proxy에 필요한 API 키가 설정되어 있지 않습니다. 운영자에게 문의하세요."
33
+ _REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent.parent
34
+
35
+ # (섹션 키, 사람이 읽는 라벨, 단품 스킬 디렉토리, helper 파일명)
36
+ _SIBLINGS = {
37
+ "nts_status": ("국세청 사업자등록 상태", "nts-business-registration", "nts_business_registration.py"),
38
+ "national_pension": ("국민연금 가입 사업장", "national-pension-workplace", "national_pension_workplace.py"),
39
+ "fsc_corp": ("금융위 기업기본정보", "fsc-corporate-info", "fsc_corporate_info.py"),
40
+ "g2b_sanction": ("조달청 부정당제재", "g2b-sanctioned-supplier", "g2b_sanctioned_supplier.py"),
41
+ "tax_delinquency": ("국세 체납 명단공개", "nts-tax-delinquency", "nts_tax_delinquency.py"),
42
+ "localdata": ("지방행정 인허가 영업상태", "localdata-business-status", "localdata_business_status.py"),
43
+ }
44
+
45
+
46
+ def _now_iso() -> str:
47
+ return dt.datetime.now(KST).isoformat(timespec="seconds")
48
+
49
+
50
+ def _normalize_b_no(value: Any) -> str:
51
+ normalized = re.sub(r"\D", "", str(value or ""))
52
+ if not re.fullmatch(r"\d{10}", normalized):
53
+ raise ValueError("사업자등록번호는 숫자 10자리여야 합니다 (하이픈 허용).")
54
+ return normalized
55
+
56
+
57
+ def _unavailable(module_key: str, note: str) -> dict:
58
+ label, skill_dir, _ = _SIBLINGS[module_key]
59
+ return {"provider": label, "skill": skill_dir, "status": "unavailable",
60
+ "looked_up_at": _now_iso(), "data": None, "note": note}
61
+
62
+ def _load(module_key: str) -> Any | None:
63
+ """단품 스킬 helper를 레포 레이아웃 기준 파일 경로로 로드. 없으면 None."""
64
+ _, skill_dir, filename = _SIBLINGS[module_key]
65
+ path = _REPO_ROOT / skill_dir / "scripts" / filename
66
+ if not path.exists():
67
+ return None
68
+ spec = importlib.util.spec_from_file_location(f"_bhc_{module_key}", path)
69
+ if spec is None or spec.loader is None:
70
+ return None
71
+ module = importlib.util.module_from_spec(spec)
72
+ spec.loader.exec_module(module)
73
+ return module
74
+
75
+
76
+ def _section(module_key: str, caller: Callable[[Any], dict]) -> dict:
77
+ """단품 helper 하나를 호출해 섹션 결과로 감싼다. 어떤 오류든 강등."""
78
+ label, skill_dir, _ = _SIBLINGS[module_key]
79
+ base = {"provider": label, "skill": skill_dir, "looked_up_at": _now_iso()}
80
+ try:
81
+ module = _load(module_key)
82
+ except Exception as err:
83
+ return {**base, "status": "unavailable", "data": None,
84
+ "note": f"단품 스킬 '{skill_dir}' helper import 실패({type(err).__name__}: {err})."}
85
+ if module is None:
86
+ return {**base, "status": "unavailable", "data": None,
87
+ "note": f"단품 스킬 '{skill_dir}' helper를 찾지 못해 건너뜀 (개별 설치 시 함께 두세요)."}
88
+ try:
89
+ data = caller(module)
90
+ status = "unavailable" if isinstance(data, dict) and (data.get("status") == "unavailable" or data.get("error")) else "ok"
91
+ return {**base, "status": status, "data": data}
92
+ except Exception as err: # 경계 계약: 한 항목 실패가 전체를 막지 않는다
93
+ return {**base, "status": "unavailable", "data": None, "note": f"조회 실패({type(err).__name__}: {err})."}
94
+
95
+
96
+ def run(b_no: str | None, name: str | None = None, region: str | None = None,
97
+ industries: list[str] | None = None, *, base_url: str | None = None) -> dict:
98
+ no = _normalize_b_no(b_no) if b_no else None
99
+ name = (name or "").strip() or None
100
+ sections: dict[str, dict] = {}
101
+
102
+ if no:
103
+ sections["nts_status"] = _section(
104
+ "nts_status", lambda m: m.query_status([no], base_url=base_url))
105
+ else:
106
+ sections["nts_status"] = _unavailable("nts_status", "사업자등록번호가 없어 상태조회 생략.")
107
+
108
+ sections["national_pension"] = _section(
109
+ "national_pension",
110
+ lambda m: m.query_workplace(name, no, base_url=base_url)) if name else \
111
+ _unavailable("national_pension", "상호(--name)가 없어 국민연금 조회 생략.")
112
+
113
+ sections["fsc_corp"] = _section(
114
+ "fsc_corp",
115
+ lambda m: m.query_corp_outline(name, no, base_url=base_url)) if name else \
116
+ _unavailable("fsc_corp", "법인명(--name)이 없어 금융위 조회 생략.")
117
+
118
+ sections["g2b_sanction"] = _section(
119
+ "g2b_sanction", lambda m: m.query_sanctions(no, base_url=base_url)) if no else \
120
+ _unavailable("g2b_sanction", "사업자등록번호가 없어 부정당제재 조회 생략.")
121
+
122
+ sections["tax_delinquency"] = _section(
123
+ "tax_delinquency", lambda m: m.lookup(name)) if name else \
124
+ _unavailable("tax_delinquency", "상호(--name)가 없어 체납 명단 조회 생략.")
125
+
126
+ if name and region:
127
+ sections["localdata"] = _section(
128
+ "localdata", lambda m: m.lookup(name, region, industries))
129
+ else:
130
+ sections["localdata"] = _unavailable("localdata", "동네 사업장 인허가 조회는 상호(--name)와 지역(--region)이 함께 필요.")
131
+
132
+ return {
133
+ "query": {"b_no": no, "name": name, "region": region, "industries": industries},
134
+ "generated_at": _now_iso(),
135
+ "disclaimer": ("무료 공공 데이터의 사실만 병렬한 실사 리포트다. 점수·등급·위험 판정은 "
136
+ "하지 않으며, 동일성·해석은 사용자가 판단한다."),
137
+ "sections": sections,
138
+ }
139
+
140
+
141
+ def build_parser() -> argparse.ArgumentParser:
142
+ parser = argparse.ArgumentParser(description="사업자 실사 복합 조회 (단품 k-skill 6종 묶음)")
143
+ parser.add_argument("b_no", nargs="?", default=None, help="사업자등록번호 10자리(하이픈 허용)")
144
+ parser.add_argument("--name", help="상호·법인명 — 국민연금/금융위/체납/인허가 조회에 필요")
145
+ parser.add_argument("--region", help="시군구 (동네 사업장 인허가 조회용 — 예: 제주제주시)")
146
+ parser.add_argument("--industry", action="append", dest="industries", help="인허가 업종(여러 번 지정 가능)")
147
+ parser.add_argument("--proxy-base-url")
148
+ return parser
149
+
150
+
151
+ def main(argv: list[str] | None = None) -> int:
152
+ args = build_parser().parse_args(argv)
153
+ try:
154
+ report = run(args.b_no, args.name, args.region, args.industries, base_url=args.proxy_base_url)
155
+ except ValueError as err:
156
+ print(json.dumps({"error": str(err)}, ensure_ascii=False, indent=2), file=sys.stderr)
157
+ return 1
158
+ print(json.dumps(report, ensure_ascii=False, indent=2))
159
+ return 0
160
+
161
+
162
+ if __name__ == "__main__":
163
+ raise SystemExit(main())
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "biz-health-check",
3
+ "description": "사업자등록번호 하나로 \"이 사업자, 실제 문제 없나\"를 확인한다 — 국세청 사업자등록 상태·국민연금 가입 사업장·국세 체납 명단·금융위 법인개요·조달청 부정당제재·지방행정 인허가 영업상태를 무료 공공 데이터로 교차 조회해 사실만 병렬하는 실사 리포트(점수·등급·위험 판정 없음).",
4
+ "profiles": [
5
+ "proxy",
6
+ "vault",
7
+ "lookup"
8
+ ],
9
+ "frontmatter": "name: biz-health-check\ndescription: 사업자등록번호 하나로 \"이 사업자, 실제 문제 없나\"를 확인한다 — 국세청 사업자등록 상태·국민연금 가입 사업장·국세 체납 명단·금융위 법인개요·조달청 부정당제재·지방행정 인허가 영업상태를 무료 공공 데이터로 교차 조회해 사실만 병렬하는 실사 리포트(점수·등급·위험 판정 없음).\nlicense: MIT\nmetadata:\n category: business\n locale: ko-KR\n phase: v1"
10
+ }
@@ -0,0 +1,95 @@
1
+ # 한국은행 ECOS 경제통계 조회
2
+
3
+ ## What this skill does
4
+
5
+ 한국은행 경제통계시스템(ECOS) Open API `https://ecos.bok.or.kr/api/` 로 중앙은행 경제통계를 조회한다.
6
+
7
+ - `search` — 통계코드(또는 alias) 기반 시계열 데이터 조회
8
+ - `tables` — 통계표 카탈로그 목록
9
+ - `items` — 특정 통계표의 항목(item) 목록
10
+ - `key` — 100대 핵심지표 (환율/금리/물가/국민소득 등 최신값)
11
+ - `word` — 통계 용어 사전 검색
12
+
13
+ **조회 전용**이다. 투자 판단·전망 단정은 범위 밖이다.
14
+
15
+ ## When to use
16
+
17
+ - "지금 한국은행 기준금리 몇 %야?"
18
+ - "최근 원달러 환율 추이 보여줘"
19
+ - "소비자물가지수 월별로 뽑아줘"
20
+ - "M2 통화량 통계 찾아줘"
21
+ - "ECOS에서 국고채 3년 금리 조회해줘"
22
+
23
+ ## When not to use
24
+
25
+ - 주식/증권 시세 → `korean-stock-search`, `toss-securities`
26
+ - KOSIS 일반 통계(인구/가구/고용 등) → `kosis-stats`
27
+ - 환전 수수료·실시간 매매 환율 비교 (ECOS는 공식 통계 기준)
28
+
29
+ ## Prerequisites
30
+
31
+ - Python 3.9+ (stdlib only, 외부 패키지 없음)
32
+ - 사용자 API 키 **불필요** — ECOS 공개 데모 키(`sample`)로 무가입 동작 확인 (2026-07-21). 단 **호출당 최대 10행** 제한이 있다. 공개 엔드포인트이므로 k-skill-proxy를 경유하지 않고 직접 호출한다.
33
+
34
+ 선택 환경변수 (더 많은 행이 필요할 때):
35
+
36
+ - `KSKILL_BOK_ECOS_API_KEY` — https://ecos.bok.or.kr/api 회원가입 후 무료 발급. `~/.config/k-skill/secrets.env` 의 같은 키도 읽는다.
37
+
38
+ ## Workflow
39
+
40
+ ### 1. 자주 쓰는 지표는 alias로 바로 조회
41
+
42
+ ```bash
43
+ python3 bok-ecos-stats/scripts/bok_ecos.py search --alias 기준금리 --start 20260101 --end 20260721 --text
44
+ python3 bok-ecos-stats/scripts/bok_ecos.py search --alias 원달러환율 --start 20260701 --end 20260721 --text
45
+ python3 bok-ecos-stats/scripts/bok_ecos.py search --alias 소비자물가지수 --start 202501 --end 202606 --text
46
+ ```
47
+
48
+ 지원 alias: `기준금리`, `원달러환율`, `소비자물가지수`(=`cpi`), `M2`(=`통화량`), `국고채3년`.
49
+
50
+ `--start`/`--end`는 주기 형식을 따른다: 일(D) `YYYYMMDD`, 월(M) `YYYYMM`, 분기(Q) `YYYYQn`, 연(A) `YYYY`.
51
+
52
+ ### 2. 최신 핵심지표 한 번에 보기
53
+
54
+ ```bash
55
+ python3 bok-ecos-stats/scripts/bok_ecos.py key --limit 10 --text
56
+ ```
57
+
58
+ ### 3. 임의 통계표 탐색 → 항목 확인 → 시계열 조회
59
+
60
+ ```bash
61
+ python3 bok-ecos-stats/scripts/bok_ecos.py tables --text
62
+ python3 bok-ecos-stats/scripts/bok_ecos.py items --stat-code 722Y001 --text
63
+ python3 bok-ecos-stats/scripts/bok_ecos.py search --stat-code 722Y001 --cycle D \
64
+ --start 20260101 --end 20260721 --item-code 0101000 --text
65
+ ```
66
+
67
+ ### 4. 용어가 낯설면 사전 검색
68
+
69
+ ```bash
70
+ python3 bok-ecos-stats/scripts/bok_ecos.py word --query 소비자물가지수 --text
71
+ ```
72
+
73
+ `--text` 없이 실행하면 구조화 JSON(`result`, `rows`, `source`)을 출력한다.
74
+
75
+ ## Data source
76
+
77
+ - `https://ecos.bok.or.kr/api/<Service>/<key>/json/kr/<start>/<end>/<segments...>` — 쿼리스트링 없는 positional URL. 한글 검색어는 helper가 percent-encoding 처리한다.
78
+ - 데모 키 `sample`: 무가입, 호출당 최대 10행 (초과 시 `ERROR-301`).
79
+ - 잘못된 키: HTTP 200 + `{"RESULT":{"CODE":"INFO-100"}}`.
80
+ - 빈 결과: `{"RESULT":{"CODE":"INFO-200","MESSAGE":"해당하는 데이터가 없습니다."}}` → `result: "empty"`.
81
+
82
+ ## Failure modes
83
+
84
+ | 상황 | 동작 |
85
+ | --- | --- |
86
+ | 빈 결과 (`INFO-200`) | `result: "empty"` — 기간/코드 확인 안내 |
87
+ | 인증키 오류 (`INFO-100`) | 개인 키 발급/확인 안내 |
88
+ | sample 10행 초과 (`ERROR-301`) | 개인 키 발급 안내 (helper는 sample 사용 시 limit을 10으로 자동 캡) |
89
+ | 알 수 없는 alias, stat-code 없는 search | upstream 미호출, 사용법 오류 출력 |
90
+ | HTTP 오류/타임아웃/JSON 파싱 실패 | 차단·점검 가능성 안내 후 종료 코드 1 |
91
+
92
+ ## Notes
93
+
94
+ - 시계열 값은 공식 통계 원천 그대로 전달하고, 해석·전망은 덧붙이지 않는다.
95
+ - 통계 기준 시점(`time`)을 반드시 함께 표시한다.