agent-dj 0.1.2 → 0.1.3
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/README.md +36 -7
- package/dist/cli.js +116 -3
- package/dist/server.js +97 -3
- package/package.json +1 -1
- package/web/dist/assets/index-BprVp71W.js +348 -0
- package/web/dist/assets/index-tOqJ_oLn.css +1 -0
- package/web/dist/index.html +2 -2
- package/web/dist/assets/index-CVUo4o24.js +0 -348
- package/web/dist/assets/index-MHuCb1sM.css +0 -1
package/README.md
CHANGED
|
@@ -1,23 +1,49 @@
|
|
|
1
1
|
# Agent DJ
|
|
2
2
|
|
|
3
|
-
Self-hosted AI agent platform
|
|
3
|
+
**Self-hosted AI agent platform. One command, beautiful dashboard, 8 providers, multi-agent orchestration.**
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx agent-dj@latest
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Bring your own API key. Supports Claude, GPT, Gemini, Grok, Mistral, DeepSeek, Groq, and Ollama (local/free). No cloud accounts, no sign-ups — runs entirely on your machine. Apache-2.0.
|
|
10
|
+
|
|
11
|
+
**What you get:**
|
|
12
|
+
|
|
13
|
+
- Beautiful web dashboard at localhost
|
|
14
|
+
- 8 LLM providers — Claude, GPT-4o, Gemini, Grok, Mistral, DeepSeek, Groq, Ollama
|
|
15
|
+
- Multi-agent system — orchestrator auto-routes to specialist agents (Coder, Researcher, Writer, System, RAG)
|
|
16
|
+
- Knowledge base with RAG — upload documents, agents search them automatically
|
|
17
|
+
- MCP support — connect external tools (GitHub, Slack, databases, etc.)
|
|
18
|
+
- Skills — create custom instructions that shape how all agents behave
|
|
19
|
+
- Memory — agents remember context across conversations
|
|
20
|
+
- Full audit log of every action
|
|
21
|
+
- Permission system — control what agents can do
|
|
22
|
+
|
|
23
|
+
**BYOK (Bring Your Own Key).** Your keys, your data, your machine. Nothing leaves localhost unless you tell it to.
|
|
24
|
+
|
|
25
|
+
---
|
|
4
26
|
|
|
5
27
|
## Quick Start
|
|
6
28
|
|
|
7
29
|
```bash
|
|
8
|
-
|
|
9
|
-
npm install -g agent-dj
|
|
10
|
-
|
|
11
|
-
# Or run directly with npx
|
|
12
|
-
npx agent-dj
|
|
30
|
+
npx agent-dj@latest
|
|
13
31
|
```
|
|
14
32
|
|
|
15
|
-
On first run, the setup wizard walks you through choosing a provider and entering your API key. Then the dashboard opens automatically
|
|
33
|
+
On first run, the setup wizard walks you through choosing a provider and entering your API key. Then the dashboard opens automatically at **http://localhost:3456**.
|
|
34
|
+
|
|
35
|
+
You can also install globally:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install -g agent-dj
|
|
39
|
+
agent-dj
|
|
40
|
+
```
|
|
16
41
|
|
|
17
42
|
## Features
|
|
18
43
|
|
|
19
44
|
- Multi-agent orchestration (Coder, Researcher, Writer, System, RAG)
|
|
20
45
|
- Chat interface with conversation history
|
|
46
|
+
- Skills system (custom instructions for all agents, works across all providers)
|
|
21
47
|
- Memory system (user context, feedback, projects)
|
|
22
48
|
- Knowledge base with RAG (document upload, hybrid search)
|
|
23
49
|
- MCP (Model Context Protocol) server support
|
|
@@ -32,6 +58,9 @@ On first run, the setup wizard walks you through choosing a provider and enterin
|
|
|
32
58
|
| **Anthropic** | API key or OAuth token | Claude Opus, Sonnet, Haiku |
|
|
33
59
|
| **OpenAI** | API key | GPT-4o, o1, o3-mini |
|
|
34
60
|
| **Google** | API key | Gemini 2.0 Flash/Pro |
|
|
61
|
+
| **xAI** | API key | Grok-3 |
|
|
62
|
+
| **Mistral** | API key | Mistral Large |
|
|
63
|
+
| **DeepSeek** | API key | DeepSeek Chat |
|
|
35
64
|
| **Groq** | API key | Llama 3.3 70B (fast, free tier) |
|
|
36
65
|
| **Ollama** | None | Local models, free |
|
|
37
66
|
|
package/dist/cli.js
CHANGED
|
@@ -670,6 +670,17 @@ CREATE TABLE IF NOT EXISTS permission_cache (
|
|
|
670
670
|
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
|
|
671
671
|
);
|
|
672
672
|
CREATE INDEX IF NOT EXISTS idx_perm_session ON permission_cache(session_id, resource_type, resource_path);
|
|
673
|
+
|
|
674
|
+
-- Skills
|
|
675
|
+
CREATE TABLE IF NOT EXISTS skills (
|
|
676
|
+
id TEXT PRIMARY KEY,
|
|
677
|
+
name TEXT NOT NULL,
|
|
678
|
+
description TEXT NOT NULL DEFAULT '',
|
|
679
|
+
content TEXT NOT NULL,
|
|
680
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
681
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
682
|
+
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
|
|
683
|
+
);
|
|
673
684
|
`;
|
|
674
685
|
}
|
|
675
686
|
});
|
|
@@ -780,6 +791,37 @@ function getAuditLog(limit = 100, offset = 0) {
|
|
|
780
791
|
function clearAuditLog() {
|
|
781
792
|
getDb().prepare("DELETE FROM audit_log").run();
|
|
782
793
|
}
|
|
794
|
+
function createSkill(params) {
|
|
795
|
+
const id = randomUUID();
|
|
796
|
+
getDb().prepare("INSERT INTO skills (id, name, description, content) VALUES (?, ?, ?, ?)").run(id, params.name, params.description, params.content);
|
|
797
|
+
return id;
|
|
798
|
+
}
|
|
799
|
+
function listSkills() {
|
|
800
|
+
return getDb().prepare("SELECT * FROM skills ORDER BY created_at DESC").all();
|
|
801
|
+
}
|
|
802
|
+
function getSkill(id) {
|
|
803
|
+
return getDb().prepare("SELECT * FROM skills WHERE id = ?").get(id);
|
|
804
|
+
}
|
|
805
|
+
function updateSkill(id, updates) {
|
|
806
|
+
const sets = [];
|
|
807
|
+
const values2 = [];
|
|
808
|
+
for (const [key, val] of Object.entries(updates)) {
|
|
809
|
+
if (val !== void 0) {
|
|
810
|
+
sets.push(`${key} = ?`);
|
|
811
|
+
values2.push(val);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (sets.length === 0) return;
|
|
815
|
+
sets.push("updated_at = datetime('now')");
|
|
816
|
+
values2.push(id);
|
|
817
|
+
getDb().prepare(`UPDATE skills SET ${sets.join(", ")} WHERE id = ?`).run(...values2);
|
|
818
|
+
}
|
|
819
|
+
function deleteSkill(id) {
|
|
820
|
+
getDb().prepare("DELETE FROM skills WHERE id = ?").run(id);
|
|
821
|
+
}
|
|
822
|
+
function getEnabledSkills() {
|
|
823
|
+
return getDb().prepare("SELECT * FROM skills WHERE enabled = 1 ORDER BY created_at ASC").all();
|
|
824
|
+
}
|
|
783
825
|
var db;
|
|
784
826
|
var init_db = __esm({
|
|
785
827
|
"src/db/index.ts"() {
|
|
@@ -273408,8 +273450,21 @@ function routeMessage(message) {
|
|
|
273408
273450
|
}
|
|
273409
273451
|
return "orchestrator";
|
|
273410
273452
|
}
|
|
273453
|
+
function buildSkillsSection() {
|
|
273454
|
+
const skills = getEnabledSkills();
|
|
273455
|
+
if (skills.length === 0) return "";
|
|
273456
|
+
const skillsText = skills.map((s) => `### ${s.name}
|
|
273457
|
+
${s.content}`).join("\n\n");
|
|
273458
|
+
return `
|
|
273459
|
+
|
|
273460
|
+
## Custom Skills & Instructions
|
|
273461
|
+
Follow these additional instructions:
|
|
273462
|
+
|
|
273463
|
+
${skillsText}`;
|
|
273464
|
+
}
|
|
273411
273465
|
function buildSystemPrompt() {
|
|
273412
273466
|
let prompt = BASE_SYSTEM_PROMPT;
|
|
273467
|
+
prompt += buildSkillsSection();
|
|
273413
273468
|
const mcpSummary = getMcpToolSummary();
|
|
273414
273469
|
if (mcpSummary) {
|
|
273415
273470
|
prompt += `
|
|
@@ -273638,6 +273693,7 @@ async function delegateToAgent(targetAgent, messages, lastMessage, model, provid
|
|
|
273638
273693
|
const memoryCtx = memory.buildContext(lastMessage);
|
|
273639
273694
|
const knowledgeCtx = buildKnowledgeContext(lastMessage);
|
|
273640
273695
|
let augmentedSystem = agentDef.systemPrompt;
|
|
273696
|
+
augmentedSystem += buildSkillsSection();
|
|
273641
273697
|
const mcpSummary = getMcpToolSummary();
|
|
273642
273698
|
if (mcpSummary) augmentedSystem += `
|
|
273643
273699
|
|
|
@@ -273728,6 +273784,7 @@ async function delegateToAgentStreaming(targetAgent, messages, lastMessage, mode
|
|
|
273728
273784
|
const memoryCtx = memory.buildContext(lastMessage);
|
|
273729
273785
|
const knowledgeCtx = buildKnowledgeContext(lastMessage);
|
|
273730
273786
|
let augmentedSystem = agentDef.systemPrompt;
|
|
273787
|
+
augmentedSystem += buildSkillsSection();
|
|
273731
273788
|
const mcpSummary = getMcpToolSummary();
|
|
273732
273789
|
if (mcpSummary) augmentedSystem += `
|
|
273733
273790
|
|
|
@@ -274724,12 +274781,66 @@ var init_apps = __esm({
|
|
|
274724
274781
|
}
|
|
274725
274782
|
});
|
|
274726
274783
|
|
|
274784
|
+
// src/server/routes/skills.ts
|
|
274785
|
+
import { Hono as Hono9 } from "hono";
|
|
274786
|
+
var skillsRoutes;
|
|
274787
|
+
var init_skills = __esm({
|
|
274788
|
+
"src/server/routes/skills.ts"() {
|
|
274789
|
+
"use strict";
|
|
274790
|
+
init_db();
|
|
274791
|
+
skillsRoutes = new Hono9();
|
|
274792
|
+
skillsRoutes.get("/", (c) => {
|
|
274793
|
+
return c.json(listSkills());
|
|
274794
|
+
});
|
|
274795
|
+
skillsRoutes.get("/:id", (c) => {
|
|
274796
|
+
const skill = getSkill(c.req.param("id"));
|
|
274797
|
+
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
274798
|
+
return c.json(skill);
|
|
274799
|
+
});
|
|
274800
|
+
skillsRoutes.post("/", async (c) => {
|
|
274801
|
+
const body = await c.req.json();
|
|
274802
|
+
const { name, description, content } = body;
|
|
274803
|
+
if (!name || !content) {
|
|
274804
|
+
return c.json({ error: "name and content are required" }, 400);
|
|
274805
|
+
}
|
|
274806
|
+
const id = createSkill({ name, description: description || "", content });
|
|
274807
|
+
return c.json({ id }, 201);
|
|
274808
|
+
});
|
|
274809
|
+
skillsRoutes.put("/:id", async (c) => {
|
|
274810
|
+
const id = c.req.param("id");
|
|
274811
|
+
const skill = getSkill(id);
|
|
274812
|
+
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
274813
|
+
const body = await c.req.json();
|
|
274814
|
+
const updates = {};
|
|
274815
|
+
if (body.name !== void 0) updates.name = body.name;
|
|
274816
|
+
if (body.description !== void 0) updates.description = body.description;
|
|
274817
|
+
if (body.content !== void 0) updates.content = body.content;
|
|
274818
|
+
if (body.enabled !== void 0) updates.enabled = body.enabled;
|
|
274819
|
+
updateSkill(id, updates);
|
|
274820
|
+
return c.json({ ok: true });
|
|
274821
|
+
});
|
|
274822
|
+
skillsRoutes.delete("/:id", (c) => {
|
|
274823
|
+
const id = c.req.param("id");
|
|
274824
|
+
deleteSkill(id);
|
|
274825
|
+
return c.json({ ok: true });
|
|
274826
|
+
});
|
|
274827
|
+
skillsRoutes.patch("/:id/toggle", (c) => {
|
|
274828
|
+
const id = c.req.param("id");
|
|
274829
|
+
const skill = getSkill(id);
|
|
274830
|
+
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
274831
|
+
updateSkill(id, { enabled: skill.enabled ? 0 : 1 });
|
|
274832
|
+
const updated = getSkill(id);
|
|
274833
|
+
return c.json(updated);
|
|
274834
|
+
});
|
|
274835
|
+
}
|
|
274836
|
+
});
|
|
274837
|
+
|
|
274727
274838
|
// src/server/index.ts
|
|
274728
274839
|
var server_exports = {};
|
|
274729
274840
|
__export(server_exports, {
|
|
274730
274841
|
createApp: () => createApp
|
|
274731
274842
|
});
|
|
274732
|
-
import { Hono as
|
|
274843
|
+
import { Hono as Hono10 } from "hono";
|
|
274733
274844
|
import { cors } from "hono/cors";
|
|
274734
274845
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
274735
274846
|
import { fileURLToPath } from "url";
|
|
@@ -274750,9 +274861,9 @@ function findWebDist() {
|
|
|
274750
274861
|
return candidates[0];
|
|
274751
274862
|
}
|
|
274752
274863
|
function createApp() {
|
|
274753
|
-
const app = new
|
|
274864
|
+
const app = new Hono10();
|
|
274754
274865
|
app.use("*", cors());
|
|
274755
|
-
const SILENT_ROUTES = ["/api/tasks", "/api/settings", "/api/conversations", "/api/health", "/api/memory", "/api/mcp", "/api/agents", "/api/knowledge", "/api/apps"];
|
|
274866
|
+
const SILENT_ROUTES = ["/api/tasks", "/api/settings", "/api/conversations", "/api/health", "/api/memory", "/api/mcp", "/api/agents", "/api/knowledge", "/api/apps", "/api/skills"];
|
|
274756
274867
|
app.use("/api/*", async (c, next) => {
|
|
274757
274868
|
const path = c.req.path;
|
|
274758
274869
|
const method = c.req.method;
|
|
@@ -274772,6 +274883,7 @@ function createApp() {
|
|
|
274772
274883
|
app.route("/api/settings", settingsRoutes);
|
|
274773
274884
|
app.route("/api/memory", memoryRoutes);
|
|
274774
274885
|
app.route("/api/apps", appsRoutes);
|
|
274886
|
+
app.route("/api/skills", skillsRoutes);
|
|
274775
274887
|
app.get("/api/health", (c) => {
|
|
274776
274888
|
return c.json({
|
|
274777
274889
|
status: "ok",
|
|
@@ -274795,6 +274907,7 @@ var init_server = __esm({
|
|
|
274795
274907
|
init_settings();
|
|
274796
274908
|
init_memory2();
|
|
274797
274909
|
init_apps();
|
|
274910
|
+
init_skills();
|
|
274798
274911
|
__filename = fileURLToPath(import.meta.url);
|
|
274799
274912
|
__dirname = dirname(__filename);
|
|
274800
274913
|
WEB_DIST = findWebDist();
|
package/dist/server.js
CHANGED
|
@@ -270567,7 +270567,7 @@ var require_lib6 = __commonJS({
|
|
|
270567
270567
|
});
|
|
270568
270568
|
|
|
270569
270569
|
// src/server/index.ts
|
|
270570
|
-
import { Hono as
|
|
270570
|
+
import { Hono as Hono10 } from "hono";
|
|
270571
270571
|
import { cors } from "hono/cors";
|
|
270572
270572
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
270573
270573
|
import { fileURLToPath } from "url";
|
|
@@ -270729,6 +270729,37 @@ function getAuditLog(limit = 100, offset = 0) {
|
|
|
270729
270729
|
function clearAuditLog() {
|
|
270730
270730
|
getDb().prepare("DELETE FROM audit_log").run();
|
|
270731
270731
|
}
|
|
270732
|
+
function createSkill(params) {
|
|
270733
|
+
const id = randomUUID();
|
|
270734
|
+
getDb().prepare("INSERT INTO skills (id, name, description, content) VALUES (?, ?, ?, ?)").run(id, params.name, params.description, params.content);
|
|
270735
|
+
return id;
|
|
270736
|
+
}
|
|
270737
|
+
function listSkills() {
|
|
270738
|
+
return getDb().prepare("SELECT * FROM skills ORDER BY created_at DESC").all();
|
|
270739
|
+
}
|
|
270740
|
+
function getSkill(id) {
|
|
270741
|
+
return getDb().prepare("SELECT * FROM skills WHERE id = ?").get(id);
|
|
270742
|
+
}
|
|
270743
|
+
function updateSkill(id, updates) {
|
|
270744
|
+
const sets = [];
|
|
270745
|
+
const values2 = [];
|
|
270746
|
+
for (const [key, val] of Object.entries(updates)) {
|
|
270747
|
+
if (val !== void 0) {
|
|
270748
|
+
sets.push(`${key} = ?`);
|
|
270749
|
+
values2.push(val);
|
|
270750
|
+
}
|
|
270751
|
+
}
|
|
270752
|
+
if (sets.length === 0) return;
|
|
270753
|
+
sets.push("updated_at = datetime('now')");
|
|
270754
|
+
values2.push(id);
|
|
270755
|
+
getDb().prepare(`UPDATE skills SET ${sets.join(", ")} WHERE id = ?`).run(...values2);
|
|
270756
|
+
}
|
|
270757
|
+
function deleteSkill(id) {
|
|
270758
|
+
getDb().prepare("DELETE FROM skills WHERE id = ?").run(id);
|
|
270759
|
+
}
|
|
270760
|
+
function getEnabledSkills() {
|
|
270761
|
+
return getDb().prepare("SELECT * FROM skills WHERE enabled = 1 ORDER BY created_at ASC").all();
|
|
270762
|
+
}
|
|
270732
270763
|
|
|
270733
270764
|
// src/config/index.ts
|
|
270734
270765
|
import { readFileSync, writeFileSync, mkdirSync, existsSync, cpSync } from "fs";
|
|
@@ -272661,8 +272692,21 @@ You have direct access to tools including web search, file operations, knowledge
|
|
|
272661
272692
|
- When listing options, briefly note pros/cons
|
|
272662
272693
|
- End with a clear next step or action item when relevant
|
|
272663
272694
|
- ALWAYS try to use your tools to answer questions \u2014 don't just give generic advice`;
|
|
272695
|
+
function buildSkillsSection() {
|
|
272696
|
+
const skills = getEnabledSkills();
|
|
272697
|
+
if (skills.length === 0) return "";
|
|
272698
|
+
const skillsText = skills.map((s) => `### ${s.name}
|
|
272699
|
+
${s.content}`).join("\n\n");
|
|
272700
|
+
return `
|
|
272701
|
+
|
|
272702
|
+
## Custom Skills & Instructions
|
|
272703
|
+
Follow these additional instructions:
|
|
272704
|
+
|
|
272705
|
+
${skillsText}`;
|
|
272706
|
+
}
|
|
272664
272707
|
function buildSystemPrompt() {
|
|
272665
272708
|
let prompt = BASE_SYSTEM_PROMPT;
|
|
272709
|
+
prompt += buildSkillsSection();
|
|
272666
272710
|
const mcpSummary = getMcpToolSummary();
|
|
272667
272711
|
if (mcpSummary) {
|
|
272668
272712
|
prompt += `
|
|
@@ -272899,6 +272943,7 @@ async function delegateToAgent(targetAgent, messages, lastMessage, model, provid
|
|
|
272899
272943
|
const memoryCtx = memory.buildContext(lastMessage);
|
|
272900
272944
|
const knowledgeCtx = buildKnowledgeContext(lastMessage);
|
|
272901
272945
|
let augmentedSystem = agentDef.systemPrompt;
|
|
272946
|
+
augmentedSystem += buildSkillsSection();
|
|
272902
272947
|
const mcpSummary = getMcpToolSummary();
|
|
272903
272948
|
if (mcpSummary) augmentedSystem += `
|
|
272904
272949
|
|
|
@@ -272989,6 +273034,7 @@ async function delegateToAgentStreaming(targetAgent, messages, lastMessage, mode
|
|
|
272989
273034
|
const memoryCtx = memory.buildContext(lastMessage);
|
|
272990
273035
|
const knowledgeCtx = buildKnowledgeContext(lastMessage);
|
|
272991
273036
|
let augmentedSystem = agentDef.systemPrompt;
|
|
273037
|
+
augmentedSystem += buildSkillsSection();
|
|
272992
273038
|
const mcpSummary = getMcpToolSummary();
|
|
272993
273039
|
if (mcpSummary) augmentedSystem += `
|
|
272994
273040
|
|
|
@@ -273966,6 +274012,53 @@ appsRoutes.post("/refresh", async (c) => {
|
|
|
273966
274012
|
return c.json({ status: "ok", count: cachedCatalog.apps.length });
|
|
273967
274013
|
});
|
|
273968
274014
|
|
|
274015
|
+
// src/server/routes/skills.ts
|
|
274016
|
+
import { Hono as Hono9 } from "hono";
|
|
274017
|
+
var skillsRoutes = new Hono9();
|
|
274018
|
+
skillsRoutes.get("/", (c) => {
|
|
274019
|
+
return c.json(listSkills());
|
|
274020
|
+
});
|
|
274021
|
+
skillsRoutes.get("/:id", (c) => {
|
|
274022
|
+
const skill = getSkill(c.req.param("id"));
|
|
274023
|
+
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
274024
|
+
return c.json(skill);
|
|
274025
|
+
});
|
|
274026
|
+
skillsRoutes.post("/", async (c) => {
|
|
274027
|
+
const body = await c.req.json();
|
|
274028
|
+
const { name, description, content } = body;
|
|
274029
|
+
if (!name || !content) {
|
|
274030
|
+
return c.json({ error: "name and content are required" }, 400);
|
|
274031
|
+
}
|
|
274032
|
+
const id = createSkill({ name, description: description || "", content });
|
|
274033
|
+
return c.json({ id }, 201);
|
|
274034
|
+
});
|
|
274035
|
+
skillsRoutes.put("/:id", async (c) => {
|
|
274036
|
+
const id = c.req.param("id");
|
|
274037
|
+
const skill = getSkill(id);
|
|
274038
|
+
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
274039
|
+
const body = await c.req.json();
|
|
274040
|
+
const updates = {};
|
|
274041
|
+
if (body.name !== void 0) updates.name = body.name;
|
|
274042
|
+
if (body.description !== void 0) updates.description = body.description;
|
|
274043
|
+
if (body.content !== void 0) updates.content = body.content;
|
|
274044
|
+
if (body.enabled !== void 0) updates.enabled = body.enabled;
|
|
274045
|
+
updateSkill(id, updates);
|
|
274046
|
+
return c.json({ ok: true });
|
|
274047
|
+
});
|
|
274048
|
+
skillsRoutes.delete("/:id", (c) => {
|
|
274049
|
+
const id = c.req.param("id");
|
|
274050
|
+
deleteSkill(id);
|
|
274051
|
+
return c.json({ ok: true });
|
|
274052
|
+
});
|
|
274053
|
+
skillsRoutes.patch("/:id/toggle", (c) => {
|
|
274054
|
+
const id = c.req.param("id");
|
|
274055
|
+
const skill = getSkill(id);
|
|
274056
|
+
if (!skill) return c.json({ error: "Skill not found" }, 404);
|
|
274057
|
+
updateSkill(id, { enabled: skill.enabled ? 0 : 1 });
|
|
274058
|
+
const updated = getSkill(id);
|
|
274059
|
+
return c.json(updated);
|
|
274060
|
+
});
|
|
274061
|
+
|
|
273969
274062
|
// src/server/index.ts
|
|
273970
274063
|
var __filename = fileURLToPath(import.meta.url);
|
|
273971
274064
|
var __dirname = dirname(__filename);
|
|
@@ -273985,9 +274078,9 @@ function findWebDist() {
|
|
|
273985
274078
|
}
|
|
273986
274079
|
var WEB_DIST = findWebDist();
|
|
273987
274080
|
function createApp() {
|
|
273988
|
-
const app = new
|
|
274081
|
+
const app = new Hono10();
|
|
273989
274082
|
app.use("*", cors());
|
|
273990
|
-
const SILENT_ROUTES = ["/api/tasks", "/api/settings", "/api/conversations", "/api/health", "/api/memory", "/api/mcp", "/api/agents", "/api/knowledge", "/api/apps"];
|
|
274083
|
+
const SILENT_ROUTES = ["/api/tasks", "/api/settings", "/api/conversations", "/api/health", "/api/memory", "/api/mcp", "/api/agents", "/api/knowledge", "/api/apps", "/api/skills"];
|
|
273991
274084
|
app.use("/api/*", async (c, next) => {
|
|
273992
274085
|
const path = c.req.path;
|
|
273993
274086
|
const method = c.req.method;
|
|
@@ -274007,6 +274100,7 @@ function createApp() {
|
|
|
274007
274100
|
app.route("/api/settings", settingsRoutes);
|
|
274008
274101
|
app.route("/api/memory", memoryRoutes);
|
|
274009
274102
|
app.route("/api/apps", appsRoutes);
|
|
274103
|
+
app.route("/api/skills", skillsRoutes);
|
|
274010
274104
|
app.get("/api/health", (c) => {
|
|
274011
274105
|
return c.json({
|
|
274012
274106
|
status: "ok",
|
package/package.json
CHANGED