feat: add browser_console MCP tool for frontend error capture
This commit is contained in:
16879
Concise title generation request
Normal file
16879
Concise title generation request
Normal file
File diff suppressed because one or more lines are too long
4926
Testing the chatbot connection
Normal file
4926
Testing the chatbot connection
Normal file
File diff suppressed because one or more lines are too long
BIN
manifest-cursor-prompt-v2.md.pdf
Normal file
BIN
manifest-cursor-prompt-v2.md.pdf
Normal file
Binary file not shown.
159
mcp-zed-adapter.js
Executable file
159
mcp-zed-adapter.js
Executable file
@@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vibn MCP Adapter for Zed
|
||||||
|
*
|
||||||
|
* This script runs locally as a standard stdio MCP server for Zed.
|
||||||
|
* It intercepts tool calls and forwards them over HTTP to the Vibn API
|
||||||
|
* using the proprietary format that Vibn expects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { Server } = require("@modelcontextprotocol/sdk/server/index.js");
|
||||||
|
const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
|
||||||
|
const { CallToolRequestSchema, ListToolsRequestSchema } = require("@modelcontextprotocol/sdk/types.js");
|
||||||
|
|
||||||
|
// Configuration from environment variables
|
||||||
|
const VIBN_API_URL = process.env.VIBN_API_URL || "https://vibnai.com/api/mcp";
|
||||||
|
const VIBN_API_KEY = process.env.VIBN_API_KEY;
|
||||||
|
|
||||||
|
if (!VIBN_API_KEY) {
|
||||||
|
console.error("Missing VIBN_API_KEY environment variable.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the MCP server
|
||||||
|
const server = new Server(
|
||||||
|
{
|
||||||
|
name: "vibn-zed-adapter",
|
||||||
|
version: "1.0.0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
capabilities: {
|
||||||
|
tools: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let cachedTools = null;
|
||||||
|
|
||||||
|
// Fetch the tool list from the Vibn API
|
||||||
|
async function fetchTools() {
|
||||||
|
if (cachedTools) return cachedTools;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(VIBN_API_URL, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: \`Bearer \${VIBN_API_KEY}\`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(\`Failed to fetch tools: \${response.statusText}\`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// We need to fetch the actual tool schemas since the GET endpoint
|
||||||
|
// only returns a string array of tool names.
|
||||||
|
// For this adapter, we define the schema passthrough.
|
||||||
|
|
||||||
|
// Note: Since Vibn's GET /api/mcp only returns an array of names:
|
||||||
|
// "available": ["workspace.describe", "gitea.credentials", ...]
|
||||||
|
// We will construct basic MCP tool definitions for them.
|
||||||
|
// In a production scenario, you would expose the JSON schemas on the GET endpoint.
|
||||||
|
|
||||||
|
const available = data.capabilities?.tools?.available || [];
|
||||||
|
|
||||||
|
cachedTools = available.map(name => ({
|
||||||
|
name: name,
|
||||||
|
description: \`Vibn workspace tool: \${name}\`,
|
||||||
|
inputSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
// Accept any parameters generically for the proxy
|
||||||
|
projectId: { type: "string", description: "Vibn project ID" },
|
||||||
|
},
|
||||||
|
additionalProperties: true
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return cachedTools;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching tools:", error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle List Tools Request
|
||||||
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||||
|
const tools = await fetchTools();
|
||||||
|
return {
|
||||||
|
tools: tools,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle Call Tool Request
|
||||||
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
||||||
|
const { name, arguments: args } = request.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Forward the request to Vibn API
|
||||||
|
const response = await fetch(VIBN_API_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Authorization: \`Bearer \${VIBN_API_KEY}\`,
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
tool: name, // Vibn's expected format
|
||||||
|
params: args || {},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: \`Error (\${response.status}): \${JSON.stringify(data.error || data)}\`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isError: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: JSON.stringify(data.result || data, null, 2),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: \`Internal Adapter Error: \${error.message}\`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isError: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start the server
|
||||||
|
async function main() {
|
||||||
|
const transport = new StdioServerTransport();
|
||||||
|
await server.connect(transport);
|
||||||
|
console.error("Vibn Zed MCP Adapter running on stdio");
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error("Fatal error:", error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
29
mcp-zed.md
Normal file
29
mcp-zed.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
local
|
||||||
|
{
|
||||||
|
/// Configure an MCP server that runs locally via stdin/stdout
|
||||||
|
///
|
||||||
|
/// The name of your MCP server
|
||||||
|
"some-mcp-server": {
|
||||||
|
/// The command which runs the MCP server
|
||||||
|
"command": ,
|
||||||
|
/// The arguments to pass to the MCP server
|
||||||
|
"args": [],
|
||||||
|
/// The environment variables to set
|
||||||
|
"env": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remote
|
||||||
|
{
|
||||||
|
/// Configure an MCP server that you connect to over HTTP
|
||||||
|
///
|
||||||
|
/// The name of your remote MCP server
|
||||||
|
"some-remote-server": {
|
||||||
|
/// The URL of the remote MCP server
|
||||||
|
"url": "https://example.com/mcp",
|
||||||
|
"headers": {
|
||||||
|
/// Any headers to send along
|
||||||
|
// "Authorization": "Bearer <token>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,7 @@
|
|||||||
# vibn-dev — per-project AI development container.
|
# vibn-dev — per-project AI development container.
|
||||||
#
|
#
|
||||||
# Goal: a small, fast-pulling base image (~500 MB target) that gives the AI
|
# Ships with Node.js (LTS), Python 3.12, and Go 1.23 pre-installed so the AI
|
||||||
# (and the user, eventually) a real shell with git, ripgrep, and the
|
# can start running code immediately without a mise install step.
|
||||||
# scaffolding to lazy-install language toolchains via mise on first use.
|
|
||||||
#
|
|
||||||
# Heavy toolchains (Node / Python / Go / Rust) are NOT baked in — they
|
|
||||||
# install on demand via `mise install` the first time the AI runs
|
|
||||||
# `npm`, `python`, `go`, etc. This keeps the base image lean and lets us
|
|
||||||
# bump toolchain versions without rebuilding the image.
|
|
||||||
#
|
#
|
||||||
# Spec is in AI_PATH_B_EXECUTION_PLAN.md §3.
|
# Spec is in AI_PATH_B_EXECUTION_PLAN.md §3.
|
||||||
|
|
||||||
@@ -18,55 +12,50 @@ ENV DEBIAN_FRONTEND=noninteractive \
|
|||||||
LC_ALL=C.UTF-8 \
|
LC_ALL=C.UTF-8 \
|
||||||
TZ=UTC
|
TZ=UTC
|
||||||
|
|
||||||
# Core OS packages: shell, git, network, build essentials, ripgrep
|
# Core OS packages + shell/git/ripgrep/tini/supervisor.
|
||||||
# (powers fs.grep), tini (PID 1 reaper), supervisord (process supervisor
|
# Language toolchains installed below.
|
||||||
# for sshd + dev servers), curl/ca-certs (downloads), unzip (mise
|
|
||||||
# tarballs), sudo (toolchain installers expect it).
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
bash coreutils ca-certificates curl wget git openssh-client \
|
bash coreutils ca-certificates curl wget git openssh-client \
|
||||||
ripgrep jq nano vim less procps lsof net-tools dnsutils \
|
ripgrep jq nano vim less procps lsof net-tools dnsutils \
|
||||||
build-essential pkg-config \
|
build-essential pkg-config \
|
||||||
sudo tini supervisor unzip xz-utils \
|
sudo tini supervisor unzip xz-utils \
|
||||||
python3-minimal \
|
python3 python3-pip python3-venv \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|
||||||
|
# Playwright System Dependencies (for headless Chromium)
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
|
||||||
|
libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
|
||||||
|
libgbm1 libasound2t64 libpangocairo-1.0-0 libpango-1.0-0 libcairo2 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Node.js LTS (via NodeSource)
|
||||||
|
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \
|
||||||
|
&& apt-get install -y nodejs \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Go 1.23 — scrape latest patch version from go.dev/dl
|
||||||
|
RUN GO_TAR=$(curl -fsSL https://go.dev/dl/ | grep -oE 'go1\.23\.[0-9]+\.linux-amd64\.tar\.gz' | head -1) \
|
||||||
|
&& curl -fsSL "https://go.dev/dl/${GO_TAR}" | tar -C /usr/local -xz \
|
||||||
|
&& echo 'export PATH=/usr/local/go/bin:$PATH' >> /etc/profile.d/go.sh
|
||||||
|
|
||||||
# vibn user — the AI runs as this, NOT root.
|
# vibn user — the AI runs as this, NOT root.
|
||||||
# Ubuntu 24.04 base image preallocates a default `ubuntu` user at uid 1000;
|
|
||||||
# delete it first so we can claim 1000 for vibn (matches the docker exec
|
|
||||||
# `--user vibn` calls in lib/coolify-exec.ts and the workspace volume's
|
|
||||||
# default ownership in the compose template).
|
|
||||||
RUN userdel -r ubuntu 2>/dev/null || true \
|
RUN userdel -r ubuntu 2>/dev/null || true \
|
||||||
&& useradd --create-home --shell /bin/bash --uid 1000 vibn \
|
&& useradd --create-home --shell /bin/bash --uid 1000 vibn \
|
||||||
&& mkdir -p /workspace /home/vibn/.cache /home/vibn/.local /var/log/vibn-dev \
|
&& mkdir -p /workspace /home/vibn/.cache /home/vibn/.local /var/log/vibn-dev \
|
||||||
&& chown -R vibn:vibn /workspace /home/vibn /var/log/vibn-dev \
|
&& chown -R vibn:vibn /workspace /home/vibn /var/log/vibn-dev \
|
||||||
&& echo 'vibn ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vibn
|
&& echo 'vibn ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vibn
|
||||||
|
|
||||||
# mise — polyglot version manager. Installs Node/Python/Go/Rust on demand.
|
# Toolchain env for vibn user
|
||||||
# Pinned to a specific version for reproducibility; bump in this Dockerfile.
|
RUN echo 'export PATH=/usr/local/go/bin:$PATH' >> /home/vibn/.bashrc \
|
||||||
ENV MISE_VERSION=v2024.12.14
|
|
||||||
RUN curl -fsSL "https://mise.run" | MISE_VERSION=${MISE_VERSION} sh \
|
|
||||||
&& mv /root/.local/bin/mise /usr/local/bin/mise \
|
|
||||||
&& chmod +x /usr/local/bin/mise
|
|
||||||
|
|
||||||
# Hook mise into vibn's shell so `node`, `python` etc. resolve once
|
|
||||||
# installed via `mise install`.
|
|
||||||
RUN echo 'eval "$(/usr/local/bin/mise activate bash)"' >> /home/vibn/.bashrc \
|
|
||||||
&& echo 'export PATH="$HOME/.local/bin:$PATH"' >> /home/vibn/.bashrc
|
&& echo 'export PATH="$HOME/.local/bin:$PATH"' >> /home/vibn/.bashrc
|
||||||
|
|
||||||
# Default mise toolchain config — lazily materialised. The AI can
|
|
||||||
# override per-project by writing /workspace/.mise.toml.
|
|
||||||
COPY --chown=vibn:vibn mise.default.toml /home/vibn/.config/mise/config.toml
|
|
||||||
|
|
||||||
# supervisord runs sshd-less; we don't need ssh in the container because
|
|
||||||
# all exec happens via `docker exec` from the Coolify host. Supervisord
|
|
||||||
# is reserved for dev_server.* (Vite/Next/etc) once that ships.
|
|
||||||
COPY supervisord.conf /etc/supervisor/conf.d/vibn-dev.conf
|
COPY supervisord.conf /etc/supervisor/conf.d/vibn-dev.conf
|
||||||
|
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
USER vibn
|
USER vibn
|
||||||
|
|
||||||
# Keep-alive process. The container's job is to exist; commands run via
|
# Keep-alive. Commands run via docker exec.
|
||||||
# `docker exec`. tail -f /dev/null is the canonical "stay running, do
|
|
||||||
# nothing" pattern — cheaper than supervisord for the no-dev-server case.
|
|
||||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||||
CMD ["tail", "-f", "/dev/null"]
|
CMD ["tail", "-f", "/dev/null"]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# vibn-dev
|
# vibn-dev
|
||||||
|
|
||||||
Per-project AI development container. One of these runs in Coolify per
|
Per-project AI development container. One of these runs in Coolify per
|
||||||
Vibn project; the AI agent (Gemini) drives it via `shell.exec` and
|
Vibn project; the AI agent drives it via `shell.exec` and
|
||||||
`fs.*` MCP tools.
|
`fs.*` MCP tools.
|
||||||
|
|
||||||
See `/AI_PATH_B_EXECUTION_PLAN.md` for the architecture.
|
See `/AI_PATH_B_EXECUTION_PLAN.md` for the architecture.
|
||||||
@@ -9,26 +9,36 @@ See `/AI_PATH_B_EXECUTION_PLAN.md` for the architecture.
|
|||||||
## Build & publish
|
## Build & publish
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t registry.vibnai.com/vibn-dev:latest .
|
docker buildx build --platform linux/amd64 -t ghcr.io/vibnai/vibn-dev:latest --push .
|
||||||
docker push registry.vibnai.com/vibn-dev:latest
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The image is pre-pulled on every Coolify host on deploy so first-use
|
The image is pre-pulled on every Coolify host on deploy so first-use
|
||||||
spin-up stays under 5 seconds.
|
spin-up stays under 5 seconds.
|
||||||
|
|
||||||
## Smoke test locally
|
## Smoke test locally (requires Docker with QEMU for cross-platform)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t vibn-dev .
|
docker buildx build --platform linux/amd64 -t vibn-dev --load .
|
||||||
docker run --rm -it -v "$PWD/scratch:/workspace" vibn-dev bash
|
docker run --rm -it -v "$PWD/scratch:/workspace" vibn-dev bash
|
||||||
# inside: mise install # pulls Node lts + Python 3.12 (~90s, one-time)
|
# inside: node --version # Node LTS ships in the image
|
||||||
# inside: rg --version # ripgrep ships in the base image
|
# inside: npm --version
|
||||||
|
# inside: python3 --version
|
||||||
|
# inside: go version
|
||||||
|
# inside: rg --version # ripgrep ships in the image
|
||||||
# inside: git --version
|
# inside: git --version
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## What's in the image
|
||||||
|
|
||||||
|
- Node.js LTS (via NodeSource)
|
||||||
|
- Python 3.12 + pip + venv
|
||||||
|
- Go 1.23
|
||||||
|
- ripgrep, git, build-essential, jq, curl, nano, vim
|
||||||
|
- supervisord (reserved for future dev_server use)
|
||||||
|
- tini (PID 1 reaper)
|
||||||
|
|
||||||
## What's NOT in the image (by design)
|
## What's NOT in the image (by design)
|
||||||
|
|
||||||
- Node/Python/Go/Rust toolchains — lazy-installed via mise
|
|
||||||
- Coolify control-plane creds — never. The container has no route to
|
- Coolify control-plane creds — never. The container has no route to
|
||||||
internal Vibn services (Docker network policy enforced at host level)
|
internal Vibn services (Docker network policy enforced at host level)
|
||||||
- SSH server — exec happens via `docker exec` from the Coolify host
|
- SSH server — exec happens via `docker exec` from the Coolify host
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
# Default toolchain hints for vibn-dev. Nothing is installed until the
|
|
||||||
# AI (or the user) runs `mise install`. Override per-project by writing
|
|
||||||
# /workspace/.mise.toml — mise auto-loads the closest config.
|
|
||||||
[tools]
|
|
||||||
node = "lts"
|
|
||||||
python = "3.12"
|
|
||||||
Submodule vibn-frontend updated: 19f284f464...fa9cfda712
Reference in New Issue
Block a user