sophhub 0.2.2 → 0.2.4

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 (109) hide show
  1. package/package.json +1 -1
  2. package/skills/consensus/skill.json +20 -0
  3. package/skills/consensus/src/SKILL.md +93 -0
  4. package/skills/deepwiki/skill.json +20 -0
  5. package/skills/deepwiki/src/SKILL.md +45 -0
  6. package/skills/deepwiki/src/_meta.json +6 -0
  7. package/skills/deepwiki/src/scripts/deepwiki.js +135 -0
  8. package/skills/feishu-bitable/skill.json +20 -0
  9. package/skills/feishu-bitable/src/CHECKLIST.md +150 -0
  10. package/skills/feishu-bitable/src/README.md +178 -0
  11. package/skills/feishu-bitable/src/SKILL.md +113 -0
  12. package/skills/feishu-bitable/src/_meta.json +6 -0
  13. package/skills/feishu-bitable/src/api.js +381 -0
  14. package/skills/feishu-bitable/src/bin/cli.js +284 -0
  15. package/skills/feishu-bitable/src/description.md +143 -0
  16. package/skills/feishu-bitable/src/examples/create-records.json +52 -0
  17. package/skills/feishu-bitable/src/examples/create-table.json +64 -0
  18. package/skills/feishu-bitable/src/package-lock.json +324 -0
  19. package/skills/feishu-bitable/src/package.json +33 -0
  20. package/skills/feishu-bitable/src/publish-config.json +14 -0
  21. package/skills/feishu-bitable/src/test-simple.js +61 -0
  22. package/skills/feishu-bitable/src/utils.js +261 -0
  23. package/skills/flight-booking/skill.json +9 -2
  24. package/skills/flight-booking/src/scripts/flight_booking.py +2 -1
  25. package/skills/google-maps/skill.json +20 -0
  26. package/skills/google-maps/src/SKILL.md +237 -0
  27. package/skills/google-maps/src/_meta.json +6 -0
  28. package/skills/google-maps/src/lib/map_helper.py +912 -0
  29. package/skills/large-task-router/skill.json +20 -0
  30. package/skills/large-task-router/src/SKILL.md +79 -0
  31. package/skills/large-task-router/src/templates/plan.md +74 -0
  32. package/skills/skillhub/skill.json +11 -4
  33. package/skills/skillhub/src/SKILL.md +11 -1
  34. package/skills/sophnet-dailynews/skill.json +20 -0
  35. package/skills/sophnet-dailynews/src/SKILL.md +179 -0
  36. package/skills/sophnet-dailynews/src/cache.json +151 -0
  37. package/skills/sophnet-dailynews/src/sources.json +230 -0
  38. package/skills/sophnet-schedule/skill.json +20 -0
  39. package/skills/sophnet-schedule/src/ARCHITECTURE.md +321 -0
  40. package/skills/sophnet-schedule/src/IMPROVEMENTS.md +145 -0
  41. package/skills/sophnet-schedule/src/SKILL.md +1050 -0
  42. package/skills/sophnet-schedule/src/_meta.json +6 -0
  43. package/skills/sophnet-schedule/src/api/__init__.py +0 -0
  44. package/skills/sophnet-schedule/src/api/models.py +245 -0
  45. package/skills/sophnet-schedule/src/apps/add_event.py +237 -0
  46. package/skills/sophnet-schedule/src/apps/check_reminders.py +112 -0
  47. package/skills/sophnet-schedule/src/apps/check_roc.py +246 -0
  48. package/skills/sophnet-schedule/src/apps/generate_daily_plan.py +342 -0
  49. package/skills/sophnet-schedule/src/apps/import_events.py +216 -0
  50. package/skills/sophnet-schedule/src/apps/monitor_calendar_changes.py +140 -0
  51. package/skills/sophnet-schedule/src/apps/register_tasks.py +169 -0
  52. package/skills/sophnet-schedule/src/apps/sync_roc_to_gcal.py +174 -0
  53. package/skills/sophnet-schedule/src/compat.py +66 -0
  54. package/skills/sophnet-schedule/src/config/__init__.py +0 -0
  55. package/skills/sophnet-schedule/src/config/reminder_rules.yaml +96 -0
  56. package/skills/sophnet-schedule/src/config/roc_events.yaml +44 -0
  57. package/skills/sophnet-schedule/src/config/settings.py +133 -0
  58. package/skills/sophnet-schedule/src/config/task_registry.yaml +92 -0
  59. package/skills/sophnet-schedule/src/docs/FRONTEND_INTEGRATION_GUIDE.md +437 -0
  60. package/skills/sophnet-schedule/src/gcal/__init__.py +0 -0
  61. package/skills/sophnet-schedule/src/gcal/client.py +374 -0
  62. package/skills/sophnet-schedule/src/gcal/models.py +91 -0
  63. package/skills/sophnet-schedule/src/requirements.txt +6 -0
  64. package/skills/sophnet-schedule/src/scripts/setup_gcal_token.py +85 -0
  65. package/skills/sophnet-schedule/src/server.py +669 -0
  66. package/skills/sophnet-schedule/src/services/__init__.py +0 -0
  67. package/skills/sophnet-schedule/src/services/calendar_backend.py +139 -0
  68. package/skills/sophnet-schedule/src/services/conflict_detector.py +96 -0
  69. package/skills/sophnet-schedule/src/services/datetime_utils.py +117 -0
  70. package/skills/sophnet-schedule/src/services/event_classifier.py +100 -0
  71. package/skills/sophnet-schedule/src/services/event_diff.py +160 -0
  72. package/skills/sophnet-schedule/src/services/google_integration.py +500 -0
  73. package/skills/sophnet-schedule/src/services/job_store.py +100 -0
  74. package/skills/sophnet-schedule/src/services/local_event_store.py +266 -0
  75. package/skills/sophnet-schedule/src/services/reminder_planner.py +116 -0
  76. package/skills/sophnet-schedule/src/services/runtime_utils.py +31 -0
  77. package/skills/sophnet-schedule/src/services/table_parser.py +286 -0
  78. package/skills/sophnet-schedule/src/services/task_builder.py +167 -0
  79. package/skills/sophnet-schedule/src/services/time_window.py +72 -0
  80. package/skills/sophnet-stock/skill.json +20 -0
  81. package/skills/sophnet-stock/src/App-Plan.md +442 -0
  82. package/skills/sophnet-stock/src/README.md +214 -0
  83. package/skills/sophnet-stock/src/SKILL.md +236 -0
  84. package/skills/sophnet-stock/src/TODO.md +394 -0
  85. package/skills/sophnet-stock/src/_meta.json +6 -0
  86. package/skills/sophnet-stock/src/docs/ARCHITECTURE.md +408 -0
  87. package/skills/sophnet-stock/src/docs/CONCEPT.md +233 -0
  88. package/skills/sophnet-stock/src/docs/HOT_SCANNER.md +288 -0
  89. package/skills/sophnet-stock/src/docs/README.md +95 -0
  90. package/skills/sophnet-stock/src/docs/USAGE.md +465 -0
  91. package/skills/sophnet-stock/src/scripts/analyze_stock.py +2565 -0
  92. package/skills/sophnet-stock/src/scripts/dividends.py +365 -0
  93. package/skills/sophnet-stock/src/scripts/hot_scanner.py +582 -0
  94. package/skills/sophnet-stock/src/scripts/portfolio.py +548 -0
  95. package/skills/sophnet-stock/src/scripts/rumor_scanner.py +342 -0
  96. package/skills/sophnet-stock/src/scripts/test_stock_analysis.py +409 -0
  97. package/skills/sophnet-stock/src/scripts/watchlist.py +336 -0
  98. package/skills/xiaohongshu/skill.json +20 -0
  99. package/skills/xiaohongshu/src/SKILL.md +91 -0
  100. package/skills/xiaohongshu/src/_meta.json +6 -0
  101. package/skills/xiaohongshu/src/assets/card.html +216 -0
  102. package/skills/xiaohongshu/src/assets/cover.html +82 -0
  103. package/skills/xiaohongshu/src/assets/example.md +84 -0
  104. package/skills/xiaohongshu/src/assets/styles.css +318 -0
  105. package/skills/xiaohongshu/src/scripts/render_xhs_v2.py +737 -0
  106. package/skills/xiaohongshu/src/scripts/sign_server.py +158 -0
  107. package/skills/xiaohongshu/src/scripts/stealth.min.js +7 -0
  108. package/skills/xiaohongshu/src/scripts/xhs_tool.py +186 -0
  109. package/skills/xiaohongshu/src/workflow.py +185 -0
@@ -0,0 +1,324 @@
1
+ {
2
+ "name": "feishu-bitable",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "feishu-bitable",
9
+ "version": "1.0.0",
10
+ "license": "MIT",
11
+ "dependencies": {
12
+ "axios": "^1.6.0",
13
+ "commander": "^11.1.0",
14
+ "dotenv": "^16.3.0"
15
+ },
16
+ "bin": {
17
+ "feishu-bitable": "bin/cli.js"
18
+ },
19
+ "engines": {
20
+ "node": ">=16.0.0"
21
+ }
22
+ },
23
+ "node_modules/asynckit": {
24
+ "version": "0.4.0",
25
+ "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
26
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
27
+ "license": "MIT"
28
+ },
29
+ "node_modules/axios": {
30
+ "version": "1.13.4",
31
+ "resolved": "https://registry.npmmirror.com/axios/-/axios-1.13.4.tgz",
32
+ "integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "follow-redirects": "^1.15.6",
36
+ "form-data": "^4.0.4",
37
+ "proxy-from-env": "^1.1.0"
38
+ }
39
+ },
40
+ "node_modules/call-bind-apply-helpers": {
41
+ "version": "1.0.2",
42
+ "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
43
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
44
+ "license": "MIT",
45
+ "dependencies": {
46
+ "es-errors": "^1.3.0",
47
+ "function-bind": "^1.1.2"
48
+ },
49
+ "engines": {
50
+ "node": ">= 0.4"
51
+ }
52
+ },
53
+ "node_modules/combined-stream": {
54
+ "version": "1.0.8",
55
+ "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
56
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
57
+ "license": "MIT",
58
+ "dependencies": {
59
+ "delayed-stream": "~1.0.0"
60
+ },
61
+ "engines": {
62
+ "node": ">= 0.8"
63
+ }
64
+ },
65
+ "node_modules/commander": {
66
+ "version": "11.1.0",
67
+ "resolved": "https://registry.npmmirror.com/commander/-/commander-11.1.0.tgz",
68
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
69
+ "license": "MIT",
70
+ "engines": {
71
+ "node": ">=16"
72
+ }
73
+ },
74
+ "node_modules/delayed-stream": {
75
+ "version": "1.0.0",
76
+ "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
77
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
78
+ "license": "MIT",
79
+ "engines": {
80
+ "node": ">=0.4.0"
81
+ }
82
+ },
83
+ "node_modules/dotenv": {
84
+ "version": "16.6.1",
85
+ "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz",
86
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
87
+ "license": "BSD-2-Clause",
88
+ "engines": {
89
+ "node": ">=12"
90
+ },
91
+ "funding": {
92
+ "url": "https://dotenvx.com"
93
+ }
94
+ },
95
+ "node_modules/dunder-proto": {
96
+ "version": "1.0.1",
97
+ "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
98
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
99
+ "license": "MIT",
100
+ "dependencies": {
101
+ "call-bind-apply-helpers": "^1.0.1",
102
+ "es-errors": "^1.3.0",
103
+ "gopd": "^1.2.0"
104
+ },
105
+ "engines": {
106
+ "node": ">= 0.4"
107
+ }
108
+ },
109
+ "node_modules/es-define-property": {
110
+ "version": "1.0.1",
111
+ "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
112
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
113
+ "license": "MIT",
114
+ "engines": {
115
+ "node": ">= 0.4"
116
+ }
117
+ },
118
+ "node_modules/es-errors": {
119
+ "version": "1.3.0",
120
+ "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
121
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
122
+ "license": "MIT",
123
+ "engines": {
124
+ "node": ">= 0.4"
125
+ }
126
+ },
127
+ "node_modules/es-object-atoms": {
128
+ "version": "1.1.1",
129
+ "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
130
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
131
+ "license": "MIT",
132
+ "dependencies": {
133
+ "es-errors": "^1.3.0"
134
+ },
135
+ "engines": {
136
+ "node": ">= 0.4"
137
+ }
138
+ },
139
+ "node_modules/es-set-tostringtag": {
140
+ "version": "2.1.0",
141
+ "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
142
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
143
+ "license": "MIT",
144
+ "dependencies": {
145
+ "es-errors": "^1.3.0",
146
+ "get-intrinsic": "^1.2.6",
147
+ "has-tostringtag": "^1.0.2",
148
+ "hasown": "^2.0.2"
149
+ },
150
+ "engines": {
151
+ "node": ">= 0.4"
152
+ }
153
+ },
154
+ "node_modules/follow-redirects": {
155
+ "version": "1.15.11",
156
+ "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz",
157
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
158
+ "funding": [
159
+ {
160
+ "type": "individual",
161
+ "url": "https://github.com/sponsors/RubenVerborgh"
162
+ }
163
+ ],
164
+ "license": "MIT",
165
+ "engines": {
166
+ "node": ">=4.0"
167
+ },
168
+ "peerDependenciesMeta": {
169
+ "debug": {
170
+ "optional": true
171
+ }
172
+ }
173
+ },
174
+ "node_modules/form-data": {
175
+ "version": "4.0.5",
176
+ "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
177
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
178
+ "license": "MIT",
179
+ "dependencies": {
180
+ "asynckit": "^0.4.0",
181
+ "combined-stream": "^1.0.8",
182
+ "es-set-tostringtag": "^2.1.0",
183
+ "hasown": "^2.0.2",
184
+ "mime-types": "^2.1.12"
185
+ },
186
+ "engines": {
187
+ "node": ">= 6"
188
+ }
189
+ },
190
+ "node_modules/function-bind": {
191
+ "version": "1.1.2",
192
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
193
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
194
+ "license": "MIT",
195
+ "funding": {
196
+ "url": "https://github.com/sponsors/ljharb"
197
+ }
198
+ },
199
+ "node_modules/get-intrinsic": {
200
+ "version": "1.3.0",
201
+ "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
202
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
203
+ "license": "MIT",
204
+ "dependencies": {
205
+ "call-bind-apply-helpers": "^1.0.2",
206
+ "es-define-property": "^1.0.1",
207
+ "es-errors": "^1.3.0",
208
+ "es-object-atoms": "^1.1.1",
209
+ "function-bind": "^1.1.2",
210
+ "get-proto": "^1.0.1",
211
+ "gopd": "^1.2.0",
212
+ "has-symbols": "^1.1.0",
213
+ "hasown": "^2.0.2",
214
+ "math-intrinsics": "^1.1.0"
215
+ },
216
+ "engines": {
217
+ "node": ">= 0.4"
218
+ },
219
+ "funding": {
220
+ "url": "https://github.com/sponsors/ljharb"
221
+ }
222
+ },
223
+ "node_modules/get-proto": {
224
+ "version": "1.0.1",
225
+ "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
226
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
227
+ "license": "MIT",
228
+ "dependencies": {
229
+ "dunder-proto": "^1.0.1",
230
+ "es-object-atoms": "^1.0.0"
231
+ },
232
+ "engines": {
233
+ "node": ">= 0.4"
234
+ }
235
+ },
236
+ "node_modules/gopd": {
237
+ "version": "1.2.0",
238
+ "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
239
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
240
+ "license": "MIT",
241
+ "engines": {
242
+ "node": ">= 0.4"
243
+ },
244
+ "funding": {
245
+ "url": "https://github.com/sponsors/ljharb"
246
+ }
247
+ },
248
+ "node_modules/has-symbols": {
249
+ "version": "1.1.0",
250
+ "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
251
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
252
+ "license": "MIT",
253
+ "engines": {
254
+ "node": ">= 0.4"
255
+ },
256
+ "funding": {
257
+ "url": "https://github.com/sponsors/ljharb"
258
+ }
259
+ },
260
+ "node_modules/has-tostringtag": {
261
+ "version": "1.0.2",
262
+ "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
263
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
264
+ "license": "MIT",
265
+ "dependencies": {
266
+ "has-symbols": "^1.0.3"
267
+ },
268
+ "engines": {
269
+ "node": ">= 0.4"
270
+ },
271
+ "funding": {
272
+ "url": "https://github.com/sponsors/ljharb"
273
+ }
274
+ },
275
+ "node_modules/hasown": {
276
+ "version": "2.0.2",
277
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
278
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
279
+ "license": "MIT",
280
+ "dependencies": {
281
+ "function-bind": "^1.1.2"
282
+ },
283
+ "engines": {
284
+ "node": ">= 0.4"
285
+ }
286
+ },
287
+ "node_modules/math-intrinsics": {
288
+ "version": "1.1.0",
289
+ "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
290
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
291
+ "license": "MIT",
292
+ "engines": {
293
+ "node": ">= 0.4"
294
+ }
295
+ },
296
+ "node_modules/mime-db": {
297
+ "version": "1.52.0",
298
+ "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
299
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
300
+ "license": "MIT",
301
+ "engines": {
302
+ "node": ">= 0.6"
303
+ }
304
+ },
305
+ "node_modules/mime-types": {
306
+ "version": "2.1.35",
307
+ "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
308
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
309
+ "license": "MIT",
310
+ "dependencies": {
311
+ "mime-db": "1.52.0"
312
+ },
313
+ "engines": {
314
+ "node": ">= 0.6"
315
+ }
316
+ },
317
+ "node_modules/proxy-from-env": {
318
+ "version": "1.1.0",
319
+ "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
320
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
321
+ "license": "MIT"
322
+ }
323
+ }
324
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "feishu-bitable",
3
+ "version": "1.0.0",
4
+ "description": "飞书多维表格(Bitable)API技能 - 用于创建、读取、更新和删除飞书多维表格的数据表、记录和字段",
5
+ "main": "src/api.js",
6
+ "bin": {
7
+ "feishu-bitable": "bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/cli.js",
11
+ "test": "node test-simple.js",
12
+ "publish": "clawdhub publish . --slug feishu-bitable --name \"Feishu Bitable\" --version 1.0.0 --changelog \"Initial release: Complete Feishu Bitable API integration\""
13
+ },
14
+ "keywords": ["feishu", "lark", "bitable", "多维表格", "api", "clawdbot", "database", "spreadsheet", "automation"],
15
+ "author": "Clawdbot Community",
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/clawdbot/skills.git"
20
+ },
21
+ "homepage": "https://clawdhub.com/skills/feishu-bitable",
22
+ "bugs": {
23
+ "url": "https://github.com/clawdbot/skills/issues"
24
+ },
25
+ "dependencies": {
26
+ "axios": "^1.6.0",
27
+ "commander": "^11.1.0",
28
+ "dotenv": "^16.3.0"
29
+ },
30
+ "engines": {
31
+ "node": ">=16.0.0"
32
+ }
33
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "slug": "feishu-bitable",
3
+ "name": "Feishu Bitable",
4
+ "version": "1.0.0",
5
+ "description": "飞书多维表格(Bitable)API技能 - 用于创建、读取、更新和删除飞书多维表格的数据表、记录和字段",
6
+ "tags": ["feishu", "lark", "bitable", "database", "spreadsheet", "automation", "api", "chinese"],
7
+ "changelog": "Initial release with complete Feishu Bitable API integration:\n- Full table management (list, create, get, delete)\n- Complete record operations (CRUD + batch)\n- Field and view management\n- Automatic token refresh\n- Error handling and retry logic\n- Command-line interface\n- Examples and documentation",
8
+ "readme": "See SKILL.md for detailed documentation",
9
+ "keywords": ["飞书", "多维表格", "bitable", "数据库", "自动化", "API"],
10
+ "author": "Clawdbot Community",
11
+ "license": "MIT",
12
+ "homepage": "https://clawdhub.com/skills/feishu-bitable",
13
+ "repository": "https://github.com/clawdbot/skills/tree/main/feishu-bitable"
14
+ }
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 简单测试脚本
5
+ */
6
+
7
+ console.log('=== 飞书多维表格技能测试 ===\n');
8
+
9
+ // 检查环境变量
10
+ const requiredEnvVars = ['FEISHU_APP_ID', 'FEISHU_APP_SECRET'];
11
+ const missingVars = requiredEnvVars.filter(varName => !process.env[varName]);
12
+
13
+ if (missingVars.length > 0) {
14
+ console.log('❌ 缺少必要的环境变量:');
15
+ missingVars.forEach(varName => {
16
+ console.log(` - ${varName}`);
17
+ });
18
+ console.log('\n请设置环境变量或创建 .env 文件');
19
+ console.log('参考 .env.example 文件');
20
+ process.exit(1);
21
+ }
22
+
23
+ console.log('✅ 环境变量检查通过');
24
+ console.log(`应用ID: ${process.env.FEISHU_APP_ID ? '已设置' : '未设置'}`);
25
+ console.log(`应用密钥: ${process.env.FEISHU_APP_SECRET ? '已设置' : '未设置'}`);
26
+
27
+ // 测试API客户端
28
+ try {
29
+ const FeishuBitableAPI = require('./src/api');
30
+ const api = new FeishuBitableAPI();
31
+
32
+ console.log('\n✅ API客户端初始化成功');
33
+
34
+ // 测试连接
35
+ console.log('\n正在测试连接...');
36
+ api.testConnection().then(result => {
37
+ if (result.success) {
38
+ console.log('✅ 连接测试成功');
39
+ console.log(`令牌有效: ${result.tokenValid ? '是' : '否'}`);
40
+ } else {
41
+ console.log('❌ 连接测试失败:', result.message);
42
+ }
43
+
44
+ console.log('\n=== 测试完成 ===');
45
+ console.log('\n可用命令:');
46
+ console.log(' node bin/cli.js test - 测试连接');
47
+ console.log(' node bin/cli.js --help - 查看所有命令');
48
+ console.log(' node bin/cli.js list-tables --help - 查看具体命令帮助');
49
+
50
+ }).catch(error => {
51
+ console.error('❌ 连接测试失败:', error.message);
52
+ console.log('\n可能的原因:');
53
+ console.log('1. 应用ID或密钥错误');
54
+ console.log('2. 网络连接问题');
55
+ console.log('3. 应用权限不足');
56
+ });
57
+
58
+ } catch (error) {
59
+ console.error('❌ API客户端初始化失败:', error.message);
60
+ process.exit(1);
61
+ }
@@ -0,0 +1,261 @@
1
+ /**
2
+ * 工具函数
3
+ */
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+
8
+ /**
9
+ * 读取环境变量
10
+ */
11
+ function getEnvVar(name, defaultValue = null) {
12
+ // 从环境变量读取
13
+ let value = process.env[name];
14
+
15
+ // 如果是文件路径,从文件读取
16
+ if (name.endsWith('_PATH') && value) {
17
+ try {
18
+ const filePath = value.startsWith('~')
19
+ ? path.join(process.env.HOME, value.slice(1))
20
+ : value;
21
+
22
+ if (fs.existsSync(filePath)) {
23
+ value = fs.readFileSync(filePath, 'utf8').trim();
24
+ }
25
+ } catch (error) {
26
+ console.warn(`无法读取文件 ${value}: ${error.message}`);
27
+ }
28
+ }
29
+
30
+ return value || defaultValue;
31
+ }
32
+
33
+ /**
34
+ * 获取飞书访问令牌
35
+ */
36
+ async function getAccessToken(appId, appSecret) {
37
+ const axios = require('axios');
38
+
39
+ try {
40
+ const response = await axios.post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/', {
41
+ app_id: appId,
42
+ app_secret: appSecret
43
+ }, {
44
+ headers: {
45
+ 'Content-Type': 'application/json; charset=utf-8'
46
+ }
47
+ });
48
+
49
+ if (response.data.code === 0) {
50
+ return response.data.tenant_access_token;
51
+ } else {
52
+ throw new Error(`获取访问令牌失败: ${response.data.msg}`);
53
+ }
54
+ } catch (error) {
55
+ throw new Error(`获取访问令牌时出错: ${error.message}`);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * 验证必填参数
61
+ */
62
+ function validateRequired(params, requiredFields) {
63
+ for (const field of requiredFields) {
64
+ if (!params[field]) {
65
+ throw new Error(`缺少必填参数: ${field}`);
66
+ }
67
+ }
68
+ }
69
+
70
+ /**
71
+ * 解析JSON字符串或文件
72
+ */
73
+ function parseJsonInput(input) {
74
+ if (!input) return null;
75
+
76
+ // 如果是文件路径(以@开头)
77
+ if (typeof input === 'string' && input.startsWith('@')) {
78
+ const filePath = input.slice(1);
79
+ try {
80
+ const content = fs.readFileSync(filePath, 'utf8');
81
+ return JSON.parse(content);
82
+ } catch (error) {
83
+ throw new Error(`无法读取或解析文件 ${filePath}: ${error.message}`);
84
+ }
85
+ }
86
+
87
+ // 如果是JSON字符串
88
+ if (typeof input === 'string') {
89
+ try {
90
+ return JSON.parse(input);
91
+ } catch (error) {
92
+ // 如果不是有效的JSON,返回原始字符串
93
+ return input;
94
+ }
95
+ }
96
+
97
+ // 已经是对象
98
+ return input;
99
+ }
100
+
101
+ /**
102
+ * 格式化日期
103
+ */
104
+ function formatDate(date, format = 'YYYY-MM-DD') {
105
+ const d = date instanceof Date ? date : new Date(date);
106
+
107
+ const year = d.getFullYear();
108
+ const month = String(d.getMonth() + 1).padStart(2, '0');
109
+ const day = String(d.getDate()).padStart(2, '0');
110
+ const hours = String(d.getHours()).padStart(2, '0');
111
+ const minutes = String(d.getMinutes()).padStart(2, '0');
112
+ const seconds = String(d.getSeconds()).padStart(2, '0');
113
+
114
+ return format
115
+ .replace('YYYY', year)
116
+ .replace('MM', month)
117
+ .replace('DD', day)
118
+ .replace('HH', hours)
119
+ .replace('mm', minutes)
120
+ .replace('ss', seconds);
121
+ }
122
+
123
+ /**
124
+ * 延迟函数
125
+ */
126
+ function delay(ms) {
127
+ return new Promise(resolve => setTimeout(resolve, ms));
128
+ }
129
+
130
+ /**
131
+ * 分页处理
132
+ */
133
+ async function paginate(fetchFunction, params = {}, pageSize = 100) {
134
+ let allItems = [];
135
+ let pageToken = null;
136
+ let hasMore = true;
137
+ let page = 1;
138
+
139
+ while (hasMore) {
140
+ try {
141
+ const response = await fetchFunction({
142
+ ...params,
143
+ page_size: pageSize,
144
+ page_token: pageToken
145
+ });
146
+
147
+ if (response.data && response.data.items) {
148
+ allItems = allItems.concat(response.data.items);
149
+
150
+ if (response.data.has_more && response.data.page_token) {
151
+ pageToken = response.data.page_token;
152
+ page++;
153
+
154
+ // 避免速率限制
155
+ await delay(100);
156
+ } else {
157
+ hasMore = false;
158
+ }
159
+ } else {
160
+ hasMore = false;
161
+ }
162
+ } catch (error) {
163
+ console.error(`分页获取第 ${page} 页时出错:`, error.message);
164
+ hasMore = false;
165
+ }
166
+ }
167
+
168
+ return allItems;
169
+ }
170
+
171
+ /**
172
+ * 构建字段值
173
+ */
174
+ function buildFieldValue(fieldType, value) {
175
+ switch (fieldType) {
176
+ case 'text':
177
+ return value;
178
+ case 'number':
179
+ return Number(value);
180
+ case 'single_select':
181
+ return { name: value };
182
+ case 'multi_select':
183
+ return Array.isArray(value) ? value.map(v => ({ name: v })) : [{ name: value }];
184
+ case 'date':
185
+ return { start: formatDate(value, 'YYYY-MM-DD') };
186
+ case 'person':
187
+ return Array.isArray(value) ? value.map(id => ({ id })) : [{ id: value }];
188
+ case 'checkbox':
189
+ return Boolean(value);
190
+ case 'url':
191
+ return value;
192
+ case 'phone':
193
+ return value;
194
+ case 'email':
195
+ return value;
196
+ case 'attachment':
197
+ // 附件需要先上传
198
+ return value;
199
+ default:
200
+ return value;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * 解析记录字段
206
+ */
207
+ function parseRecordFields(record, fieldsMap) {
208
+ const result = {};
209
+
210
+ if (!record.fields) return result;
211
+
212
+ for (const [fieldId, value] of Object.entries(record.fields)) {
213
+ const fieldInfo = fieldsMap[fieldId];
214
+ if (fieldInfo) {
215
+ result[fieldInfo.field_name] = parseFieldValue(fieldInfo.type, value);
216
+ } else {
217
+ result[fieldId] = value;
218
+ }
219
+ }
220
+
221
+ return result;
222
+ }
223
+
224
+ /**
225
+ * 解析字段值
226
+ */
227
+ function parseFieldValue(fieldType, value) {
228
+ if (value === null || value === undefined) return null;
229
+
230
+ switch (fieldType) {
231
+ case 'text':
232
+ return String(value);
233
+ case 'number':
234
+ return Number(value);
235
+ case 'single_select':
236
+ return value?.name || value;
237
+ case 'multi_select':
238
+ return Array.isArray(value) ? value.map(v => v.name || v) : [value];
239
+ case 'date':
240
+ return value?.start || value;
241
+ case 'person':
242
+ return Array.isArray(value) ? value.map(p => p.id || p) : [value];
243
+ case 'checkbox':
244
+ return Boolean(value);
245
+ default:
246
+ return value;
247
+ }
248
+ }
249
+
250
+ module.exports = {
251
+ getEnvVar,
252
+ getAccessToken,
253
+ validateRequired,
254
+ parseJsonInput,
255
+ formatDate,
256
+ delay,
257
+ paginate,
258
+ buildFieldValue,
259
+ parseRecordFields,
260
+ parseFieldValue
261
+ };