tolingcode 2026.3.9 → 2026.3.11
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/README.md +74 -300
- package/bin/tolingcode.js +48 -11
- package/package.json +11 -3
- package/QUICKSTART.md +0 -196
- package/scripts/publish-skill.ps1 +0 -74
- package/scripts/publish.bat +0 -30
- package/server/registry.js +0 -220
package/README.md
CHANGED
|
@@ -1,364 +1,138 @@
|
|
|
1
|
-
```{=html}
|
|
2
1
|
<p align="center">
|
|
3
|
-
|
|
4
|
-
`<img src="docs/logo.png" width="180">`{=html}
|
|
5
|
-
```{=html}
|
|
2
|
+
<img src="https://raw.githubusercontent.com/tolingcode/tolingcode/main/docs/logo.png" width="120" alt="TolingCode Logo">
|
|
6
3
|
</p>
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
```{=html}
|
|
10
4
|
<p align="center">
|
|
11
|
-
|
|
12
|
-
`<img src="docs/banner.png" width="100%">`{=html}
|
|
13
|
-
```{=html}
|
|
5
|
+
<img src="https://raw.githubusercontent.com/tolingcode/tolingcode/main/docs/banner.png" alt="TolingCode banner">
|
|
14
6
|
</p>
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
|
|
17
8
|
|
|
18
|
-
```{=html}
|
|
19
|
-
<h1 align="center">
|
|
20
|
-
```
|
|
21
|
-
TolingCode
|
|
22
|
-
```{=html}
|
|
23
|
-
</h1>
|
|
24
|
-
```
|
|
25
|
-
```{=html}
|
|
26
|
-
<p align="center">
|
|
27
|
-
```
|
|
28
|
-
AI Agent CLI for Cross‑Border E‑commerce Automation
|
|
29
|
-
```{=html}
|
|
30
|
-
</p>
|
|
31
|
-
```
|
|
32
|
-
```{=html}
|
|
33
|
-
<p align="center">
|
|
34
|
-
```
|
|
35
9
|

|
|
36
10
|

|
|
37
11
|

|
|
38
|
-

|
|
39
|
-

|
|
40
|
-
|
|
41
|
-
```{=html}
|
|
42
|
-
</p>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
12
|
|
|
46
13
|
# TolingCode CLI
|
|
47
14
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
它为跨境卖家和企业提供 **本地化 AI
|
|
51
|
-
自动化能力**,支持订单履约、库存管理、产品刊登、广告管理、数据分析等核心业务。
|
|
52
|
-
|
|
53
|
-
同时 **tolingcode skill 库** 可以兼容 **OpenClaw AI
|
|
54
|
-
Agent**,用于构建跨境企业 **AI 数字员工**。
|
|
55
|
-
|
|
56
|
-
------------------------------------------------------------------------
|
|
15
|
+
**跨境电商私人 AI 助手** - 在个人设备上运行的本地化 AI 自动化工具 , tolingcode Skills完全兼容openclaw。
|
|
57
16
|
|
|
58
|
-
|
|
17
|
+
为跨境卖家提供订单履约、库存管理、产品刊登、广告管理、数据分析等核心业务能力。
|
|
59
18
|
|
|
60
|
-
|
|
61
|
-
------------ -------------------------------
|
|
62
|
-
本地运行 AI 在个人设备运行,不依赖云端
|
|
63
|
-
永不离线 本地模型可持续运行
|
|
64
|
-
响应迅速 避免云端延迟
|
|
65
|
-
数据本地化 API 数据可同步到本地数据库
|
|
66
|
-
AI 员工 自动执行跨境电商任务
|
|
67
|
-
Skill 生态 支持安装技能扩展能力
|
|
19
|
+
---
|
|
68
20
|
|
|
69
|
-
|
|
21
|
+
## 安装
|
|
70
22
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
## 电商平台技能
|
|
74
|
-
|
|
75
|
-
功能 描述
|
|
76
|
-
---------- ------------------
|
|
77
|
-
订单履约 自动处理订单发货
|
|
78
|
-
智能备货 AI 预测库存
|
|
79
|
-
发票确认 自动核对发票
|
|
80
|
-
发货确认 同步物流信息
|
|
81
|
-
订单获取 拉取平台订单
|
|
82
|
-
库存编辑 修改库存
|
|
83
|
-
产品上架 自动发布商品
|
|
84
|
-
价格管理 修改产品价格
|
|
85
|
-
广告管理 自动调整广告
|
|
86
|
-
数据分析 获取平台报告
|
|
87
|
-
|
|
88
|
-
------------------------------------------------------------------------
|
|
89
|
-
|
|
90
|
-
## 海外仓技能
|
|
91
|
-
|
|
92
|
-
功能 描述
|
|
93
|
-
------------ -----------------
|
|
94
|
-
实时库存 获取仓库库存
|
|
95
|
-
出库单 查询出库
|
|
96
|
-
入库单 查询入库
|
|
97
|
-
创建出库单 创建订单出库
|
|
98
|
-
LTL 出运 创建 LTL 运输单
|
|
99
|
-
运费查询 获取物流费用
|
|
100
|
-
|
|
101
|
-
------------------------------------------------------------------------
|
|
102
|
-
|
|
103
|
-
## 物流技能
|
|
104
|
-
|
|
105
|
-
功能
|
|
106
|
-
----------
|
|
107
|
-
物流报价
|
|
108
|
-
创建面单
|
|
109
|
-
物流跟踪
|
|
110
|
-
|
|
111
|
-
支持物流:
|
|
112
|
-
|
|
113
|
-
- FedEx
|
|
114
|
-
- UPS
|
|
115
|
-
- DHL
|
|
116
|
-
- Amazon Logistics
|
|
117
|
-
- ITTRACK
|
|
118
|
-
|
|
119
|
-
------------------------------------------------------------------------
|
|
120
|
-
|
|
121
|
-
# 安装
|
|
122
|
-
|
|
123
|
-
## 安装最新版本
|
|
124
|
-
|
|
125
|
-
``` bash
|
|
23
|
+
```bash
|
|
24
|
+
# 安装最新版本
|
|
126
25
|
npm install -g tolingcode@latest
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## 安装指定版本
|
|
130
26
|
|
|
131
|
-
|
|
132
|
-
npm install -g tolingcode@2026.03.
|
|
27
|
+
# 安装指定版本
|
|
28
|
+
npm install -g tolingcode@2026.03.09
|
|
133
29
|
```
|
|
134
30
|
|
|
135
|
-
|
|
31
|
+
**当前版本**: 2026.03.09
|
|
136
32
|
|
|
137
|
-
|
|
33
|
+
---
|
|
138
34
|
|
|
139
|
-
|
|
35
|
+
## 使用
|
|
140
36
|
|
|
141
|
-
|
|
37
|
+
### 安装技能 (Skill)
|
|
142
38
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
安装最新版本
|
|
146
|
-
|
|
147
|
-
``` bash
|
|
39
|
+
```bash
|
|
40
|
+
# 安装技能
|
|
148
41
|
tolingcode install skills weather
|
|
149
|
-
```
|
|
150
42
|
|
|
151
|
-
安装指定版本
|
|
152
|
-
|
|
153
|
-
``` bash
|
|
154
|
-
tolingcode install skills weather -v 2026.03.06
|
|
43
|
+
# 安装指定版本
|
|
44
|
+
tolingcode install skills weather -v 2026.03.08
|
|
155
45
|
```
|
|
156
46
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
## 安装应用 (App)
|
|
47
|
+
### 安装应用 (App)
|
|
160
48
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
``` bash
|
|
49
|
+
```bash
|
|
50
|
+
# 安装到当前目录
|
|
164
51
|
tolingcode install apps myapp
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
全局安装
|
|
168
52
|
|
|
169
|
-
|
|
53
|
+
# 全局安装
|
|
170
54
|
tolingcode install apps myapp -g
|
|
171
55
|
```
|
|
172
56
|
|
|
173
|
-
|
|
57
|
+
### 查看和搜索
|
|
174
58
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
列出所有包
|
|
178
|
-
|
|
179
|
-
``` bash
|
|
59
|
+
```bash
|
|
60
|
+
# 列出所有包
|
|
180
61
|
tolingcode list
|
|
181
|
-
```
|
|
182
62
|
|
|
183
|
-
只列出技能
|
|
184
|
-
|
|
185
|
-
``` bash
|
|
63
|
+
# 只列出技能
|
|
186
64
|
tolingcode list skills
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
只列出应用
|
|
190
65
|
|
|
191
|
-
|
|
192
|
-
tolingcode
|
|
66
|
+
# 搜索技能 订单发货
|
|
67
|
+
tolingcode search order-fulfillment
|
|
193
68
|
```
|
|
194
69
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
## 搜索技能
|
|
198
|
-
|
|
199
|
-
``` bash
|
|
200
|
-
tolingcode search weather
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
------------------------------------------------------------------------
|
|
204
|
-
|
|
205
|
-
# 发布技能(开发者)
|
|
206
|
-
|
|
207
|
-
``` bash
|
|
208
|
-
tolingcode publish ./my-skill \
|
|
209
|
-
--type skills \
|
|
210
|
-
--name my-skill \
|
|
211
|
-
--version 2026.03.06
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
------------------------------------------------------------------------
|
|
215
|
-
|
|
216
|
-
# 版本规范
|
|
217
|
-
|
|
218
|
-
推荐使用 **日期版本号**
|
|
219
|
-
|
|
220
|
-
YYYY.MM.DD
|
|
70
|
+
---
|
|
221
71
|
|
|
222
|
-
|
|
72
|
+
## 核心能力
|
|
223
73
|
|
|
224
|
-
|
|
225
|
-
------------ ------------------
|
|
226
|
-
2026.03.06 2026年3月6日版本
|
|
227
|
-
latest 最新版本
|
|
74
|
+
### 电商平台技能
|
|
228
75
|
|
|
229
|
-
|
|
76
|
+
| 功能 | 描述 |
|
|
77
|
+
|------|------|
|
|
78
|
+
| 订单履约 | 自动处理订单发货 |
|
|
79
|
+
| 智能备货 | AI 预测库存 |
|
|
80
|
+
| 产品上架 | 自动发布商品 |
|
|
81
|
+
| 价格管理 | 修改产品价格 |
|
|
82
|
+
| 广告管理 | 自动调整广告 |
|
|
83
|
+
| 数据分析 | 获取平台报告 |
|
|
230
84
|
|
|
231
|
-
|
|
85
|
+
### 海外仓技能
|
|
232
86
|
|
|
233
|
-
|
|
87
|
+
| 功能 | 描述 |
|
|
88
|
+
|------|------|
|
|
89
|
+
| 实时库存 | 获取仓库库存 |
|
|
90
|
+
| 出入库单 | 查询入库/出库 |
|
|
91
|
+
| 创建出库单 | 创建订单出库 |
|
|
92
|
+
| LTL 出运 | 创建 LTL 运输单 |
|
|
93
|
+
| 运费查询 | 获取物流费用 |
|
|
234
94
|
|
|
235
|
-
|
|
236
|
-
export TOLINGCODE_REGISTRY=https://toling.me/api/registry
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
自定义 workspace
|
|
240
|
-
|
|
241
|
-
``` bash
|
|
242
|
-
export OPENCLAW_WORKSPACE=/path/to/workspace
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
------------------------------------------------------------------------
|
|
95
|
+
### 物流技能
|
|
246
96
|
|
|
247
|
-
|
|
97
|
+
- 物流报价、创建面单、物流跟踪
|
|
98
|
+
- 支持:FedEx、UPS、DHL、Amazon Logistics、ITTRACK
|
|
248
99
|
|
|
249
|
-
|
|
100
|
+
---
|
|
250
101
|
|
|
251
|
-
|
|
252
|
-
cd tolingcode
|
|
253
|
-
npm link
|
|
254
|
-
tolingcode --help
|
|
255
|
-
```
|
|
102
|
+
## 发布技能 (开发者)
|
|
256
103
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
104
|
+
```bash
|
|
105
|
+
tolingcode publish ./my-skill \
|
|
106
|
+
--type skills \
|
|
107
|
+
--name my-skill \
|
|
108
|
+
--version 2026.03.09
|
|
262
109
|
```
|
|
263
110
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
# 项目结构
|
|
267
|
-
|
|
268
|
-
tolingcode
|
|
269
|
-
│
|
|
270
|
-
├── bin
|
|
271
|
-
│ └── tolingcode.js
|
|
272
|
-
│
|
|
273
|
-
├── docs
|
|
274
|
-
│ └── SERVER.md
|
|
275
|
-
│
|
|
276
|
-
├── server
|
|
277
|
-
│ └── registry.js
|
|
278
|
-
│
|
|
279
|
-
├── scripts
|
|
280
|
-
│ └── publish-skill.ps1
|
|
281
|
-
│
|
|
282
|
-
├── package.json
|
|
283
|
-
└── README.md
|
|
284
|
-
|
|
285
|
-
------------------------------------------------------------------------
|
|
286
|
-
|
|
287
|
-
# 支持跨境平台
|
|
288
|
-
|
|
289
|
-
## 主流电商平台
|
|
290
|
-
|
|
291
|
-
平台
|
|
292
|
-
---------------
|
|
293
|
-
Amazon
|
|
294
|
-
eBay
|
|
295
|
-
AliExpress
|
|
296
|
-
Wish
|
|
297
|
-
Shopee
|
|
298
|
-
Lazada
|
|
299
|
-
Mercado Libre
|
|
300
|
-
Etsy
|
|
301
|
-
Wayfair
|
|
302
|
-
Newegg
|
|
303
|
-
Temu
|
|
304
|
-
Shein
|
|
305
|
-
TikTok Shop
|
|
306
|
-
|
|
307
|
-
------------------------------------------------------------------------
|
|
308
|
-
|
|
309
|
-
## 独立站平台
|
|
310
|
-
|
|
311
|
-
平台
|
|
312
|
-
-------------
|
|
313
|
-
Shopify
|
|
314
|
-
WooCommerce
|
|
315
|
-
Magento
|
|
316
|
-
BigCommerce
|
|
317
|
-
|
|
318
|
-
------------------------------------------------------------------------
|
|
319
|
-
|
|
320
|
-
## 大型零售平台
|
|
321
|
-
|
|
322
|
-
平台
|
|
323
|
-
------------
|
|
324
|
-
Walmart
|
|
325
|
-
Target
|
|
326
|
-
Costco
|
|
327
|
-
Best Buy
|
|
328
|
-
Home Depot
|
|
329
|
-
Lowe's
|
|
330
|
-
|
|
331
|
-
------------------------------------------------------------------------
|
|
111
|
+
### 版本规范
|
|
332
112
|
|
|
333
|
-
|
|
113
|
+
使用日期版本号:`YYYY.MM.DD`
|
|
334
114
|
|
|
335
|
-
|
|
115
|
+
---
|
|
336
116
|
|
|
337
|
-
|
|
338
|
-
---------- -------------
|
|
339
|
-
物流仓 中通国际
|
|
340
|
-
电商仓 Walmart WFS
|
|
341
|
-
货代仓 马士基
|
|
342
|
-
第三方仓 RMS 红鼠
|
|
117
|
+
## 支持平台
|
|
343
118
|
|
|
344
|
-
|
|
119
|
+
**电商平台**: Amazon、eBay、AliExpress、Wish、Shopee、Lazada、Mercado Libre、Etsy、Wayfair、TikTok Shop 等
|
|
345
120
|
|
|
346
|
-
|
|
121
|
+
**独立站**: Shopify、WooCommerce、Magento、BigCommerce
|
|
347
122
|
|
|
348
|
-
|
|
349
|
-
---------- -------------------
|
|
350
|
-
Registry https://toling.me
|
|
351
|
-
源代码 GitHub (待添加)
|
|
352
|
-
问题反馈 GitHub Issues
|
|
123
|
+
**零售平台**: Walmart、Target、Costco、Best Buy 等
|
|
353
124
|
|
|
354
|
-
|
|
125
|
+
**海外仓**: 支持 100+ 海外仓系统 (中通国际、Walmart WFS、马士基、RMS 红鼠等)
|
|
355
126
|
|
|
356
|
-
|
|
127
|
+
---
|
|
357
128
|
|
|
358
|
-
|
|
129
|
+
## 相关链接
|
|
359
130
|
|
|
360
|
-
|
|
131
|
+
- **Registry**: https://toling.me
|
|
132
|
+
- **GitHub**: https://github.com/tolingcode/tolingcode
|
|
133
|
+
- **问题反馈**: GitHub Issues
|
|
361
134
|
|
|
362
|
-
|
|
135
|
+
---
|
|
363
136
|
|
|
364
|
-
|
|
137
|
+
**作者**: 韩宝军 (TolingCode)
|
|
138
|
+
**License**: MIT
|
package/bin/tolingcode.js
CHANGED
|
@@ -16,15 +16,15 @@ const REGISTRY_URL = process.env.TOLINGCODE_REGISTRY || 'https://toling.me/api/r
|
|
|
16
16
|
|
|
17
17
|
program
|
|
18
18
|
.name('tolingcode')
|
|
19
|
-
.description('TolingCode CLI -
|
|
20
|
-
.version(pkg.version);
|
|
19
|
+
.description('TolingCode CLI - 跨境电商 AI 助手技能管理工具')
|
|
20
|
+
.version(pkg.version, '-v, --version', '显示版本号');
|
|
21
21
|
|
|
22
22
|
// install command
|
|
23
23
|
program
|
|
24
24
|
.command('install <type> <name>')
|
|
25
|
-
.description('
|
|
26
|
-
.option('-v, --version <version>', '
|
|
27
|
-
.option('-g, --global', '
|
|
25
|
+
.description('安装技能或应用')
|
|
26
|
+
.option('-v, --version <version>', '指定版本 (默认:latest)')
|
|
27
|
+
.option('-g, --global', '全局安装 (仅 apps)')
|
|
28
28
|
.action(async (type, name, options) => {
|
|
29
29
|
const version = options.version || 'latest';
|
|
30
30
|
|
|
@@ -114,7 +114,7 @@ program
|
|
|
114
114
|
// list command - list available skills/apps
|
|
115
115
|
program
|
|
116
116
|
.command('list [type]')
|
|
117
|
-
.description('
|
|
117
|
+
.description('列出可用的技能或应用 (skills | apps | all)')
|
|
118
118
|
.action(async (type) => {
|
|
119
119
|
console.log(chalk.blue('\n📦 Available packages:\n'));
|
|
120
120
|
|
|
@@ -160,7 +160,7 @@ program
|
|
|
160
160
|
// search command
|
|
161
161
|
program
|
|
162
162
|
.command('search <query>')
|
|
163
|
-
.description('
|
|
163
|
+
.description('搜索技能或应用')
|
|
164
164
|
.action(async (query) => {
|
|
165
165
|
console.log(chalk.blue(`\n🔍 Searching for: ${query}\n`));
|
|
166
166
|
|
|
@@ -189,10 +189,10 @@ program
|
|
|
189
189
|
// publish command - for publishing skills/apps to registry
|
|
190
190
|
program
|
|
191
191
|
.command('publish <path>')
|
|
192
|
-
.description('
|
|
193
|
-
.option('--type <type>', '
|
|
194
|
-
.option('--name <name>', '
|
|
195
|
-
.option('--version <version>', '
|
|
192
|
+
.description('发布技能或应用到 registry')
|
|
193
|
+
.option('--type <type>', '包类型 (skills 或 apps)', 'skills')
|
|
194
|
+
.option('--name <name>', '包名称')
|
|
195
|
+
.option('--version <version>', '包版本号')
|
|
196
196
|
.action(async (pkgPath, options) => {
|
|
197
197
|
const absPath = path.resolve(pkgPath);
|
|
198
198
|
|
|
@@ -228,4 +228,41 @@ program
|
|
|
228
228
|
console.log(chalk.gray(' See: docs/PUBLISH.md for details'));
|
|
229
229
|
});
|
|
230
230
|
|
|
231
|
+
// examples command
|
|
232
|
+
program
|
|
233
|
+
.command('examples')
|
|
234
|
+
.description('显示使用示例')
|
|
235
|
+
.action(() => {
|
|
236
|
+
console.log(`
|
|
237
|
+
${chalk.bold('常用命令示例:')}
|
|
238
|
+
|
|
239
|
+
${chalk.green('1. 安装技能')}
|
|
240
|
+
$ tolingcode install skills gigacloud-warehouse
|
|
241
|
+
$ tolingcode install skills order-fulfillment
|
|
242
|
+
$ tolingcode install skills weather -v 2026.3.8
|
|
243
|
+
|
|
244
|
+
${chalk.green('2. 列出技能')}
|
|
245
|
+
$ tolingcode list skills
|
|
246
|
+
$ tolingcode list apps
|
|
247
|
+
$ tolingcode list
|
|
248
|
+
|
|
249
|
+
${chalk.green('3. 搜索技能')}
|
|
250
|
+
$ tolingcode search 电商
|
|
251
|
+
$ tolingcode search gigacloud
|
|
252
|
+
$ tolingcode search order
|
|
253
|
+
|
|
254
|
+
${chalk.green('4. 发布技能')}
|
|
255
|
+
$ tolingcode publish ./skills/gigacloud-warehouse --type skills --name gigacloud-warehouse --version 2026.3.8
|
|
256
|
+
|
|
257
|
+
${chalk.green('5. 查看帮助')}
|
|
258
|
+
$ tolingcode --help
|
|
259
|
+
$ tolingcode install --help
|
|
260
|
+
$ tolingcode search --help
|
|
261
|
+
|
|
262
|
+
${chalk.green('6. 查看版本')}
|
|
263
|
+
$ tolingcode -v
|
|
264
|
+
$ tolingcode --version
|
|
265
|
+
`);
|
|
266
|
+
});
|
|
267
|
+
|
|
231
268
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tolingcode",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.3.11",
|
|
4
4
|
"description": "TolingCode CLI - Install skills and apps from toling.me",
|
|
5
5
|
"main": "bin/tolingcode.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"bin",
|
|
8
|
+
"docs",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
6
11
|
"bin": {
|
|
7
12
|
"tolingcode": "bin/tolingcode.js",
|
|
8
13
|
"tlc": "bin/tolingcode.js"
|
|
@@ -16,10 +21,13 @@
|
|
|
16
21
|
"author": "TolingCode",
|
|
17
22
|
"license": "MIT",
|
|
18
23
|
"dependencies": {
|
|
19
|
-
"
|
|
24
|
+
"axios": "^1.6.0",
|
|
20
25
|
"chalk": "^4.1.2",
|
|
26
|
+
"commander": "^11.0.0",
|
|
27
|
+
"cors": "^2.8.6",
|
|
28
|
+
"express": "^5.2.1",
|
|
29
|
+
"multer": "^2.1.1",
|
|
21
30
|
"ora": "^5.4.1",
|
|
22
|
-
"axios": "^1.6.0",
|
|
23
31
|
"tar": "^6.2.0"
|
|
24
32
|
},
|
|
25
33
|
"engines": {
|
package/QUICKSTART.md
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# TolingCode 快速开始指南
|
|
2
|
-
|
|
3
|
-
## 🎯 目标
|
|
4
|
-
|
|
5
|
-
创建一个类似 `clawhub` 的 CLI 工具,通过 `toling.me` 托管和分发 skills 和 apps。
|
|
6
|
-
|
|
7
|
-
## 📦 使用流程
|
|
8
|
-
|
|
9
|
-
### 1. 用户安装 CLI
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install -g tolingcode@latest
|
|
13
|
-
# 或指定版本
|
|
14
|
-
npm install -g tolingcode@2026.03.06
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### 2. 用户安装 Skill
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
tolingcode install skills weather
|
|
21
|
-
tolingcode install skills weather -v 2026.03.06
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### 3. 开发者发布 Skill
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
# 方法 1: 使用 publish 命令(需要 API 支持)
|
|
28
|
-
tolingcode publish ./my-skill --type skills --name my-skill --version 2026.03.06
|
|
29
|
-
|
|
30
|
-
# 方法 2: 手动上传
|
|
31
|
-
tar -czf my-skill-2026.03.06.tar.gz -C ./my-skill .
|
|
32
|
-
scp my-skill-2026.03.06.tar.gz user@toling.me:/var/www/toling.me/packages/skills/
|
|
33
|
-
# 然后更新 registry.json
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## 🚀 部署步骤
|
|
37
|
-
|
|
38
|
-
### 第一步:准备 toling.me 服务器
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
# SSH 登录服务器
|
|
42
|
-
ssh user@toling.me
|
|
43
|
-
|
|
44
|
-
# 创建目录
|
|
45
|
-
sudo mkdir -p /var/www/toling.me/{packages/skills,packages/apps,api}
|
|
46
|
-
sudo chown -R $USER:$USER /var/www/toling.me
|
|
47
|
-
|
|
48
|
-
# 安装 Node.js (如果没有)
|
|
49
|
-
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
|
50
|
-
sudo apt-get install -y nodejs
|
|
51
|
-
|
|
52
|
-
# 安装依赖
|
|
53
|
-
cd /var/www/toling.me/api
|
|
54
|
-
npm init -y
|
|
55
|
-
npm install express multer
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 第二步:部署服务端代码
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
# 上传 registry.js 到服务器
|
|
62
|
-
scp registry.js user@toling.me:/var/www/toling.me/api/
|
|
63
|
-
|
|
64
|
-
# 创建 systemd 服务
|
|
65
|
-
sudo tee /etc/systemd/system/tolingcode-registry.service > /dev/null <<EOF
|
|
66
|
-
[Unit]
|
|
67
|
-
Description=TolingCode Registry Server
|
|
68
|
-
After=network.target
|
|
69
|
-
|
|
70
|
-
[Service]
|
|
71
|
-
Type=simple
|
|
72
|
-
User=www-data
|
|
73
|
-
WorkingDirectory=/var/www/toling.me/api
|
|
74
|
-
ExecStart=/usr/bin/node registry.js
|
|
75
|
-
Restart=on-failure
|
|
76
|
-
|
|
77
|
-
[Install]
|
|
78
|
-
WantedBy=multi-user.target
|
|
79
|
-
EOF
|
|
80
|
-
|
|
81
|
-
# 启动服务
|
|
82
|
-
sudo systemctl daemon-reload
|
|
83
|
-
sudo systemctl enable tolingcode-registry
|
|
84
|
-
sudo systemctl start tolingcode-registry
|
|
85
|
-
sudo systemctl status tolingcode-registry
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 第三步:配置 Nginx
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
# 编辑 Nginx 配置
|
|
92
|
-
sudo nano /etc/nginx/sites-available/toling.me
|
|
93
|
-
|
|
94
|
-
# 添加以下内容:
|
|
95
|
-
server {
|
|
96
|
-
listen 443 ssl;
|
|
97
|
-
server_name toling.me;
|
|
98
|
-
|
|
99
|
-
ssl_certificate /etc/letsencrypt/live/toling.me/fullchain.pem;
|
|
100
|
-
ssl_certificate_key /etc/letsencrypt/live/toling.me/privkey.pem;
|
|
101
|
-
|
|
102
|
-
root /var/www/toling.me;
|
|
103
|
-
|
|
104
|
-
# API
|
|
105
|
-
location /api/ {
|
|
106
|
-
proxy_pass http://localhost:3000;
|
|
107
|
-
proxy_set_header Host $host;
|
|
108
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
109
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
# Packages
|
|
113
|
-
location /packages/ {
|
|
114
|
-
alias /var/www/toling.me/packages/;
|
|
115
|
-
autoindex on;
|
|
116
|
-
add_header Content-Type application/octet-stream;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
# 测试并重载
|
|
121
|
-
sudo nginx -t
|
|
122
|
-
sudo systemctl reload nginx
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### 第四步:发布 CLI 到 npm
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
# 在本地开发机器上
|
|
129
|
-
cd tolingcode
|
|
130
|
-
|
|
131
|
-
# 登录 npm
|
|
132
|
-
npm login
|
|
133
|
-
|
|
134
|
-
# 发布
|
|
135
|
-
npm version 1.0.0
|
|
136
|
-
npm publish
|
|
137
|
-
|
|
138
|
-
# 验证
|
|
139
|
-
npm view tolingcode
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### 第五步:发布第一个 Skill
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
# 创建测试 skill
|
|
146
|
-
mkdir -p test-skill
|
|
147
|
-
echo '{"name": "test", "description": "Test skill"}' > test-skill/SKILL.md
|
|
148
|
-
|
|
149
|
-
# 发布
|
|
150
|
-
cd tolingcode
|
|
151
|
-
node bin/tolingcode.js publish ../test-skill --type skills --name test-skill --version 2026.03.06
|
|
152
|
-
|
|
153
|
-
# 或者手动上传
|
|
154
|
-
tar -czf test-skill-2026.03.06.tar.gz -C ../test-skill .
|
|
155
|
-
scp test-skill-2026.03.06.tar.gz user@toling.me:/var/www/toling.me/packages/skills/
|
|
156
|
-
|
|
157
|
-
# 更新 registry.json (SSH 到服务器编辑)
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
## ✅ 测试
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
# 安装 CLI
|
|
164
|
-
npm install -g tolingcode@latest
|
|
165
|
-
|
|
166
|
-
# 列出可用技能
|
|
167
|
-
tolingcode list skills
|
|
168
|
-
|
|
169
|
-
# 安装技能
|
|
170
|
-
tolingcode install skills test-skill
|
|
171
|
-
|
|
172
|
-
# 验证安装
|
|
173
|
-
ls ~/.openclaw/workspace/skills/
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
## 📝 注意事项
|
|
177
|
-
|
|
178
|
-
1. **版本命名**: 使用 `YYYY.MM.DD` 格式,便于追踪发布日期
|
|
179
|
-
2. **认证**: 生产环境需要添加 API 认证(API Key 或 JWT)
|
|
180
|
-
3. **HTTPS**: 确保 toling.me 配置了 SSL 证书
|
|
181
|
-
4. **备份**: 定期备份 registry.json 和 packages 目录
|
|
182
|
-
5. **监控**: 添加日志和监控,跟踪下载量和错误
|
|
183
|
-
|
|
184
|
-
## 🔧 后续扩展
|
|
185
|
-
|
|
186
|
-
- [ ] 添加用户认证系统
|
|
187
|
-
- [ ] 支持私有包(需要 token)
|
|
188
|
-
- [ ] 添加下载统计
|
|
189
|
-
- [ ] Web 管理界面
|
|
190
|
-
- [ ] 自动版本递增
|
|
191
|
-
- [ ] 依赖管理
|
|
192
|
-
- [ ] 包签名验证
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
有问题?查看 `docs/SERVER.md` 获取详细服务端文档。
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env pwsh
|
|
2
|
-
# TolingCode Skill Publish Script (PowerShell)
|
|
3
|
-
# Usage: .\publish-skill.ps1 <skill-name> [version]
|
|
4
|
-
|
|
5
|
-
param(
|
|
6
|
-
[Parameter(Mandatory=$true)]
|
|
7
|
-
[string]$SkillName,
|
|
8
|
-
|
|
9
|
-
[string]$Version = (Get-Date -Format "yyyy.MM.dd"),
|
|
10
|
-
|
|
11
|
-
[string]$ServerHost = "iZwz91qi4kjnj5l58gbhj5Z",
|
|
12
|
-
[string]$ServerUser = "root",
|
|
13
|
-
[string]$SkillSource = "C:\Users\Administrator\.openclaw\workspace\skills"
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
Write-Host "📦 Publishing $SkillName@$Version" -ForegroundColor Blue
|
|
17
|
-
Write-Host ""
|
|
18
|
-
|
|
19
|
-
# 1. Check source exists
|
|
20
|
-
$sourcePath = Join-Path $SkillSource $SkillName
|
|
21
|
-
if (!(Test-Path $sourcePath)) {
|
|
22
|
-
Write-Host "❌ Skill not found: $sourcePath" -ForegroundColor Red
|
|
23
|
-
exit 1
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
Write-Host "✓ Source: $sourcePath" -ForegroundColor Green
|
|
27
|
-
|
|
28
|
-
# 2. Create tar.gz
|
|
29
|
-
$tarFile = "$SkillName-$Version.tar.gz"
|
|
30
|
-
Write-Host "📦 Creating $tarFile..." -ForegroundColor Yellow
|
|
31
|
-
tar -czf $tarFile -C $SkillSource $SkillName
|
|
32
|
-
|
|
33
|
-
if (!(Test-Path $tarFile)) {
|
|
34
|
-
Write-Host "❌ Failed to create tarball" -ForegroundColor Red
|
|
35
|
-
exit 1
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
Write-Host "✓ Created: $tarFile ($(Get-Item $tarFile).Length bytes)" -ForegroundColor Green
|
|
39
|
-
|
|
40
|
-
# 3. Upload to server
|
|
41
|
-
Write-Host "📤 Uploading to server..." -ForegroundColor Yellow
|
|
42
|
-
scp $tarFile "${ServerUser}@${ServerHost}:/var/www/toling.me/packages/skills/"
|
|
43
|
-
|
|
44
|
-
if ($LASTEXITCODE -ne 0) {
|
|
45
|
-
Write-Host "❌ Upload failed" -ForegroundColor Red
|
|
46
|
-
exit 1
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
Write-Host "✓ Uploaded to /var/www/toling.me/packages/skills/" -ForegroundColor Green
|
|
50
|
-
Write-Host ""
|
|
51
|
-
Write-Host "📝 Next step: Update registry.json on server" -ForegroundColor Yellow
|
|
52
|
-
Write-Host ""
|
|
53
|
-
Write-Host "SSH to server and run:" -ForegroundColor Gray
|
|
54
|
-
Write-Host @"
|
|
55
|
-
cat >> /var/www/toling.me/registry.json << 'EOF'
|
|
56
|
-
{
|
|
57
|
-
"skills": {
|
|
58
|
-
"$SkillName": {
|
|
59
|
-
"description": "$SkillName skill",
|
|
60
|
-
"latestVersion": "$Version",
|
|
61
|
-
"versions": {
|
|
62
|
-
"$Version": {
|
|
63
|
-
"publishedAt": "$(Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
"apps": {}
|
|
69
|
-
}
|
|
70
|
-
EOF
|
|
71
|
-
"@
|
|
72
|
-
|
|
73
|
-
Write-Host ""
|
|
74
|
-
Write-Host "🎉 Done!" -ForegroundColor Green
|
package/scripts/publish.bat
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
@echo off
|
|
2
|
-
REM TolingCode Publish Script (Windows)
|
|
3
|
-
REM Usage: publish.bat <skill-path> <name> [version]
|
|
4
|
-
|
|
5
|
-
SET SKILL_PATH=%1
|
|
6
|
-
SET NAME=%2
|
|
7
|
-
SET VERSION=%3
|
|
8
|
-
|
|
9
|
-
IF "%VERSION%"=="" (
|
|
10
|
-
REM Use today's date as version
|
|
11
|
-
FOR /F "tokens=2-4 delims=/ " %%A IN ('date /T') DO (SET VERSION=%%C.%%B.%%A)
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
ECHO Publishing %NAME%@%VERSION%...
|
|
15
|
-
|
|
16
|
-
REM Create tarball (requires tar.exe on Windows 10+)
|
|
17
|
-
tar -czf %NAME%-%VERSION%.tar.gz -C %SKILL_PATH% .
|
|
18
|
-
|
|
19
|
-
ECHO Created: %NAME%-%VERSION%.tar.gz
|
|
20
|
-
ECHO.
|
|
21
|
-
ECHO Next steps:
|
|
22
|
-
ECHO 1. Upload to toling.me: scp %NAME%-%VERSION%.tar.gz user@toling.me:/var/www/toling.me/packages/skills/
|
|
23
|
-
ECHO 2. Update registry.json on server
|
|
24
|
-
ECHO.
|
|
25
|
-
ECHO Or use the API (when implemented):
|
|
26
|
-
ECHO curl -X POST https://toling.me/api/registry/publish ^
|
|
27
|
-
ECHO -F "type=skills" ^
|
|
28
|
-
ECHO -F "name=%NAME%" ^
|
|
29
|
-
ECHO -F "version=%VERSION%" ^
|
|
30
|
-
ECHO -F "package=@%NAME%-%VERSION%.tar.gz"
|
package/server/registry.js
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
// TolingCode Registry Server - Simple Node.js Implementation
|
|
2
|
-
// Deploy this on toling.me
|
|
3
|
-
|
|
4
|
-
const express = require('express');
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const multer = require('multer');
|
|
8
|
-
const crypto = require('crypto');
|
|
9
|
-
|
|
10
|
-
const app = express();
|
|
11
|
-
const PORT = process.env.PORT || 3000;
|
|
12
|
-
|
|
13
|
-
// Paths
|
|
14
|
-
const BASE_DIR = process.env.REGISTRY_BASE_DIR || '/var/www/toling.me';
|
|
15
|
-
const REGISTRY_FILE = path.join(BASE_DIR, 'registry.json');
|
|
16
|
-
const PACKAGES_DIR = path.join(BASE_DIR, 'packages');
|
|
17
|
-
|
|
18
|
-
// Ensure directories exist
|
|
19
|
-
if (!fs.existsSync(PACKAGES_DIR)) {
|
|
20
|
-
fs.mkdirSync(path.join(PACKAGES_DIR, 'skills'), { recursive: true });
|
|
21
|
-
fs.mkdirSync(path.join(PACKAGES_DIR, 'apps'), { recursive: true });
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Initialize registry if not exists
|
|
25
|
-
if (!fs.existsSync(REGISTRY_FILE)) {
|
|
26
|
-
fs.writeFileSync(REGISTRY_FILE, JSON.stringify({ skills: {}, apps: {} }, null, 2));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Middleware
|
|
30
|
-
app.use(express.json());
|
|
31
|
-
const upload = multer({ dest: path.join(BASE_DIR, 'uploads') });
|
|
32
|
-
|
|
33
|
-
// Helper: Read registry
|
|
34
|
-
function getRegistry() {
|
|
35
|
-
return JSON.parse(fs.readFileSync(REGISTRY_FILE, 'utf-8'));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Helper: Write registry
|
|
39
|
-
function saveRegistry(data) {
|
|
40
|
-
fs.writeFileSync(REGISTRY_FILE, JSON.stringify(data, null, 2));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Helper: Calculate file hash
|
|
44
|
-
function hashFile(filePath) {
|
|
45
|
-
const content = fs.readFileSync(filePath);
|
|
46
|
-
return crypto.createHash('sha256').update(content).digest('hex');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// GET /api/registry/:type/:name - Get package info
|
|
50
|
-
app.get('/api/registry/:type/:name', (req, res) => {
|
|
51
|
-
const { type, name } = req.params;
|
|
52
|
-
const { version = 'latest' } = req.query;
|
|
53
|
-
|
|
54
|
-
if (!['skills', 'apps'].includes(type)) {
|
|
55
|
-
return res.status(400).json({ error: 'Invalid type. Use "skills" or "apps"' });
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const registry = getRegistry();
|
|
59
|
-
const pkg = registry[type]?.[name];
|
|
60
|
-
|
|
61
|
-
if (!pkg) {
|
|
62
|
-
return res.status(404).json({ error: `Package ${name} not found` });
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const ver = version === 'latest' ? pkg.latestVersion : version;
|
|
66
|
-
const verInfo = pkg.versions?.[ver];
|
|
67
|
-
|
|
68
|
-
if (!verInfo) {
|
|
69
|
-
return res.status(404).json({ error: `Version ${ver} not found` });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
res.json({
|
|
73
|
-
name,
|
|
74
|
-
type,
|
|
75
|
-
version: ver,
|
|
76
|
-
description: pkg.description || '',
|
|
77
|
-
downloadUrl: `https://toling.me/packages/${type}/${name}-${ver}.tar.gz`,
|
|
78
|
-
latestVersion: pkg.latestVersion,
|
|
79
|
-
versions: Object.keys(pkg.versions || {}).sort().reverse()
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// GET /api/registry/list - List all packages
|
|
84
|
-
app.get('/api/registry/list', (req, res) => {
|
|
85
|
-
const { type = 'all' } = req.query;
|
|
86
|
-
const registry = getRegistry();
|
|
87
|
-
const result = [];
|
|
88
|
-
|
|
89
|
-
const types = type === 'all' ? ['skills', 'apps'] : [type];
|
|
90
|
-
|
|
91
|
-
types.forEach(t => {
|
|
92
|
-
if (registry[t]) {
|
|
93
|
-
Object.entries(registry[t]).forEach(([name, pkg]) => {
|
|
94
|
-
result.push({
|
|
95
|
-
name,
|
|
96
|
-
type: t,
|
|
97
|
-
version: pkg.latestVersion,
|
|
98
|
-
description: pkg.description || '',
|
|
99
|
-
latestVersion: pkg.latestVersion
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
res.json(result);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// GET /api/registry/search - Search packages
|
|
109
|
-
app.get('/api/registry/search', (req, res) => {
|
|
110
|
-
const { q } = req.query;
|
|
111
|
-
if (!q) {
|
|
112
|
-
return res.status(400).json({ error: 'Query parameter "q" is required' });
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const registry = getRegistry();
|
|
116
|
-
const result = [];
|
|
117
|
-
const query = q.toLowerCase();
|
|
118
|
-
|
|
119
|
-
['skills', 'apps'].forEach(type => {
|
|
120
|
-
if (registry[type]) {
|
|
121
|
-
Object.entries(registry[type]).forEach(([name, pkg]) => {
|
|
122
|
-
if (name.toLowerCase().includes(query) ||
|
|
123
|
-
(pkg.description && pkg.description.toLowerCase().includes(query))) {
|
|
124
|
-
result.push({
|
|
125
|
-
name,
|
|
126
|
-
type,
|
|
127
|
-
version: pkg.latestVersion,
|
|
128
|
-
description: pkg.description || ''
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
res.json(result);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// POST /api/registry/publish - Publish a package (requires auth)
|
|
139
|
-
app.post('/api/registry/publish', upload.single('package'), (req, res) => {
|
|
140
|
-
// TODO: Add authentication (API key, JWT, etc.)
|
|
141
|
-
const { type, name, version } = req.body;
|
|
142
|
-
|
|
143
|
-
if (!type || !name || !version) {
|
|
144
|
-
return res.status(400).json({ error: 'Missing required fields: type, name, version' });
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (!['skills', 'apps'].includes(type)) {
|
|
148
|
-
return res.status(400).json({ error: 'Invalid type. Use "skills" or "apps"' });
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (!req.file) {
|
|
152
|
-
return res.status(400).json({ error: 'No package file uploaded' });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const registry = getRegistry();
|
|
156
|
-
|
|
157
|
-
// Initialize type if not exists
|
|
158
|
-
if (!registry[type]) {
|
|
159
|
-
registry[type] = {};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Initialize package if not exists
|
|
163
|
-
if (!registry[type][name]) {
|
|
164
|
-
registry[type][name] = {
|
|
165
|
-
description: req.body.description || '',
|
|
166
|
-
latestVersion: version,
|
|
167
|
-
versions: {}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Add version
|
|
172
|
-
const fileHash = hashFile(req.file.path);
|
|
173
|
-
registry[type][name].versions[version] = {
|
|
174
|
-
publishedAt: new Date().toISOString(),
|
|
175
|
-
hash: `sha256:${fileHash}`,
|
|
176
|
-
size: req.file.size
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
// Update latest version
|
|
180
|
-
registry[type][name].latestVersion = version;
|
|
181
|
-
|
|
182
|
-
// Move file to packages directory
|
|
183
|
-
const destDir = path.join(PACKAGES_DIR, type);
|
|
184
|
-
const destFile = path.join(destDir, `${name}-${version}.tar.gz`);
|
|
185
|
-
|
|
186
|
-
if (!fs.existsSync(destDir)) {
|
|
187
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
fs.renameSync(req.file.path, destFile);
|
|
191
|
-
|
|
192
|
-
// Save registry
|
|
193
|
-
saveRegistry(registry);
|
|
194
|
-
|
|
195
|
-
// Cleanup uploads dir
|
|
196
|
-
try {
|
|
197
|
-
fs.unlinkSync(req.file.path);
|
|
198
|
-
} catch (e) {}
|
|
199
|
-
|
|
200
|
-
res.json({
|
|
201
|
-
success: true,
|
|
202
|
-
name,
|
|
203
|
-
type,
|
|
204
|
-
version,
|
|
205
|
-
downloadUrl: `https://toling.me/packages/${type}/${name}-${version}.tar.gz`
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
// Serve static packages
|
|
210
|
-
app.use('/packages', express.static(path.join(BASE_DIR, 'packages')));
|
|
211
|
-
|
|
212
|
-
// Health check
|
|
213
|
-
app.get('/health', (req, res) => {
|
|
214
|
-
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
app.listen(PORT, () => {
|
|
218
|
-
console.log(`TolingCode Registry Server running on port ${PORT}`);
|
|
219
|
-
console.log(`Base directory: ${BASE_DIR}`);
|
|
220
|
-
});
|