skill-base 2.0.4 → 2.0.7

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 (46) hide show
  1. package/README.md +177 -115
  2. package/bin/skill-base.js +29 -3
  3. package/package.json +4 -1
  4. package/src/cappy.js +416 -0
  5. package/src/database.js +11 -0
  6. package/src/index.js +125 -25
  7. package/src/middleware/auth.js +96 -32
  8. package/src/routes/auth.js +1 -1
  9. package/src/routes/skills.js +10 -5
  10. package/src/utils/zip.js +15 -4
  11. package/static/android-chrome-192x192.png +0 -0
  12. package/static/android-chrome-512x512.png +0 -0
  13. package/static/apple-touch-icon.png +0 -0
  14. package/static/assets/index-BkwByEEp.css +1 -0
  15. package/static/assets/index-CB4Diul3.js +209 -0
  16. package/static/favicon-16x16.png +0 -0
  17. package/static/favicon-32x32.png +0 -0
  18. package/static/favicon.ico +0 -0
  19. package/static/favicon.svg +14 -0
  20. package/static/index.html +18 -248
  21. package/static/site.webmanifest +1 -0
  22. package/static/admin/users.html +0 -593
  23. package/static/cli-code.html +0 -203
  24. package/static/css/.gitkeep +0 -0
  25. package/static/css/style.css +0 -1567
  26. package/static/diff.html +0 -466
  27. package/static/file.html +0 -443
  28. package/static/js/.gitkeep +0 -0
  29. package/static/js/admin/users.js +0 -346
  30. package/static/js/app.js +0 -508
  31. package/static/js/auth.js +0 -151
  32. package/static/js/cli-code.js +0 -184
  33. package/static/js/collaborators.js +0 -283
  34. package/static/js/diff.js +0 -540
  35. package/static/js/file.js +0 -619
  36. package/static/js/i18n.js +0 -739
  37. package/static/js/index.js +0 -168
  38. package/static/js/publish.js +0 -718
  39. package/static/js/settings.js +0 -124
  40. package/static/js/setup.js +0 -157
  41. package/static/js/skill.js +0 -808
  42. package/static/login.html +0 -82
  43. package/static/publish.html +0 -459
  44. package/static/settings.html +0 -163
  45. package/static/setup.html +0 -101
  46. package/static/skill.html +0 -851
@@ -1,124 +0,0 @@
1
- /**
2
- * 账户设置页面脚本
3
- */
4
-
5
- // 页面初始化
6
- document.addEventListener('DOMContentLoaded', async () => {
7
- const user = await getCurrentUser();
8
- if (!user) {
9
- // 未登录,checkAuth 会自动跳转
10
- return;
11
- }
12
-
13
- renderNavbar(user);
14
- loadUserProfile();
15
- bindEvents();
16
- });
17
-
18
- // 绑定事件
19
- function bindEvents() {
20
- // 基本信息表单提交
21
- const profileForm = document.getElementById('profileForm');
22
- profileForm.addEventListener('submit', handleProfileUpdate);
23
-
24
- // 修改密码表单提交
25
- const passwordForm = document.getElementById('passwordForm');
26
- passwordForm.addEventListener('submit', handlePasswordChange);
27
- }
28
-
29
- // 加载用户资料
30
- async function loadUserProfile() {
31
- try {
32
- const user = await getCurrentUser(true); // 强制刷新
33
-
34
- if (user) {
35
- document.getElementById('username').value = user.username || '';
36
- document.getElementById('name').value = user.name || '';
37
- }
38
- } catch (error) {
39
- showToast(error.message || t('settings.loadFailed'), 'error');
40
- }
41
- }
42
-
43
- // 处理基本信息更新
44
- async function handleProfileUpdate(e) {
45
- e.preventDefault();
46
-
47
- const username = document.getElementById('username').value.trim();
48
- const name = document.getElementById('name').value.trim();
49
-
50
- if (!username || username.length < 1 || username.length > 50) {
51
- showToast(t('settings.usernameLenError'), 'warning');
52
- return;
53
- }
54
-
55
- const submitBtn = document.getElementById('saveProfileBtn');
56
- submitBtn.disabled = true;
57
- submitBtn.innerHTML = '<span class="spinner spinner-sm"></span> ' + t('settings.saving');
58
-
59
- try {
60
- const result = await api('/auth/me', {
61
- method: 'PATCH',
62
- body: JSON.stringify({ username, name })
63
- });
64
-
65
- if (result.ok) {
66
- showToast(t('settings.updateSuccess'), 'success');
67
- // 刷新当前用户缓存
68
- await getCurrentUser(true);
69
- }
70
- } catch (error) {
71
- showToast(error.message || t('settings.updateFailed'), 'error');
72
- } finally {
73
- submitBtn.disabled = false;
74
- submitBtn.textContent = t('settings.saveBtn');
75
- }
76
- }
77
-
78
- // 处理密码修改
79
- async function handlePasswordChange(e) {
80
- e.preventDefault();
81
-
82
- const oldPassword = document.getElementById('oldPassword').value;
83
- const newPassword = document.getElementById('newPassword').value;
84
- const confirmPassword = document.getElementById('confirmPassword').value;
85
-
86
- if (!oldPassword) {
87
- showToast(t('settings.noOldPassword'), 'warning');
88
- return;
89
- }
90
-
91
- if (newPassword.length < 6) {
92
- showToast(t('settings.newPassTooShort'), 'warning');
93
- return;
94
- }
95
-
96
- if (newPassword !== confirmPassword) {
97
- showToast(t('settings.passMismatch'), 'warning');
98
- return;
99
- }
100
-
101
- const submitBtn = document.getElementById('changePasswordBtn');
102
- submitBtn.disabled = true;
103
- submitBtn.innerHTML = '<span class="spinner spinner-sm"></span> ' + t('settings.changing');
104
-
105
- try {
106
- const result = await apiPost('/auth/me/change-password', {
107
- old_password: oldPassword,
108
- new_password: newPassword
109
- });
110
-
111
- if (result.ok) {
112
- showToast(t('settings.changeSuccess'), 'success');
113
- // 清空密码表单
114
- document.getElementById('oldPassword').value = '';
115
- document.getElementById('newPassword').value = '';
116
- document.getElementById('confirmPassword').value = '';
117
- }
118
- } catch (error) {
119
- showToast(error.message || t('settings.changeFailed'), 'error');
120
- } finally {
121
- submitBtn.disabled = false;
122
- submitBtn.textContent = t('settings.changePasswordBtn');
123
- }
124
- }
@@ -1,157 +0,0 @@
1
- /**
2
- * Skill Base - Initial Setup Page
3
- * Handles first-time admin account creation
4
- */
5
-
6
- (function() {
7
- 'use strict';
8
-
9
- const API_BASE = '/api/v1';
10
-
11
- // DOM elements
12
- const form = document.getElementById('setupForm');
13
- const errorEl = document.getElementById('setupError');
14
- const successEl = document.getElementById('setupSuccess');
15
- const submitBtn = document.getElementById('setupButton');
16
- const usernameInput = document.getElementById('username');
17
- const passwordInput = document.getElementById('password');
18
- const confirmPasswordInput = document.getElementById('confirmPassword');
19
-
20
- // Check if system is already initialized
21
- async function checkInitStatus() {
22
- try {
23
- const res = await fetch(`${API_BASE}/init/status`);
24
- const data = await res.json();
25
-
26
- if (data.initialized) {
27
- // Already initialized, redirect to home
28
- window.location.href = '/';
29
- }
30
- } catch (err) {
31
- console.error('Failed to check init status:', err);
32
- }
33
- }
34
-
35
- // Show error message
36
- function showError(message) {
37
- errorEl.textContent = message;
38
- errorEl.style.display = 'block';
39
- successEl.style.display = 'none';
40
- }
41
-
42
- // Show success message
43
- function showSuccess(message) {
44
- successEl.textContent = message;
45
- successEl.style.display = 'block';
46
- errorEl.style.display = 'none';
47
- }
48
-
49
- // Clear messages
50
- function clearMessages() {
51
- errorEl.style.display = 'none';
52
- successEl.style.display = 'none';
53
- }
54
-
55
- // Set button loading state
56
- function setLoading(loading) {
57
- submitBtn.disabled = loading;
58
- const btnText = submitBtn.querySelector('span');
59
- if (loading) {
60
- btnText.textContent = window._t ? window._t('setup.loading') : '创建中...';
61
- } else {
62
- btnText.textContent = window._t ? window._t('setup.submit') : '创建管理员账号';
63
- }
64
- }
65
-
66
- // Handle form submit
67
- async function handleSubmit(e) {
68
- e.preventDefault();
69
- clearMessages();
70
-
71
- const username = usernameInput.value.trim();
72
- const password = passwordInput.value;
73
- const confirmPassword = confirmPasswordInput.value;
74
-
75
- // Validate
76
- if (!username) {
77
- showError(window._t ? window._t('setup.errUsername') : '请输入用户名');
78
- usernameInput.focus();
79
- return;
80
- }
81
-
82
- if (username.length < 3 || username.length > 50) {
83
- showError(window._t ? window._t('setup.errUsernameLength') : '用户名需要 3-50 个字符');
84
- usernameInput.focus();
85
- return;
86
- }
87
-
88
- if (!password) {
89
- showError(window._t ? window._t('setup.errPassword') : '请输入密码');
90
- passwordInput.focus();
91
- return;
92
- }
93
-
94
- if (password.length < 6) {
95
- showError(window._t ? window._t('setup.errPasswordLength') : '密码至少需要 6 个字符');
96
- passwordInput.focus();
97
- return;
98
- }
99
-
100
- if (password !== confirmPassword) {
101
- showError(window._t ? window._t('setup.errPasswordMismatch') : '两次输入的密码不一致');
102
- confirmPasswordInput.focus();
103
- return;
104
- }
105
-
106
- setLoading(true);
107
-
108
- try {
109
- const res = await fetch(`${API_BASE}/init/setup`, {
110
- method: 'POST',
111
- headers: { 'Content-Type': 'application/json' },
112
- body: JSON.stringify({ username, password })
113
- });
114
-
115
- const data = await res.json();
116
-
117
- if (!res.ok) {
118
- throw new Error(data.error || 'Setup failed');
119
- }
120
-
121
- // Success
122
- showSuccess(window._t ? window._t('setup.success') : '管理员账号创建成功,即将跳转到登录页...');
123
- form.reset();
124
-
125
- // Redirect to login after 2 seconds
126
- setTimeout(() => {
127
- window.location.href = '/login';
128
- }, 2000);
129
-
130
- } catch (err) {
131
- showError(err.message || (window._t ? window._t('setup.errFailed') : '创建失败,请重试'));
132
- } finally {
133
- setLoading(false);
134
- }
135
- }
136
-
137
- // Initialize
138
- function init() {
139
- // Apply i18n if available
140
- if (window.applyI18n) {
141
- window.applyI18n();
142
- }
143
-
144
- // Check init status
145
- checkInitStatus();
146
-
147
- // Bind form submit
148
- form.addEventListener('submit', handleSubmit);
149
- }
150
-
151
- // Run on DOM ready
152
- if (document.readyState === 'loading') {
153
- document.addEventListener('DOMContentLoaded', init);
154
- } else {
155
- init();
156
- }
157
- })();