@ian2018cs/agenthub 0.1.10 → 0.1.12
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/dist/assets/index-C_e8oVyx.js +151 -0
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/server/builtin-skills/html-deploy/SKILL.md +30 -0
- package/server/builtin-skills/html-deploy/scripts/deploy.py +36 -0
- package/server/builtin-skills/html-deploy/scripts/update.py +38 -0
- package/server/routes/auth.js +4 -0
- package/server/services/builtin-skills.js +35 -0
- package/dist/assets/index-BV3BueqH.js +0 -151
- package/server/builtin-skills/deploy-frontend/SKILL.md +0 -298
- package/server/builtin-skills/deploy-frontend/scripts/cleanup.py +0 -158
- package/server/builtin-skills/deploy-frontend/scripts/deploy.py +0 -216
package/dist/index.html
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
<!-- Prevent zoom on iOS -->
|
|
27
27
|
<meta name="format-detection" content="telephone=no" />
|
|
28
|
-
<script type="module" crossorigin src="/assets/index-
|
|
28
|
+
<script type="module" crossorigin src="/assets/index-C_e8oVyx.js"></script>
|
|
29
29
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-BeVl62c0.js">
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/assets/vendor-codemirror-C_VWDoZS.js">
|
|
31
31
|
<link rel="modulepreload" crossorigin href="/assets/vendor-utils-00TdZexr.js">
|
package/package.json
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: html-deploy
|
|
3
|
+
description: 将 HTML 内容部署为可访问的网页。使用场景:(1) 用户要求将生成的 HTML/网页部署上线或发布,(2) 用户要求更新已部署的页面内容,(3) 用户提到"部署"、"发布"、"上线"HTML 页面,(4) 用户要求预览生成的网页效果。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HTML Deploy
|
|
7
|
+
|
|
8
|
+
将 HTML 内容部署到远程服务,生成可访问的 URL。
|
|
9
|
+
|
|
10
|
+
## 使用流程
|
|
11
|
+
|
|
12
|
+
1. 根据用户需求生成完整的 HTML 页面,写入文件
|
|
13
|
+
2. 调用脚本部署或更新,传入该文件路径
|
|
14
|
+
3. 将返回的访问 URL 告知用户
|
|
15
|
+
|
|
16
|
+
### 部署新页面
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
python3 skills/html-deploy/scripts/deploy.py <html_file>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 更新已有页面
|
|
23
|
+
|
|
24
|
+
从之前的部署 URL 中提取 page_id(UUID 部分):
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
python3 skills/html-deploy/scripts/update.py <page_id> <html_file>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
page_id 不存在时会报 404 错误。
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""部署 HTML 文件为网页。
|
|
3
|
+
|
|
4
|
+
用法: deploy.py <html_file>
|
|
5
|
+
输出: 部署成功后的访问 URL
|
|
6
|
+
"""
|
|
7
|
+
import sys
|
|
8
|
+
import json
|
|
9
|
+
import urllib.request
|
|
10
|
+
|
|
11
|
+
API_BASE = "http://10.0.0.252:11004"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
if len(sys.argv) != 2:
|
|
16
|
+
print(f"用法: {sys.argv[0]} <html_file>", file=sys.stderr)
|
|
17
|
+
sys.exit(1)
|
|
18
|
+
|
|
19
|
+
with open(sys.argv[1], "r", encoding="utf-8") as f:
|
|
20
|
+
html = f.read()
|
|
21
|
+
|
|
22
|
+
data = json.dumps({"html": html}).encode("utf-8")
|
|
23
|
+
req = urllib.request.Request(
|
|
24
|
+
f"{API_BASE}/deploy",
|
|
25
|
+
data=data,
|
|
26
|
+
headers={"Content-Type": "application/json"},
|
|
27
|
+
method="POST",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
with urllib.request.urlopen(req) as resp:
|
|
31
|
+
result = json.loads(resp.read())
|
|
32
|
+
print(result["url"])
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""更新已部署的页面内容。
|
|
3
|
+
|
|
4
|
+
用法: update.py <page_id> <html_file>
|
|
5
|
+
输出: 更新成功后的访问 URL
|
|
6
|
+
"""
|
|
7
|
+
import sys
|
|
8
|
+
import json
|
|
9
|
+
import urllib.request
|
|
10
|
+
|
|
11
|
+
API_BASE = "http://10.0.0.252:11004"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
if len(sys.argv) != 3:
|
|
16
|
+
print(f"用法: {sys.argv[0]} <page_id> <html_file>", file=sys.stderr)
|
|
17
|
+
sys.exit(1)
|
|
18
|
+
|
|
19
|
+
page_id = sys.argv[1]
|
|
20
|
+
|
|
21
|
+
with open(sys.argv[2], "r", encoding="utf-8") as f:
|
|
22
|
+
html = f.read()
|
|
23
|
+
|
|
24
|
+
data = json.dumps({"html": html}).encode("utf-8")
|
|
25
|
+
req = urllib.request.Request(
|
|
26
|
+
f"{API_BASE}/deploy/{page_id}",
|
|
27
|
+
data=data,
|
|
28
|
+
headers={"Content-Type": "application/json"},
|
|
29
|
+
method="PUT",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
with urllib.request.urlopen(req) as resp:
|
|
33
|
+
result = json.loads(resp.read())
|
|
34
|
+
print(result["url"])
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if __name__ == "__main__":
|
|
38
|
+
main()
|
package/server/routes/auth.js
CHANGED
|
@@ -4,6 +4,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
4
4
|
import { userDb, verificationDb, domainWhitelistDb, usageDb } from '../database/db.js';
|
|
5
5
|
import { generateToken, authenticateToken } from '../middleware/auth.js';
|
|
6
6
|
import { initUserDirectories } from '../services/user-directories.js';
|
|
7
|
+
import { initBuiltinSkills } from '../services/builtin-skills.js';
|
|
7
8
|
import { sendVerificationCode, isSmtpConfigured } from '../services/email.js';
|
|
8
9
|
|
|
9
10
|
const router = express.Router();
|
|
@@ -115,6 +116,9 @@ router.post('/verify-code', async (req, res) => {
|
|
|
115
116
|
|
|
116
117
|
// Initialize user directories
|
|
117
118
|
await initUserDirectories(uuid);
|
|
119
|
+
} else {
|
|
120
|
+
// Sync built-in skills for existing user (clean up dangling + add new)
|
|
121
|
+
await initBuiltinSkills(user.uuid);
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
// Check if user is disabled
|
|
@@ -95,12 +95,47 @@ export async function saveBuiltinSkillsState(userUuid, state) {
|
|
|
95
95
|
/**
|
|
96
96
|
* Initialize built-in skills for a user
|
|
97
97
|
* Creates symlinks for all built-in skills not in user's removed list
|
|
98
|
+
* Also cleans up dangling symlinks from deleted built-in skills
|
|
98
99
|
*/
|
|
99
100
|
export async function initBuiltinSkills(userUuid) {
|
|
100
101
|
const userPaths = getUserPaths(userUuid);
|
|
101
102
|
const builtinSkills = await getBuiltinSkills();
|
|
102
103
|
const state = await loadBuiltinSkillsState(userUuid);
|
|
104
|
+
// Clean up dangling symlinks pointing to removed built-in skills
|
|
105
|
+
try {
|
|
106
|
+
const entries = await fs.readdir(userPaths.skillsDir, { withFileTypes: true });
|
|
107
|
+
for (const entry of entries) {
|
|
108
|
+
const entryPath = path.join(userPaths.skillsDir, entry.name);
|
|
109
|
+
try {
|
|
110
|
+
const stat = await fs.lstat(entryPath);
|
|
111
|
+
if (!stat.isSymbolicLink()) continue;
|
|
112
|
+
|
|
113
|
+
const target = await fs.readlink(entryPath);
|
|
114
|
+
const realBuiltinDir = await fs.realpath(BUILTIN_SKILLS_DIR);
|
|
115
|
+
const resolvedTarget = path.resolve(path.dirname(entryPath), target);
|
|
116
|
+
|
|
117
|
+
// Only clean up symlinks that point into builtin-skills directory
|
|
118
|
+
if (!resolvedTarget.startsWith(realBuiltinDir)) continue;
|
|
119
|
+
|
|
120
|
+
// Check if the symlink target still exists
|
|
121
|
+
try {
|
|
122
|
+
await fs.access(resolvedTarget);
|
|
123
|
+
} catch {
|
|
124
|
+
// Target no longer exists, remove the dangling symlink
|
|
125
|
+
await fs.unlink(entryPath);
|
|
126
|
+
console.log(`Removed dangling builtin skill symlink: ${entry.name}`);
|
|
127
|
+
}
|
|
128
|
+
} catch (err) {
|
|
129
|
+
// Ignore errors on individual entries
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
if (err.code !== 'ENOENT') {
|
|
134
|
+
console.error('Error cleaning up builtin skill symlinks:', err);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
103
137
|
|
|
138
|
+
// Create symlinks for new built-in skills
|
|
104
139
|
for (const skill of builtinSkills) {
|
|
105
140
|
// Skip if user has explicitly removed this skill
|
|
106
141
|
if (state.removedSkills.includes(skill.name)) {
|