@kevin5251984/guild 0.2.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/LICENSE +21 -0
- package/bin/guildd.mjs +20 -0
- package/cordis.yml +24 -0
- package/package.json +52 -0
- package/src/agent-file.ts +125 -0
- package/src/browser.ts +668 -0
- package/src/catalog/default-bots.ts +263 -0
- package/src/catalog/skills.ts +128 -0
- package/src/catalog/subagents.ts +70 -0
- package/src/chat-parts.ts +71 -0
- package/src/cli-args.ts +75 -0
- package/src/cli.ts +60 -0
- package/src/compact.ts +355 -0
- package/src/cordis.d.ts +40 -0
- package/src/db.ts +653 -0
- package/src/generate.ts +673 -0
- package/src/handlers.ts +1623 -0
- package/src/harness.ts +326 -0
- package/src/host-agents.ts +137 -0
- package/src/host-browse.ts +199 -0
- package/src/host-skills.ts +150 -0
- package/src/image-gen.ts +270 -0
- package/src/index.ts +12 -0
- package/src/llm.ts +993 -0
- package/src/mcp.ts +563 -0
- package/src/memory.ts +159 -0
- package/src/mention.ts +176 -0
- package/src/oauth.ts +1474 -0
- package/src/plugins/api.ts +8 -0
- package/src/plugins/chat.ts +31 -0
- package/src/plugins/harness.ts +77 -0
- package/src/plugins/llm.ts +50 -0
- package/src/plugins/mcp.ts +58 -0
- package/src/plugins/memory.ts +42 -0
- package/src/plugins/oauth.ts +47 -0
- package/src/plugins/server.ts +126 -0
- package/src/plugins/store.ts +29 -0
- package/src/plugins/tools.ts +79 -0
- package/src/public/buddy.js +432 -0
- package/src/public/chat.css +3045 -0
- package/src/public/chat.html +5834 -0
- package/src/public/favicon-16.png +0 -0
- package/src/public/favicon-16.svg +10 -0
- package/src/public/favicon-32.png +0 -0
- package/src/public/favicon.ico +0 -0
- package/src/public/favicon.svg +13 -0
- package/src/public/i18n.js +663 -0
- package/src/public/index.html +143 -0
- package/src/public/library.html +678 -0
- package/src/public/mcp-add.html +126 -0
- package/src/public/md.js +332 -0
- package/src/public/rpg/inn-street.jpg +0 -0
- package/src/public/settings.html +795 -0
- package/src/public/skills-add.html +212 -0
- package/src/public/studio.html +1181 -0
- package/src/public/style.css +1678 -0
- package/src/public/subagents-add.html +152 -0
- package/src/router.ts +978 -0
- package/src/send-budget.ts +52 -0
- package/src/server.ts +1 -0
- package/src/skill-import.ts +250 -0
- package/src/slash.ts +15 -0
- package/src/start.ts +103 -0
- package/src/store.ts +1208 -0
- package/src/subagent.ts +355 -0
- package/src/tools.ts +818 -0
- package/src/trajectory.ts +339 -0
- package/src/usage.ts +111 -0
- package/vendor/protocol/package.json +19 -0
- package/vendor/protocol/src/index.ts +159 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-Hant">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<link rel="icon" href="/favicon.ico" sizes="32x32" />
|
|
7
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
8
|
+
<link rel="icon" href="/favicon-32.png" type="image/png" sizes="32x32" />
|
|
9
|
+
<link rel="icon" href="/favicon-16.png" type="image/png" sizes="16x16" />
|
|
10
|
+
<title>Guild — 追加技能</title>
|
|
11
|
+
<link rel="stylesheet" href="/style.css" />
|
|
12
|
+
<script src="/i18n.js"></script>
|
|
13
|
+
</head>
|
|
14
|
+
<body class="app skills-add-page" data-i18n-page="skillsAdd">
|
|
15
|
+
<aside class="sidebar">
|
|
16
|
+
<div class="side-brand"><a class="logo" href="/">Guild</a></div>
|
|
17
|
+
<nav class="side-nav">
|
|
18
|
+
<a href="/" data-i18n="nav.chat">大廳</a>
|
|
19
|
+
<a href="/studio" data-i18n="nav.studio">編制</a>
|
|
20
|
+
<a class="on" href="/library" data-i18n="nav.library">工坊</a>
|
|
21
|
+
<a href="/settings" data-i18n="nav.settings">模型</a>
|
|
22
|
+
</nav>
|
|
23
|
+
<div class="sidebar-resizer" data-i18n-title="sidebar.resize" title="拖曳調整寬度"></div>
|
|
24
|
+
</aside>
|
|
25
|
+
<section class="pane">
|
|
26
|
+
<header class="pane-head">
|
|
27
|
+
<h1 data-i18n="skillsAdd.title">追加技能</h1>
|
|
28
|
+
</header>
|
|
29
|
+
<div class="page-body">
|
|
30
|
+
<p class="lede" data-i18n="skillsAdd.lede">這裡才是安裝入口。裝進技能庫之後,再到編制點每個人,各自勾選要用的技能。</p>
|
|
31
|
+
<p id="flash" class="muted"></p>
|
|
32
|
+
|
|
33
|
+
<div class="tabs">
|
|
34
|
+
<button type="button" class="tab on" data-tab="ai" data-i18n="skillsAdd.tabAi">AI 生成</button>
|
|
35
|
+
<button type="button" class="tab" data-tab="url" data-i18n="skillsAdd.tabUrl">網址下載</button>
|
|
36
|
+
<button type="button" class="tab" data-tab="github" data-i18n="skillsAdd.tabGh">GitHub repo</button>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<section class="card tab-pane" id="pane-ai">
|
|
40
|
+
<h2 data-i18n="skillsAdd.aiTitle">自行輸入,請 AI 生成</h2>
|
|
41
|
+
<label data-i18n="skillsAdd.what">這項技能要做什麼?</label>
|
|
42
|
+
<input id="ai-prompt" placeholder="審查 PR 的安全風險,並寫成可執行的修法" data-i18n-placeholder="skillsAdd.whatPh" />
|
|
43
|
+
<button type="button" class="secondary" id="ai-generate" data-i18n="skillsAdd.gen">用 AI 生成 SKILL.md</button>
|
|
44
|
+
<label data-i18n="skillsAdd.name">名稱</label>
|
|
45
|
+
<input id="ai-name" placeholder="Security Review" />
|
|
46
|
+
<label>SKILL.md</label>
|
|
47
|
+
<textarea id="ai-body" class="body" placeholder="--- name: ... description: ... ---"></textarea>
|
|
48
|
+
<button type="button" id="ai-save" data-i18n="skillsAdd.save">加入技能庫</button>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<section class="card tab-pane hidden" id="pane-url">
|
|
52
|
+
<h2 data-i18n="skillsAdd.urlTitle">從網上下載</h2>
|
|
53
|
+
<p class="muted" data-i18n="skillsAdd.urlHint">貼 SKILL.md 的直接連結(raw 檔或 GitHub blob)。</p>
|
|
54
|
+
<label>URL</label>
|
|
55
|
+
<input id="url-input" placeholder="https://raw.githubusercontent.com/org/repo/main/SKILL.md" />
|
|
56
|
+
<button type="button" id="url-import" data-i18n="skillsAdd.urlImport">下載並加入</button>
|
|
57
|
+
</section>
|
|
58
|
+
|
|
59
|
+
<section class="card tab-pane hidden" id="pane-github">
|
|
60
|
+
<h2 data-i18n="skillsAdd.ghTitle">載入 GitHub repo</h2>
|
|
61
|
+
<p class="muted" data-i18n="skillsAdd.ghHint">掃描 repo 內所有 SKILL.md。例:owner/repo 或完整 GitHub 網址。</p>
|
|
62
|
+
<label>Repo</label>
|
|
63
|
+
<input id="github-input" placeholder="anthropics/skills" />
|
|
64
|
+
<button type="button" id="github-import" data-i18n="skillsAdd.ghImport">掃描並加入</button>
|
|
65
|
+
</section>
|
|
66
|
+
|
|
67
|
+
<section class="card">
|
|
68
|
+
<h2 data-i18n="skillsAdd.recent">剛裝進技能庫的會出現在下面</h2>
|
|
69
|
+
<p class="muted" data-i18n-html="skillsAdd.recentHint">完整清單在 <a href="/library">技能庫</a>。要讓某人帶上,到 <a href="/studio">編制</a> 點那個人勾選。</p>
|
|
70
|
+
<ul id="library-skills" class="plain-list"></ul>
|
|
71
|
+
</section>
|
|
72
|
+
</div>
|
|
73
|
+
</section>
|
|
74
|
+
<script>
|
|
75
|
+
const flash = document.getElementById("flash");
|
|
76
|
+
function setFlash(kind, text) {
|
|
77
|
+
flash.className = kind;
|
|
78
|
+
flash.textContent = text;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
document.querySelectorAll(".tab").forEach((tab) => {
|
|
82
|
+
tab.addEventListener("click", () => {
|
|
83
|
+
document.querySelectorAll(".tab").forEach((t) => t.classList.remove("on"));
|
|
84
|
+
tab.classList.add("on");
|
|
85
|
+
const id = tab.getAttribute("data-tab");
|
|
86
|
+
document.querySelectorAll(".tab-pane").forEach((pane) => pane.classList.add("hidden"));
|
|
87
|
+
document.getElementById("pane-" + id).classList.remove("hidden");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
document.getElementById("ai-generate").addEventListener("click", async () => {
|
|
92
|
+
const prompt = document.getElementById("ai-prompt").value.trim();
|
|
93
|
+
if (!prompt) {
|
|
94
|
+
setFlash("error", t("skillsAdd.needDesc"));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const button = document.getElementById("ai-generate");
|
|
98
|
+
if (button.disabled || button.getAttribute("aria-busy") === "true") return;
|
|
99
|
+
button.disabled = true;
|
|
100
|
+
button.setAttribute("aria-busy", "true");
|
|
101
|
+
button.classList.add("is-busy");
|
|
102
|
+
const idle = button.textContent;
|
|
103
|
+
button.textContent = t("studio.generating");
|
|
104
|
+
try {
|
|
105
|
+
const response = await fetch("/generate", {
|
|
106
|
+
method: "POST",
|
|
107
|
+
headers: { "content-type": "application/json" },
|
|
108
|
+
body: JSON.stringify({ kind: "skill", prompt }),
|
|
109
|
+
});
|
|
110
|
+
const body = await response.json();
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
setFlash("error", body.error || "generate failed");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
document.getElementById("ai-name").value = body.name;
|
|
116
|
+
document.getElementById("ai-body").value = body.body;
|
|
117
|
+
setFlash(
|
|
118
|
+
"health",
|
|
119
|
+
body.source === "llm" ? t("skillsAdd.generated") : t("skillsAdd.generatedLocal"),
|
|
120
|
+
);
|
|
121
|
+
} finally {
|
|
122
|
+
button.disabled = false;
|
|
123
|
+
button.removeAttribute("aria-busy");
|
|
124
|
+
button.classList.remove("is-busy");
|
|
125
|
+
button.textContent = idle;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
document.getElementById("ai-save").addEventListener("click", async () => {
|
|
130
|
+
const name = document.getElementById("ai-name").value.trim();
|
|
131
|
+
const body = document.getElementById("ai-body").value.trim();
|
|
132
|
+
if (!name || !body) {
|
|
133
|
+
setFlash("error", t("skillsAdd.needName"));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const response = await fetch("/library/skills", {
|
|
137
|
+
method: "POST",
|
|
138
|
+
headers: { "content-type": "application/json" },
|
|
139
|
+
body: JSON.stringify({ name, body, description: name }),
|
|
140
|
+
});
|
|
141
|
+
const json = await response.json();
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
setFlash("error", json.error || "save failed");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
setFlash("health", t("skillsAdd.added", { name: json.name }));
|
|
147
|
+
loadLibrary();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
async function importSkills(payload) {
|
|
151
|
+
const response = await fetch("/library/skills/import", {
|
|
152
|
+
method: "POST",
|
|
153
|
+
headers: { "content-type": "application/json" },
|
|
154
|
+
body: JSON.stringify(payload),
|
|
155
|
+
});
|
|
156
|
+
const json = await response.json();
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
setFlash("error", json.error || "import failed");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const names = (json.imported || []).map((item) => item.name).join("、");
|
|
162
|
+
setFlash("health", t("skillsAdd.imported", { n: (json.imported || []).length, names: names }));
|
|
163
|
+
loadLibrary();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
document.getElementById("url-import").addEventListener("click", () => {
|
|
167
|
+
const url = document.getElementById("url-input").value.trim();
|
|
168
|
+
if (!url) {
|
|
169
|
+
setFlash("error", t("skillsAdd.needUrl"));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
importSkills({ source: "url", url });
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
async function loadLibrary() {
|
|
176
|
+
const list = document.getElementById("library-skills");
|
|
177
|
+
try {
|
|
178
|
+
const skills = await fetch("/library/skills").then((r) => r.json());
|
|
179
|
+
if (!Array.isArray(skills) || skills.length === 0) {
|
|
180
|
+
list.innerHTML = '<li class="muted">' + t("skillsAdd.empty") + "</li>";
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
list.innerHTML = skills
|
|
184
|
+
.map((skill) => {
|
|
185
|
+
const source = skill.source === "catalog" ? t("skillsAdd.catalog") : t("library.user");
|
|
186
|
+
return (
|
|
187
|
+
"<li><strong>" +
|
|
188
|
+
skill.name +
|
|
189
|
+
'</strong> <span class="muted">· ' +
|
|
190
|
+
source +
|
|
191
|
+
"</span></li>"
|
|
192
|
+
);
|
|
193
|
+
})
|
|
194
|
+
.join("");
|
|
195
|
+
} catch (err) {
|
|
196
|
+
list.innerHTML = '<li class="muted">' + err.message + "</li>";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
loadLibrary();
|
|
200
|
+
|
|
201
|
+
document.getElementById("github-import").addEventListener("click", () => {
|
|
202
|
+
const repo = document.getElementById("github-input").value.trim();
|
|
203
|
+
if (!repo) {
|
|
204
|
+
setFlash("error", t("skillsAdd.needRepo"));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
importSkills({ source: "github", repo });
|
|
208
|
+
});
|
|
209
|
+
window.addEventListener("guild-locale", loadLibrary);
|
|
210
|
+
</script>
|
|
211
|
+
</body>
|
|
212
|
+
</html>
|