@ian2018cs/agenthub 0.1.34 → 0.1.36

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.
File without changes
@@ -1,40 +0,0 @@
1
- ---
2
- name: html-deploy
3
- description: 将 HTML 内容部署为可访问的网页。使用场景:(1) 用户要求将生成的 HTML/网页部署上线或发布,(2) 用户要求更新已部署的页面内容,(3) 用户要求删除已部署的页面,(4) 用户提到"部署"、"发布"、"上线"HTML 页面,(5) 用户要求预览生成的网页效果。
4
- ---
5
-
6
- # HTML Deploy
7
-
8
- 将 HTML 内容部署到远程服务,生成可访问的 URL。
9
-
10
- ## 使用流程
11
-
12
- 1. 根据用户需求生成完整的 HTML 页面,写入文件
13
- 2. 调用脚本部署、更新或删除,传入相应参数
14
- 3. 将结果告知用户
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 错误。
31
-
32
- ### 删除已有页面
33
-
34
- 从之前的部署 URL 中提取 page_id(UUID 部分):
35
-
36
- ```bash
37
- python3 skills/html-deploy/scripts/delete.py <page_id>
38
- ```
39
-
40
- page_id 不存在时会报 404 错误。
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env python3
2
- """删除已部署的页面。
3
-
4
- 用法: delete.py <page_id>
5
- 输出: 删除结果
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]} <page_id>", file=sys.stderr)
17
- sys.exit(1)
18
-
19
- page_id = sys.argv[1]
20
- req = urllib.request.Request(
21
- f"{API_BASE}/deploy/{page_id}",
22
- method="DELETE",
23
- )
24
-
25
- with urllib.request.urlopen(req) as resp:
26
- result = json.loads(resp.read())
27
- print(result["detail"])
28
-
29
-
30
- if __name__ == "__main__":
31
- main()
@@ -1,36 +0,0 @@
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()
@@ -1,38 +0,0 @@
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()
@@ -1,182 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { getUserPaths } from './user-directories.js';
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- // Path to built-in skills directory
10
- const BUILTIN_SKILLS_DIR = path.join(__dirname, '../builtin-skills');
11
-
12
- // State file version for future migrations
13
- const STATE_VERSION = 1;
14
-
15
- /**
16
- * Get list of all available built-in skills
17
- */
18
- export async function getBuiltinSkills() {
19
- const skills = [];
20
-
21
- try {
22
- const entries = await fs.readdir(BUILTIN_SKILLS_DIR, { withFileTypes: true });
23
-
24
- for (const entry of entries) {
25
- if (entry.isDirectory() && !entry.name.startsWith('.')) {
26
- const skillPath = path.join(BUILTIN_SKILLS_DIR, entry.name);
27
-
28
- // Check for SKILLS.md or SKILL.md
29
- const skillsFile = path.join(skillPath, 'SKILLS.md');
30
- const skillFile = path.join(skillPath, 'SKILL.md');
31
-
32
- try {
33
- // Try SKILLS.md first, then SKILL.md
34
- let found = false;
35
- try {
36
- await fs.access(skillsFile);
37
- found = true;
38
- } catch {
39
- await fs.access(skillFile);
40
- found = true;
41
- }
42
-
43
- if (found) {
44
- skills.push({
45
- name: entry.name,
46
- path: skillPath
47
- });
48
- }
49
- } catch {
50
- // Skip if neither file exists
51
- }
52
- }
53
- }
54
- } catch (err) {
55
- if (err.code !== 'ENOENT') {
56
- console.error('Error reading builtin skills:', err);
57
- }
58
- }
59
-
60
- return skills;
61
- }
62
-
63
- /**
64
- * Get path to user's builtin skills state file
65
- */
66
- function getStatePath(userUuid) {
67
- const userPaths = getUserPaths(userUuid);
68
- return path.join(userPaths.claudeDir, '.builtin-skills-state.json');
69
- }
70
-
71
- /**
72
- * Load user's builtin skills state
73
- */
74
- export async function loadBuiltinSkillsState(userUuid) {
75
- try {
76
- const statePath = getStatePath(userUuid);
77
- const content = await fs.readFile(statePath, 'utf-8');
78
- return JSON.parse(content);
79
- } catch {
80
- return {
81
- version: STATE_VERSION,
82
- removedSkills: []
83
- };
84
- }
85
- }
86
-
87
- /**
88
- * Save user's builtin skills state
89
- */
90
- export async function saveBuiltinSkillsState(userUuid, state) {
91
- const statePath = getStatePath(userUuid);
92
- await fs.writeFile(statePath, JSON.stringify(state, null, 2));
93
- }
94
-
95
- /**
96
- * Initialize built-in skills for a user
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
99
- */
100
- export async function initBuiltinSkills(userUuid) {
101
- const userPaths = getUserPaths(userUuid);
102
- const builtinSkills = await getBuiltinSkills();
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
- }
137
-
138
- // Create symlinks for new built-in skills
139
- for (const skill of builtinSkills) {
140
- // Skip if user has explicitly removed this skill
141
- if (state.removedSkills.includes(skill.name)) {
142
- continue;
143
- }
144
-
145
- const linkPath = path.join(userPaths.skillsDir, skill.name);
146
-
147
- try {
148
- // Check if link already exists
149
- await fs.lstat(linkPath);
150
- // Link exists, skip
151
- } catch {
152
- // Link doesn't exist, create it
153
- try {
154
- await fs.symlink(skill.path, linkPath);
155
- console.log(`Created builtin skill symlink: ${skill.name}`);
156
- } catch (err) {
157
- console.error(`Error creating builtin skill symlink ${skill.name}:`, err);
158
- }
159
- }
160
- }
161
- }
162
-
163
- /**
164
- * Mark a built-in skill as removed by user
165
- */
166
- export async function markBuiltinSkillRemoved(userUuid, skillName) {
167
- const state = await loadBuiltinSkillsState(userUuid);
168
-
169
- if (!state.removedSkills.includes(skillName)) {
170
- state.removedSkills.push(skillName);
171
- await saveBuiltinSkillsState(userUuid, state);
172
- }
173
- }
174
-
175
- /**
176
- * Check if a path is a built-in skill
177
- */
178
- export function isBuiltinSkillPath(realPath) {
179
- return realPath?.includes('/builtin-skills/') ?? false;
180
- }
181
-
182
- export { BUILTIN_SKILLS_DIR };