@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,270 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
logger
|
|
4
|
+
} from "./index-88ym10cs.js";
|
|
5
|
+
import {
|
|
6
|
+
Elysia,
|
|
7
|
+
t
|
|
8
|
+
} from "./index-wr0mkm57.js";
|
|
9
|
+
import {
|
|
10
|
+
apiDelete,
|
|
11
|
+
apiGet,
|
|
12
|
+
apiPut,
|
|
13
|
+
blank,
|
|
14
|
+
fail,
|
|
15
|
+
getAgentUrl,
|
|
16
|
+
header,
|
|
17
|
+
info,
|
|
18
|
+
kv,
|
|
19
|
+
success
|
|
20
|
+
} from "./index-xmeskdnb.js";
|
|
21
|
+
import"./index-g8dczzvv.js";
|
|
22
|
+
|
|
23
|
+
// src/plugins/state/routes.ts
|
|
24
|
+
class LocalPluginStateBackend {
|
|
25
|
+
db;
|
|
26
|
+
constructor(db) {
|
|
27
|
+
this.db = db;
|
|
28
|
+
}
|
|
29
|
+
async getAll(pluginName) {
|
|
30
|
+
return this.db.getAllPluginState(pluginName).map((e) => ({
|
|
31
|
+
key: e.key,
|
|
32
|
+
value: e.value
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
async get(pluginName, key) {
|
|
36
|
+
return this.db.getPluginState(pluginName, key);
|
|
37
|
+
}
|
|
38
|
+
async set(pluginName, key, value) {
|
|
39
|
+
this.db.setPluginState(pluginName, key, value);
|
|
40
|
+
}
|
|
41
|
+
async delete(pluginName, key) {
|
|
42
|
+
return this.db.deletePluginState(pluginName, key);
|
|
43
|
+
}
|
|
44
|
+
async deleteAll(pluginName) {
|
|
45
|
+
return this.db.deleteAllPluginState(pluginName);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class PluginStateRouter {
|
|
50
|
+
db;
|
|
51
|
+
_agentId;
|
|
52
|
+
localBackend;
|
|
53
|
+
externalConfig;
|
|
54
|
+
constructor(db, _agentId) {
|
|
55
|
+
this.db = db;
|
|
56
|
+
this._agentId = _agentId;
|
|
57
|
+
this.localBackend = new LocalPluginStateBackend(db);
|
|
58
|
+
}
|
|
59
|
+
configureExternal(config) {
|
|
60
|
+
this.externalConfig = config;
|
|
61
|
+
}
|
|
62
|
+
resolve(backend) {
|
|
63
|
+
switch (backend) {
|
|
64
|
+
case "remote":
|
|
65
|
+
logger.warn("plugin-state", "Remote backend not yet implemented, falling back to local");
|
|
66
|
+
return this.localBackend;
|
|
67
|
+
case "external":
|
|
68
|
+
if (!this.externalConfig) {
|
|
69
|
+
logger.warn("plugin-state", "External backend not configured, falling back to local");
|
|
70
|
+
return this.localBackend;
|
|
71
|
+
}
|
|
72
|
+
logger.warn("plugin-state", "External backend not yet implemented, falling back to local");
|
|
73
|
+
return this.localBackend;
|
|
74
|
+
case "local":
|
|
75
|
+
default:
|
|
76
|
+
return this.localBackend;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function createRoutes(deps) {
|
|
81
|
+
const { db } = deps;
|
|
82
|
+
const agentId = db.getConfig("gateway-auth:clientId");
|
|
83
|
+
const router = new PluginStateRouter(db, agentId);
|
|
84
|
+
const externalConfigStr = db.getConfig("plugin-state:external-config");
|
|
85
|
+
if (externalConfigStr) {
|
|
86
|
+
try {
|
|
87
|
+
const config = JSON.parse(externalConfigStr);
|
|
88
|
+
router.configureExternal(config);
|
|
89
|
+
} catch {
|
|
90
|
+
logger.warn("plugin-state-routes", "Failed to parse saved external config");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return new Elysia().post("/config/external", ({ body, set }) => {
|
|
94
|
+
if (!body.baseUrl) {
|
|
95
|
+
set.status = 400;
|
|
96
|
+
return { error: "Missing required field: baseUrl" };
|
|
97
|
+
}
|
|
98
|
+
router.configureExternal(body);
|
|
99
|
+
db.setConfig("plugin-state:external-config", JSON.stringify(body));
|
|
100
|
+
return { configured: true, baseUrl: body.baseUrl };
|
|
101
|
+
}, {
|
|
102
|
+
body: t.Object({
|
|
103
|
+
baseUrl: t.String(),
|
|
104
|
+
headers: t.Optional(t.Record(t.String(), t.String()))
|
|
105
|
+
})
|
|
106
|
+
}).get("/:pluginName", async ({ params, query }) => {
|
|
107
|
+
const q = query;
|
|
108
|
+
const backend = router.resolve(q.backend);
|
|
109
|
+
const entries = await backend.getAll(params.pluginName);
|
|
110
|
+
return {
|
|
111
|
+
pluginName: params.pluginName,
|
|
112
|
+
entries,
|
|
113
|
+
count: entries.length,
|
|
114
|
+
backend: q.backend ?? "local"
|
|
115
|
+
};
|
|
116
|
+
}).get("/:pluginName/:key", async ({ params, query, set }) => {
|
|
117
|
+
const q = query;
|
|
118
|
+
const backend = router.resolve(q.backend);
|
|
119
|
+
const value = await backend.get(params.pluginName, params.key);
|
|
120
|
+
if (value === undefined) {
|
|
121
|
+
set.status = 404;
|
|
122
|
+
return {
|
|
123
|
+
error: "Not found",
|
|
124
|
+
message: `Key "${params.key}" not found for plugin "${params.pluginName}"`
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
pluginName: params.pluginName,
|
|
129
|
+
key: params.key,
|
|
130
|
+
value,
|
|
131
|
+
backend: q.backend ?? "local"
|
|
132
|
+
};
|
|
133
|
+
}).put("/:pluginName/:key", async ({ params, body, query, set }) => {
|
|
134
|
+
if (body.value === undefined || body.value === null) {
|
|
135
|
+
set.status = 400;
|
|
136
|
+
return { error: "Missing required field: value" };
|
|
137
|
+
}
|
|
138
|
+
const q = query;
|
|
139
|
+
const strValue = typeof body.value === "string" ? body.value : JSON.stringify(body.value);
|
|
140
|
+
const backend = router.resolve(q.backend);
|
|
141
|
+
await backend.set(params.pluginName, params.key, strValue);
|
|
142
|
+
return {
|
|
143
|
+
pluginName: params.pluginName,
|
|
144
|
+
key: params.key,
|
|
145
|
+
value: strValue,
|
|
146
|
+
updated: true,
|
|
147
|
+
backend: q.backend ?? "local"
|
|
148
|
+
};
|
|
149
|
+
}, {
|
|
150
|
+
body: t.Object({
|
|
151
|
+
value: t.Union([t.String(), t.Any()])
|
|
152
|
+
})
|
|
153
|
+
}).delete("/:pluginName/:key", async ({ params, query, set }) => {
|
|
154
|
+
const q = query;
|
|
155
|
+
const backend = router.resolve(q.backend);
|
|
156
|
+
const deleted = await backend.delete(params.pluginName, params.key);
|
|
157
|
+
if (!deleted) {
|
|
158
|
+
set.status = 404;
|
|
159
|
+
return {
|
|
160
|
+
error: "Not found",
|
|
161
|
+
message: `Key "${params.key}" not found for plugin "${params.pluginName}"`
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
pluginName: params.pluginName,
|
|
166
|
+
key: params.key,
|
|
167
|
+
deleted: true,
|
|
168
|
+
backend: q.backend ?? "local"
|
|
169
|
+
};
|
|
170
|
+
}).delete("/:pluginName", async ({ params, query }) => {
|
|
171
|
+
const q = query;
|
|
172
|
+
const backend = router.resolve(q.backend);
|
|
173
|
+
const count = await backend.deleteAll(params.pluginName);
|
|
174
|
+
return {
|
|
175
|
+
pluginName: params.pluginName,
|
|
176
|
+
deletedCount: count,
|
|
177
|
+
backend: q.backend ?? "local"
|
|
178
|
+
};
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/cli/commands/state.cmd.ts
|
|
183
|
+
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
184
|
+
function register(program) {
|
|
185
|
+
const cmd = program.command("state").description("Manage plugin key-value state");
|
|
186
|
+
cmd.command("list").description("List all state entries for a plugin").argument("<plugin>", "Plugin name").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (plugin, options) => {
|
|
187
|
+
try {
|
|
188
|
+
const url = getAgentUrl(options);
|
|
189
|
+
const entries = await apiGet(url, `/api/plugin-state/${encodeURIComponent(plugin)}`);
|
|
190
|
+
if (!entries || typeof entries === "object" && Object.keys(entries).length === 0) {
|
|
191
|
+
info(`No state entries for plugin "${plugin}".`);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
header(`State: ${plugin}`);
|
|
195
|
+
blank();
|
|
196
|
+
if (Array.isArray(entries)) {
|
|
197
|
+
for (const entry of entries) {
|
|
198
|
+
kv(entry.key, JSON.stringify(entry.value));
|
|
199
|
+
}
|
|
200
|
+
} else if (typeof entries === "object") {
|
|
201
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
202
|
+
kv(key, JSON.stringify(value));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
} catch (err) {
|
|
206
|
+
fail(err.message);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
cmd.command("get").description("Get a state value").argument("<plugin>", "Plugin name").argument("<key>", "State key").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (plugin, key, options) => {
|
|
210
|
+
try {
|
|
211
|
+
const url = getAgentUrl(options);
|
|
212
|
+
const result = await apiGet(url, `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`);
|
|
213
|
+
if (result?.value !== undefined) {
|
|
214
|
+
header(`${plugin} / ${key}`);
|
|
215
|
+
console.log(typeof result.value === "string" ? result.value : JSON.stringify(result.value, null, 2));
|
|
216
|
+
} else {
|
|
217
|
+
info(`No value found for key "${key}" in plugin "${plugin}".`);
|
|
218
|
+
}
|
|
219
|
+
} catch (err) {
|
|
220
|
+
fail(err.message);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
cmd.command("set").description("Set a state value").argument("<plugin>", "Plugin name").argument("<key>", "State key").argument("<value>", "Value to set").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (plugin, key, value, options) => {
|
|
224
|
+
try {
|
|
225
|
+
const url = getAgentUrl(options);
|
|
226
|
+
let parsedValue = value;
|
|
227
|
+
try {
|
|
228
|
+
parsedValue = JSON.parse(value);
|
|
229
|
+
} catch {}
|
|
230
|
+
await apiPut(url, `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`, { value: parsedValue });
|
|
231
|
+
success(`State set: ${plugin}/${key}`);
|
|
232
|
+
} catch (err) {
|
|
233
|
+
fail(err.message);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
cmd.command("unset").description("Remove a state value").argument("<plugin>", "Plugin name").argument("<key>", "State key").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (plugin, key, options) => {
|
|
237
|
+
try {
|
|
238
|
+
const url = getAgentUrl(options);
|
|
239
|
+
await apiDelete(url, `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`);
|
|
240
|
+
success(`State removed: ${plugin}/${key}`);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
fail(err.message);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/plugins/state/commands.ts
|
|
248
|
+
function registerCommands(program, _hostServices) {
|
|
249
|
+
register(program);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/plugins/state/index.ts
|
|
253
|
+
var vibePlugin = {
|
|
254
|
+
name: "state",
|
|
255
|
+
version: "2.2.0",
|
|
256
|
+
description: "Scoped key-value store for plugin state management",
|
|
257
|
+
tags: ["backend", "cli"],
|
|
258
|
+
cliCommand: "state",
|
|
259
|
+
apiPrefix: "/api/plugin-state",
|
|
260
|
+
createRoutes: (deps) => createRoutes(deps),
|
|
261
|
+
onCliSetup: async (program, hostServices) => {
|
|
262
|
+
registerCommands(program, hostServices);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
export {
|
|
266
|
+
vibePlugin
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
//# debugId=B336A2A2717B47BE64756E2164756E21
|
|
270
|
+
//# sourceMappingURL=index-hefqxwht.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugins/state/routes.ts", "../src/cli/commands/state.cmd.ts", "../src/plugins/state/commands.ts", "../src/plugins/state/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Plugin State Routes\n *\n * Scoped key-value store for plugins. Each plugin has its own namespace.\n * Supports multiple backends: local (bun:sqlite), remote (GraphQL), external (REST).\n *\n * Endpoints:\n * POST /config/external — Configure external backend\n * GET /:pluginName — List all keys for a plugin\n * GET /:pluginName/:key — Get a single value\n * PUT /:pluginName/:key — Set a value\n * DELETE /:pluginName/:key — Delete a key\n * DELETE /:pluginName — Delete all keys for a plugin\n */\n\nimport { Elysia, t } from \"elysia\";\n\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport type { AgentDatabase } from \"../../db/database.js\";\nimport { logger } from \"../../services/logger.js\";\n\n// ── Backend Types ───────────────────────────────────────────────────────\n\ntype BackendType = \"local\" | \"remote\" | \"external\";\n\ninterface PluginStateBackend {\n getAll(pluginName: string): Promise<Array<{ key: string; value: string }>>;\n get(pluginName: string, key: string): Promise<string | undefined>;\n set(pluginName: string, key: string, value: string): Promise<void>;\n delete(pluginName: string, key: string): Promise<boolean>;\n deleteAll(pluginName: string): Promise<number>;\n}\n\n// ── Local Backend (bun:sqlite) ──────────────────────────────────────────\n\nclass LocalPluginStateBackend implements PluginStateBackend {\n constructor(private db: AgentDatabase) {}\n\n async getAll(pluginName: string) {\n return this.db.getAllPluginState(pluginName).map((e) => ({\n key: e.key,\n value: e.value,\n }));\n }\n\n async get(pluginName: string, key: string) {\n return this.db.getPluginState(pluginName, key);\n }\n\n async set(pluginName: string, key: string, value: string) {\n this.db.setPluginState(pluginName, key, value);\n }\n\n async delete(pluginName: string, key: string) {\n return this.db.deletePluginState(pluginName, key);\n }\n\n async deleteAll(pluginName: string) {\n return this.db.deleteAllPluginState(pluginName);\n }\n}\n\n// ── External Backend Config ─────────────────────────────────────────────\n\ninterface ExternalStoreConfig {\n baseUrl: string;\n headers?: Record<string, string>;\n}\n\n// ── Plugin State Router ─────────────────────────────────────────────────\n\nclass PluginStateRouter {\n private localBackend: LocalPluginStateBackend;\n private externalConfig?: ExternalStoreConfig;\n\n constructor(\n private db: AgentDatabase,\n private _agentId?: string,\n ) {\n this.localBackend = new LocalPluginStateBackend(db);\n }\n\n configureExternal(config: ExternalStoreConfig): void {\n this.externalConfig = config;\n }\n\n resolve(backend?: BackendType): PluginStateBackend {\n // For now, always use local backend.\n // Remote and external backends will be implemented in the plugin-state/ directory.\n switch (backend) {\n case \"remote\":\n logger.warn(\n \"plugin-state\",\n \"Remote backend not yet implemented, falling back to local\",\n );\n return this.localBackend;\n case \"external\":\n if (!this.externalConfig) {\n logger.warn(\n \"plugin-state\",\n \"External backend not configured, falling back to local\",\n );\n return this.localBackend;\n }\n logger.warn(\n \"plugin-state\",\n \"External backend not yet implemented, falling back to local\",\n );\n return this.localBackend;\n case \"local\":\n default:\n return this.localBackend;\n }\n }\n}\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n const agentId = db.getConfig(\"gateway-auth:clientId\");\n const router = new PluginStateRouter(db, agentId);\n\n // Restore external config from agent config store\n const externalConfigStr = db.getConfig(\"plugin-state:external-config\");\n if (externalConfigStr) {\n try {\n const config = JSON.parse(externalConfigStr) as ExternalStoreConfig;\n router.configureExternal(config);\n } catch {\n logger.warn(\n \"plugin-state-routes\",\n \"Failed to parse saved external config\",\n );\n }\n }\n\n return (\n new Elysia()\n // Configure external backend\n .post(\n \"/config/external\",\n ({ body, set }) => {\n if (!body.baseUrl) {\n set.status = 400;\n return { error: \"Missing required field: baseUrl\" };\n }\n router.configureExternal(body);\n // Persist so it survives restarts\n db.setConfig(\"plugin-state:external-config\", JSON.stringify(body));\n return { configured: true, baseUrl: body.baseUrl };\n },\n {\n body: t.Object({\n baseUrl: t.String(),\n headers: t.Optional(t.Record(t.String(), t.String())),\n }),\n },\n )\n\n // List all key-value pairs for a plugin\n .get(\"/:pluginName\", async ({ params, query }) => {\n const q = query as Record<string, string>;\n const backend = router.resolve(q.backend as BackendType);\n const entries = await backend.getAll(params.pluginName);\n return {\n pluginName: params.pluginName,\n entries,\n count: entries.length,\n backend: q.backend ?? \"local\",\n };\n })\n\n // Get a single value\n .get(\"/:pluginName/:key\", async ({ params, query, set }) => {\n const q = query as Record<string, string>;\n const backend = router.resolve(q.backend as BackendType);\n const value = await backend.get(params.pluginName, params.key);\n\n if (value === undefined) {\n set.status = 404;\n return {\n error: \"Not found\",\n message: `Key \"${params.key}\" not found for plugin \"${params.pluginName}\"`,\n };\n }\n\n return {\n pluginName: params.pluginName,\n key: params.key,\n value,\n backend: q.backend ?? \"local\",\n };\n })\n\n // Set a value\n .put(\n \"/:pluginName/:key\",\n async ({ params, body, query, set }) => {\n if (body.value === undefined || body.value === null) {\n set.status = 400;\n return { error: \"Missing required field: value\" };\n }\n\n const q = query as Record<string, string>;\n const strValue =\n typeof body.value === \"string\"\n ? body.value\n : JSON.stringify(body.value);\n const backend = router.resolve(q.backend as BackendType);\n await backend.set(params.pluginName, params.key, strValue);\n\n return {\n pluginName: params.pluginName,\n key: params.key,\n value: strValue,\n updated: true,\n backend: q.backend ?? \"local\",\n };\n },\n {\n body: t.Object({\n value: t.Union([t.String(), t.Any()]),\n }),\n },\n )\n\n // Delete a single key\n .delete(\"/:pluginName/:key\", async ({ params, query, set }) => {\n const q = query as Record<string, string>;\n const backend = router.resolve(q.backend as BackendType);\n const deleted = await backend.delete(params.pluginName, params.key);\n\n if (!deleted) {\n set.status = 404;\n return {\n error: \"Not found\",\n message: `Key \"${params.key}\" not found for plugin \"${params.pluginName}\"`,\n };\n }\n\n return {\n pluginName: params.pluginName,\n key: params.key,\n deleted: true,\n backend: q.backend ?? \"local\",\n };\n })\n\n // Delete all state for a plugin\n .delete(\"/:pluginName\", async ({ params, query }) => {\n const q = query as Record<string, string>;\n const backend = router.resolve(q.backend as BackendType);\n const count = await backend.deleteAll(params.pluginName);\n return {\n pluginName: params.pluginName,\n deletedCount: count,\n backend: q.backend ?? \"local\",\n };\n })\n );\n}\n",
|
|
6
|
+
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPut,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n blank,\n colors,\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(\"state\")\n .description(\"Manage plugin key-value state\");\n\n // state list\n cmd\n .command(\"list\")\n .description(\"List all state entries for a plugin\")\n .argument(\"<plugin>\", \"Plugin name\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (plugin: string, options) => {\n try {\n const url = getAgentUrl(options);\n const entries = await apiGet<any>(\n url,\n `/api/plugin-state/${encodeURIComponent(plugin)}`,\n );\n if (\n !entries ||\n (typeof entries === \"object\" && Object.keys(entries).length === 0)\n ) {\n info(`No state entries for plugin \"${plugin}\".`);\n return;\n }\n header(`State: ${plugin}`);\n blank();\n if (Array.isArray(entries)) {\n for (const entry of entries) {\n kv(entry.key, JSON.stringify(entry.value));\n }\n } else if (typeof entries === \"object\") {\n for (const [key, value] of Object.entries(entries)) {\n kv(key, JSON.stringify(value));\n }\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // state get\n cmd\n .command(\"get\")\n .description(\"Get a state value\")\n .argument(\"<plugin>\", \"Plugin name\")\n .argument(\"<key>\", \"State key\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (plugin: string, key: string, options) => {\n try {\n const url = getAgentUrl(options);\n const result = await apiGet<any>(\n url,\n `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`,\n );\n if (result?.value !== undefined) {\n header(`${plugin} / ${key}`);\n console.log(\n typeof result.value === \"string\"\n ? result.value\n : JSON.stringify(result.value, null, 2),\n );\n } else {\n info(`No value found for key \"${key}\" in plugin \"${plugin}\".`);\n }\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // state set\n cmd\n .command(\"set\")\n .description(\"Set a state value\")\n .argument(\"<plugin>\", \"Plugin name\")\n .argument(\"<key>\", \"State key\")\n .argument(\"<value>\", \"Value to set\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (plugin: string, key: string, value: string, options) => {\n try {\n const url = getAgentUrl(options);\n let parsedValue: any = value;\n try {\n parsedValue = JSON.parse(value);\n } catch {\n // keep as string\n }\n await apiPut<any>(\n url,\n `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`,\n { value: parsedValue },\n );\n success(`State set: ${plugin}/${key}`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // state unset\n cmd\n .command(\"unset\")\n .description(\"Remove a state value\")\n .argument(\"<plugin>\", \"Plugin name\")\n .argument(\"<key>\", \"State key\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (plugin: string, key: string, options) => {\n try {\n const url = getAgentUrl(options);\n await apiDelete<any>(\n url,\n `/api/plugin-state/${encodeURIComponent(plugin)}/${encodeURIComponent(key)}`,\n );\n success(`State removed: ${plugin}/${key}`);\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 registerState } from \"../../cli/commands/state.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerState(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: \"state\",\n version: \"2.2.0\",\n description: \"Scoped key-value store for plugin state management\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"state\",\n apiPrefix: \"/api/plugin-state\",\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": "B336A2A2717B47BE64756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
Elysia,
|
|
4
|
+
t
|
|
5
|
+
} from "./index-wr0mkm57.js";
|
|
6
|
+
import {
|
|
7
|
+
apiDelete,
|
|
8
|
+
apiGet,
|
|
9
|
+
apiPost,
|
|
10
|
+
fail,
|
|
11
|
+
formatStatus,
|
|
12
|
+
formatTable,
|
|
13
|
+
getAgentUrl,
|
|
14
|
+
header,
|
|
15
|
+
info,
|
|
16
|
+
kv,
|
|
17
|
+
shortId,
|
|
18
|
+
success
|
|
19
|
+
} from "./index-xmeskdnb.js";
|
|
20
|
+
import"./index-g8dczzvv.js";
|
|
21
|
+
|
|
22
|
+
// src/plugins/tunnel/routes.ts
|
|
23
|
+
function getTunnelProvider(registry) {
|
|
24
|
+
const provider = registry.getProvider("tunnel");
|
|
25
|
+
if (!provider)
|
|
26
|
+
throw new Error("No tunnel provider registered");
|
|
27
|
+
return provider;
|
|
28
|
+
}
|
|
29
|
+
function createRoutes(deps) {
|
|
30
|
+
const { serviceRegistry } = deps;
|
|
31
|
+
return new Elysia().get("/", async ({ set }) => {
|
|
32
|
+
try {
|
|
33
|
+
const provider = getTunnelProvider(serviceRegistry);
|
|
34
|
+
const tunnels = await provider.list();
|
|
35
|
+
return { tunnels };
|
|
36
|
+
} catch (err) {
|
|
37
|
+
set.status = 500;
|
|
38
|
+
return { error: "Failed to list tunnels", details: String(err) };
|
|
39
|
+
}
|
|
40
|
+
}).get("/status", async ({ set }) => {
|
|
41
|
+
try {
|
|
42
|
+
const provider = getTunnelProvider(serviceRegistry);
|
|
43
|
+
const tunnels = await provider.list();
|
|
44
|
+
const active = tunnels.filter((t2) => t2.status === "active");
|
|
45
|
+
const inactive = tunnels.filter((t2) => t2.status === "stopped");
|
|
46
|
+
const errored = tunnels.filter((t2) => t2.status === "error");
|
|
47
|
+
return {
|
|
48
|
+
total: tunnels.length,
|
|
49
|
+
active: active.length,
|
|
50
|
+
inactive: inactive.length,
|
|
51
|
+
errored: errored.length,
|
|
52
|
+
tunnels: active.map((t2) => ({
|
|
53
|
+
id: t2.id,
|
|
54
|
+
port: t2.port,
|
|
55
|
+
url: t2.url,
|
|
56
|
+
pid: t2.pid
|
|
57
|
+
}))
|
|
58
|
+
};
|
|
59
|
+
} catch (err) {
|
|
60
|
+
set.status = 500;
|
|
61
|
+
return { error: "Failed to get tunnel status", details: String(err) };
|
|
62
|
+
}
|
|
63
|
+
}).post("/start", async ({ body, set }) => {
|
|
64
|
+
if (body.localPort < 1 || body.localPort > 65535) {
|
|
65
|
+
set.status = 400;
|
|
66
|
+
return { error: "Invalid localPort" };
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const provider = getTunnelProvider(serviceRegistry);
|
|
70
|
+
const existing = await provider.list();
|
|
71
|
+
const portTunnel = existing.find((t2) => t2.port === body.localPort && t2.status === "active");
|
|
72
|
+
if (portTunnel) {
|
|
73
|
+
set.status = 409;
|
|
74
|
+
return {
|
|
75
|
+
error: `Active tunnel exists for port ${body.localPort}`,
|
|
76
|
+
tunnel: portTunnel
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const tunnel = await provider.start({
|
|
80
|
+
port: body.localPort,
|
|
81
|
+
name: body.subdomain,
|
|
82
|
+
metadata: body.sessionId ? { sessionId: body.sessionId } : undefined
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
id: tunnel.id,
|
|
86
|
+
localPort: tunnel.port,
|
|
87
|
+
publicUrl: tunnel.url,
|
|
88
|
+
pid: tunnel.pid,
|
|
89
|
+
status: tunnel.status,
|
|
90
|
+
sessionId: body.sessionId || null
|
|
91
|
+
};
|
|
92
|
+
} catch (err) {
|
|
93
|
+
set.status = 500;
|
|
94
|
+
return { error: "Failed to start tunnel", details: String(err) };
|
|
95
|
+
}
|
|
96
|
+
}, {
|
|
97
|
+
body: t.Object({
|
|
98
|
+
localPort: t.Number(),
|
|
99
|
+
subdomain: t.Optional(t.String()),
|
|
100
|
+
sessionId: t.Optional(t.String())
|
|
101
|
+
})
|
|
102
|
+
}).get("/:id", async ({ params, set }) => {
|
|
103
|
+
try {
|
|
104
|
+
const provider = getTunnelProvider(serviceRegistry);
|
|
105
|
+
const tunnel = await provider.getStatus(params.id);
|
|
106
|
+
if (!tunnel) {
|
|
107
|
+
set.status = 404;
|
|
108
|
+
return { error: "Tunnel not found" };
|
|
109
|
+
}
|
|
110
|
+
return { tunnel };
|
|
111
|
+
} catch (err) {
|
|
112
|
+
set.status = 500;
|
|
113
|
+
return { error: "Failed to get tunnel", details: String(err) };
|
|
114
|
+
}
|
|
115
|
+
}).post("/:id/stop", async ({ params, set }) => {
|
|
116
|
+
try {
|
|
117
|
+
const provider = getTunnelProvider(serviceRegistry);
|
|
118
|
+
const tunnel = await provider.getStatus(params.id);
|
|
119
|
+
if (!tunnel) {
|
|
120
|
+
set.status = 404;
|
|
121
|
+
return { error: "Tunnel not found" };
|
|
122
|
+
}
|
|
123
|
+
if (tunnel.status !== "active") {
|
|
124
|
+
set.status = 400;
|
|
125
|
+
return { error: "Tunnel is not active" };
|
|
126
|
+
}
|
|
127
|
+
await provider.stop(params.id);
|
|
128
|
+
return { success: true };
|
|
129
|
+
} catch (err) {
|
|
130
|
+
set.status = 500;
|
|
131
|
+
return { error: "Failed to stop tunnel", details: String(err) };
|
|
132
|
+
}
|
|
133
|
+
}).delete("/:id", async ({ params, set }) => {
|
|
134
|
+
try {
|
|
135
|
+
const provider = getTunnelProvider(serviceRegistry);
|
|
136
|
+
const tunnel = await provider.getStatus(params.id);
|
|
137
|
+
if (!tunnel) {
|
|
138
|
+
set.status = 404;
|
|
139
|
+
return { error: "Tunnel not found" };
|
|
140
|
+
}
|
|
141
|
+
if (tunnel.status === "active") {
|
|
142
|
+
await provider.stop(params.id);
|
|
143
|
+
}
|
|
144
|
+
await provider.delete(params.id);
|
|
145
|
+
return { success: true };
|
|
146
|
+
} catch (err) {
|
|
147
|
+
set.status = 500;
|
|
148
|
+
return { error: "Failed to delete tunnel", details: String(err) };
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/cli/commands/tunnel.cmd.ts
|
|
154
|
+
var DEFAULT_AGENT_URL = "http://localhost:3005";
|
|
155
|
+
function register(program) {
|
|
156
|
+
const cmd = program.command("tunnel").description("Manage tunnels for exposing local ports");
|
|
157
|
+
cmd.command("list").description("List all tunnels").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
158
|
+
try {
|
|
159
|
+
const url = getAgentUrl(options);
|
|
160
|
+
const tunnels = await apiGet(url, "/api/tunnels");
|
|
161
|
+
if (!tunnels || tunnels.length === 0) {
|
|
162
|
+
info("No tunnels found.");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
header("Tunnels");
|
|
166
|
+
formatTable(tunnels.map((t2) => ({
|
|
167
|
+
ID: shortId(t2.id),
|
|
168
|
+
Port: t2.port ?? "-",
|
|
169
|
+
"Public URL": t2.publicUrl || t2.url || "-",
|
|
170
|
+
Status: formatStatus(t2.status),
|
|
171
|
+
PID: t2.pid ?? "-"
|
|
172
|
+
})));
|
|
173
|
+
} catch (err) {
|
|
174
|
+
fail(err.message);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
cmd.command("start").description("Start a new tunnel").requiredOption("-p, --port <port>", "Local port to expose").option("-s, --subdomain <subdomain>", "Preferred subdomain").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
178
|
+
try {
|
|
179
|
+
const url = getAgentUrl(options);
|
|
180
|
+
const body = {
|
|
181
|
+
port: parseInt(options.port, 10)
|
|
182
|
+
};
|
|
183
|
+
if (options.subdomain)
|
|
184
|
+
body.subdomain = options.subdomain;
|
|
185
|
+
const result = await apiPost(url, "/api/tunnels/start", body);
|
|
186
|
+
success("Tunnel started.");
|
|
187
|
+
if (result?.id)
|
|
188
|
+
kv("ID", shortId(result.id));
|
|
189
|
+
if (result?.publicUrl || result?.url)
|
|
190
|
+
kv("Public URL", result.publicUrl || result.url);
|
|
191
|
+
kv("Port", options.port);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
fail(err.message);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
cmd.command("stop").description("Stop a tunnel").requiredOption("-i, --id <id>", "Tunnel ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
197
|
+
try {
|
|
198
|
+
const url = getAgentUrl(options);
|
|
199
|
+
await apiPost(url, `/api/tunnels/${options.id}/stop`, {});
|
|
200
|
+
success(`Tunnel ${shortId(options.id)} stopped.`);
|
|
201
|
+
} catch (err) {
|
|
202
|
+
fail(err.message);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
cmd.command("delete").description("Delete a tunnel").requiredOption("-i, --id <id>", "Tunnel ID").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
206
|
+
try {
|
|
207
|
+
const url = getAgentUrl(options);
|
|
208
|
+
await apiDelete(url, `/api/tunnels/${options.id}`);
|
|
209
|
+
success(`Tunnel ${shortId(options.id)} deleted.`);
|
|
210
|
+
} catch (err) {
|
|
211
|
+
fail(err.message);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
cmd.command("status").description("Show tunnel status summary").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
215
|
+
try {
|
|
216
|
+
const url = getAgentUrl(options);
|
|
217
|
+
const result = await apiGet(url, "/api/tunnels/status");
|
|
218
|
+
header("Tunnel Status");
|
|
219
|
+
kv("Total", result?.total ?? 0);
|
|
220
|
+
kv("Active", result?.active ?? 0);
|
|
221
|
+
kv("Inactive", result?.inactive ?? 0);
|
|
222
|
+
kv("Errored", result?.errored ?? 0);
|
|
223
|
+
} catch (err) {
|
|
224
|
+
fail(err.message);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
cmd.command("agent").description("Manage agent tunnel").option("--start", "Start the agent tunnel").option("--stop", "Stop the agent tunnel").option("--agent-url <url>", "Agent URL", DEFAULT_AGENT_URL).action(async (options) => {
|
|
228
|
+
try {
|
|
229
|
+
const url = getAgentUrl(options);
|
|
230
|
+
if (options.start) {
|
|
231
|
+
const result = await apiPost(url, "/api/agent/tunnel", {
|
|
232
|
+
action: "start"
|
|
233
|
+
});
|
|
234
|
+
success("Agent tunnel started.");
|
|
235
|
+
if (result?.publicUrl || result?.url)
|
|
236
|
+
kv("Public URL", result.publicUrl || result.url);
|
|
237
|
+
} else if (options.stop) {
|
|
238
|
+
const result = await apiPost(url, "/api/agent/tunnel", {
|
|
239
|
+
action: "stop"
|
|
240
|
+
});
|
|
241
|
+
success("Agent tunnel stopped.");
|
|
242
|
+
} else {
|
|
243
|
+
const result = await apiGet(url, "/api/agent/tunnel");
|
|
244
|
+
header("Agent Tunnel");
|
|
245
|
+
kv("Status", formatStatus(result?.status || "unknown"));
|
|
246
|
+
if (result?.publicUrl || result?.url)
|
|
247
|
+
kv("Public URL", result.publicUrl || result.url);
|
|
248
|
+
if (result?.port)
|
|
249
|
+
kv("Port", result.port);
|
|
250
|
+
}
|
|
251
|
+
} catch (err) {
|
|
252
|
+
fail(err.message);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// src/plugins/tunnel/commands.ts
|
|
258
|
+
function registerCommands(program, _hostServices) {
|
|
259
|
+
register(program);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/plugins/tunnel/index.ts
|
|
263
|
+
var vibePlugin = {
|
|
264
|
+
name: "tunnel",
|
|
265
|
+
version: "2.2.0",
|
|
266
|
+
description: "Tunnel management via registered tunnel provider",
|
|
267
|
+
tags: ["backend", "cli", "provider"],
|
|
268
|
+
cliCommand: "tunnel",
|
|
269
|
+
apiPrefix: "/api/tunnels",
|
|
270
|
+
createRoutes: (deps) => createRoutes(deps),
|
|
271
|
+
onCliSetup: async (program, hostServices) => {
|
|
272
|
+
registerCommands(program, hostServices);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
export {
|
|
276
|
+
vibePlugin
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
//# debugId=295E54DE0BD81D3964756E2164756E21
|
|
280
|
+
//# sourceMappingURL=index-k9hb0b93.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugins/tunnel/routes.ts", "../src/cli/commands/tunnel.cmd.ts", "../src/plugins/tunnel/commands.ts", "../src/plugins/tunnel/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Elysia, t } from \"elysia\";\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport type { ServiceRegistry } from \"../../core/service-registry.js\";\nimport type { TunnelProvider } from \"../../core/providers/tunnel.provider.js\";\n\nfunction getTunnelProvider(registry: ServiceRegistry): TunnelProvider {\n const provider = registry.getProvider<TunnelProvider>(\"tunnel\");\n if (!provider) throw new Error(\"No tunnel provider registered\");\n return provider;\n}\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { serviceRegistry } = deps;\n\n return new Elysia()\n .get(\"/\", async ({ set }) => {\n try {\n const provider = getTunnelProvider(serviceRegistry);\n const tunnels = await provider.list();\n return { tunnels };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to list tunnels\", details: String(err) };\n }\n })\n .get(\"/status\", async ({ set }) => {\n try {\n const provider = getTunnelProvider(serviceRegistry);\n const tunnels = await provider.list();\n const active = tunnels.filter((t) => t.status === \"active\");\n const inactive = tunnels.filter((t) => t.status === \"stopped\");\n const errored = tunnels.filter((t) => t.status === \"error\");\n return {\n total: tunnels.length,\n active: active.length,\n inactive: inactive.length,\n errored: errored.length,\n tunnels: active.map((t) => ({\n id: t.id,\n port: t.port,\n url: t.url,\n pid: t.pid,\n })),\n };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to get tunnel status\", details: String(err) };\n }\n })\n .post(\n \"/start\",\n async ({ body, set }) => {\n if (body.localPort < 1 || body.localPort > 65535) {\n set.status = 400;\n return { error: \"Invalid localPort\" };\n }\n try {\n const provider = getTunnelProvider(serviceRegistry);\n const existing = await provider.list();\n const portTunnel = existing.find(\n (t) => t.port === body.localPort && t.status === \"active\",\n );\n if (portTunnel) {\n set.status = 409;\n return {\n error: `Active tunnel exists for port ${body.localPort}`,\n tunnel: portTunnel,\n };\n }\n const tunnel = await provider.start({\n port: body.localPort,\n name: body.subdomain,\n metadata: body.sessionId\n ? { sessionId: body.sessionId }\n : undefined,\n });\n return {\n id: tunnel.id,\n localPort: tunnel.port,\n publicUrl: tunnel.url,\n pid: tunnel.pid,\n status: tunnel.status,\n sessionId: body.sessionId || null,\n };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to start tunnel\", details: String(err) };\n }\n },\n {\n body: t.Object({\n localPort: t.Number(),\n subdomain: t.Optional(t.String()),\n sessionId: t.Optional(t.String()),\n }),\n },\n )\n .get(\"/:id\", async ({ params, set }) => {\n try {\n const provider = getTunnelProvider(serviceRegistry);\n const tunnel = await provider.getStatus(params.id);\n if (!tunnel) {\n set.status = 404;\n return { error: \"Tunnel not found\" };\n }\n return { tunnel };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to get tunnel\", details: String(err) };\n }\n })\n .post(\"/:id/stop\", async ({ params, set }) => {\n try {\n const provider = getTunnelProvider(serviceRegistry);\n const tunnel = await provider.getStatus(params.id);\n if (!tunnel) {\n set.status = 404;\n return { error: \"Tunnel not found\" };\n }\n if (tunnel.status !== \"active\") {\n set.status = 400;\n return { error: \"Tunnel is not active\" };\n }\n await provider.stop(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to stop tunnel\", details: String(err) };\n }\n })\n .delete(\"/:id\", async ({ params, set }) => {\n try {\n const provider = getTunnelProvider(serviceRegistry);\n const tunnel = await provider.getStatus(params.id);\n if (!tunnel) {\n set.status = 404;\n return { error: \"Tunnel not found\" };\n }\n if (tunnel.status === \"active\") {\n await provider.stop(params.id);\n }\n await provider.delete(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to delete tunnel\", details: String(err) };\n }\n });\n}\n",
|
|
6
|
+
"import { Command } from \"commander\";\nimport {\n getAgentUrl,\n apiGet,\n apiPost,\n apiDelete,\n fail,\n success,\n info,\n header,\n kv,\n blank,\n formatTable,\n formatStatus,\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(\"tunnel\")\n .description(\"Manage tunnels for exposing local ports\");\n\n // tunnel list\n cmd\n .command(\"list\")\n .description(\"List all tunnels\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const tunnels = await apiGet<any[]>(url, \"/api/tunnels\");\n if (!tunnels || tunnels.length === 0) {\n info(\"No tunnels found.\");\n return;\n }\n header(\"Tunnels\");\n formatTable(\n tunnels.map((t: any) => ({\n ID: shortId(t.id),\n Port: t.port ?? \"-\",\n \"Public URL\": t.publicUrl || t.url || \"-\",\n Status: formatStatus(t.status),\n PID: t.pid ?? \"-\",\n })),\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // tunnel start\n cmd\n .command(\"start\")\n .description(\"Start a new tunnel\")\n .requiredOption(\"-p, --port <port>\", \"Local port to expose\")\n .option(\"-s, --subdomain <subdomain>\", \"Preferred subdomain\")\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 port: parseInt(options.port, 10),\n };\n if (options.subdomain) body.subdomain = options.subdomain;\n const result = await apiPost<any>(url, \"/api/tunnels/start\", body);\n success(\"Tunnel started.\");\n if (result?.id) kv(\"ID\", shortId(result.id));\n if (result?.publicUrl || result?.url)\n kv(\"Public URL\", result.publicUrl || result.url);\n kv(\"Port\", options.port);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // tunnel stop\n cmd\n .command(\"stop\")\n .description(\"Stop a tunnel\")\n .requiredOption(\"-i, --id <id>\", \"Tunnel ID\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n await apiPost<any>(url, `/api/tunnels/${options.id}/stop`, {});\n success(`Tunnel ${shortId(options.id)} stopped.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // tunnel delete\n cmd\n .command(\"delete\")\n .description(\"Delete a tunnel\")\n .requiredOption(\"-i, --id <id>\", \"Tunnel 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/tunnels/${options.id}`);\n success(`Tunnel ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // tunnel status\n cmd\n .command(\"status\")\n .description(\"Show tunnel status summary\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const result = await apiGet<any>(url, \"/api/tunnels/status\");\n header(\"Tunnel Status\");\n kv(\"Total\", result?.total ?? 0);\n kv(\"Active\", result?.active ?? 0);\n kv(\"Inactive\", result?.inactive ?? 0);\n kv(\"Errored\", result?.errored ?? 0);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // tunnel agent\n cmd\n .command(\"agent\")\n .description(\"Manage agent tunnel\")\n .option(\"--start\", \"Start the agent tunnel\")\n .option(\"--stop\", \"Stop the agent tunnel\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n if (options.start) {\n const result = await apiPost<any>(url, \"/api/agent/tunnel\", {\n action: \"start\",\n });\n success(\"Agent tunnel started.\");\n if (result?.publicUrl || result?.url)\n kv(\"Public URL\", result.publicUrl || result.url);\n } else if (options.stop) {\n const result = await apiPost<any>(url, \"/api/agent/tunnel\", {\n action: \"stop\",\n });\n success(\"Agent tunnel stopped.\");\n } else {\n const result = await apiGet<any>(url, \"/api/agent/tunnel\");\n header(\"Agent Tunnel\");\n kv(\"Status\", formatStatus(result?.status || \"unknown\"));\n if (result?.publicUrl || result?.url)\n kv(\"Public URL\", result.publicUrl || result.url);\n if (result?.port) kv(\"Port\", result.port);\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 registerTunnel } from \"../../cli/commands/tunnel.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerTunnel(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: \"tunnel\",\n version: \"2.2.0\",\n description: \"Tunnel management via registered tunnel provider\",\n tags: [\"backend\", \"cli\", \"provider\"],\n cliCommand: \"tunnel\",\n apiPrefix: \"/api/tunnels\",\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": "295E54DE0BD81D3964756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|