@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,229 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
logger
|
|
4
|
+
} from "./index-88ym10cs.js";
|
|
5
|
+
import {
|
|
6
|
+
Elysia
|
|
7
|
+
} from "./index-wr0mkm57.js";
|
|
8
|
+
import {
|
|
9
|
+
apiGet,
|
|
10
|
+
blank,
|
|
11
|
+
colors,
|
|
12
|
+
fail,
|
|
13
|
+
getAgentUrl,
|
|
14
|
+
header,
|
|
15
|
+
info,
|
|
16
|
+
timeAgo
|
|
17
|
+
} from "./index-xmeskdnb.js";
|
|
18
|
+
import"./index-g8dczzvv.js";
|
|
19
|
+
|
|
20
|
+
// src/plugins/log/routes.ts
|
|
21
|
+
var LEVEL_PRIORITY = {
|
|
22
|
+
debug: 0,
|
|
23
|
+
info: 1,
|
|
24
|
+
warn: 2,
|
|
25
|
+
error: 3
|
|
26
|
+
};
|
|
27
|
+
function createRoutes(_deps) {
|
|
28
|
+
return new Elysia().get("/", async ({ query }) => {
|
|
29
|
+
const q = query;
|
|
30
|
+
const entries = await logger.readHistory({
|
|
31
|
+
level: q.level,
|
|
32
|
+
source: q.source,
|
|
33
|
+
from: q.from,
|
|
34
|
+
to: q.to,
|
|
35
|
+
limit: q.limit ? parseInt(q.limit, 10) : 200,
|
|
36
|
+
offset: q.offset ? parseInt(q.offset, 10) : 0
|
|
37
|
+
});
|
|
38
|
+
return { entries, count: entries.length };
|
|
39
|
+
}).get("/stream", ({ query, set }) => {
|
|
40
|
+
const q = query;
|
|
41
|
+
const minLevel = q.level ?? "info";
|
|
42
|
+
const sourceFilter = q.source ?? "";
|
|
43
|
+
set.headers["Content-Type"] = "text/event-stream";
|
|
44
|
+
set.headers["Cache-Control"] = "no-cache";
|
|
45
|
+
set.headers["Connection"] = "keep-alive";
|
|
46
|
+
set.headers["X-Accel-Buffering"] = "no";
|
|
47
|
+
return new ReadableStream({
|
|
48
|
+
start(controller) {
|
|
49
|
+
const encoder = new TextEncoder;
|
|
50
|
+
controller.enqueue(encoder.encode(`: connected
|
|
51
|
+
|
|
52
|
+
`));
|
|
53
|
+
const onLog = (entry) => {
|
|
54
|
+
if (LEVEL_PRIORITY[entry.level] < LEVEL_PRIORITY[minLevel])
|
|
55
|
+
return;
|
|
56
|
+
if (sourceFilter && !entry.source.includes(sourceFilter))
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
controller.enqueue(encoder.encode(`event: log
|
|
60
|
+
data: ${JSON.stringify(entry)}
|
|
61
|
+
|
|
62
|
+
`));
|
|
63
|
+
} catch {
|
|
64
|
+
cleanup();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const heartbeat = setInterval(() => {
|
|
68
|
+
try {
|
|
69
|
+
controller.enqueue(encoder.encode(`: heartbeat
|
|
70
|
+
|
|
71
|
+
`));
|
|
72
|
+
} catch {
|
|
73
|
+
cleanup();
|
|
74
|
+
}
|
|
75
|
+
}, 15000);
|
|
76
|
+
const cleanup = () => {
|
|
77
|
+
clearInterval(heartbeat);
|
|
78
|
+
logger.removeListener("log", onLog);
|
|
79
|
+
try {
|
|
80
|
+
controller.close();
|
|
81
|
+
} catch {}
|
|
82
|
+
};
|
|
83
|
+
logger.on("log", onLog);
|
|
84
|
+
return () => cleanup();
|
|
85
|
+
},
|
|
86
|
+
cancel() {}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/cli/commands/log.cmd.ts
|
|
92
|
+
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
93
|
+
function register(program) {
|
|
94
|
+
const cmd = program.command("log").description("View and stream logs");
|
|
95
|
+
cmd.command("list").description("List recent log entries").option("--level <level>", "Minimum log level", "info").option("--limit <n>", "Number of entries to show", "50").option("--source <source>", "Filter by source").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
96
|
+
try {
|
|
97
|
+
const url = getAgentUrl(options);
|
|
98
|
+
const params = new URLSearchParams;
|
|
99
|
+
params.set("level", options.level);
|
|
100
|
+
params.set("limit", options.limit);
|
|
101
|
+
if (options.source)
|
|
102
|
+
params.set("source", options.source);
|
|
103
|
+
const logs = await apiGet(url, `/api/logs?${params.toString()}`);
|
|
104
|
+
if (!logs || logs.length === 0) {
|
|
105
|
+
info("No log entries found.");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
header("Logs");
|
|
109
|
+
blank();
|
|
110
|
+
for (const entry of logs) {
|
|
111
|
+
const level = formatLogLevel(entry.level);
|
|
112
|
+
const time = entry.timestamp ? colors.dim(timeAgo(entry.timestamp)) : "";
|
|
113
|
+
const source = entry.source ? colors.cyan(`[${entry.source}]`) : "";
|
|
114
|
+
const message = entry.message || "";
|
|
115
|
+
console.log(` ${level} ${source} ${message} ${time}`);
|
|
116
|
+
}
|
|
117
|
+
} catch (err) {
|
|
118
|
+
fail(err.message);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
cmd.command("stream").description("Stream logs in real-time (SSE)").option("--level <level>", "Minimum log level", "info").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
122
|
+
try {
|
|
123
|
+
const url = getAgentUrl(options);
|
|
124
|
+
const params = new URLSearchParams;
|
|
125
|
+
params.set("level", options.level);
|
|
126
|
+
const streamUrl = `${url}/api/logs/stream?${params.toString()}`;
|
|
127
|
+
info(`Streaming logs from ${url} (level: ${options.level})...`);
|
|
128
|
+
info(`Press Ctrl+C to stop.
|
|
129
|
+
`);
|
|
130
|
+
const response = await fetch(streamUrl, {
|
|
131
|
+
headers: { Accept: "text/event-stream" }
|
|
132
|
+
});
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
fail(`Failed to connect to log stream: ${response.status} ${response.statusText}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!response.body) {
|
|
138
|
+
fail("No response body for SSE stream.");
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const decoder = new TextDecoder;
|
|
142
|
+
const reader = response.body.getReader();
|
|
143
|
+
const cleanup = () => {
|
|
144
|
+
reader.cancel().catch(() => {});
|
|
145
|
+
console.log(`
|
|
146
|
+
Log stream ended.`);
|
|
147
|
+
process.exit(0);
|
|
148
|
+
};
|
|
149
|
+
process.on("SIGINT", cleanup);
|
|
150
|
+
process.on("SIGTERM", cleanup);
|
|
151
|
+
let buffer = "";
|
|
152
|
+
while (true) {
|
|
153
|
+
const { done, value } = await reader.read();
|
|
154
|
+
if (done)
|
|
155
|
+
break;
|
|
156
|
+
buffer += decoder.decode(value, { stream: true });
|
|
157
|
+
const lines = buffer.split(`
|
|
158
|
+
`);
|
|
159
|
+
buffer = lines.pop() || "";
|
|
160
|
+
for (const line of lines) {
|
|
161
|
+
if (line.startsWith("data: ")) {
|
|
162
|
+
const data = line.slice(6).trim();
|
|
163
|
+
if (!data || data === "[DONE]")
|
|
164
|
+
continue;
|
|
165
|
+
try {
|
|
166
|
+
const entry = JSON.parse(data);
|
|
167
|
+
const level = formatLogLevel(entry.level);
|
|
168
|
+
const source = entry.source ? colors.cyan(`[${entry.source}]`) : "";
|
|
169
|
+
const message = entry.message || "";
|
|
170
|
+
const time = entry.timestamp ? colors.dim(new Date(entry.timestamp).toLocaleTimeString()) : "";
|
|
171
|
+
console.log(`${level} ${source} ${message} ${time}`);
|
|
172
|
+
} catch {
|
|
173
|
+
if (data.trim())
|
|
174
|
+
console.log(data);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} catch (err) {
|
|
180
|
+
if (err.name === "AbortError")
|
|
181
|
+
return;
|
|
182
|
+
fail(err.message);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function formatLogLevel(level) {
|
|
187
|
+
if (!level)
|
|
188
|
+
return colors.dim("???");
|
|
189
|
+
switch (level.toLowerCase()) {
|
|
190
|
+
case "error":
|
|
191
|
+
return colors.red(colors.bold("ERR"));
|
|
192
|
+
case "warn":
|
|
193
|
+
case "warning":
|
|
194
|
+
return colors.yellow("WRN");
|
|
195
|
+
case "info":
|
|
196
|
+
return colors.blue("INF");
|
|
197
|
+
case "debug":
|
|
198
|
+
return colors.gray("DBG");
|
|
199
|
+
case "trace":
|
|
200
|
+
return colors.dim("TRC");
|
|
201
|
+
default:
|
|
202
|
+
return colors.dim(level.toUpperCase().slice(0, 3));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/plugins/log/commands.ts
|
|
207
|
+
function registerCommands(program, _hostServices) {
|
|
208
|
+
register(program);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/plugins/log/index.ts
|
|
212
|
+
var vibePlugin = {
|
|
213
|
+
name: "log",
|
|
214
|
+
version: "2.2.0",
|
|
215
|
+
description: "Log viewing and real-time streaming via SSE",
|
|
216
|
+
tags: ["backend", "cli"],
|
|
217
|
+
cliCommand: "log",
|
|
218
|
+
apiPrefix: "/api/logs",
|
|
219
|
+
createRoutes: (deps) => createRoutes(deps),
|
|
220
|
+
onCliSetup: async (program, hostServices) => {
|
|
221
|
+
registerCommands(program, hostServices);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
export {
|
|
225
|
+
vibePlugin
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
//# debugId=04448E46225BA29664756E2164756E21
|
|
229
|
+
//# sourceMappingURL=index-a9g7hbj9.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugins/log/routes.ts", "../src/cli/commands/log.cmd.ts", "../src/plugins/log/commands.ts", "../src/plugins/log/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Log Plugin Routes\n *\n * Log viewing and real-time streaming via Server-Sent Events.\n *\n * Endpoints:\n * GET / — List recent log entries (query: level, limit, source, from, to, offset)\n * GET /stream — SSE stream of log entries (query: level, source)\n */\n\nimport { Elysia } from \"elysia\";\n\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport type { LogLevel, LogEntry } from \"../../core/types.js\";\nimport { logger } from \"../../services/logger.js\";\n\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport function createRoutes(_deps: PluginRouteDeps) {\n return (\n new Elysia()\n // List recent log entries from the log file\n .get(\"/\", async ({ query }) => {\n const q = query as Record<string, string>;\n const entries = await logger.readHistory({\n level: q.level as LogLevel | undefined,\n source: q.source,\n from: q.from,\n to: q.to,\n limit: q.limit ? parseInt(q.limit, 10) : 200,\n offset: q.offset ? parseInt(q.offset, 10) : 0,\n });\n return { entries, count: entries.length };\n })\n\n // SSE stream logs using EventEmitter\n .get(\"/stream\", ({ query, set }) => {\n const q = query as Record<string, string>;\n const minLevel = (q.level ?? \"info\") as LogLevel;\n const sourceFilter = q.source ?? \"\";\n\n set.headers[\"Content-Type\"] = \"text/event-stream\";\n set.headers[\"Cache-Control\"] = \"no-cache\";\n set.headers[\"Connection\"] = \"keep-alive\";\n set.headers[\"X-Accel-Buffering\"] = \"no\";\n\n return new ReadableStream({\n start(controller) {\n const encoder = new TextEncoder();\n\n // Initial comment to establish connection\n controller.enqueue(encoder.encode(\": connected\\n\\n\"));\n\n // Log event handler\n const onLog = (entry: LogEntry) => {\n if (LEVEL_PRIORITY[entry.level] < LEVEL_PRIORITY[minLevel])\n return;\n if (sourceFilter && !entry.source.includes(sourceFilter)) return;\n\n try {\n controller.enqueue(\n encoder.encode(\n `event: log\\ndata: ${JSON.stringify(entry)}\\n\\n`,\n ),\n );\n } catch {\n cleanup();\n }\n };\n\n // Heartbeat every 15s\n const heartbeat = setInterval(() => {\n try {\n controller.enqueue(encoder.encode(\": heartbeat\\n\\n\"));\n } catch {\n cleanup();\n }\n }, 15_000);\n\n const cleanup = () => {\n clearInterval(heartbeat);\n logger.removeListener(\"log\", onLog);\n try {\n controller.close();\n } catch {\n /* already closed */\n }\n };\n\n logger.on(\"log\", onLog);\n\n // Cleanup on stream cancel\n return () => cleanup();\n },\n\n cancel() {\n // Client disconnected — cleanup handled by start's return\n },\n });\n })\n );\n}\n",
|
|
6
|
+
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n agentFetch,\n apiGet,\n fail,\n info,\n header,\n blank,\n colors,\n timeAgo,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\nexport function register(program: Command): void {\n const cmd = program.command(\"log\").description(\"View and stream logs\");\n\n // log list\n cmd\n .command(\"list\")\n .description(\"List recent log entries\")\n .option(\"--level <level>\", \"Minimum log level\", \"info\")\n .option(\"--limit <n>\", \"Number of entries to show\", \"50\")\n .option(\"--source <source>\", \"Filter by source\")\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 params.set(\"level\", options.level);\n params.set(\"limit\", options.limit);\n if (options.source) params.set(\"source\", options.source);\n const logs = await apiGet<any[]>(url, `/api/logs?${params.toString()}`);\n if (!logs || logs.length === 0) {\n info(\"No log entries found.\");\n return;\n }\n header(\"Logs\");\n blank();\n for (const entry of logs) {\n const level = formatLogLevel(entry.level);\n const time = entry.timestamp\n ? colors.dim(timeAgo(entry.timestamp))\n : \"\";\n const source = entry.source ? colors.cyan(`[${entry.source}]`) : \"\";\n const message = entry.message || \"\";\n console.log(` ${level} ${source} ${message} ${time}`);\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // log stream\n cmd\n .command(\"stream\")\n .description(\"Stream logs in real-time (SSE)\")\n .option(\"--level <level>\", \"Minimum log level\", \"info\")\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 params.set(\"level\", options.level);\n const streamUrl = `${url}/api/logs/stream?${params.toString()}`;\n\n info(`Streaming logs from ${url} (level: ${options.level})...`);\n info(\"Press Ctrl+C to stop.\\n\");\n\n const response = await fetch(streamUrl, {\n headers: { Accept: \"text/event-stream\" },\n });\n\n if (!response.ok) {\n fail(\n `Failed to connect to log stream: ${response.status} ${response.statusText}`,\n );\n return;\n }\n\n if (!response.body) {\n fail(\"No response body for SSE stream.\");\n return;\n }\n\n const decoder = new TextDecoder();\n const reader = response.body.getReader();\n\n const cleanup = () => {\n reader.cancel().catch(() => {});\n console.log(\"\\nLog stream ended.\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n let buffer = \"\";\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n const data = line.slice(6).trim();\n if (!data || data === \"[DONE]\") continue;\n try {\n const entry = JSON.parse(data);\n const level = formatLogLevel(entry.level);\n const source = entry.source\n ? colors.cyan(`[${entry.source}]`)\n : \"\";\n const message = entry.message || \"\";\n const time = entry.timestamp\n ? colors.dim(new Date(entry.timestamp).toLocaleTimeString())\n : \"\";\n console.log(`${level} ${source} ${message} ${time}`);\n } catch {\n // raw text line\n if (data.trim()) console.log(data);\n }\n }\n }\n }\n } catch (err: any) {\n if (err.name === \"AbortError\") return;\n fail(err.message);\n }\n });\n}\n\nfunction formatLogLevel(level: string | undefined): string {\n if (!level) return colors.dim(\"???\");\n switch (level.toLowerCase()) {\n case \"error\":\n return colors.red(colors.bold(\"ERR\"));\n case \"warn\":\n case \"warning\":\n return colors.yellow(\"WRN\");\n case \"info\":\n return colors.blue(\"INF\");\n case \"debug\":\n return colors.gray(\"DBG\");\n case \"trace\":\n return colors.dim(\"TRC\");\n default:\n return colors.dim(level.toUpperCase().slice(0, 3));\n }\n}\n",
|
|
7
|
+
"import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerLog } from \"../../cli/commands/log.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerLog(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: \"log\",\n version: \"2.2.0\",\n description: \"Log viewing and real-time streaming via SSE\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"log\",\n apiPrefix: \"/api/logs\",\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": "04448E46225BA29664756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
logger
|
|
4
|
+
} from "./index-88ym10cs.js";
|
|
5
|
+
|
|
6
|
+
// src/core/service-registry.ts
|
|
7
|
+
class ServiceRegistry {
|
|
8
|
+
providers = new Map;
|
|
9
|
+
providerOrder = new Map;
|
|
10
|
+
services = new Map;
|
|
11
|
+
db;
|
|
12
|
+
constructor(db) {
|
|
13
|
+
this.db = db;
|
|
14
|
+
}
|
|
15
|
+
registerProvider(type, provider, pluginName) {
|
|
16
|
+
if (!this.providers.has(type)) {
|
|
17
|
+
this.providers.set(type, new Map);
|
|
18
|
+
this.providerOrder.set(type, []);
|
|
19
|
+
}
|
|
20
|
+
const typeMap = this.providers.get(type);
|
|
21
|
+
const order = this.providerOrder.get(type);
|
|
22
|
+
if (typeMap.has(pluginName)) {
|
|
23
|
+
logger.info("service-registry", `Updating ${type} provider from plugin '${pluginName}'`);
|
|
24
|
+
} else {
|
|
25
|
+
logger.info("service-registry", `Registered ${type} provider from plugin '${pluginName}'`);
|
|
26
|
+
}
|
|
27
|
+
typeMap.set(pluginName, {
|
|
28
|
+
provider,
|
|
29
|
+
pluginName,
|
|
30
|
+
registeredAt: new Date
|
|
31
|
+
});
|
|
32
|
+
const idx = order.indexOf(pluginName);
|
|
33
|
+
if (idx !== -1)
|
|
34
|
+
order.splice(idx, 1);
|
|
35
|
+
order.push(pluginName);
|
|
36
|
+
}
|
|
37
|
+
getProvider(type) {
|
|
38
|
+
const typeMap = this.providers.get(type);
|
|
39
|
+
if (!typeMap || typeMap.size === 0)
|
|
40
|
+
return;
|
|
41
|
+
if (this.db) {
|
|
42
|
+
try {
|
|
43
|
+
const defaultName = this.db.getConfig(`provider:default:${type}`);
|
|
44
|
+
if (defaultName && typeMap.has(defaultName)) {
|
|
45
|
+
return typeMap.get(defaultName).provider;
|
|
46
|
+
}
|
|
47
|
+
} catch {}
|
|
48
|
+
}
|
|
49
|
+
const order = this.providerOrder.get(type);
|
|
50
|
+
if (order && order.length > 0) {
|
|
51
|
+
const lastPluginName = order[order.length - 1];
|
|
52
|
+
return typeMap.get(lastPluginName)?.provider;
|
|
53
|
+
}
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
getProviderByName(type, pluginName) {
|
|
57
|
+
const typeMap = this.providers.get(type);
|
|
58
|
+
if (!typeMap)
|
|
59
|
+
return;
|
|
60
|
+
return typeMap.get(pluginName)?.provider;
|
|
61
|
+
}
|
|
62
|
+
hasProvider(type) {
|
|
63
|
+
const typeMap = this.providers.get(type);
|
|
64
|
+
return !!typeMap && typeMap.size > 0;
|
|
65
|
+
}
|
|
66
|
+
unregisterProvider(type, pluginName) {
|
|
67
|
+
const typeMap = this.providers.get(type);
|
|
68
|
+
if (!typeMap)
|
|
69
|
+
return false;
|
|
70
|
+
const removed = typeMap.delete(pluginName);
|
|
71
|
+
if (removed) {
|
|
72
|
+
const order = this.providerOrder.get(type);
|
|
73
|
+
if (order) {
|
|
74
|
+
const idx = order.indexOf(pluginName);
|
|
75
|
+
if (idx !== -1)
|
|
76
|
+
order.splice(idx, 1);
|
|
77
|
+
}
|
|
78
|
+
logger.info("service-registry", `Unregistered ${type} provider from plugin '${pluginName}'`);
|
|
79
|
+
}
|
|
80
|
+
return removed;
|
|
81
|
+
}
|
|
82
|
+
listProvidersForType(type) {
|
|
83
|
+
const typeMap = this.providers.get(type);
|
|
84
|
+
if (!typeMap)
|
|
85
|
+
return [];
|
|
86
|
+
let defaultName;
|
|
87
|
+
if (this.db) {
|
|
88
|
+
try {
|
|
89
|
+
defaultName = this.db.getConfig(`provider:default:${type}`) ?? undefined;
|
|
90
|
+
} catch {}
|
|
91
|
+
}
|
|
92
|
+
if (!defaultName || !typeMap.has(defaultName)) {
|
|
93
|
+
const order = this.providerOrder.get(type);
|
|
94
|
+
defaultName = order && order.length > 0 ? order[order.length - 1] : undefined;
|
|
95
|
+
}
|
|
96
|
+
return Array.from(typeMap.keys()).map((name) => ({
|
|
97
|
+
pluginName: name,
|
|
98
|
+
isDefault: name === defaultName
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
registerService(pluginName, serviceName, service) {
|
|
102
|
+
const key = `${pluginName}:${serviceName}`;
|
|
103
|
+
this.services.set(key, { service, pluginName });
|
|
104
|
+
logger.debug("service-registry", `Registered service '${key}'`);
|
|
105
|
+
}
|
|
106
|
+
getService(pluginName, serviceName) {
|
|
107
|
+
const key = `${pluginName}:${serviceName}`;
|
|
108
|
+
return this.services.get(key)?.service;
|
|
109
|
+
}
|
|
110
|
+
unregisterServices(pluginName) {
|
|
111
|
+
const keysToDelete = [];
|
|
112
|
+
for (const [key, entry] of this.services) {
|
|
113
|
+
if (entry.pluginName === pluginName) {
|
|
114
|
+
keysToDelete.push(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const key of keysToDelete) {
|
|
118
|
+
this.services.delete(key);
|
|
119
|
+
}
|
|
120
|
+
if (keysToDelete.length > 0) {
|
|
121
|
+
logger.info("service-registry", `Unregistered ${keysToDelete.length} services from ${pluginName}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
listProviders() {
|
|
125
|
+
const result = [];
|
|
126
|
+
for (const [type, typeMap] of this.providers) {
|
|
127
|
+
for (const [pluginName, entry] of typeMap) {
|
|
128
|
+
result.push({ type, name: pluginName, pluginName: entry.pluginName });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
listServices() {
|
|
134
|
+
return Array.from(this.services.entries()).map(([key, entry]) => ({
|
|
135
|
+
pluginName: entry.pluginName,
|
|
136
|
+
serviceName: key.split(":").slice(1).join(":")
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
clear() {
|
|
140
|
+
this.providers.clear();
|
|
141
|
+
this.providerOrder.clear();
|
|
142
|
+
this.services.clear();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export { ServiceRegistry };
|
|
147
|
+
|
|
148
|
+
//# debugId=7B6692C0FD509A9264756E2164756E21
|
|
149
|
+
//# sourceMappingURL=index-atjhkm74.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/core/service-registry.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Service Registry\n *\n * Central registry for providers and named services.\n * Supports multiple providers per type with configurable defaults.\n *\n * Default provider resolution order:\n * 1. DB config key `provider:default:<type>` (if db is available)\n * 2. Last registered provider (fallback)\n */\n\nimport { logger } from \"../services/logger.js\";\nimport type { AgentDatabase } from \"../db/database.js\";\n\n// Provider types\nexport type ProviderType = \"tunnel\" | \"session\";\n\ninterface RegisteredProvider {\n provider: unknown;\n pluginName: string;\n registeredAt: Date;\n}\n\ninterface RegisteredService {\n service: unknown;\n pluginName: string;\n}\n\nexport class ServiceRegistry {\n // Multi-provider: type → Map<pluginName, RegisteredProvider>\n private providers = new Map<ProviderType, Map<string, RegisteredProvider>>();\n // Track registration order for fallback default\n private providerOrder = new Map<ProviderType, string[]>();\n // Named services\n private services = new Map<string, RegisteredService>();\n // Optional DB for default provider lookups\n private db?: AgentDatabase;\n\n constructor(db?: AgentDatabase) {\n this.db = db;\n }\n\n // ── Provider Registration ──────────────────────────────────────────\n\n /**\n * Register a provider for a given type.\n * Multiple providers per type are supported, keyed by plugin name.\n */\n registerProvider(\n type: ProviderType,\n provider: unknown,\n pluginName: string,\n ): void {\n if (!this.providers.has(type)) {\n this.providers.set(type, new Map());\n this.providerOrder.set(type, []);\n }\n\n const typeMap = this.providers.get(type)!;\n const order = this.providerOrder.get(type)!;\n\n if (typeMap.has(pluginName)) {\n logger.info(\n \"service-registry\",\n `Updating ${type} provider from plugin '${pluginName}'`,\n );\n } else {\n logger.info(\n \"service-registry\",\n `Registered ${type} provider from plugin '${pluginName}'`,\n );\n }\n\n typeMap.set(pluginName, {\n provider,\n pluginName,\n registeredAt: new Date(),\n });\n\n // Update order: move to end if already present, otherwise append\n const idx = order.indexOf(pluginName);\n if (idx !== -1) order.splice(idx, 1);\n order.push(pluginName);\n }\n\n /**\n * Get the default provider for a type.\n *\n * Resolution:\n * 1. DB config `provider:default:<type>` → matching provider\n * 2. Last registered provider (fallback)\n * 3. undefined\n */\n getProvider<T>(type: ProviderType): T | undefined {\n const typeMap = this.providers.get(type);\n if (!typeMap || typeMap.size === 0) return undefined;\n\n // Check DB for configured default\n if (this.db) {\n try {\n const defaultName = this.db.getConfig(`provider:default:${type}`);\n if (defaultName && typeMap.has(defaultName)) {\n return typeMap.get(defaultName)!.provider as T;\n }\n } catch {\n // DB not available or errored, fall through to fallback\n }\n }\n\n // Fallback: last registered\n const order = this.providerOrder.get(type);\n if (order && order.length > 0) {\n const lastPluginName = order[order.length - 1];\n return typeMap.get(lastPluginName)?.provider as T;\n }\n\n return undefined;\n }\n\n /**\n * Get a specific provider by plugin name.\n */\n getProviderByName<T>(type: ProviderType, pluginName: string): T | undefined {\n const typeMap = this.providers.get(type);\n if (!typeMap) return undefined;\n return typeMap.get(pluginName)?.provider as T;\n }\n\n /**\n * Check if at least one provider is registered for a type.\n */\n hasProvider(type: ProviderType): boolean {\n const typeMap = this.providers.get(type);\n return !!typeMap && typeMap.size > 0;\n }\n\n /**\n * Unregister a specific provider by type and plugin name.\n */\n unregisterProvider(type: ProviderType, pluginName: string): boolean {\n const typeMap = this.providers.get(type);\n if (!typeMap) return false;\n\n const removed = typeMap.delete(pluginName);\n\n if (removed) {\n const order = this.providerOrder.get(type);\n if (order) {\n const idx = order.indexOf(pluginName);\n if (idx !== -1) order.splice(idx, 1);\n }\n logger.info(\n \"service-registry\",\n `Unregistered ${type} provider from plugin '${pluginName}'`,\n );\n }\n\n return removed;\n }\n\n /**\n * List all registered providers for a given type, with default indicator.\n */\n listProvidersForType(\n type: ProviderType,\n ): Array<{ pluginName: string; isDefault: boolean }> {\n const typeMap = this.providers.get(type);\n if (!typeMap) return [];\n\n let defaultName: string | undefined;\n\n // Resolve default from DB config\n if (this.db) {\n try {\n defaultName =\n this.db.getConfig(`provider:default:${type}`) ?? undefined;\n } catch {\n // Ignore DB errors\n }\n }\n\n // If no DB default (or DB default doesn't match any registered provider),\n // fall back to last registered\n if (!defaultName || !typeMap.has(defaultName)) {\n const order = this.providerOrder.get(type);\n defaultName =\n order && order.length > 0 ? order[order.length - 1] : undefined;\n }\n\n return Array.from(typeMap.keys()).map((name) => ({\n pluginName: name,\n isDefault: name === defaultName,\n }));\n }\n\n // ── Named Service Registration ──────────────────────────────────────\n\n /**\n * Register a named service from a plugin.\n */\n registerService(\n pluginName: string,\n serviceName: string,\n service: unknown,\n ): void {\n const key = `${pluginName}:${serviceName}`;\n this.services.set(key, { service, pluginName });\n logger.debug(\"service-registry\", `Registered service '${key}'`);\n }\n\n /**\n * Get a named service.\n */\n getService<T>(pluginName: string, serviceName: string): T | undefined {\n const key = `${pluginName}:${serviceName}`;\n return this.services.get(key)?.service as T;\n }\n\n /**\n * Unregister all services from a plugin.\n */\n unregisterServices(pluginName: string): void {\n const keysToDelete: string[] = [];\n for (const [key, entry] of this.services) {\n if (entry.pluginName === pluginName) {\n keysToDelete.push(key);\n }\n }\n for (const key of keysToDelete) {\n this.services.delete(key);\n }\n if (keysToDelete.length > 0) {\n logger.info(\n \"service-registry\",\n `Unregistered ${keysToDelete.length} services from ${pluginName}`,\n );\n }\n }\n\n // ── Introspection ──────────────────────────────────────────────────\n\n /**\n * List all registered providers across all types.\n */\n listProviders(): Array<{\n type: ProviderType;\n name: string;\n pluginName: string;\n }> {\n const result: Array<{\n type: ProviderType;\n name: string;\n pluginName: string;\n }> = [];\n for (const [type, typeMap] of this.providers) {\n for (const [pluginName, entry] of typeMap) {\n result.push({ type, name: pluginName, pluginName: entry.pluginName });\n }\n }\n return result;\n }\n\n /**\n * List all registered services.\n */\n listServices(): Array<{\n pluginName: string;\n serviceName: string;\n }> {\n return Array.from(this.services.entries()).map(([key, entry]) => ({\n pluginName: entry.pluginName,\n serviceName: key.split(\":\").slice(1).join(\":\"),\n }));\n }\n\n /**\n * Clear all registrations (providers, order tracking, and services).\n */\n clear(): void {\n this.providers.clear();\n this.providerOrder.clear();\n this.services.clear();\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "7B6692C0FD509A9264756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
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
|
+
formatTable,
|
|
15
|
+
getAgentUrl,
|
|
16
|
+
header,
|
|
17
|
+
icons,
|
|
18
|
+
info,
|
|
19
|
+
kv,
|
|
20
|
+
success
|
|
21
|
+
} from "./index-xmeskdnb.js";
|
|
22
|
+
import"./index-g8dczzvv.js";
|
|
23
|
+
|
|
24
|
+
// src/plugins/config/routes.ts
|
|
25
|
+
function createRoutes(deps) {
|
|
26
|
+
const { db } = deps;
|
|
27
|
+
return new Elysia().get("/", () => {
|
|
28
|
+
const config = db.getAllConfig();
|
|
29
|
+
return { config };
|
|
30
|
+
}).get("/status", () => {
|
|
31
|
+
const status = db.getConfigStatus();
|
|
32
|
+
return status;
|
|
33
|
+
}).get("/:key", ({ params, set }) => {
|
|
34
|
+
const value = db.getConfig(params.key);
|
|
35
|
+
if (value === undefined) {
|
|
36
|
+
set.status = 404;
|
|
37
|
+
return { error: "Configuration key not found" };
|
|
38
|
+
}
|
|
39
|
+
return { key: params.key, value };
|
|
40
|
+
}).put("/:key", ({ params, body, set }) => {
|
|
41
|
+
try {
|
|
42
|
+
db.setConfig(params.key, body.value);
|
|
43
|
+
return { success: true };
|
|
44
|
+
} catch (err) {
|
|
45
|
+
set.status = 500;
|
|
46
|
+
return {
|
|
47
|
+
error: "Failed to set configuration",
|
|
48
|
+
details: String(err)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}, { body: t.Object({ value: t.String() }) }).delete("/:key", ({ params, set }) => {
|
|
52
|
+
const current = db.getConfig(params.key);
|
|
53
|
+
if (current === undefined) {
|
|
54
|
+
set.status = 404;
|
|
55
|
+
return { error: "Configuration key not found" };
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
db.deleteConfig(params.key);
|
|
59
|
+
return { success: true };
|
|
60
|
+
} catch (err) {
|
|
61
|
+
set.status = 500;
|
|
62
|
+
return {
|
|
63
|
+
error: "Failed to delete configuration",
|
|
64
|
+
details: String(err)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}).post("/bulk", ({ body, set }) => {
|
|
68
|
+
try {
|
|
69
|
+
db.bulkSetConfig(body.configs);
|
|
70
|
+
return { success: true };
|
|
71
|
+
} catch (err) {
|
|
72
|
+
set.status = 500;
|
|
73
|
+
return {
|
|
74
|
+
error: "Failed to set configuration",
|
|
75
|
+
details: String(err)
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}, { body: t.Object({ configs: t.Record(t.String(), t.String()) }) });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/cli/commands/config.cmd.ts
|
|
82
|
+
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
83
|
+
function register(program) {
|
|
84
|
+
program.command("config").description("Manage VibeControls agent configuration").option("--set <key=value>", "Set a configuration value").option("--get <key>", "Get a configuration value").option("--delete <key>", "Delete a configuration value").option("--list", "List all configuration values", false).option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (opts) => {
|
|
85
|
+
try {
|
|
86
|
+
const agentUrl = getAgentUrl(opts);
|
|
87
|
+
if (opts.set) {
|
|
88
|
+
const eqIndex = opts.set.indexOf("=");
|
|
89
|
+
if (eqIndex === -1) {
|
|
90
|
+
fail(`Invalid format. Use ${colors.bold("--set key=value")}`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const key = opts.set.slice(0, eqIndex).trim();
|
|
94
|
+
const value = opts.set.slice(eqIndex + 1).trim();
|
|
95
|
+
if (!key) {
|
|
96
|
+
fail("Configuration key cannot be empty.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
await apiPut(agentUrl, `/api/config/${encodeURIComponent(key)}`, {
|
|
101
|
+
value
|
|
102
|
+
});
|
|
103
|
+
} catch {
|
|
104
|
+
await apiPost(agentUrl, "/api/config/", { key, value });
|
|
105
|
+
}
|
|
106
|
+
success(`${icons.success} Set ${colors.bold(key)} = ${colors.cyan(value)}`);
|
|
107
|
+
} else if (opts.get) {
|
|
108
|
+
header("Configuration");
|
|
109
|
+
blank();
|
|
110
|
+
const data = await apiGet(agentUrl, `/api/config/${encodeURIComponent(opts.get)}`);
|
|
111
|
+
kv(data.key, colors.bold(data.value));
|
|
112
|
+
blank();
|
|
113
|
+
} else if (opts.delete) {
|
|
114
|
+
await apiDelete(agentUrl, `/api/config/${encodeURIComponent(opts.delete)}`);
|
|
115
|
+
success(`${icons.success} Deleted configuration key: ${colors.bold(opts.delete)}`);
|
|
116
|
+
} else if (opts.list) {
|
|
117
|
+
header("Agent Configuration");
|
|
118
|
+
blank();
|
|
119
|
+
const data = await apiGet(agentUrl, "/api/config/");
|
|
120
|
+
if (!data.configs || data.configs.length === 0) {
|
|
121
|
+
info(`${icons.info} No configuration entries found.`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const rows = data.configs.map((c) => ({
|
|
125
|
+
Key: c.key,
|
|
126
|
+
Value: c.value
|
|
127
|
+
}));
|
|
128
|
+
formatTable(rows);
|
|
129
|
+
blank();
|
|
130
|
+
info(`${icons.info} ${data.configs.length} configuration(s) found.`);
|
|
131
|
+
} else {
|
|
132
|
+
info(`${icons.info} Usage:`);
|
|
133
|
+
info(` ${colors.bold("vibe config --list")} List all config values`);
|
|
134
|
+
info(` ${colors.bold("vibe config --get <key>")} Get a config value`);
|
|
135
|
+
info(` ${colors.bold("vibe config --set <key=value>")} Set a config value`);
|
|
136
|
+
info(` ${colors.bold("vibe config --delete <key>")} Delete a config value`);
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
fail(`Config operation failed: ${err.message}`);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/plugins/config/commands.ts
|
|
145
|
+
function registerCommands(program, _hostServices) {
|
|
146
|
+
register(program);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/plugins/config/index.ts
|
|
150
|
+
var vibePlugin = {
|
|
151
|
+
name: "config",
|
|
152
|
+
version: "2.2.0",
|
|
153
|
+
description: "Agent configuration key-value store",
|
|
154
|
+
tags: ["backend", "cli"],
|
|
155
|
+
cliCommand: "config",
|
|
156
|
+
apiPrefix: "/api/config",
|
|
157
|
+
createRoutes: (deps) => createRoutes(deps),
|
|
158
|
+
onCliSetup: async (program, hostServices) => {
|
|
159
|
+
registerCommands(program, hostServices);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
export {
|
|
163
|
+
vibePlugin
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
//# debugId=9ACD369BD3C87E6764756E2164756E21
|
|
167
|
+
//# sourceMappingURL=index-c7zy3n33.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugins/config/routes.ts", "../src/cli/commands/config.cmd.ts", "../src/plugins/config/commands.ts", "../src/plugins/config/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Elysia, t } from \"elysia\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n return new Elysia()\n .get(\"/\", () => {\n const config = db.getAllConfig();\n return { config };\n })\n .get(\"/status\", () => {\n const status = db.getConfigStatus();\n return status;\n })\n .get(\"/:key\", ({ params, set }) => {\n const value = db.getConfig(params.key);\n if (value === undefined) {\n set.status = 404;\n return { error: \"Configuration key not found\" };\n }\n return { key: params.key, value };\n })\n .put(\n \"/:key\",\n ({ params, body, set }) => {\n try {\n db.setConfig(params.key, body.value);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to set configuration\",\n details: String(err),\n };\n }\n },\n { body: t.Object({ value: t.String() }) },\n )\n .delete(\"/:key\", ({ params, set }) => {\n const current = db.getConfig(params.key);\n if (current === undefined) {\n set.status = 404;\n return { error: \"Configuration key not found\" };\n }\n try {\n db.deleteConfig(params.key);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to delete configuration\",\n details: String(err),\n };\n }\n })\n .post(\n \"/bulk\",\n ({ body, set }) => {\n try {\n db.bulkSetConfig(body.configs);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to set configuration\",\n details: String(err),\n };\n }\n },\n { body: t.Object({ configs: t.Record(t.String(), t.String()) }) },\n );\n}\n",
|
|
6
|
+
"import { Command } from \"commander\";\nimport {\n success,\n info,\n fail,\n header,\n kv,\n blank,\n colors,\n icons,\n formatTable,\n getAgentUrl,\n apiGet,\n apiPost,\n apiPut,\n apiDelete,\n} from \"../utils/index.js\";\n\nconst DEFAULT_AGENT_URL = \"http://localhost:3005\";\n\ninterface ConfigEntry {\n key: string;\n value: string;\n}\n\ninterface ConfigListResponse {\n configs: ConfigEntry[];\n}\n\ninterface ConfigGetResponse {\n key: string;\n value: string;\n}\n\nexport function register(program: Command): void {\n program\n .command(\"config\")\n .description(\"Manage VibeControls agent configuration\")\n .option(\"--set <key=value>\", \"Set a configuration value\")\n .option(\"--get <key>\", \"Get a configuration value\")\n .option(\"--delete <key>\", \"Delete a configuration value\")\n .option(\"--list\", \"List all configuration values\", false)\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (opts) => {\n try {\n const agentUrl = getAgentUrl(opts);\n\n if (opts.set) {\n // Set a configuration value\n const eqIndex = opts.set.indexOf(\"=\");\n\n if (eqIndex === -1) {\n fail(`Invalid format. Use ${colors.bold(\"--set key=value\")}`);\n return;\n }\n\n const key = opts.set.slice(0, eqIndex).trim();\n const value = opts.set.slice(eqIndex + 1).trim();\n\n if (!key) {\n fail(\"Configuration key cannot be empty.\");\n return;\n }\n\n // Try PUT first (update), fall back to POST (create)\n try {\n await apiPut(agentUrl, `/api/config/${encodeURIComponent(key)}`, {\n value,\n });\n } catch {\n await apiPost(agentUrl, \"/api/config/\", { key, value });\n }\n\n success(\n `${icons.success} Set ${colors.bold(key)} = ${colors.cyan(value)}`,\n );\n } else if (opts.get) {\n // Get a configuration value\n header(\"Configuration\");\n blank();\n\n const data = await apiGet<ConfigGetResponse>(\n agentUrl,\n `/api/config/${encodeURIComponent(opts.get)}`,\n );\n\n kv(data.key, colors.bold(data.value));\n blank();\n } else if (opts.delete) {\n // Delete a configuration value\n await apiDelete(\n agentUrl,\n `/api/config/${encodeURIComponent(opts.delete)}`,\n );\n\n success(\n `${icons.success} Deleted configuration key: ${colors.bold(opts.delete)}`,\n );\n } else if (opts.list) {\n // List all configuration values\n header(\"Agent Configuration\");\n blank();\n\n const data = await apiGet<ConfigListResponse>(\n agentUrl,\n \"/api/config/\",\n );\n\n if (!data.configs || data.configs.length === 0) {\n info(`${icons.info} No configuration entries found.`);\n return;\n }\n\n const rows = data.configs.map((c) => ({\n Key: c.key,\n Value: c.value,\n }));\n\n formatTable(rows);\n\n blank();\n info(`${icons.info} ${data.configs.length} configuration(s) found.`);\n } else {\n // Default: show usage hint\n info(`${icons.info} Usage:`);\n info(\n ` ${colors.bold(\"vibe config --list\")} List all config values`,\n );\n info(\n ` ${colors.bold(\"vibe config --get <key>\")} Get a config value`,\n );\n info(\n ` ${colors.bold(\"vibe config --set <key=value>\")} Set a config value`,\n );\n info(\n ` ${colors.bold(\"vibe config --delete <key>\")} Delete a config value`,\n );\n }\n } catch (err: any) {\n fail(`Config operation failed: ${err.message}`);\n }\n });\n}\n",
|
|
7
|
+
"import type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerConfig } from \"../../cli/commands/config.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerConfig(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: \"config\",\n version: \"2.2.0\",\n description: \"Agent configuration key-value store\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"config\",\n apiPrefix: \"/api/config\",\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": "9ACD369BD3C87E6764756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|