@burdenoff/vibe-agent 2.1.1 → 2.2.0
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/app-6mmbmske.js +1166 -0
- package/dist/app-6mmbmske.js.map +19 -0
- package/dist/cli.js +152 -2036
- package/dist/cli.js.map +6 -28
- package/dist/index-05qfwz8r.js +122 -0
- package/dist/index-05qfwz8r.js.map +10 -0
- package/dist/index-30p492yv.js +294 -0
- package/dist/index-30p492yv.js.map +13 -0
- package/dist/index-3v78e2cn.js +373 -0
- package/dist/index-3v78e2cn.js.map +11 -0
- package/dist/index-41m1exz7.js +269 -0
- package/dist/index-41m1exz7.js.map +13 -0
- package/dist/index-88ym10cs.js +194 -0
- package/dist/index-88ym10cs.js.map +10 -0
- package/dist/index-9tgyd3ep.js +513 -0
- package/dist/index-9tgyd3ep.js.map +19 -0
- package/dist/index-a9g7hbj9.js +229 -0
- package/dist/index-a9g7hbj9.js.map +13 -0
- package/dist/index-atjhkm74.js +149 -0
- package/dist/index-atjhkm74.js.map +10 -0
- package/dist/index-c7zy3n33.js +167 -0
- package/dist/index-c7zy3n33.js.map +13 -0
- package/dist/index-hefqxwht.js +270 -0
- package/dist/index-hefqxwht.js.map +13 -0
- package/dist/index-k9hb0b93.js +280 -0
- package/dist/index-k9hb0b93.js.map +13 -0
- package/dist/index-npmvh1x9.js +385 -0
- package/dist/index-npmvh1x9.js.map +13 -0
- package/dist/index-q4ytrfx7.js +286 -0
- package/dist/index-q4ytrfx7.js.map +13 -0
- package/dist/index-qthbtg9n.js +302 -0
- package/dist/index-qthbtg9n.js.map +13 -0
- package/dist/index-rdm6e3rr.js +587 -0
- package/dist/index-rdm6e3rr.js.map +13 -0
- package/dist/index-wdtxbebz.js +339 -0
- package/dist/index-wdtxbebz.js.map +13 -0
- package/dist/{app-31chs2a1.js → index-wr0mkm57.js} +8 -3201
- package/dist/{app-31chs2a1.js.map → index-wr0mkm57.js.map} +4 -25
- package/dist/index-xmeskdnb.js +292 -0
- package/dist/index-xmeskdnb.js.map +11 -0
- package/dist/index-xn4tarcd.js +287 -0
- package/dist/index-xn4tarcd.js.map +13 -0
- package/dist/index.js +9 -6
- package/dist/index.js.map +2 -2
- package/dist/{package-hb6db316.js → package-ywexp6sg.js} +3 -3
- package/dist/{package-hb6db316.js.map → package-ywexp6sg.js.map} +1 -1
- package/dist/plugin-system-v7a7xnhk.js +475 -0
- package/dist/plugin-system-v7a7xnhk.js.map +10 -0
- package/package.json +1 -1
- package/dist/index-t06ktmx9.js +0 -216
- package/dist/index-t06ktmx9.js.map +0 -11
- package/dist/plugin-system-bg1pzjj9.js +0 -450
- package/dist/plugin-system-bg1pzjj9.js.map +0 -11
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Elysia,
|
|
4
|
+
t
|
|
5
|
+
} from "./index-wr0mkm57.js";
|
|
6
|
+
import {
|
|
7
|
+
apiDelete,
|
|
8
|
+
apiGet,
|
|
9
|
+
apiPost,
|
|
10
|
+
apiPut,
|
|
11
|
+
fail,
|
|
12
|
+
formatTable,
|
|
13
|
+
getAgentUrl,
|
|
14
|
+
header,
|
|
15
|
+
info,
|
|
16
|
+
shortId,
|
|
17
|
+
success
|
|
18
|
+
} from "./index-xmeskdnb.js";
|
|
19
|
+
import"./index-g8dczzvv.js";
|
|
20
|
+
|
|
21
|
+
// src/plugins/bookmark/routes.ts
|
|
22
|
+
import crypto from "crypto";
|
|
23
|
+
function createRoutes(deps) {
|
|
24
|
+
const { db, serviceRegistry } = deps;
|
|
25
|
+
return new Elysia().get("/", ({ query }) => {
|
|
26
|
+
const q = query;
|
|
27
|
+
const bookmarks = q.projectId !== undefined ? db.getBookmarkedCommandsByProject(q.projectId) : db.getAllBookmarkedCommands();
|
|
28
|
+
return { bookmarks };
|
|
29
|
+
}).get("/global", () => {
|
|
30
|
+
const bookmarks = db.getBookmarkedCommandsByProject(null);
|
|
31
|
+
return { bookmarks };
|
|
32
|
+
}).get("/project/:projectId", ({ params }) => {
|
|
33
|
+
const bookmarks = db.getBookmarkedCommandsByProject(params.projectId);
|
|
34
|
+
return { bookmarks };
|
|
35
|
+
}).get("/category/:category", ({ params }) => {
|
|
36
|
+
const bookmarks = db.getBookmarkedCommandsByCategory(params.category);
|
|
37
|
+
return { bookmarks, category: params.category };
|
|
38
|
+
}).get("/:id", ({ params, set }) => {
|
|
39
|
+
const bookmark = db.getBookmarkedCommand(params.id);
|
|
40
|
+
if (!bookmark) {
|
|
41
|
+
set.status = 404;
|
|
42
|
+
return { error: "Bookmarked command not found" };
|
|
43
|
+
}
|
|
44
|
+
return { bookmark };
|
|
45
|
+
}).post("/", ({ body, set }) => {
|
|
46
|
+
try {
|
|
47
|
+
const bookmark = db.createBookmarkedCommand({
|
|
48
|
+
id: crypto.randomUUID(),
|
|
49
|
+
projectId: body.projectId,
|
|
50
|
+
command: body.command,
|
|
51
|
+
description: body.description,
|
|
52
|
+
category: body.category
|
|
53
|
+
});
|
|
54
|
+
return { bookmark };
|
|
55
|
+
} catch (err) {
|
|
56
|
+
set.status = 500;
|
|
57
|
+
return {
|
|
58
|
+
error: "Failed to create bookmarked command",
|
|
59
|
+
details: String(err)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}, {
|
|
63
|
+
body: t.Object({
|
|
64
|
+
projectId: t.Optional(t.String()),
|
|
65
|
+
command: t.String(),
|
|
66
|
+
description: t.Optional(t.String()),
|
|
67
|
+
category: t.Optional(t.String())
|
|
68
|
+
})
|
|
69
|
+
}).put("/:id", ({ params, body, set }) => {
|
|
70
|
+
const bookmark = db.getBookmarkedCommand(params.id);
|
|
71
|
+
if (!bookmark) {
|
|
72
|
+
set.status = 404;
|
|
73
|
+
return { error: "Bookmarked command not found" };
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
const updates = {};
|
|
77
|
+
if (body.command !== undefined)
|
|
78
|
+
updates.command = body.command;
|
|
79
|
+
if (body.description !== undefined)
|
|
80
|
+
updates.description = body.description;
|
|
81
|
+
if (body.category !== undefined)
|
|
82
|
+
updates.category = body.category;
|
|
83
|
+
db.updateBookmarkedCommand(params.id, updates);
|
|
84
|
+
const updatedBookmark = db.getBookmarkedCommand(params.id);
|
|
85
|
+
return { bookmark: updatedBookmark };
|
|
86
|
+
} catch (err) {
|
|
87
|
+
set.status = 500;
|
|
88
|
+
return {
|
|
89
|
+
error: "Failed to update bookmarked command",
|
|
90
|
+
details: String(err)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}, {
|
|
94
|
+
body: t.Object({
|
|
95
|
+
command: t.Optional(t.String()),
|
|
96
|
+
description: t.Optional(t.String()),
|
|
97
|
+
category: t.Optional(t.String())
|
|
98
|
+
})
|
|
99
|
+
}).delete("/:id", ({ params, set }) => {
|
|
100
|
+
const bookmark = db.getBookmarkedCommand(params.id);
|
|
101
|
+
if (!bookmark) {
|
|
102
|
+
set.status = 404;
|
|
103
|
+
return { error: "Bookmarked command not found" };
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
db.deleteBookmarkedCommand(params.id);
|
|
107
|
+
return { success: true };
|
|
108
|
+
} catch (err) {
|
|
109
|
+
set.status = 500;
|
|
110
|
+
return {
|
|
111
|
+
error: "Failed to delete bookmarked command",
|
|
112
|
+
details: String(err)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}).post("/:id/execute", async ({ params, body, set }) => {
|
|
116
|
+
const bookmark = db.getBookmarkedCommand(params.id);
|
|
117
|
+
if (!bookmark) {
|
|
118
|
+
set.status = 404;
|
|
119
|
+
return { error: "Bookmarked command not found" };
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
if (body.sessionId) {
|
|
123
|
+
const sessionProvider = serviceRegistry.getProvider("session");
|
|
124
|
+
if (!sessionProvider) {
|
|
125
|
+
set.status = 400;
|
|
126
|
+
return { error: "No session provider registered" };
|
|
127
|
+
}
|
|
128
|
+
const session = await sessionProvider.get(body.sessionId);
|
|
129
|
+
if (!session) {
|
|
130
|
+
set.status = 404;
|
|
131
|
+
return { error: "Session not found" };
|
|
132
|
+
}
|
|
133
|
+
await sessionProvider.sendCommand(body.sessionId, bookmark.command);
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
executedIn: "session",
|
|
137
|
+
sessionId: body.sessionId
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const task = db.createTask({
|
|
141
|
+
id: crypto.randomUUID(),
|
|
142
|
+
type: "command",
|
|
143
|
+
status: "pending",
|
|
144
|
+
payload: JSON.stringify({
|
|
145
|
+
command: bookmark.command,
|
|
146
|
+
cwd: body.cwd || process.cwd()
|
|
147
|
+
})
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
success: true,
|
|
151
|
+
executedIn: "task",
|
|
152
|
+
taskId: task.id
|
|
153
|
+
};
|
|
154
|
+
} catch (err) {
|
|
155
|
+
set.status = 500;
|
|
156
|
+
return {
|
|
157
|
+
error: "Failed to execute bookmarked command",
|
|
158
|
+
details: String(err)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}, {
|
|
162
|
+
body: t.Object({
|
|
163
|
+
sessionId: t.Optional(t.String()),
|
|
164
|
+
cwd: t.Optional(t.String())
|
|
165
|
+
})
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/cli/commands/bookmark.cmd.ts
|
|
170
|
+
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
171
|
+
function register(program) {
|
|
172
|
+
const cmd = program.command("bookmark").description("Manage command bookmarks");
|
|
173
|
+
cmd.command("list").description("List bookmarks").option("--project <id>", "Filter by project ID").option("--category <cat>", "Filter by category").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
174
|
+
try {
|
|
175
|
+
const url = getAgentUrl(options);
|
|
176
|
+
const params = new URLSearchParams;
|
|
177
|
+
if (options.project)
|
|
178
|
+
params.set("project", options.project);
|
|
179
|
+
if (options.category)
|
|
180
|
+
params.set("category", options.category);
|
|
181
|
+
const query = params.toString();
|
|
182
|
+
const endpoint = query ? `/api/bookmarks?${query}` : "/api/bookmarks";
|
|
183
|
+
const data = await apiGet(url, endpoint);
|
|
184
|
+
const bookmarks = data.bookmarks || [];
|
|
185
|
+
if (!bookmarks || bookmarks.length === 0) {
|
|
186
|
+
info("No bookmarks found.");
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
header("Bookmarks");
|
|
190
|
+
formatTable(bookmarks.map((b) => ({
|
|
191
|
+
ID: shortId(b.id),
|
|
192
|
+
Command: b.command || "-",
|
|
193
|
+
Description: b.description || "-",
|
|
194
|
+
Category: b.category || "-",
|
|
195
|
+
Project: b.project || b.projectId || "-"
|
|
196
|
+
})));
|
|
197
|
+
} catch (err) {
|
|
198
|
+
fail(err.message);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
cmd.command("create").description("Create a new bookmark").requiredOption("-c, --command <cmd>", "Command to bookmark").option("--description <desc>", "Bookmark description").option("--category <cat>", "Category").option("--project <id>", "Project ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
202
|
+
try {
|
|
203
|
+
const url = getAgentUrl(options);
|
|
204
|
+
const body = { command: options.command };
|
|
205
|
+
if (options.description)
|
|
206
|
+
body.description = options.description;
|
|
207
|
+
if (options.category)
|
|
208
|
+
body.category = options.category;
|
|
209
|
+
if (options.project)
|
|
210
|
+
body.project = options.project;
|
|
211
|
+
const result = await apiPost(url, "/api/bookmarks", body);
|
|
212
|
+
success(`Bookmark created: ${shortId(result?.id)}`);
|
|
213
|
+
} catch (err) {
|
|
214
|
+
fail(err.message);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
cmd.command("update").description("Update a bookmark").requiredOption("-i, --id <id>", "Bookmark ID").option("-c, --command <cmd>", "New command").option("--description <desc>", "New description").option("--category <cat>", "New category").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
218
|
+
try {
|
|
219
|
+
const url = getAgentUrl(options);
|
|
220
|
+
const body = {};
|
|
221
|
+
if (options.command)
|
|
222
|
+
body.command = options.command;
|
|
223
|
+
if (options.description)
|
|
224
|
+
body.description = options.description;
|
|
225
|
+
if (options.category)
|
|
226
|
+
body.category = options.category;
|
|
227
|
+
if (Object.keys(body).length === 0) {
|
|
228
|
+
fail("No fields to update. Provide at least one of --command, --description, or --category.");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
await apiPut(url, `/api/bookmarks/${options.id}`, body);
|
|
232
|
+
success(`Bookmark ${shortId(options.id)} updated.`);
|
|
233
|
+
} catch (err) {
|
|
234
|
+
fail(err.message);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
cmd.command("delete").description("Delete a bookmark").requiredOption("-i, --id <id>", "Bookmark ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
238
|
+
try {
|
|
239
|
+
const url = getAgentUrl(options);
|
|
240
|
+
await apiDelete(url, `/api/bookmarks/${options.id}`);
|
|
241
|
+
success(`Bookmark ${shortId(options.id)} deleted.`);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
fail(err.message);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
cmd.command("execute").description("Execute a bookmarked command").requiredOption("-i, --id <id>", "Bookmark ID").option("--session <sessionId>", "Session ID to execute in").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
247
|
+
try {
|
|
248
|
+
const url = getAgentUrl(options);
|
|
249
|
+
const body = {};
|
|
250
|
+
if (options.session)
|
|
251
|
+
body.sessionId = options.session;
|
|
252
|
+
const result = await apiPost(url, `/api/bookmarks/${options.id}/execute`, body);
|
|
253
|
+
success(`Bookmark ${shortId(options.id)} executed.`);
|
|
254
|
+
if (result?.output) {
|
|
255
|
+
console.log(result.output);
|
|
256
|
+
}
|
|
257
|
+
} catch (err) {
|
|
258
|
+
fail(err.message);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/plugins/bookmark/commands.ts
|
|
264
|
+
function registerCommands(program, _hostServices) {
|
|
265
|
+
register(program);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/plugins/bookmark/index.ts
|
|
269
|
+
var vibePlugin = {
|
|
270
|
+
name: "bookmark",
|
|
271
|
+
version: "2.2.0",
|
|
272
|
+
description: "Bookmarked command management \u2014 CRUD and execute",
|
|
273
|
+
tags: ["backend", "cli"],
|
|
274
|
+
cliCommand: "bookmark",
|
|
275
|
+
apiPrefix: "/api/bookmarks",
|
|
276
|
+
createRoutes: (deps) => createRoutes(deps),
|
|
277
|
+
onCliSetup: async (program, hostServices) => {
|
|
278
|
+
registerCommands(program, hostServices);
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
export {
|
|
282
|
+
vibePlugin
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
//# debugId=180562EA8CFA2EAC64756E2164756E21
|
|
286
|
+
//# sourceMappingURL=index-q4ytrfx7.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugins/bookmark/routes.ts", "../src/cli/commands/bookmark.cmd.ts", "../src/plugins/bookmark/commands.ts", "../src/plugins/bookmark/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Bookmark Plugin — Routes\n *\n * Bookmarked command management — CRUD + execute in session or as task.\n *\n * Endpoints (mounted by plugin system at /api/bookmarks):\n * GET / — List bookmarks (optional projectId filter)\n * GET /global — Get global (no project) bookmarks\n * GET /project/:projectId — Get bookmarks by project\n * GET /category/:category — Get bookmarks by category\n * GET /:id — Get bookmark by ID\n * POST / — Create new bookmark\n * PUT /:id — Update bookmark\n * DELETE /:id — Delete bookmark\n * POST /:id/execute — Execute bookmarked command\n */\n\nimport { Elysia, t } from \"elysia\";\nimport crypto from \"node:crypto\";\n\nimport type { AgentDatabase } from \"../../db/database.js\";\nimport type { ServiceRegistry } from \"../../core/service-registry.js\";\nimport type { SessionProvider } from \"../../core/providers/session.provider.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db, serviceRegistry } = deps;\n\n return (\n new Elysia()\n // List bookmarks (optional projectId filter)\n .get(\"/\", ({ query }) => {\n const q = query as Record<string, string>;\n const bookmarks =\n q.projectId !== undefined\n ? db.getBookmarkedCommandsByProject(q.projectId)\n : db.getAllBookmarkedCommands();\n return { bookmarks };\n })\n\n // Get global bookmarks (no project)\n .get(\"/global\", () => {\n const bookmarks = db.getBookmarkedCommandsByProject(null);\n return { bookmarks };\n })\n\n // Get bookmarks by project\n .get(\"/project/:projectId\", ({ params }) => {\n const bookmarks = db.getBookmarkedCommandsByProject(params.projectId);\n return { bookmarks };\n })\n\n // Get bookmarks by category\n .get(\"/category/:category\", ({ params }) => {\n const bookmarks = db.getBookmarkedCommandsByCategory(params.category);\n return { bookmarks, category: params.category };\n })\n\n // Get bookmark by ID\n .get(\"/:id\", ({ params, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n return { bookmark };\n })\n\n // Create new bookmark\n .post(\n \"/\",\n ({ body, set }) => {\n try {\n const bookmark = db.createBookmarkedCommand({\n id: crypto.randomUUID(),\n projectId: body.projectId,\n command: body.command,\n description: body.description,\n category: body.category,\n });\n return { bookmark };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to create bookmarked command\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n projectId: t.Optional(t.String()),\n command: t.String(),\n description: t.Optional(t.String()),\n category: t.Optional(t.String()),\n }),\n },\n )\n\n // Update bookmark\n .put(\n \"/:id\",\n ({ params, body, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n\n try {\n const updates: Record<string, string | undefined> = {};\n if (body.command !== undefined) updates.command = body.command;\n if (body.description !== undefined)\n updates.description = body.description;\n if (body.category !== undefined) updates.category = body.category;\n\n db.updateBookmarkedCommand(params.id, updates);\n const updatedBookmark = db.getBookmarkedCommand(params.id)!;\n return { bookmark: updatedBookmark };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to update bookmarked command\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n command: t.Optional(t.String()),\n description: t.Optional(t.String()),\n category: t.Optional(t.String()),\n }),\n },\n )\n\n // Delete bookmark\n .delete(\"/:id\", ({ params, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n\n try {\n db.deleteBookmarkedCommand(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to delete bookmarked command\",\n details: String(err),\n };\n }\n })\n\n // Execute bookmarked command\n .post(\n \"/:id/execute\",\n async ({ params, body, set }) => {\n const bookmark = db.getBookmarkedCommand(params.id);\n if (!bookmark) {\n set.status = 404;\n return { error: \"Bookmarked command not found\" };\n }\n\n try {\n // If sessionId provided, execute in session via SessionProvider\n if (body.sessionId) {\n const sessionProvider =\n serviceRegistry.getProvider<SessionProvider>(\"session\");\n if (!sessionProvider) {\n set.status = 400;\n return { error: \"No session provider registered\" };\n }\n\n const session = await sessionProvider.get(body.sessionId);\n if (!session) {\n set.status = 404;\n return { error: \"Session not found\" };\n }\n\n await sessionProvider.sendCommand(\n body.sessionId,\n bookmark.command,\n );\n\n return {\n success: true,\n executedIn: \"session\",\n sessionId: body.sessionId,\n };\n }\n\n // Otherwise, execute as a background task\n const task = db.createTask({\n id: crypto.randomUUID(),\n type: \"command\",\n status: \"pending\",\n payload: JSON.stringify({\n command: bookmark.command,\n cwd: body.cwd || process.cwd(),\n }),\n });\n\n return {\n success: true,\n executedIn: \"task\",\n taskId: task.id,\n };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to execute bookmarked command\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n sessionId: t.Optional(t.String()),\n cwd: t.Optional(t.String()),\n }),\n },\n )\n );\n}\n",
|
|
6
|
+
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n formatTable,\n shortId,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program\n .command(\"bookmark\")\n .description(\"Manage command bookmarks\");\n\n // bookmark list\n cmd\n .command(\"list\")\n .description(\"List bookmarks\")\n .option(\"--project <id>\", \"Filter by project ID\")\n .option(\"--category <cat>\", \"Filter by category\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const params = new URLSearchParams();\n if (options.project) params.set(\"project\", options.project);\n if (options.category) params.set(\"category\", options.category);\n const query = params.toString();\n const endpoint = query ? `/api/bookmarks?${query}` : \"/api/bookmarks\";\n const data = await apiGet<{ bookmarks: any[] }>(url, endpoint);\n const bookmarks = data.bookmarks || [];\n if (!bookmarks || bookmarks.length === 0) {\n info(\"No bookmarks found.\");\n return;\n }\n header(\"Bookmarks\");\n formatTable(\n bookmarks.map((b: any) => ({\n ID: shortId(b.id),\n Command: b.command || \"-\",\n Description: b.description || \"-\",\n Category: b.category || \"-\",\n Project: b.project || b.projectId || \"-\",\n })),\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark create\n cmd\n .command(\"create\")\n .description(\"Create a new bookmark\")\n .requiredOption(\"-c, --command <cmd>\", \"Command to bookmark\")\n .option(\"--description <desc>\", \"Bookmark description\")\n .option(\"--category <cat>\", \"Category\")\n .option(\"--project <id>\", \"Project ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = { command: options.command };\n if (options.description) body.description = options.description;\n if (options.category) body.category = options.category;\n if (options.project) body.project = options.project;\n const result = await apiPost<any>(url, \"/api/bookmarks\", body);\n success(`Bookmark created: ${shortId(result?.id)}`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark update\n cmd\n .command(\"update\")\n .description(\"Update a bookmark\")\n .requiredOption(\"-i, --id <id>\", \"Bookmark ID\")\n .option(\"-c, --command <cmd>\", \"New command\")\n .option(\"--description <desc>\", \"New description\")\n .option(\"--category <cat>\", \"New category\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.command) body.command = options.command;\n if (options.description) body.description = options.description;\n if (options.category) body.category = options.category;\n if (Object.keys(body).length === 0) {\n fail(\n \"No fields to update. Provide at least one of --command, --description, or --category.\",\n );\n return;\n }\n await apiPut<any>(url, `/api/bookmarks/${options.id}`, body);\n success(`Bookmark ${shortId(options.id)} updated.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark delete\n cmd\n .command(\"delete\")\n .description(\"Delete a bookmark\")\n .requiredOption(\"-i, --id <id>\", \"Bookmark ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(url, `/api/bookmarks/${options.id}`);\n success(`Bookmark ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // bookmark execute\n cmd\n .command(\"execute\")\n .description(\"Execute a bookmarked command\")\n .requiredOption(\"-i, --id <id>\", \"Bookmark ID\")\n .option(\"--session <sessionId>\", \"Session ID to execute in\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const body: Record<string, any> = {};\n if (options.session) body.sessionId = options.session;\n const result = await apiPost<any>(\n url,\n `/api/bookmarks/${options.id}/execute`,\n body,\n );\n success(`Bookmark ${shortId(options.id)} executed.`);\n if (result?.output) {\n console.log(result.output);\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
|
|
7
|
+
"import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerBookmark } from \"../../cli/commands/bookmark.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerBookmark(program);\n}\n",
|
|
8
|
+
"import type { VibePlugin } from \"../../core/plugin-system.js\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport { createRoutes } from \"./routes.js\";\nimport { registerCommands } from \"./commands.js\";\n\nexport const vibePlugin: VibePlugin = {\n name: \"bookmark\",\n version: \"2.2.0\",\n description: \"Bookmarked command management — CRUD and execute\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"bookmark\",\n apiPrefix: \"/api/bookmarks\",\n createRoutes: (deps: PluginRouteDeps) => createRoutes(deps),\n onCliSetup: async (program, hostServices) => {\n registerCommands(program, hostServices);\n },\n};\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "180562EA8CFA2EAC64756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Elysia,
|
|
4
|
+
t
|
|
5
|
+
} from "./index-wr0mkm57.js";
|
|
6
|
+
import {
|
|
7
|
+
apiDelete,
|
|
8
|
+
apiGet,
|
|
9
|
+
apiPost,
|
|
10
|
+
apiPut,
|
|
11
|
+
blank,
|
|
12
|
+
colors,
|
|
13
|
+
fail,
|
|
14
|
+
formatNotificationType,
|
|
15
|
+
getAgentUrl,
|
|
16
|
+
header,
|
|
17
|
+
info,
|
|
18
|
+
shortId,
|
|
19
|
+
success,
|
|
20
|
+
timeAgo
|
|
21
|
+
} from "./index-xmeskdnb.js";
|
|
22
|
+
import"./index-g8dczzvv.js";
|
|
23
|
+
|
|
24
|
+
// src/plugins/notification/routes.ts
|
|
25
|
+
import crypto from "crypto";
|
|
26
|
+
function createRoutes(deps) {
|
|
27
|
+
const { db } = deps;
|
|
28
|
+
return new Elysia().get("/", ({ query }) => {
|
|
29
|
+
const q = query;
|
|
30
|
+
if (q.status === "unread") {
|
|
31
|
+
return { notifications: db.getUnreadNotifications() };
|
|
32
|
+
}
|
|
33
|
+
if (q.projectId !== undefined) {
|
|
34
|
+
return { notifications: db.getNotificationsByProject(q.projectId) };
|
|
35
|
+
}
|
|
36
|
+
return { notifications: db.getAllNotifications() };
|
|
37
|
+
}).get("/unread", () => {
|
|
38
|
+
const notifications = db.getUnreadNotifications();
|
|
39
|
+
return { notifications, count: notifications.length };
|
|
40
|
+
}).get("/global", () => {
|
|
41
|
+
const notifications = db.getGlobalNotifications();
|
|
42
|
+
return { notifications, count: notifications.length };
|
|
43
|
+
}).get("/project/:projectId", ({ params }) => {
|
|
44
|
+
const notifications = db.getNotificationsByProject(params.projectId);
|
|
45
|
+
return { notifications };
|
|
46
|
+
}).put("/read-all", ({ set }) => {
|
|
47
|
+
try {
|
|
48
|
+
const count = db.markAllNotificationsRead();
|
|
49
|
+
return { success: true, markedCount: count };
|
|
50
|
+
} catch (err) {
|
|
51
|
+
set.status = 500;
|
|
52
|
+
return {
|
|
53
|
+
error: "Failed to mark all notifications as read",
|
|
54
|
+
details: String(err)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}).delete("/clear/old", ({ query }) => {
|
|
58
|
+
const q = query;
|
|
59
|
+
const days = q.days ? parseInt(q.days, 10) : 30;
|
|
60
|
+
const count = db.clearOldNotifications(days);
|
|
61
|
+
return { success: true, deletedCount: count };
|
|
62
|
+
}).get("/:id", ({ params, set }) => {
|
|
63
|
+
const notification = db.getNotification(params.id);
|
|
64
|
+
if (!notification) {
|
|
65
|
+
set.status = 404;
|
|
66
|
+
return { error: "Notification not found" };
|
|
67
|
+
}
|
|
68
|
+
return { notification };
|
|
69
|
+
}).post("/", ({ body, set }) => {
|
|
70
|
+
try {
|
|
71
|
+
const notification = db.createNotification({
|
|
72
|
+
id: crypto.randomUUID(),
|
|
73
|
+
sessionName: body.sessionName,
|
|
74
|
+
projectId: body.projectId,
|
|
75
|
+
type: body.type || "info",
|
|
76
|
+
title: body.title,
|
|
77
|
+
message: body.message,
|
|
78
|
+
status: "unread"
|
|
79
|
+
});
|
|
80
|
+
return { notification };
|
|
81
|
+
} catch (err) {
|
|
82
|
+
set.status = 500;
|
|
83
|
+
return {
|
|
84
|
+
error: "Failed to create notification",
|
|
85
|
+
details: String(err)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}, {
|
|
89
|
+
body: t.Object({
|
|
90
|
+
sessionName: t.Optional(t.String()),
|
|
91
|
+
projectId: t.Optional(t.String()),
|
|
92
|
+
type: t.Optional(t.Union([
|
|
93
|
+
t.Literal("info"),
|
|
94
|
+
t.Literal("success"),
|
|
95
|
+
t.Literal("warning"),
|
|
96
|
+
t.Literal("error")
|
|
97
|
+
])),
|
|
98
|
+
title: t.String(),
|
|
99
|
+
message: t.String()
|
|
100
|
+
})
|
|
101
|
+
}).put("/:id/read", ({ params, set }) => {
|
|
102
|
+
const notification = db.getNotification(params.id);
|
|
103
|
+
if (!notification) {
|
|
104
|
+
set.status = 404;
|
|
105
|
+
return { error: "Notification not found" };
|
|
106
|
+
}
|
|
107
|
+
db.updateNotificationStatus(params.id, "read");
|
|
108
|
+
return { success: true };
|
|
109
|
+
}).put("/:id/unread", ({ params, set }) => {
|
|
110
|
+
const notification = db.getNotification(params.id);
|
|
111
|
+
if (!notification) {
|
|
112
|
+
set.status = 404;
|
|
113
|
+
return { error: "Notification not found" };
|
|
114
|
+
}
|
|
115
|
+
db.updateNotificationStatus(params.id, "unread");
|
|
116
|
+
return { success: true };
|
|
117
|
+
}).delete("/:id", ({ params, set }) => {
|
|
118
|
+
const notification = db.getNotification(params.id);
|
|
119
|
+
if (!notification) {
|
|
120
|
+
set.status = 404;
|
|
121
|
+
return { error: "Notification not found" };
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
db.deleteNotification(params.id);
|
|
125
|
+
return { success: true };
|
|
126
|
+
} catch (err) {
|
|
127
|
+
set.status = 500;
|
|
128
|
+
return {
|
|
129
|
+
error: "Failed to delete notification",
|
|
130
|
+
details: String(err)
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}).post("/webhook/:sessionId", ({ params, body, set }) => {
|
|
134
|
+
try {
|
|
135
|
+
const typeMap = {
|
|
136
|
+
task_completed: "success",
|
|
137
|
+
info: "info",
|
|
138
|
+
success: "success",
|
|
139
|
+
warning: "warning",
|
|
140
|
+
error: "error"
|
|
141
|
+
};
|
|
142
|
+
const mappedType = typeMap[body.type || "info"] || "info";
|
|
143
|
+
const message = body.metadata ? `${body.message}
|
|
144
|
+
|
|
145
|
+
Metadata: ${JSON.stringify(body.metadata, null, 2)}` : body.message;
|
|
146
|
+
const notification = db.createNotification({
|
|
147
|
+
id: crypto.randomUUID(),
|
|
148
|
+
sessionName: body.projectName,
|
|
149
|
+
projectId: params.sessionId,
|
|
150
|
+
type: mappedType,
|
|
151
|
+
title: body.title,
|
|
152
|
+
message,
|
|
153
|
+
status: "unread"
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
notification,
|
|
157
|
+
webhook: true,
|
|
158
|
+
originalType: body.type || "info",
|
|
159
|
+
mappedType
|
|
160
|
+
};
|
|
161
|
+
} catch (err) {
|
|
162
|
+
set.status = 500;
|
|
163
|
+
return {
|
|
164
|
+
error: "Failed to create webhook notification",
|
|
165
|
+
details: String(err)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}, {
|
|
169
|
+
body: t.Object({
|
|
170
|
+
type: t.Optional(t.String()),
|
|
171
|
+
title: t.String(),
|
|
172
|
+
message: t.String(),
|
|
173
|
+
metadata: t.Optional(t.Record(t.String(), t.Unknown())),
|
|
174
|
+
projectName: t.Optional(t.String())
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/cli/commands/notify.cmd.ts
|
|
180
|
+
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
181
|
+
function register(program) {
|
|
182
|
+
const cmd = program.command("notify").description("Manage notifications");
|
|
183
|
+
cmd.command("list").description("List notifications").option("--unread", "Show only unread notifications").option("--project <id>", "Filter by project ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
184
|
+
try {
|
|
185
|
+
const url = getAgentUrl(options);
|
|
186
|
+
const params = new URLSearchParams;
|
|
187
|
+
if (options.unread)
|
|
188
|
+
params.set("unread", "true");
|
|
189
|
+
if (options.project)
|
|
190
|
+
params.set("project", options.project);
|
|
191
|
+
const query = params.toString();
|
|
192
|
+
const endpoint = query ? `/api/notifications?${query}` : "/api/notifications";
|
|
193
|
+
const data = await apiGet(url, endpoint);
|
|
194
|
+
const notifications = data.notifications || [];
|
|
195
|
+
if (!notifications || notifications.length === 0) {
|
|
196
|
+
info("No notifications found.");
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
header("Notifications");
|
|
200
|
+
blank();
|
|
201
|
+
for (const n of notifications) {
|
|
202
|
+
const icon = formatNotificationType(n.type);
|
|
203
|
+
const time = n.createdAt ? colors.dim(timeAgo(n.createdAt)) : "";
|
|
204
|
+
const title = colors.bold(n.title || "Untitled");
|
|
205
|
+
const id = colors.dim(`[${shortId(n.id)}]`);
|
|
206
|
+
console.log(` ${icon} ${title} ${id} ${time}`);
|
|
207
|
+
if (n.message) {
|
|
208
|
+
console.log(` ${n.message}`);
|
|
209
|
+
}
|
|
210
|
+
blank();
|
|
211
|
+
}
|
|
212
|
+
} catch (err) {
|
|
213
|
+
fail(err.message);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
cmd.command("create").description("Create a notification").requiredOption("--title <title>", "Notification title").requiredOption("--message <msg>", "Notification message").option("--type <type>", "Notification type", "info").option("--project <id>", "Project ID").option("--session <name>", "Session name").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
217
|
+
try {
|
|
218
|
+
const url = getAgentUrl(options);
|
|
219
|
+
const body = {
|
|
220
|
+
title: options.title,
|
|
221
|
+
message: options.message,
|
|
222
|
+
type: options.type
|
|
223
|
+
};
|
|
224
|
+
if (options.project)
|
|
225
|
+
body.project = options.project;
|
|
226
|
+
if (options.session)
|
|
227
|
+
body.session = options.session;
|
|
228
|
+
const result = await apiPost(url, "/api/notifications", body);
|
|
229
|
+
success(`Notification created: ${shortId(result?.id)}`);
|
|
230
|
+
} catch (err) {
|
|
231
|
+
fail(err.message);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
cmd.command("delete").description("Delete a notification").requiredOption("-i, --id <id>", "Notification ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
235
|
+
try {
|
|
236
|
+
const url = getAgentUrl(options);
|
|
237
|
+
await apiDelete(url, `/api/notifications/${options.id}`);
|
|
238
|
+
success(`Notification ${shortId(options.id)} deleted.`);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
fail(err.message);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
cmd.command("read-all").description("Mark all notifications as read").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
244
|
+
try {
|
|
245
|
+
const url = getAgentUrl(options);
|
|
246
|
+
await apiPut(url, "/api/notifications/read-all", {});
|
|
247
|
+
success("All notifications marked as read.");
|
|
248
|
+
} catch (err) {
|
|
249
|
+
fail(err.message);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
cmd.command("clear-old").description("Clear old notifications").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
253
|
+
try {
|
|
254
|
+
const url = getAgentUrl(options);
|
|
255
|
+
await apiDelete(url, "/api/notifications/clear/old");
|
|
256
|
+
success("Old notifications cleared.");
|
|
257
|
+
} catch (err) {
|
|
258
|
+
fail(err.message);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
cmd.command("webhook").description("Send a webhook notification to a session").requiredOption("--session <sessionId>", "Target session ID").option("--title <title>", "Notification title").option("--message <msg>", "Notification message").option("--type <type>", "Notification type", "info").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
262
|
+
try {
|
|
263
|
+
const url = getAgentUrl(options);
|
|
264
|
+
const body = {};
|
|
265
|
+
if (options.title)
|
|
266
|
+
body.title = options.title;
|
|
267
|
+
if (options.message)
|
|
268
|
+
body.message = options.message;
|
|
269
|
+
if (options.type)
|
|
270
|
+
body.type = options.type;
|
|
271
|
+
await apiPost(url, `/api/notifications/webhook/${options.session}`, body);
|
|
272
|
+
success(`Webhook notification sent to session ${shortId(options.session)}.`);
|
|
273
|
+
} catch (err) {
|
|
274
|
+
fail(err.message);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/plugins/notification/commands.ts
|
|
280
|
+
function registerCommands(program, _hostServices) {
|
|
281
|
+
register(program);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/plugins/notification/index.ts
|
|
285
|
+
var vibePlugin = {
|
|
286
|
+
name: "notification",
|
|
287
|
+
version: "2.2.0",
|
|
288
|
+
description: "Notification management \u2014 CRUD, read/unread status, webhooks",
|
|
289
|
+
tags: ["backend", "cli"],
|
|
290
|
+
cliCommand: "notify",
|
|
291
|
+
apiPrefix: "/api/notifications",
|
|
292
|
+
createRoutes: (deps) => createRoutes(deps),
|
|
293
|
+
onCliSetup: async (program, hostServices) => {
|
|
294
|
+
registerCommands(program, hostServices);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
export {
|
|
298
|
+
vibePlugin
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
//# debugId=933C583CBD4F9A8B64756E2164756E21
|
|
302
|
+
//# sourceMappingURL=index-qthbtg9n.js.map
|