@burdenoff/vibe-agent 2.1.1 → 2.3.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-sm6n9xst.js +1165 -0
- package/dist/app-sm6n9xst.js.map +19 -0
- package/dist/cli.js +167 -2050
- package/dist/cli.js.map +8 -30
- 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-3rjnbp97.js +268 -0
- package/dist/index-3rjnbp97.js.map +13 -0
- package/dist/index-6vry08rz.js +285 -0
- package/dist/index-6vry08rz.js.map +13 -0
- package/dist/index-88ym10cs.js +194 -0
- package/dist/index-88ym10cs.js.map +10 -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-b1eq3qvs.js +515 -0
- package/dist/index-b1eq3qvs.js.map +19 -0
- package/dist/index-c7zy3n33.js +167 -0
- package/dist/index-c7zy3n33.js.map +13 -0
- package/dist/index-fm6gqenc.js +338 -0
- package/dist/index-fm6gqenc.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-rdm6e3rr.js +587 -0
- package/dist/index-rdm6e3rr.js.map +13 -0
- package/dist/index-s7ff1fj1.js +415 -0
- package/dist/index-s7ff1fj1.js.map +11 -0
- package/dist/index-t4qgjy5w.js +287 -0
- package/dist/index-t4qgjy5w.js.map +13 -0
- package/dist/index-wmvkjcjj.js +301 -0
- package/dist/index-wmvkjcjj.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.js +9 -6
- package/dist/index.js.map +2 -2
- package/dist/{package-hb6db316.js → package-04nkt49b.js} +5 -3
- package/dist/{package-hb6db316.js.map → package-04nkt49b.js.map} +1 -1
- package/dist/plugin-system-7r9mb1tb.js +479 -0
- package/dist/plugin-system-7r9mb1tb.js.map +10 -0
- package/package.json +3 -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,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/plugins/git/routes.ts", "../src/cli/commands/git.cmd.ts", "../src/plugins/git/commands.ts", "../src/plugins/git/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Git Plugin — Routes\n *\n * Git repository scanning, tracking, and hierarchy management.\n *\n * Endpoints:\n * GET / — List all tracked git repositories\n * GET /:id — Get repository by ID\n * POST /scan — Scan directory for git repositories\n * PUT /:id — Update repository metadata\n * DELETE /:id — Delete repository from tracking\n * POST /fix-hierarchy — Fix parent/child relationships\n */\n\nimport { Elysia, t } from \"elysia\";\nimport { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { PluginRouteDeps } from \"../../core/types.js\";\nimport type { AgentDatabase } from \"../../db/database.js\";\n\n// ── Project Type Detection ──────────────────────────────────────────────\n\nasync function detectProjectType(\n directory: string,\n): Promise<string | undefined> {\n try {\n const entries = await fs.readdir(directory);\n\n if (entries.includes(\"package.json\")) {\n try {\n const packageJson = JSON.parse(\n await fs.readFile(path.join(directory, \"package.json\"), \"utf8\"),\n );\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (deps.react || deps[\"@types/react\"]) return \"react\";\n if (deps.vue || deps[\"@vue/cli\"]) return \"vue\";\n if (deps.angular || deps[\"@angular/core\"]) return \"angular\";\n if (deps.next || deps[\"@types/next\"]) return \"nextjs\";\n if (deps.nuxt || deps[\"@nuxt/core\"]) return \"nuxtjs\";\n if (deps.svelte || deps[\"@sveltejs/kit\"]) return \"svelte\";\n if (deps.express || deps.fastify || deps.koa) return \"nodejs-backend\";\n if (deps.electron) return \"electron\";\n if (deps.vite) return \"vite\";\n } catch {\n /* fallback */\n }\n return \"nodejs\";\n }\n\n if (\n entries.includes(\"setup.py\") ||\n entries.includes(\"requirements.txt\") ||\n entries.includes(\"pyproject.toml\") ||\n entries.includes(\"Pipfile\")\n ) {\n if (entries.includes(\"manage.py\")) return \"django\";\n if (entries.includes(\"app.py\")) return \"flask\";\n return \"python\";\n }\n\n if (entries.includes(\"go.mod\")) return \"go\";\n if (entries.includes(\"Cargo.toml\")) return \"rust\";\n if (entries.includes(\"pom.xml\")) return \"maven\";\n if (\n entries.includes(\"build.gradle\") ||\n entries.includes(\"build.gradle.kts\")\n )\n return \"gradle\";\n if (entries.includes(\"Gemfile\")) return \"ruby\";\n if (entries.includes(\"composer.json\")) return \"php\";\n if (entries.some((e) => e.endsWith(\".csproj\") || e.endsWith(\".sln\")))\n return \"dotnet\";\n if (entries.includes(\"CMakeLists.txt\") || entries.includes(\"Makefile\"))\n return \"cpp\";\n if (entries.includes(\"Package.swift\")) return \"swift\";\n if (entries.includes(\"pubspec.yaml\")) return \"flutter\";\n if (entries.some((e) => e.endsWith(\".tf\"))) return \"terraform\";\n if (entries.includes(\"Dockerfile\")) return \"docker\";\n } catch {\n /* ignore */\n }\n\n return undefined;\n}\n\nasync function detectVitePort(directory: string): Promise<number | undefined> {\n try {\n const variants = [\"vite.config.ts\", \"vite.config.js\"];\n for (const name of variants) {\n try {\n const content = await fs.readFile(path.join(directory, name), \"utf-8\");\n const match = content.match(/port:\\s*(\\d+)/);\n if (match) return parseInt(match[1], 10);\n } catch {\n /* next */\n }\n }\n } catch {\n /* ignore */\n }\n return undefined;\n}\n\n// ── Git Repo Scanner ────────────────────────────────────────────────────\n\nconst SKIP_DIRS = new Set([\n \".git\",\n \"node_modules\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \"dist\",\n \"build\",\n]);\n\nasync function scanForGitRepositories(\n directory: string,\n includeSubmodules: boolean,\n parentPath?: string,\n): Promise<\n Array<{\n path: string;\n name: string;\n parentPath?: string;\n isSubmodule: boolean;\n projectType?: string;\n vitePort?: number;\n }>\n> {\n const repositories: Array<{\n path: string;\n name: string;\n parentPath?: string;\n isSubmodule: boolean;\n projectType?: string;\n vitePort?: number;\n }> = [];\n\n try {\n const entries = await fs.readdir(directory, { withFileTypes: true });\n const hasGit = entries.some((e) => e.name === \".git\" && e.isDirectory());\n\n if (hasGit) {\n repositories.push({\n path: directory,\n name: path.basename(directory),\n parentPath,\n isSubmodule: !!parentPath,\n projectType: await detectProjectType(directory),\n vitePort: await detectVitePort(directory),\n });\n\n if (!includeSubmodules) return repositories;\n parentPath = directory;\n }\n\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n !SKIP_DIRS.has(entry.name) &&\n !entry.name.startsWith(\".\")\n ) {\n const subPath = path.join(directory, entry.name);\n const subRepos = await scanForGitRepositories(\n subPath,\n includeSubmodules,\n parentPath,\n );\n repositories.push(...subRepos);\n }\n }\n } catch {\n /* permission errors */\n }\n\n return repositories;\n}\n\n// ── Routes ──────────────────────────────────────────────────────────────\n\nexport function createRoutes(deps: PluginRouteDeps) {\n const { db } = deps;\n\n return (\n new Elysia()\n // List all tracked git repositories\n .get(\"/\", () => {\n const repositories = db.getAllGitRepositories();\n return { repositories };\n })\n\n // Get repository by ID\n .get(\"/:id\", ({ params, set }) => {\n const repository = db.getGitRepository(params.id);\n if (!repository) {\n set.status = 404;\n return { error: \"Repository not found\" };\n }\n return { repository };\n })\n\n // Scan directory for git repositories\n .post(\n \"/scan\",\n async ({ body, set }) => {\n try {\n const stats = await fs.stat(body.directory);\n if (!stats.isDirectory()) {\n set.status = 400;\n return { error: \"Path is not a directory\" };\n }\n\n const repositories = await scanForGitRepositories(\n body.directory,\n body.includeSubmodules ?? true,\n );\n\n const savedRepos = [];\n for (const repo of repositories) {\n const existing = db.getGitRepositoryByPath(repo.path);\n if (existing) {\n db.updateGitRepository(existing.id, repo);\n savedRepos.push({ ...existing, ...repo });\n } else {\n const newRepo = db.createGitRepository({\n id: globalThis.crypto.randomUUID(),\n ...repo,\n });\n savedRepos.push(newRepo);\n }\n }\n\n return {\n repositories: savedRepos,\n scannedPath: body.directory,\n totalFound: savedRepos.length,\n };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to scan directory\", details: String(err) };\n }\n },\n {\n body: t.Object({\n directory: t.String(),\n includeSubmodules: t.Optional(t.Boolean()),\n }),\n },\n )\n\n // Update repository metadata\n .put(\n \"/:id\",\n ({ params, body, set }) => {\n const repository = db.getGitRepository(params.id);\n if (!repository) {\n set.status = 404;\n return { error: \"Repository not found\" };\n }\n\n try {\n db.updateGitRepository(params.id, body);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return {\n error: \"Failed to update repository\",\n details: String(err),\n };\n }\n },\n {\n body: t.Object({\n name: t.Optional(t.String()),\n projectType: t.Optional(t.String()),\n vitePort: t.Optional(t.Number()),\n }),\n },\n )\n\n // Delete repository from tracking\n .delete(\"/:id\", ({ params, set }) => {\n const repository = db.getGitRepository(params.id);\n if (!repository) {\n set.status = 404;\n return { error: \"Repository not found\" };\n }\n\n try {\n db.deleteGitRepository(params.id);\n return { success: true };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to delete repository\", details: String(err) };\n }\n })\n\n // Fix repository hierarchy\n .post(\"/fix-hierarchy\", ({ set }) => {\n try {\n const result = db.fixGitHierarchy();\n const repos = db.getAllGitRepositories();\n return { success: true, fixed: result.fixed, total: repos.length };\n } catch (err) {\n set.status = 500;\n return { error: \"Failed to fix hierarchy\", details: String(err) };\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 timeAgo,\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.command(\"git\").description(\"Manage git repositories\");\n\n // git list\n cmd\n .command(\"list\")\n .description(\"List discovered git repositories\")\n .option(\"--agent-url <url>\", \"Agent URL\", DEFAULT_AGENT_URL)\n .action(async (options) => {\n try {\n const url = getAgentUrl(options);\n const data = await apiGet<{ repositories: any[] }>(url, \"/api/git\");\n const repos = data.repositories || [];\n if (!repos || repos.length === 0) {\n info(\"No git repositories found.\");\n return;\n }\n header(\"Git Repositories\");\n formatTable(\n repos.map((r: any) => ({\n ID: shortId(r.id),\n Name: r.name || \"-\",\n Path: r.path || \"-\",\n Type: r.type || r.projectType || \"-\",\n Submodule: r.isSubmodule ? \"Yes\" : \"No\",\n Scanned: r.scannedAt ? timeAgo(r.scannedAt) : \"-\",\n })),\n );\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git scan\n cmd\n .command(\"scan\")\n .description(\"Scan a directory for git repositories\")\n .requiredOption(\"--dir <directory>\", \"Directory to scan\")\n .option(\"--depth <depth>\", \"Scan depth\", \"3\")\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 apiPost<any>(url, \"/api/git/scan\", {\n directory: options.dir,\n depth: parseInt(options.depth, 10),\n });\n success(\"Git scan completed.\");\n if (result?.found !== undefined) kv(\"Repositories found\", result.found);\n if (result?.repositories)\n kv(\"Repositories found\", result.repositories.length);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git update\n cmd\n .command(\"update\")\n .description(\"Update a git repository entry\")\n .requiredOption(\"-i, --id <id>\", \"Repository ID\")\n .option(\"--vite-port <port>\", \"Vite dev server port\")\n .option(\"--project-type <type>\", \"Project type\")\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.vitePort) body.vitePort = parseInt(options.vitePort, 10);\n if (options.projectType) body.projectType = options.projectType;\n await apiPut<any>(url, `/api/git/${options.id}`, body);\n success(`Repository ${shortId(options.id)} updated.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git delete\n cmd\n .command(\"delete\")\n .description(\"Delete a git repository entry\")\n .requiredOption(\"-i, --id <id>\", \"Repository 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/git/${options.id}`);\n success(`Repository ${shortId(options.id)} deleted.`);\n } catch (err: any) {\n fail(err.message);\n }\n });\n\n // git fix-hierarchy\n cmd\n .command(\"fix-hierarchy\")\n .description(\"Fix repository parent-child hierarchy\")\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 apiPost<any>(url, \"/api/git/fix-hierarchy\", {});\n success(\"Hierarchy fix completed.\");\n if (result?.fixed !== undefined) kv(\"Fixed\", result.fixed);\n } catch (err: any) {\n fail(err.message);\n }\n });\n}\n",
|
|
7
|
+
"/**\n * Git Plugin — CLI Commands\n *\n * Delegates to the shared git CLI command registration.\n */\n\nimport type { Command } from \"commander\";\nimport type { HostServices } from \"../../core/plugin-system.js\";\nimport { register as registerGit } from \"../../cli/commands/git.cmd.js\";\n\nexport function registerCommands(\n program: Command,\n _hostServices: HostServices,\n): void {\n registerGit(program);\n}\n",
|
|
8
|
+
"/**\n * Git Plugin — Entry Point\n *\n * Core plugin for git repository scanning, tracking, and hierarchy management.\n */\n\nimport 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: \"git\",\n version: \"2.2.0\",\n description: \"Git repository scanning, tracking, and hierarchy management\",\n tags: [\"backend\", \"cli\"],\n cliCommand: \"git\",\n apiPrefix: \"/api/git\",\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": "7833782DA41E97E464756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -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
|
+
}
|