skill-base 2.0.1

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 (51) hide show
  1. package/README.md +141 -0
  2. package/bin/skill-base.js +53 -0
  3. package/data/.gitkeep +0 -0
  4. package/package.json +36 -0
  5. package/src/database.js +119 -0
  6. package/src/index.js +88 -0
  7. package/src/middleware/.gitkeep +0 -0
  8. package/src/middleware/admin.js +23 -0
  9. package/src/middleware/auth.js +96 -0
  10. package/src/middleware/error.js +23 -0
  11. package/src/models/.gitkeep +0 -0
  12. package/src/models/skill.js +57 -0
  13. package/src/models/user.js +130 -0
  14. package/src/models/version.js +57 -0
  15. package/src/routes/.gitkeep +0 -0
  16. package/src/routes/auth.js +173 -0
  17. package/src/routes/collaborators.js +260 -0
  18. package/src/routes/init.js +86 -0
  19. package/src/routes/publish.js +108 -0
  20. package/src/routes/skills.js +119 -0
  21. package/src/routes/users.js +169 -0
  22. package/src/utils/.gitkeep +0 -0
  23. package/src/utils/crypto.js +35 -0
  24. package/src/utils/permission.js +45 -0
  25. package/src/utils/zip.js +35 -0
  26. package/static/admin/users.html +593 -0
  27. package/static/cli-code.html +203 -0
  28. package/static/css/.gitkeep +0 -0
  29. package/static/css/style.css +1567 -0
  30. package/static/diff.html +466 -0
  31. package/static/file.html +443 -0
  32. package/static/index.html +251 -0
  33. package/static/js/.gitkeep +0 -0
  34. package/static/js/admin/users.js +346 -0
  35. package/static/js/app.js +508 -0
  36. package/static/js/auth.js +151 -0
  37. package/static/js/cli-code.js +184 -0
  38. package/static/js/collaborators.js +283 -0
  39. package/static/js/diff.js +540 -0
  40. package/static/js/file.js +619 -0
  41. package/static/js/i18n.js +739 -0
  42. package/static/js/index.js +168 -0
  43. package/static/js/publish.js +718 -0
  44. package/static/js/settings.js +124 -0
  45. package/static/js/setup.js +157 -0
  46. package/static/js/skill.js +808 -0
  47. package/static/login.html +82 -0
  48. package/static/publish.html +459 -0
  49. package/static/settings.html +163 -0
  50. package/static/setup.html +101 -0
  51. package/static/skill.html +851 -0
@@ -0,0 +1,466 @@
1
+ <!DOCTYPE html>
2
+ <html lang="">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title data-i18n="diff.title">版本对比 - Skill Base</title>
7
+ <link rel="stylesheet" href="/css/style.css">
8
+ <!-- diff2html 样式 -->
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/diff2html@3.4.47/bundles/css/diff2html.min.css">
10
+ <style>
11
+ /* 面包屑导航 */
12
+ .breadcrumb {
13
+ display: flex;
14
+ align-items: center;
15
+ gap: var(--spacing-sm);
16
+ font-size: 0.875rem;
17
+ color: var(--text-secondary);
18
+ margin-bottom: var(--spacing-lg);
19
+ }
20
+
21
+ .breadcrumb a {
22
+ color: var(--text-secondary);
23
+ }
24
+
25
+ .breadcrumb a:hover {
26
+ color: var(--primary-color);
27
+ }
28
+
29
+ .breadcrumb-separator {
30
+ color: var(--text-muted);
31
+ }
32
+
33
+ .breadcrumb-current {
34
+ color: var(--text-color);
35
+ font-weight: 500;
36
+ }
37
+
38
+ /* 顶部控制栏 */
39
+ .diff-controls {
40
+ background-color: var(--white);
41
+ border-radius: var(--radius);
42
+ box-shadow: var(--shadow);
43
+ padding: var(--spacing-lg);
44
+ margin-bottom: var(--spacing-lg);
45
+ }
46
+
47
+ .diff-controls-row {
48
+ display: flex;
49
+ align-items: center;
50
+ gap: var(--spacing-md);
51
+ flex-wrap: wrap;
52
+ }
53
+
54
+ .diff-controls-row + .diff-controls-row {
55
+ margin-top: var(--spacing-md);
56
+ }
57
+
58
+ .diff-control-group {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: var(--spacing-sm);
62
+ }
63
+
64
+ .diff-control-label {
65
+ font-size: 0.875rem;
66
+ color: var(--text-secondary);
67
+ font-weight: 500;
68
+ white-space: nowrap;
69
+ }
70
+
71
+ .diff-control-group select {
72
+ min-width: 150px;
73
+ }
74
+
75
+ .diff-arrow {
76
+ font-size: 1.25rem;
77
+ color: var(--text-muted);
78
+ }
79
+
80
+ /* 视图切换按钮组 */
81
+ .btn-group {
82
+ display: flex;
83
+ border: 1px solid var(--border-color);
84
+ border-radius: var(--radius);
85
+ overflow: hidden;
86
+ }
87
+
88
+ .btn-group .btn {
89
+ border: none;
90
+ border-radius: 0;
91
+ border-right: 1px solid var(--border-color);
92
+ }
93
+
94
+ .btn-group .btn:last-child {
95
+ border-right: none;
96
+ }
97
+
98
+ .btn-group .btn.active {
99
+ background-color: var(--primary-color);
100
+ color: var(--white);
101
+ }
102
+
103
+ /* 文件路径显示 */
104
+ .diff-file-path {
105
+ font-family: 'SF Mono', Monaco, 'Courier New', monospace;
106
+ font-size: 0.875rem;
107
+ color: var(--text-secondary);
108
+ background-color: var(--bg-color);
109
+ padding: var(--spacing-xs) var(--spacing-sm);
110
+ border-radius: var(--radius-sm);
111
+ word-break: break-all;
112
+ }
113
+
114
+ /* Diff 统计信息 */
115
+ .diff-stats {
116
+ display: flex;
117
+ align-items: center;
118
+ gap: var(--spacing-md);
119
+ padding: var(--spacing-md) var(--spacing-lg);
120
+ background-color: var(--bg-color);
121
+ border-radius: var(--radius);
122
+ margin-bottom: var(--spacing-lg);
123
+ font-size: 0.875rem;
124
+ }
125
+
126
+ .diff-stats-added {
127
+ color: var(--success-color);
128
+ font-weight: 500;
129
+ }
130
+
131
+ .diff-stats-removed {
132
+ color: var(--error-color);
133
+ font-weight: 500;
134
+ }
135
+
136
+ .diff-stats-files {
137
+ color: var(--text-secondary);
138
+ }
139
+
140
+ /* Diff 渲染区域 */
141
+ .diff-output-container {
142
+ background-color: var(--white);
143
+ border-radius: var(--radius);
144
+ box-shadow: var(--shadow);
145
+ overflow: hidden;
146
+ margin-bottom: var(--spacing-lg);
147
+ }
148
+
149
+ .diff-output-header {
150
+ padding: var(--spacing-md) var(--spacing-lg);
151
+ border-bottom: 1px solid var(--border-color);
152
+ background-color: var(--bg-color);
153
+ font-weight: 500;
154
+ }
155
+
156
+ #diff-output {
157
+ overflow-x: auto;
158
+ }
159
+
160
+ /* diff2html 样式覆盖 */
161
+ .d2h-wrapper {
162
+ border: none !important;
163
+ }
164
+
165
+ .d2h-file-wrapper {
166
+ border: none !important;
167
+ border-radius: 0 !important;
168
+ margin-bottom: 0 !important;
169
+ }
170
+
171
+ .d2h-file-header {
172
+ background-color: var(--bg-color) !important;
173
+ border-bottom: 1px solid var(--border-color) !important;
174
+ }
175
+
176
+ /* 变更文件列表 */
177
+ .changed-files {
178
+ background-color: var(--white);
179
+ border-radius: var(--radius);
180
+ box-shadow: var(--shadow);
181
+ margin-bottom: var(--spacing-lg);
182
+ }
183
+
184
+ .changed-files-header {
185
+ padding: var(--spacing-md) var(--spacing-lg);
186
+ border-bottom: 1px solid var(--border-color);
187
+ font-weight: 600;
188
+ color: var(--text-color);
189
+ display: flex;
190
+ align-items: center;
191
+ gap: var(--spacing-sm);
192
+ }
193
+
194
+ .changed-files-list {
195
+ max-height: 400px;
196
+ overflow-y: auto;
197
+ }
198
+
199
+ .changed-file-item {
200
+ display: flex;
201
+ align-items: center;
202
+ gap: var(--spacing-md);
203
+ padding: var(--spacing-sm) var(--spacing-lg);
204
+ border-bottom: 1px solid var(--border-color);
205
+ cursor: pointer;
206
+ transition: var(--transition);
207
+ }
208
+
209
+ .changed-file-item:last-child {
210
+ border-bottom: none;
211
+ }
212
+
213
+ .changed-file-item:hover {
214
+ background-color: var(--bg-color);
215
+ }
216
+
217
+ .changed-file-item.active {
218
+ background-color: var(--primary-light);
219
+ }
220
+
221
+ .changed-file-status {
222
+ font-size: 0.75rem;
223
+ font-weight: 500;
224
+ padding: 0.125rem 0.5rem;
225
+ border-radius: var(--radius-sm);
226
+ }
227
+
228
+ .changed-file-status.added {
229
+ background-color: var(--success-light);
230
+ color: var(--success-color);
231
+ }
232
+
233
+ .changed-file-status.deleted {
234
+ background-color: var(--error-light);
235
+ color: var(--error-color);
236
+ }
237
+
238
+ .changed-file-status.modified {
239
+ background-color: var(--warning-light);
240
+ color: var(--warning-color);
241
+ }
242
+
243
+ .changed-file-path {
244
+ flex: 1;
245
+ font-family: 'SF Mono', Monaco, 'Courier New', monospace;
246
+ font-size: 0.8125rem;
247
+ color: var(--text-color);
248
+ overflow: hidden;
249
+ text-overflow: ellipsis;
250
+ white-space: nowrap;
251
+ }
252
+
253
+ /* 空状态 */
254
+ .empty-state {
255
+ text-align: center;
256
+ padding: var(--spacing-xl);
257
+ color: var(--text-secondary);
258
+ }
259
+
260
+ .empty-state-icon {
261
+ font-size: 3rem;
262
+ margin-bottom: var(--spacing-md);
263
+ opacity: 0.5;
264
+ }
265
+
266
+ /* Loading */
267
+ .loading-content {
268
+ display: flex;
269
+ align-items: center;
270
+ justify-content: center;
271
+ min-height: 200px;
272
+ }
273
+
274
+ .loading-overlay {
275
+ position: relative;
276
+ }
277
+
278
+ .loading-overlay::before {
279
+ content: '';
280
+ position: absolute;
281
+ top: 0;
282
+ left: 0;
283
+ right: 0;
284
+ bottom: 0;
285
+ background-color: rgba(255, 255, 255, 0.8);
286
+ z-index: 10;
287
+ }
288
+
289
+ .loading-overlay::after {
290
+ content: '';
291
+ position: absolute;
292
+ top: 50%;
293
+ left: 50%;
294
+ transform: translate(-50%, -50%);
295
+ width: 32px;
296
+ height: 32px;
297
+ border: 3px solid var(--border-color);
298
+ border-top-color: var(--primary-color);
299
+ border-radius: 50%;
300
+ animation: spin 0.8s linear infinite;
301
+ z-index: 11;
302
+ }
303
+
304
+ /* 二进制文件提示 */
305
+ .binary-diff-notice {
306
+ text-align: center;
307
+ padding: var(--spacing-xl);
308
+ color: var(--text-secondary);
309
+ }
310
+
311
+ @media (max-width: 768px) {
312
+ .diff-controls-row {
313
+ flex-direction: column;
314
+ align-items: stretch;
315
+ }
316
+
317
+ .diff-control-group {
318
+ width: 100%;
319
+ }
320
+
321
+ .diff-control-group select {
322
+ flex: 1;
323
+ }
324
+
325
+ .diff-arrow {
326
+ transform: rotate(90deg);
327
+ align-self: center;
328
+ }
329
+
330
+ .btn-group {
331
+ width: 100%;
332
+ }
333
+
334
+ .btn-group .btn {
335
+ flex: 1;
336
+ }
337
+ }
338
+ </style>
339
+ </head>
340
+ <body class="app-devtools">
341
+ <!-- 导航栏 -->
342
+ <nav class="navbar">
343
+ <div class="container">
344
+ <a href="/" class="navbar-brand">
345
+ <svg class="navbar-brand-icon" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
346
+ <span>Skill Base</span>
347
+ </a>
348
+ <div class="navbar-nav">
349
+ <a href="/" data-i18n="nav.home">首页</a>
350
+ <a href="/publish.html" class="hide-mobile" data-i18n="nav.publish">发布</a>
351
+ </div>
352
+ </div>
353
+ </nav>
354
+
355
+ <!-- 页面内容 -->
356
+ <main class="page-content">
357
+ <div class="container">
358
+ <!-- 面包屑导航 -->
359
+ <nav class="breadcrumb">
360
+ <a href="/" data-i18n="skill.breadcrumbHome">首页</a>
361
+ <span class="breadcrumb-separator">›</span>
362
+ <a href="#" id="breadcrumb-skill" data-i18n="state.loading">加载中...</a>
363
+ <span class="breadcrumb-separator">›</span>
364
+ <span class="breadcrumb-current" data-i18n="diff.breadcrumbCurrent">版本对比</span>
365
+ </nav>
366
+
367
+ <!-- 顶部控制栏 -->
368
+ <div class="diff-controls">
369
+ <div class="diff-controls-row">
370
+ <div class="diff-control-group">
371
+ <span class="diff-control-label" data-i18n="diff.versionA">版本 A (旧):</span>
372
+ <select id="version-a" onchange="onVersionChange()">
373
+ <option value="" data-i18n="diff.selectVersion">选择版本...</option>
374
+ </select>
375
+ </div>
376
+
377
+ <span class="diff-arrow">→</span>
378
+
379
+ <div class="diff-control-group">
380
+ <span class="diff-control-label" data-i18n="diff.versionB">版本 B (新):</span>
381
+ <select id="version-b" onchange="onVersionChange()">
382
+ <option value="" data-i18n="diff.selectVersion">选择版本...</option>
383
+ </select>
384
+ </div>
385
+
386
+ <button class="btn btn-primary" onclick="performDiff()">
387
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
388
+ <polyline points="23 4 23 10 17 10"/>
389
+ <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/>
390
+ </svg>
391
+ <span data-i18n="diff.recalculate">重新计算</span>
392
+ </button>
393
+ </div>
394
+
395
+ <div class="diff-controls-row">
396
+ <div class="diff-control-group">
397
+ <span class="diff-control-label" data-i18n="diff.file">文件:</span>
398
+ <span id="current-file-path" class="diff-file-path" data-i18n="diff.allFiles">全部文件</span>
399
+ </div>
400
+
401
+ <div class="btn-group" style="margin-left: auto;">
402
+ <button class="btn btn-secondary active" id="btn-side-by-side" onclick="toggleOutputFormat('side-by-side')" data-i18n="diff.sideBySide">
403
+ 左右对比
404
+ </button>
405
+ <button class="btn btn-secondary" id="btn-line-by-line" onclick="toggleOutputFormat('line-by-line')" data-i18n="diff.unified">
406
+ 统一视图
407
+ </button>
408
+ </div>
409
+ </div>
410
+ </div>
411
+
412
+ <!-- Diff 统计信息 -->
413
+ <div class="diff-stats" id="diff-stats" style="display: none;">
414
+ <span class="diff-stats-added" id="stats-added">+0 行</span>
415
+ <span class="diff-stats-removed" id="stats-removed">-0 行</span>
416
+ <span class="diff-stats-files" id="stats-files">0 个文件变更</span>
417
+ </div>
418
+
419
+ <!-- 变更文件列表(整体对比时显示) -->
420
+ <div class="changed-files" id="changed-files" style="display: none;">
421
+ <div class="changed-files-header">
422
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
423
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
424
+ <polyline points="14 2 14 8 20 8"/>
425
+ </svg>
426
+ <span data-i18n="diff.changedFiles">变更文件列表</span>
427
+ </div>
428
+ <div class="changed-files-list" id="changed-files-list">
429
+ <!-- 动态渲染 -->
430
+ </div>
431
+ </div>
432
+
433
+ <!-- Diff 渲染区域 -->
434
+ <div class="diff-output-container" id="diff-output-container">
435
+ <div id="diff-output">
436
+ <div class="empty-state">
437
+ <div class="empty-state-icon">📊</div>
438
+ <p data-i18n="diff.empty">选择两个版本后点击"重新计算"查看差异</p>
439
+ </div>
440
+ </div>
441
+ </div>
442
+
443
+ <!-- 底部操作栏 -->
444
+ <div style="display: flex; gap: var(--spacing-md); flex-wrap: wrap;">
445
+ <button class="btn btn-secondary" onclick="goToSkillDetail()">
446
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
447
+ <line x1="19" y1="12" x2="5" y2="12"/>
448
+ <polyline points="12 19 5 12 12 5"/>
449
+ </svg>
450
+ <span data-i18n="diff.back">返回详情页</span>
451
+ </button>
452
+ </div>
453
+ </div>
454
+ </main>
455
+
456
+ <!-- CDN 库 -->
457
+ <script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
458
+ <script src="https://cdn.jsdelivr.net/npm/diff@5.1.0/dist/diff.min.js"></script>
459
+ <script src="https://cdn.jsdelivr.net/npm/diff2html@3.4.47/bundles/js/diff2html-ui.min.js"></script>
460
+
461
+ <!-- 引入 JS -->
462
+ <script src="/js/i18n.js"></script>
463
+ <script src="/js/app.js"></script>
464
+ <script src="/js/diff.js"></script>
465
+ </body>
466
+ </html>