jibsa 0.2.0__tar.gz

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 (213) hide show
  1. jibsa-0.2.0/.github/ISSUE_TEMPLATE/bug_report.yml +61 -0
  2. jibsa-0.2.0/.github/ISSUE_TEMPLATE/chore.yml +41 -0
  3. jibsa-0.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. jibsa-0.2.0/.github/ISSUE_TEMPLATE/docs.yml +30 -0
  5. jibsa-0.2.0/.github/ISSUE_TEMPLATE/feature.yml +40 -0
  6. jibsa-0.2.0/.github/ISSUE_TEMPLATE/task.yml +30 -0
  7. jibsa-0.2.0/.github/PULL_REQUEST_TEMPLATE.md +32 -0
  8. jibsa-0.2.0/.github/workflows/ci.yml +87 -0
  9. jibsa-0.2.0/.github/workflows/release.yml +82 -0
  10. jibsa-0.2.0/.gitignore +229 -0
  11. jibsa-0.2.0/AGENTS.md +79 -0
  12. jibsa-0.2.0/CHANGELOG.md +35 -0
  13. jibsa-0.2.0/CLAUDE.md +4 -0
  14. jibsa-0.2.0/LICENSE +21 -0
  15. jibsa-0.2.0/PKG-INFO +252 -0
  16. jibsa-0.2.0/README.md +223 -0
  17. jibsa-0.2.0/docs/common.md +175 -0
  18. jibsa-0.2.0/docs/daangn.md +851 -0
  19. jibsa-0.2.0/docs/llm.md +124 -0
  20. jibsa-0.2.0/docs/naver.md +637 -0
  21. jibsa-0.2.0/docs/zigbang.md +541 -0
  22. jibsa-0.2.0/pyproject.toml +122 -0
  23. jibsa-0.2.0/references/architecture.md +66 -0
  24. jibsa-0.2.0/references/code-style.md +157 -0
  25. jibsa-0.2.0/references/development.md +81 -0
  26. jibsa-0.2.0/references/output-contract.md +127 -0
  27. jibsa-0.2.0/references/provider-conventions.md +257 -0
  28. jibsa-0.2.0/references/providers/daangn.md +137 -0
  29. jibsa-0.2.0/references/providers/naver.md +81 -0
  30. jibsa-0.2.0/references/providers/zigbang.md +113 -0
  31. jibsa-0.2.0/references/release.md +110 -0
  32. jibsa-0.2.0/references/workflow.md +81 -0
  33. jibsa-0.2.0/src/jibsa/__init__.py +1 -0
  34. jibsa-0.2.0/src/jibsa/__main__.py +5 -0
  35. jibsa-0.2.0/src/jibsa/cli/__init__.py +0 -0
  36. jibsa-0.2.0/src/jibsa/cli/app.py +210 -0
  37. jibsa-0.2.0/src/jibsa/cli/daangn.py +1141 -0
  38. jibsa-0.2.0/src/jibsa/cli/naver.py +955 -0
  39. jibsa-0.2.0/src/jibsa/cli/options.py +17 -0
  40. jibsa-0.2.0/src/jibsa/cli/output.py +325 -0
  41. jibsa-0.2.0/src/jibsa/cli/zigbang.py +1045 -0
  42. jibsa-0.2.0/src/jibsa/core/__init__.py +0 -0
  43. jibsa-0.2.0/src/jibsa/core/errors.py +107 -0
  44. jibsa-0.2.0/src/jibsa/core/geo.py +217 -0
  45. jibsa-0.2.0/src/jibsa/core/http.py +421 -0
  46. jibsa-0.2.0/src/jibsa/core/korean.py +67 -0
  47. jibsa-0.2.0/src/jibsa/core/listing.py +488 -0
  48. jibsa-0.2.0/src/jibsa/core/ratelimit.py +353 -0
  49. jibsa-0.2.0/src/jibsa/core/schema.py +46 -0
  50. jibsa-0.2.0/src/jibsa/providers/__init__.py +0 -0
  51. jibsa-0.2.0/src/jibsa/providers/daangn/__init__.py +46 -0
  52. jibsa-0.2.0/src/jibsa/providers/daangn/api/__init__.py +1 -0
  53. jibsa-0.2.0/src/jibsa/providers/daangn/api/client.py +1887 -0
  54. jibsa-0.2.0/src/jibsa/providers/daangn/api/parser.py +155 -0
  55. jibsa-0.2.0/src/jibsa/providers/daangn/api/relay.py +106 -0
  56. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/__init__.py +1 -0
  57. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/common.py +288 -0
  58. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/commute.py +69 -0
  59. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/compare.py +44 -0
  60. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/complex.py +152 -0
  61. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/development.py +50 -0
  62. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/listing.py +17 -0
  63. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/neighborhood.py +64 -0
  64. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/popular.py +29 -0
  65. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/real_price.py +183 -0
  66. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/region.py +80 -0
  67. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/review.py +47 -0
  68. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/school.py +88 -0
  69. jibsa-0.2.0/src/jibsa/providers/daangn/api/request/search.py +161 -0
  70. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/__init__.py +1 -0
  71. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/common.py +749 -0
  72. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/commute.py +157 -0
  73. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/compare.py +536 -0
  74. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/complex.py +557 -0
  75. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/development.py +178 -0
  76. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/listing.py +21 -0
  77. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/neighborhood.py +91 -0
  78. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/popular.py +38 -0
  79. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/real_price.py +309 -0
  80. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/region.py +208 -0
  81. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/review.py +116 -0
  82. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/school.py +271 -0
  83. jibsa-0.2.0/src/jibsa/providers/daangn/api/response/search.py +201 -0
  84. jibsa-0.2.0/src/jibsa/providers/daangn/service/__init__.py +5 -0
  85. jibsa-0.2.0/src/jibsa/providers/daangn/service/common.py +904 -0
  86. jibsa-0.2.0/src/jibsa/providers/daangn/service/commute.py +464 -0
  87. jibsa-0.2.0/src/jibsa/providers/daangn/service/compare.py +571 -0
  88. jibsa-0.2.0/src/jibsa/providers/daangn/service/complex.py +883 -0
  89. jibsa-0.2.0/src/jibsa/providers/daangn/service/development.py +324 -0
  90. jibsa-0.2.0/src/jibsa/providers/daangn/service/listing.py +325 -0
  91. jibsa-0.2.0/src/jibsa/providers/daangn/service/neighborhood.py +206 -0
  92. jibsa-0.2.0/src/jibsa/providers/daangn/service/popular.py +102 -0
  93. jibsa-0.2.0/src/jibsa/providers/daangn/service/real_price.py +956 -0
  94. jibsa-0.2.0/src/jibsa/providers/daangn/service/region.py +744 -0
  95. jibsa-0.2.0/src/jibsa/providers/daangn/service/review.py +192 -0
  96. jibsa-0.2.0/src/jibsa/providers/daangn/service/school.py +490 -0
  97. jibsa-0.2.0/src/jibsa/providers/daangn/service/search.py +1025 -0
  98. jibsa-0.2.0/src/jibsa/providers/naver/__init__.py +42 -0
  99. jibsa-0.2.0/src/jibsa/providers/naver/api/__init__.py +1 -0
  100. jibsa-0.2.0/src/jibsa/providers/naver/api/client.py +1795 -0
  101. jibsa-0.2.0/src/jibsa/providers/naver/api/request/__init__.py +1 -0
  102. jibsa-0.2.0/src/jibsa/providers/naver/api/request/common.py +299 -0
  103. jibsa-0.2.0/src/jibsa/providers/naver/api/request/complex.py +102 -0
  104. jibsa-0.2.0/src/jibsa/providers/naver/api/request/listing.py +152 -0
  105. jibsa-0.2.0/src/jibsa/providers/naver/api/request/market_price.py +32 -0
  106. jibsa-0.2.0/src/jibsa/providers/naver/api/request/real_price.py +73 -0
  107. jibsa-0.2.0/src/jibsa/providers/naver/api/request/redevelopment.py +179 -0
  108. jibsa-0.2.0/src/jibsa/providers/naver/api/request/region.py +77 -0
  109. jibsa-0.2.0/src/jibsa/providers/naver/api/request/school.py +36 -0
  110. jibsa-0.2.0/src/jibsa/providers/naver/api/request/search.py +195 -0
  111. jibsa-0.2.0/src/jibsa/providers/naver/api/request/trend.py +59 -0
  112. jibsa-0.2.0/src/jibsa/providers/naver/api/response/__init__.py +1 -0
  113. jibsa-0.2.0/src/jibsa/providers/naver/api/response/common.py +945 -0
  114. jibsa-0.2.0/src/jibsa/providers/naver/api/response/complex.py +232 -0
  115. jibsa-0.2.0/src/jibsa/providers/naver/api/response/listing.py +542 -0
  116. jibsa-0.2.0/src/jibsa/providers/naver/api/response/market_price.py +44 -0
  117. jibsa-0.2.0/src/jibsa/providers/naver/api/response/real_price.py +128 -0
  118. jibsa-0.2.0/src/jibsa/providers/naver/api/response/redevelopment.py +98 -0
  119. jibsa-0.2.0/src/jibsa/providers/naver/api/response/region.py +251 -0
  120. jibsa-0.2.0/src/jibsa/providers/naver/api/response/school.py +112 -0
  121. jibsa-0.2.0/src/jibsa/providers/naver/api/response/search.py +67 -0
  122. jibsa-0.2.0/src/jibsa/providers/naver/api/response/trend.py +87 -0
  123. jibsa-0.2.0/src/jibsa/providers/naver/service/__init__.py +5 -0
  124. jibsa-0.2.0/src/jibsa/providers/naver/service/common.py +816 -0
  125. jibsa-0.2.0/src/jibsa/providers/naver/service/complex.py +662 -0
  126. jibsa-0.2.0/src/jibsa/providers/naver/service/listing.py +780 -0
  127. jibsa-0.2.0/src/jibsa/providers/naver/service/market_price.py +178 -0
  128. jibsa-0.2.0/src/jibsa/providers/naver/service/real_price.py +330 -0
  129. jibsa-0.2.0/src/jibsa/providers/naver/service/redevelopment.py +451 -0
  130. jibsa-0.2.0/src/jibsa/providers/naver/service/region.py +698 -0
  131. jibsa-0.2.0/src/jibsa/providers/naver/service/school.py +237 -0
  132. jibsa-0.2.0/src/jibsa/providers/naver/service/search.py +782 -0
  133. jibsa-0.2.0/src/jibsa/providers/naver/service/trend.py +253 -0
  134. jibsa-0.2.0/src/jibsa/providers/zigbang/__init__.py +12 -0
  135. jibsa-0.2.0/src/jibsa/providers/zigbang/api/__init__.py +1 -0
  136. jibsa-0.2.0/src/jibsa/providers/zigbang/api/client.py +1395 -0
  137. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/__init__.py +1 -0
  138. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/apt.py +108 -0
  139. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/common.py +266 -0
  140. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/complex.py +33 -0
  141. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/listing.py +123 -0
  142. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/real_price.py +47 -0
  143. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/region.py +51 -0
  144. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/stay.py +268 -0
  145. jibsa-0.2.0/src/jibsa/providers/zigbang/api/request/store.py +94 -0
  146. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/__init__.py +1 -0
  147. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/apt.py +95 -0
  148. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/common.py +501 -0
  149. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/complex.py +112 -0
  150. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/listing.py +778 -0
  151. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/real_price.py +86 -0
  152. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/region.py +64 -0
  153. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/stay.py +442 -0
  154. jibsa-0.2.0/src/jibsa/providers/zigbang/api/response/store.py +219 -0
  155. jibsa-0.2.0/src/jibsa/providers/zigbang/service/__init__.py +5 -0
  156. jibsa-0.2.0/src/jibsa/providers/zigbang/service/apt.py +592 -0
  157. jibsa-0.2.0/src/jibsa/providers/zigbang/service/common.py +623 -0
  158. jibsa-0.2.0/src/jibsa/providers/zigbang/service/complex.py +598 -0
  159. jibsa-0.2.0/src/jibsa/providers/zigbang/service/detail.py +77 -0
  160. jibsa-0.2.0/src/jibsa/providers/zigbang/service/listing.py +838 -0
  161. jibsa-0.2.0/src/jibsa/providers/zigbang/service/real_price.py +312 -0
  162. jibsa-0.2.0/src/jibsa/providers/zigbang/service/region.py +401 -0
  163. jibsa-0.2.0/src/jibsa/providers/zigbang/service/stay.py +996 -0
  164. jibsa-0.2.0/src/jibsa/providers/zigbang/service/store.py +589 -0
  165. jibsa-0.2.0/tests/conftest.py +7 -0
  166. jibsa-0.2.0/tests/fixtures/daangn/article_feed.json +250 -0
  167. jibsa-0.2.0/tests/fixtures/daangn/article_map_points.json +41 -0
  168. jibsa-0.2.0/tests/fixtures/daangn/articles.html.gz +0 -0
  169. jibsa-0.2.0/tests/fixtures/daangn/articles_by_original_article_ids.json +180 -0
  170. jibsa-0.2.0/tests/fixtures/daangn/articles_count.json +5 -0
  171. jibsa-0.2.0/tests/fixtures/daangn/commute_feed.json +93 -0
  172. jibsa-0.2.0/tests/fixtures/daangn/commute_station_article_connection.json +104 -0
  173. jibsa-0.2.0/tests/fixtures/daangn/complex_by_original_id.json +174 -0
  174. jibsa-0.2.0/tests/fixtures/daangn/get_region_by_coordinate.json +29 -0
  175. jibsa-0.2.0/tests/fixtures/daangn/map.html.gz +0 -0
  176. jibsa-0.2.0/tests/fixtures/daangn/nearest_commute_station.json +15 -0
  177. jibsa-0.2.0/tests/fixtures/daangn/region_complexes.json +126 -0
  178. jibsa-0.2.0/tests/fixtures/daangn/regions_keyword_v1.json +22 -0
  179. jibsa-0.2.0/tests/fixtures/daangn/search_complexes.json +54 -0
  180. jibsa-0.2.0/tests/fixtures/daangn/subway_station_article_connection.json +246 -0
  181. jibsa-0.2.0/tests/fixtures/naver/article_agent_fee_v1.json +11 -0
  182. jibsa-0.2.0/tests/fixtures/naver/article_basic_info_v1.json +55 -0
  183. jibsa-0.2.0/tests/fixtures/naver/article_clustered_articles_v1.json +206 -0
  184. jibsa-0.2.0/tests/fixtures/naver/article_key_v1.json +18 -0
  185. jibsa-0.2.0/tests/fixtures/naver/article_maintenance_fee_v1.json +9 -0
  186. jibsa-0.2.0/tests/fixtures/naver/article_map_article_clusters_v1.json +50 -0
  187. jibsa-0.2.0/tests/fixtures/naver/article_tax_v1.json +26 -0
  188. jibsa-0.2.0/tests/fixtures/naver/complex_article_list_v1.json +203 -0
  189. jibsa-0.2.0/tests/fixtures/naver/complex_pyeong_real_price_v2.json +43 -0
  190. jibsa-0.2.0/tests/fixtures/naver/complex_v1.json +38 -0
  191. jibsa-0.2.0/tests/fixtures/naver/data_service_transport_v1.json +20 -0
  192. jibsa-0.2.0/tests/fixtures/naver/education_building_school_v1.json +6 -0
  193. jibsa-0.2.0/tests/fixtures/naver/legal_division_article_count_weekly_info_v1.json +32 -0
  194. jibsa-0.2.0/tests/fixtures/naver/legal_division_real_trade_count_weekly_list_v1.json +29 -0
  195. jibsa-0.2.0/tests/fixtures/naver/legal_division_search_by_coordinate_v1.json +12 -0
  196. jibsa-0.2.0/tests/fixtures/zigbang/danjis.json +25 -0
  197. jibsa-0.2.0/tests/fixtures/zigbang/danjis_item_catalogs.json +117 -0
  198. jibsa-0.2.0/tests/fixtures/zigbang/guest_items.json +76 -0
  199. jibsa-0.2.0/tests/fixtures/zigbang/item_catalogs_items.json +37 -0
  200. jibsa-0.2.0/tests/fixtures/zigbang/items_detail_v1.json +81 -0
  201. jibsa-0.2.0/tests/fixtures/zigbang/items_list_v1.json +79 -0
  202. jibsa-0.2.0/tests/fixtures/zigbang/items_onerooms_v1.json +34 -0
  203. jibsa-0.2.0/tests/fixtures/zigbang/items_v3.json +83 -0
  204. jibsa-0.2.0/tests/fixtures/zigbang/locals_item_catalogs.json +103 -0
  205. jibsa-0.2.0/tests/fixtures/zigbang/nearby_danjis.json +7 -0
  206. jibsa-0.2.0/tests/fixtures/zigbang/store_article_store_v2.json +47 -0
  207. jibsa-0.2.0/tests/fixtures/zigbang/store_article_stores_list_v2.json +59 -0
  208. jibsa-0.2.0/tests/test_cli.py +283 -0
  209. jibsa-0.2.0/tests/test_daangn.py +1122 -0
  210. jibsa-0.2.0/tests/test_listing.py +82 -0
  211. jibsa-0.2.0/tests/test_naver.py +697 -0
  212. jibsa-0.2.0/tests/test_ratelimit.py +130 -0
  213. jibsa-0.2.0/tests/test_zigbang.py +774 -0
@@ -0,0 +1,61 @@
1
+ name: 🐛 버그 제보
2
+ description: 명령이 문서와 다르게 동작하거나, 매물·가격이 잘못 나올 때
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ 제보 감사합니다. 붙여 넣는 내용에서 토큰·쿠키, 중개사 연락처 같은
9
+ 개인정보는 지워 주세요.
10
+
11
+ - type: dropdown
12
+ id: area
13
+ attributes:
14
+ label: 영역
15
+ description: 어느 부분에서 문제가 생겼나요?
16
+ options:
17
+ - 통합 검색 (jibsa search)
18
+ - 직방 (jibsa zigbang)
19
+ - 네이버 부동산 (jibsa naver)
20
+ - 당근부동산 (jibsa daangn)
21
+ - 요청 제한 (jibsa limits, RATE_LIMITED)
22
+ - CLI 출력·에러 형식
23
+ - 기타 / 잘 모르겠음
24
+ validations:
25
+ required: true
26
+
27
+ - type: textarea
28
+ id: what-happened
29
+ attributes:
30
+ label: 무슨 일이 있었나요?
31
+ description: 기대한 결과와 실제 결과를 적어 주세요.
32
+ validations:
33
+ required: true
34
+
35
+ - type: textarea
36
+ id: repro
37
+ attributes:
38
+ label: 재현 방법
39
+ description: 문제를 일으키는 가장 짧은 명령.
40
+ placeholder: "jibsa search 역삼동 -t 원룸 --trade 월세 --deposit-max 1000"
41
+ render: shell
42
+ validations:
43
+ required: true
44
+
45
+ - type: textarea
46
+ id: output
47
+ attributes:
48
+ label: 출력 또는 에러
49
+ description: stdout 결과나 stderr 의 에러 JSON. `--verbose` 로그가 있으면 함께 붙여 주세요.
50
+ render: shell
51
+ validations:
52
+ required: false
53
+
54
+ - type: input
55
+ id: versions
56
+ attributes:
57
+ label: 환경
58
+ description: "`jibsa --version` 출력, Python 버전, 실행한 날짜. 비공식 API 라 날짜가 중요합니다."
59
+ placeholder: "jibsa 0.1.0 (커밋 a1b2c3d), Python 3.11.6, 2026-10-06"
60
+ validations:
61
+ required: false
@@ -0,0 +1,41 @@
1
+ name: 🧹 잡무
2
+ description: 의존성, 도구, 설정, 정리 — 동작 변화 없음
3
+ labels: ["chore"]
4
+ body:
5
+ - type: dropdown
6
+ id: kind
7
+ attributes:
8
+ label: 종류
9
+ options:
10
+ - 의존성 업데이트·고정
11
+ - 도구·CI
12
+ - 설정
13
+ - 리팩터링·정리
14
+ - 기타
15
+ validations:
16
+ required: true
17
+
18
+ - type: textarea
19
+ id: what
20
+ attributes:
21
+ label: 무엇을 해야 하나요?
22
+ validations:
23
+ required: true
24
+
25
+ - type: textarea
26
+ id: why
27
+ attributes:
28
+ label: 왜 지금 하나요?
29
+ description: |
30
+ 그대로 두면 어떤 비용이 있나요? 보안 권고, 깨진 빌드, 단순한 정리
31
+ 모두 괜찮은 이유입니다.
32
+ validations:
33
+ required: true
34
+
35
+ - type: checkboxes
36
+ id: impact
37
+ attributes:
38
+ label: 영향
39
+ options:
40
+ - label: CLI 출력 형식이나 명령·옵션이 바뀐다
41
+ required: false
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: 💬 질문·논의
4
+ url: https://github.com/Rukkakka/jibsa/discussions
5
+ about: 사용법을 묻거나, 이슈를 올리기 전에 아이디어를 논의합니다.
@@ -0,0 +1,30 @@
1
+ name: 📝 문서
2
+ description: 문서에 빠졌거나, 틀렸거나, 이해하기 어려운 부분이 있을 때
3
+ labels: ["docs"]
4
+ body:
5
+ - type: input
6
+ id: location
7
+ attributes:
8
+ label: 어디인가요?
9
+ description: 파일, 섹션, 또는 docstring.
10
+ placeholder: "README.md — 요청 제한 표"
11
+ validations:
12
+ required: true
13
+
14
+ - type: textarea
15
+ id: problem
16
+ attributes:
17
+ label: 무엇이 틀렸거나 빠졌나요?
18
+ description: |
19
+ 문서가 지금 뭐라고 하는지, 그게 왜 틀렸거나 낡았거나 따라가기
20
+ 어려운지 적어 주세요.
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: suggestion
26
+ attributes:
27
+ label: 제안 문구
28
+ description: 선택 — 바뀌었으면 하는 문장을 적어 주세요.
29
+ validations:
30
+ required: false
@@ -0,0 +1,40 @@
1
+ name: ✨ 기능
2
+ description: 새 소스, 명령, 옵션, 엔드포인트 제안
3
+ labels: ["feature"]
4
+ body:
5
+ - type: textarea
6
+ id: proposal
7
+ attributes:
8
+ label: 무엇이 있어야 하나요?
9
+ description: |
10
+ 원하는 소스, 명령, 옵션, 엔드포인트를 설명해 주세요. 새 엔드포인트라면
11
+ 확인한 요청·응답 예시를 함께 적어 주세요.
12
+ validations:
13
+ required: true
14
+
15
+ - type: textarea
16
+ id: motivation
17
+ attributes:
18
+ label: 왜 필요한가요?
19
+ description: 지금 명령으로는 할 수 없는 일이 무엇인가요?
20
+ validations:
21
+ required: true
22
+
23
+ - type: textarea
24
+ id: usage
25
+ attributes:
26
+ label: 사용 예
27
+ description: 생기면 쓰고 싶은 명령과 기대하는 출력을 적어 주세요.
28
+ render: shell
29
+ validations:
30
+ required: false
31
+
32
+ - type: checkboxes
33
+ id: conventions
34
+ attributes:
35
+ label: 규약
36
+ options:
37
+ - label: 새 엔드포인트·소스라면 references/provider-conventions.md 를 읽었다
38
+ required: false
39
+ - label: 출력이 바뀐다면 references/output-contract.md 를 읽었다
40
+ required: false
@@ -0,0 +1,30 @@
1
+ name: ✅ 작업
2
+ description: 버그·기능·문서·잡무 어디에도 속하지 않는 계획된 작업
3
+ labels: ["task"]
4
+ body:
5
+ - type: textarea
6
+ id: description
7
+ attributes:
8
+ label: 설명
9
+ description: 무엇을 해야 하나요?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: done
15
+ attributes:
16
+ label: 완료 조건
17
+ description: 끝났다는 걸 어떻게 알 수 있나요?
18
+ placeholder: |
19
+ - [ ] ...
20
+ - [ ] ...
21
+ validations:
22
+ required: true
23
+
24
+ - type: textarea
25
+ id: context
26
+ attributes:
27
+ label: 맥락
28
+ description: 관련 이슈, PR, 링크. 선택.
29
+ validations:
30
+ required: false
@@ -0,0 +1,32 @@
1
+ ## 요약
2
+
3
+ <!-- 무엇을 왜 바꾸나요? 닫는 이슈를 적어 주세요. 예: "Closes #12" -->
4
+
5
+ ## 변경 종류
6
+
7
+ <!-- 해당하는 것을 모두 체크하세요. -->
8
+
9
+ - [ ] `fix` — 버그 수정
10
+ - [ ] `feature` — 새 소스, 명령, 옵션, 엔드포인트
11
+ - [ ] `docs` — 문서만
12
+ - [ ] `chore` — 의존성, 도구, 설정, 정리
13
+ - [ ] `task` — 그 밖의 작업
14
+
15
+ ## 영향 범위
16
+
17
+ <!-- 예: providers/naver, cli 출력, search.py. 문서·도구만 바꿨다면 "없음". -->
18
+
19
+ ## 어떻게 테스트했나요?
20
+
21
+ <!-- 실제로 실행한 것을 적어 주세요. 실제 API 로 확인한 명령(CLI 직접 조회)을 먼저, 돌린 pytest 가 있으면 그다음에.
22
+ 테스트를 추가했다면 드문 엣지케이스인지 핵심 동작인지 적어 주세요. "테스트 안 함"도 괜찮습니다 — 그렇다고 적어 주세요. -->
23
+
24
+ ## 체크리스트
25
+
26
+ - [ ] [references/code-style.md](https://github.com/Rukkakka/jibsa/blob/main/references/code-style.md) 를 따른다
27
+ - [ ] 새로 만들거나 바꾼 엔드포인트가 [references/provider-conventions.md](https://github.com/Rukkakka/jibsa/blob/main/references/provider-conventions.md) 를 따른다
28
+ - [ ] 명령·옵션·출력 필드·에러 코드·요청 제한이 바뀌었다면 `docs/<source>.md`·`docs/common.md` 와 [references/output-contract.md](https://github.com/Rukkakka/jibsa/blob/main/references/output-contract.md) 를 고쳤다
29
+ - [ ] 명령을 추가·삭제했거나 에이전트가 틀리기 쉬운 해석 규칙이 바뀌었다면 `docs/llm.md` 를 고쳤다
30
+ - [ ] 사용자에게 보이는 변경이면 `CHANGELOG.md` 의 `Unreleased` 에 적었다 ([쓰는 법](https://github.com/Rukkakka/jibsa/blob/main/references/release.md#changelog-쓰는-법))
31
+ - [ ] 모듈을 추가·이름 변경·삭제했다면 `AGENTS.md` 구조 표와 해당 `references/providers/<source>.md` 를 고쳤다
32
+ - [ ] 새 픽스처와 diff 에 토큰, 쿠키, 중개사 연락처 같은 개인정보가 없다
@@ -0,0 +1,87 @@
1
+ # PR 과 main push 마다 린트·타입 검사·전체 pytest·설치본을 확인한다. 배포(release.yml)도 이 워크플로를 불러 같은 검사를
2
+ # 통과한 빌드만 올린다. 잡 이름은 main 보호 규칙의 필수 검사라 바꾸면 보호 규칙도 같이 고친다.
3
+ # 테스트는 가짜 응답만 쓰고 실제 API 는 부르지 않는다 (references/development.md '검증과 테스트').
4
+ name: CI
5
+
6
+ on:
7
+ push:
8
+ branches: [main]
9
+ pull_request:
10
+ workflow_call:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ concurrency:
16
+ group: ci-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ lint:
21
+ name: 린트·타입 검사
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v7
25
+ - uses: actions/setup-python@v7
26
+ with:
27
+ python-version: '3.11'
28
+ cache: pip
29
+ cache-dependency-path: pyproject.toml
30
+ - run: pip install -e '.[dev]'
31
+ - run: ruff check
32
+ - run: mypy
33
+ - name: docs/llm.md 200줄 이하
34
+ run: |
35
+ lines=$(wc -l < docs/llm.md)
36
+ echo "docs/llm.md: ${lines}줄"
37
+ if [ "$lines" -gt 200 ]; then
38
+ echo "::error file=docs/llm.md::${lines}줄입니다. 200줄 이하로 줄이세요 (AGENTS.md '문서 갱신')"
39
+ exit 1
40
+ fi
41
+
42
+ test:
43
+ name: pytest (${{ matrix.os }}, Python ${{ matrix.python }})
44
+ runs-on: ${{ matrix.os }}
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ os: [ubuntu-latest, macos-latest, windows-latest]
49
+ # 지원하는 가장 낮은 버전과 최신 안정 버전
50
+ python: ['3.11', '3.14']
51
+ env:
52
+ # README 의 Windows 설정(setx PYTHONUTF8 1)과 같게 한다. macOS·Linux 는 원래 UTF-8 이다
53
+ PYTHONUTF8: '1'
54
+ steps:
55
+ - uses: actions/checkout@v7
56
+ - uses: actions/setup-python@v7
57
+ with:
58
+ python-version: ${{ matrix.python }}
59
+ cache: pip
60
+ cache-dependency-path: pyproject.toml
61
+ - run: pip install -e '.[dev]'
62
+ - run: pytest
63
+
64
+ package:
65
+ name: 설치본 확인
66
+ runs-on: ubuntu-latest
67
+ steps:
68
+ - uses: actions/checkout@v7
69
+ - uses: actions/setup-python@v7
70
+ with:
71
+ python-version: '3.11'
72
+ - run: pip install build twine
73
+ - run: python -m build
74
+ # README 가 PyPI 프로젝트 페이지에서 렌더링되는지 (상대 링크는 잡지 못한다)
75
+ - run: twine check --strict dist/*
76
+ # 편집 가능 설치와 달리 docs/llm.md 를 패키지 안 사본으로 읽으므로 그 사본이 빠지거나 다르면 여기서 드러난다
77
+ - name: 새 가상환경에 설치해 실행
78
+ run: |
79
+ python -m venv "$RUNNER_TEMP/jibsa-check"
80
+ "$RUNNER_TEMP/jibsa-check/bin/pip" install dist/*.whl
81
+ "$RUNNER_TEMP/jibsa-check/bin/jibsa" --version
82
+ "$RUNNER_TEMP/jibsa-check/bin/jibsa" guide > "$RUNNER_TEMP/guide.md"
83
+ diff "$RUNNER_TEMP/guide.md" docs/llm.md
84
+ - uses: actions/upload-artifact@v7
85
+ with:
86
+ name: dist
87
+ path: dist/
@@ -0,0 +1,82 @@
1
+ # v* 태그를 push 하면 PyPI 와 GitHub Release 로 배포한다 (references/release.md '릴리스 절차').
2
+ # PyPI 는 API 토큰 없이 신뢰 게시(Trusted Publishing)로 올린다. pypi.org 의 게시자 설정은 프로젝트 jibsa,
3
+ # 저장소 Rukkakka/jibsa, 워크플로 release.yml, 환경 pypi 이고 GitHub 환경 pypi 는 v* 태그에서만 배포를 받는다.
4
+ name: Release
5
+
6
+ on:
7
+ push:
8
+ tags: ['v*']
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ tag:
15
+ name: 태그 확인
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v7
19
+ with:
20
+ # 태그 커밋이 main 에 있는지 보려고 main 기록까지 받는다
21
+ fetch-depth: 0
22
+ - uses: actions/setup-python@v7
23
+ with:
24
+ python-version: '3.11'
25
+ - name: 태그가 main 에 있고 pyproject.toml 버전·CHANGELOG 절과 맞는지
26
+ run: |
27
+ if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
28
+ echo "::error::$GITHUB_REF_NAME 이 main 에 없는 커밋을 가리킵니다. 태그는 머지 뒤 main 에만 단다"
29
+ exit 1
30
+ fi
31
+ version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
32
+ if [ "v$version" != "$GITHUB_REF_NAME" ]; then
33
+ echo "::error::태그 $GITHUB_REF_NAME 와 pyproject.toml 버전 $version 이 다릅니다"
34
+ exit 1
35
+ fi
36
+ if ! grep -q "^## $version — " CHANGELOG.md; then
37
+ echo "::error::CHANGELOG.md 에 '## $version — 날짜' 절이 없습니다"
38
+ exit 1
39
+ fi
40
+
41
+ ci:
42
+ name: CI
43
+ needs: tag
44
+ uses: ./.github/workflows/ci.yml
45
+
46
+ pypi:
47
+ name: PyPI 에 올리기
48
+ needs: ci
49
+ runs-on: ubuntu-latest
50
+ environment:
51
+ name: pypi
52
+ url: https://pypi.org/project/jibsa/
53
+ permissions:
54
+ # 신뢰 게시의 OIDC 토큰
55
+ id-token: write
56
+ steps:
57
+ # CI 의 설치본 확인이 빌드·확인한 파일을 그대로 올린다
58
+ - uses: actions/download-artifact@v8
59
+ with:
60
+ name: dist
61
+ path: dist/
62
+ - uses: pypa/gh-action-pypi-publish@release/v1
63
+
64
+ github-release:
65
+ name: GitHub Release
66
+ needs: pypi
67
+ runs-on: ubuntu-latest
68
+ permissions:
69
+ contents: write
70
+ steps:
71
+ - uses: actions/checkout@v7
72
+ - uses: actions/download-artifact@v8
73
+ with:
74
+ name: dist
75
+ path: dist/
76
+ - name: CHANGELOG 의 그 버전 절로 Release 만들기
77
+ env:
78
+ GH_TOKEN: ${{ github.token }}
79
+ run: |
80
+ version="${GITHUB_REF_NAME#v}"
81
+ awk -v head="## $version " 'index($0, head) == 1 {f=1; next} /^## /{if (f) exit} f' CHANGELOG.md > "$RUNNER_TEMP/notes.md"
82
+ gh release create "$GITHUB_REF_NAME" --verify-tag --title "$GITHUB_REF_NAME" --notes-file "$RUNNER_TEMP/notes.md" dist/*
jibsa-0.2.0/.gitignore ADDED
@@ -0,0 +1,229 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ *.lcov
51
+ .hypothesis/
52
+ .pytest_cache/
53
+ cover/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ .pybuilder/
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ # For a library or package, you might want to ignore these files since the code is
88
+ # intended to run in multiple environments; otherwise, check them in:
89
+ # .python-version
90
+
91
+ # pipenv
92
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
94
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
95
+ # install all needed dependencies.
96
+ # Pipfile.lock
97
+
98
+ # uv
99
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
100
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
101
+ # commonly ignored for libraries.
102
+ # uv.lock
103
+
104
+ # poetry
105
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
107
+ # commonly ignored for libraries.
108
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109
+ # poetry.lock
110
+ # poetry.toml
111
+
112
+ # pdm
113
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
115
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
116
+ # pdm.lock
117
+ # pdm.toml
118
+ .pdm-python
119
+ .pdm-build/
120
+
121
+ # pixi
122
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
123
+ # pixi.lock
124
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
125
+ # in the .venv directory. It is recommended not to include this directory in version control.
126
+ .pixi/*
127
+ !.pixi/config.toml
128
+
129
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
130
+ __pypackages__/
131
+
132
+ # Celery stuff
133
+ celerybeat-schedule*
134
+ celerybeat.pid
135
+
136
+ # Redis
137
+ *.rdb
138
+ *.aof
139
+ *.pid
140
+
141
+ # RabbitMQ
142
+ mnesia/
143
+ rabbitmq/
144
+ rabbitmq-data/
145
+
146
+ # ActiveMQ
147
+ activemq-data/
148
+
149
+ # SageMath parsed files
150
+ *.sage.py
151
+
152
+ # Environments
153
+ .env
154
+ .envrc
155
+ .venv
156
+ env/
157
+ venv/
158
+ ENV/
159
+ env.bak/
160
+ venv.bak/
161
+
162
+ # Spyder project settings
163
+ .spyderproject
164
+ .spyproject
165
+
166
+ # Rope project settings
167
+ .ropeproject
168
+
169
+ # mkdocs/Zensical documentation
170
+ /site
171
+
172
+ # mypy
173
+ .mypy_cache/
174
+ .dmypy.json
175
+ dmypy.json
176
+
177
+ # Pyre type checker
178
+ .pyre/
179
+
180
+ # pytype static type analyzer
181
+ .pytype/
182
+
183
+ # Cython debug symbols
184
+ cython_debug/
185
+
186
+ # PyCharm
187
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
188
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
189
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
190
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
191
+ # .idea/
192
+
193
+ # Abstra
194
+ # Abstra is an AI-powered process automation framework.
195
+ # Ignore directories containing user credentials, local state, and settings.
196
+ # Learn more at https://abstra.io/docs
197
+ .abstra/
198
+
199
+ # Visual Studio Code
200
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore that
201
+ # can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
202
+ # and can be added to the global gitignore or merged into this file. However, if you prefer, you
203
+ # could uncomment the following to ignore the entire vscode folder
204
+ # .vscode/
205
+ # Temporary file for partial code execution
206
+ tempCodeRunnerFile.py
207
+
208
+ # Ruff stuff:
209
+ .ruff_cache/
210
+
211
+ # PyPI configuration file
212
+ .pypirc
213
+
214
+ # Marimo
215
+ marimo/_static/
216
+ marimo/_lsp/
217
+ __marimo__/
218
+
219
+ # Streamlit
220
+ .streamlit/secrets.toml
221
+
222
+ # macOS
223
+ .DS_Store
224
+
225
+ # 로컬 백업 (커밋하지 않음)
226
+ .backup/
227
+
228
+ # Claude Code 개인 설정 (커밋하지 않음)
229
+ .claude/settings.local.json