skillfree 0.1.40 → 0.1.62

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.
package/bin/skillfree.js CHANGED
@@ -105,13 +105,41 @@ program
105
105
  .command('update')
106
106
  .description('更新 skillfree 到最新版本')
107
107
  .action(async () => {
108
- const { execSync } = require('child_process')
109
- console.log('🔄 正在更新 skillfree...')
108
+ const { execSync, spawnSync } = require('child_process')
109
+ const currentVersion = pkg.version
110
+
111
+ // 查最新版本号
112
+ let latestVersion = '(unknown)'
110
113
  try {
111
- execSync('npm install -g skillfree@latest', { stdio: 'inherit' })
112
- console.log(`✅ 更新成功`)
113
- } catch (e) {
114
- console.error('❌ 更新失败,请手动执行:npm install -g skillfree@latest')
114
+ latestVersion = execSync('npm show skillfree version 2>/dev/null', { encoding: 'utf8' }).trim()
115
+ } catch {}
116
+
117
+ console.log(`\n🦞 SkillFree 更新`)
118
+ console.log(` 当前版本:v${currentVersion}`)
119
+ console.log(` 最新版本:v${latestVersion}`)
120
+
121
+ if (currentVersion === latestVersion) {
122
+ console.log(`\n✅ 已经是最新版本,无需更新\n`)
123
+ process.exit(0)
124
+ }
125
+
126
+ console.log(`\n🔄 正在更新 v${currentVersion} → v${latestVersion} ...\n`)
127
+
128
+ // 尝试直接安装,失败则 sudo
129
+ const tryInstall = (useSudo) => {
130
+ const cmd = useSudo
131
+ ? ['sudo', 'npm', 'install', '-g', 'skillfree@latest']
132
+ : ['npm', 'install', '-g', 'skillfree@latest']
133
+ const result = spawnSync(cmd[0], cmd.slice(1), { stdio: 'inherit' })
134
+ return result.status === 0
135
+ }
136
+
137
+ if (tryInstall(false) || tryInstall(true)) {
138
+ console.log(`\n✅ 更新成功!已升级到 v${latestVersion}`)
139
+ console.log(` 新功能请查看:https://skillfree.tech\n`)
140
+ } else {
141
+ console.error('\n❌ 更新失败,请手动执行:')
142
+ console.error(' npm install -g skillfree@latest\n')
115
143
  process.exit(1)
116
144
  }
117
145
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillfree",
3
- "version": "0.1.40",
3
+ "version": "0.1.62",
4
4
  "description": "🦞 一个 API,满足所有龙虾技能需求",
5
5
  "main": "bin/skillfree.js",
6
6
  "bin": {
@@ -163,7 +163,104 @@ async function pilot(flags) {
163
163
  return
164
164
  }
165
165
 
166
- throw new Error(`不支持的类型: ${type}\n可选: chat | image | video | ocr | presentation`)
166
+ // ── PHARMA(摩熵数科医药数据查询)───────────────────────────────────────────
167
+ if (type === 'pharma') {
168
+ const pharmaModel = model || 'bcpm-drug-dev'
169
+
170
+ // 构建 search 参数(从 flags 透传)
171
+ const search = {}
172
+ if (flags.drug || flags['drug-name']) search.drug_name = flags.drug || flags['drug-name']
173
+ if (flags.target) search.target = flags.target
174
+ if (flags.company) search.company = flags.company
175
+ if (flags.indication) search.indication = flags.indication
176
+ if (flags.status) search.highest_status_cn = flags.status
177
+ if (flags.title) search.title = flags.title
178
+ if (flags.sponsor) search.sponsor = flags.sponsor
179
+
180
+ const inputs = pharmaModel === 'bcpm-drug-detail'
181
+ ? { keyid: flags.keyid ?? prompt } // detail 模式需要 keyid
182
+ : { search, page: Number(flags.page ?? 1) }
183
+
184
+ const res = await post('/pharma', { model: pharmaModel, inputs })
185
+
186
+ if (res.error) {
187
+ console.error(`❌ 查询失败: ${res.error.message}`)
188
+ return
189
+ }
190
+
191
+ if (output) {
192
+ fs.writeFileSync(output, JSON.stringify(res.data, null, 2))
193
+ console.log(`✅ 已保存到 ${output}`)
194
+ return
195
+ }
196
+
197
+ // 格式化输出
198
+ const data = res.data
199
+ console.log(`\n📊 ${pharmaModel} 查询结果\n${'─'.repeat(50)}`)
200
+
201
+ if (pharmaModel === 'bcpm-drug-detail') {
202
+ const b = data.baseinfo
203
+ if (b) {
204
+ console.log(`药品: ${b.drug_name_cn || b.drug_name}`)
205
+ console.log(`全球研发阶段: ${b.highest_status_cn}`)
206
+ console.log(`中国研发阶段: ${b.highest_status_china_cn}`)
207
+ console.log(`靶点: ${(b.target_json || []).map(t => t.name_short).join(', ')}`)
208
+ console.log(`作用机制: ${(b.target_action_cn || []).join(', ')}`)
209
+ console.log(`治疗领域: ${(b.therapy_area_cn || []).join(', ')}`)
210
+ }
211
+ if (data.indications?.list?.length) {
212
+ console.log(`\n适应症研发现状(前5条):`)
213
+ data.indications.list.slice(0, 5).forEach(i => {
214
+ console.log(` • ${i.indication?.cn} | ${i.status?.cn} | ${i.company?.cn} | ${i.country?.cn}`)
215
+ })
216
+ }
217
+ if (data.sales?.list?.length) {
218
+ console.log(`\n全球销售额(最新3年):`)
219
+ data.sales.list.slice(0, 3).forEach(s => {
220
+ console.log(` • ${s.year} ${s.company}: ${s.sales}`)
221
+ })
222
+ }
223
+ } else {
224
+ const list = data.list || []
225
+ const total = data.total || list.length
226
+ console.log(`共 ${total} 条结果,当前显示 ${list.length} 条\n`)
227
+
228
+ if (pharmaModel === 'bcpm-drug-dev') {
229
+ list.slice(0, 10).forEach((item, i) => {
230
+ console.log(`${i + 1}. ${item.drug_name_cn || item.drug_name} (${item.drug_name})`)
231
+ console.log(` keyid: ${item.keyid}`)
232
+ console.log(` 首家: ${item.originator_company_cn || item.originator_company}`)
233
+ console.log(` 全球阶段: ${item.highest_status_cn} 中国阶段: ${item.highest_status_china_cn}`)
234
+ console.log(` 靶点: ${(item.target_short || []).join(', ')}`)
235
+ console.log(` 适应症: ${(item.indication || []).slice(0, 3).join(', ')}`)
236
+ console.log('')
237
+ })
238
+ } else if (pharmaModel === 'bcpm-cn-evaluation') {
239
+ list.slice(0, 10).forEach((item, i) => {
240
+ console.log(`${i + 1}. [${item.acceptances_number}] ${item.drug_name}`)
241
+ console.log(` 企业: ${(item.company || []).join(', ')}`)
242
+ console.log('')
243
+ })
244
+ } else if (pharmaModel === 'bcpm-cn-clinical') {
245
+ list.slice(0, 10).forEach((item, i) => {
246
+ console.log(`${i + 1}. [${item.registration_number}] ${item.drug_name_cn}`)
247
+ console.log(` 适应症: ${item.indication} 分期: ${item.trial_phase}`)
248
+ console.log(` 申办: ${(item.sponsor || []).map(s => s.name).join(', ')}`)
249
+ console.log('')
250
+ })
251
+ } else {
252
+ // 通用输出
253
+ list.slice(0, 10).forEach((item, i) => {
254
+ console.log(`${i + 1}. ${JSON.stringify(item).slice(0, 120)}`)
255
+ })
256
+ }
257
+ }
258
+
259
+ console.log(`${'─'.repeat(50)}`)
260
+ return
261
+ }
262
+
263
+ throw new Error(`不支持的类型: ${type}\n可选: chat | image | video | ocr | presentation | pharma`)
167
264
  }
168
265
 
169
266
  module.exports = { pilot }