Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 7 additions & 54 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# Then choose your target:
# make dev # local hot-reload stack
# docker compose -f docker-compose.local.yml up -d # single-host / LAN deploy
# docker compose up -d # single-host / LAN deploy
#
# The production self-hosted compose (deploy/compose/compose.selfhost.yml)
# has its own template at deploy/compose/.env.example for image-tag /
Expand Down Expand Up @@ -58,66 +58,19 @@ PARSAR_PG_PORT=15432
PARSAR_HOST_IP=
# Set to parsar:local after running: make docker-build PARSAR_IMAGE=parsar PARSAR_IMAGE_TAG=local
PARSAR_SERVER_IMAGE=parsar:local
# Shared token between parsar-server and the compose-resident local runtime.
# install.sh generates this automatically for normal installs.
PARSAR_SHARED_RUNTIME_TOKEN=
# Internal WebSocket URL advertised to compose-resident daemon runtimes.
PARSAR_AGENT_DAEMON_WS_URL=ws://parsar-server:8080/agent-daemon/ws

# -----------------------------------------------------------------------------
# Feishu Bot (optional — see docs/deploy/lan-deploy.md)
# -----------------------------------------------------------------------------
# Bot's own open_id (ou_xxx). Required for group chat @Bot to work.
PARSAR_FEISHU_DEFAULT_BOT_OPEN_ID=

# -----------------------------------------------------------------------------
# Cloud sandbox — e2b.app (optional; powers the "Cloud isolation" agent mode)
# -----------------------------------------------------------------------------
# Both values are required to enable cloud isolation. With either empty the
# server logs a warning at boot and cloud-isolation agents fail fast, while
# local-device agents keep working.
#
# Build the template first (writes only gitignored build artifacts):
# make e2b-template
# then paste the template id it reports here. Rebuilding the same template
# name keeps the id, so this only changes on first creation.
AGENT_DAEMON_SANDBOX_TEMPLATE=
PARSAR_E2B_API_KEY=

# Optional larger tier, selected per agent via agents.config.sandbox_size="xl".
# An agent asking for a size with no template configured degrades to the
# standard one with a warning rather than failing the acquire.
AGENT_DAEMON_SANDBOX_TEMPLATE_XL=

# Optional deployment-wide sandbox lifetime. Uses Go duration syntax (for
# example 30m, 1h, or 24h) and defaults to 1h. An agent may override this with
# agents.config.sandbox_ttl. Parsar does not impose a provider-specific maximum;
# configure a value supported by your sandbox provider and account.
AGENT_DAEMON_SANDBOX_TTL=

# Deployment-wide default for periodic best-effort renewal. An agent may
# override this with agents.config.sandbox_auto_renew. Renewal requires a TTL
# longer than the five-minute scan interval. Enabled by default so a
# continuously-used agent's sandbox is not reaped mid-conversation; set to
# false to opt out (e.g. for a provider that does not support renewal).
AGENT_DAEMON_SANDBOX_AUTO_RENEW=true

# Deprecated compatibility setting. Used only when the duration above is
# empty; prefer AGENT_DAEMON_SANDBOX_TTL for new deployments.
AGENT_DAEMON_SANDBOX_TTL_HOURS=

# Self-hosted / proxied e2b only. Leave empty for e2b.app.
PARSAR_E2B_API_BASE_URL=
PARSAR_E2B_SANDBOX_HOST=
# PEM of a private CA, when the sandbox gateway serves a non-public cert.
PARSAR_E2B_CA_CERT=

# IMPORTANT for local testing: the daemon runs INSIDE the cloud sandbox and
# dials back to PARSAR_PUBLIC_URL, so a loopback URL can never work — the
# sandbox resolves 127.0.0.1 to itself and pairing times out. Expose the dev
# server through a tunnel and set PARSAR_PUBLIC_URL to that hostname, e.g.
# ngrok http 18080
# PARSAR_PUBLIC_URL=https://<subdomain>.ngrok-free.dev
# Core execution — configured independently from the product.
# See docs/deploy/product-core.md. Docker/E2B and model credentials belong to Core.
# Native development: absolute JSON file containing workspace/project/key-file bindings.
PARSAR_CORE_WORKSPACES_FILE=
# Compose deployment: directory mounted at /run/secrets/core.
PARSAR_CORE_CONFIG_DIR=

# -----------------------------------------------------------------------------
# Network proxy (optional — only if your host needs a proxy for internet)
Expand Down
347 changes: 125 additions & 222 deletions CONTRIBUTING.md

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# The image carries NO real secrets and NO internal addresses.
# Operators inject DATABASE_URL / PARSAR_MASTER_KEY / Feishu OIDC /
# E2B credentials / etc. at runtime via environment variables or a
# Core workspace credential paths / etc. at runtime via environment variables or a
# YAML config file mounted at $PARSAR_CONFIG_FILE.
#
# Build: make docker-build
Expand Down Expand Up @@ -80,6 +80,7 @@ RUN --mount=type=cache,target=/go/pkg/mod \

COPY internal ./internal
COPY catalog ./catalog
COPY packages/agents-client ./packages/agents-client
COPY server ./server

# Build all three binaries in one RUN so the layer represents one
Expand Down Expand Up @@ -129,8 +130,6 @@ RUN --mount=type=cache,target=/go/pkg/mod \
# - ca-certificates + tini ship pre-built.
# - Server-side Skills.sh installs require npx and git.
# - Operators can `docker exec -it ... bash` to debug.
# - The opencode local runner may shell out (rg, basic core utils);
# keeping a real userland avoids surprises.
###############################################################################
FROM --platform=$TARGETPLATFORM ${RUNTIME_BASE} AS runtime

Expand Down Expand Up @@ -209,10 +208,6 @@ EXPOSE 8080
HEALTHCHECK --interval=10s --timeout=3s --start-period=15s --retries=3 \
CMD wget -qO- --tries=1 --timeout=3 http://127.0.0.1:8080/healthz >/dev/null || exit 1

# tini reaps zombie subprocesses spawned by the opencode local runner
# (or any future fork-exec path). Without it the server PID-1 would
# leak zombies on every prompt that shells out and an SRE poking the
# image weeks later would find a process table full of `<defunct>`
# entries with no obvious culprit.
# tini reaps subprocesses used by product asset import tools.
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/usr/local/bin/parsar-server"]
11 changes: 1 addition & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ endif
PARSAR_IMAGE ?= parsar
PARSAR_IMAGE_TAG ?= dev

.PHONY: help setup node-deps dev dev-db check check-setup check-sqlc check-go check-store check-web check-cli check-hygiene test test-fast test-go test-web typecheck-web lint-web-design lint-web test-cli typecheck reset-dev clean-dev paths migrate-dev sqlc-generate server web cli devgateway http-runner-once http-runner-loop dev-all smoke e2e-http-agent e2e-feishu-gateway dev-server-up dev-server-down dev-server-log bootstrap docker-build docker-build-no-cache openapi e2b-template e2b-template-binaries
.PHONY: help setup node-deps dev dev-db check check-setup check-sqlc check-go check-store check-web check-cli check-hygiene test test-fast test-go test-web typecheck-web lint-web-design lint-web test-cli typecheck reset-dev clean-dev paths migrate-dev sqlc-generate server web cli devgateway dev-all smoke e2e-feishu-gateway dev-server-up dev-server-down dev-server-log bootstrap docker-build docker-build-no-cache openapi e2b-template e2b-template-binaries

help:
@printf '%s\n' \
Expand Down Expand Up @@ -211,12 +211,6 @@ cli:
devgateway:
cd server && go run ./cmd/devgateway --help

http-runner-once:
cd server && go run ./cmd/httprunner --once

http-runner-loop:
cd server && go run ./cmd/httprunner --interval $${PARSAR_HTTP_RUNNER_INTERVAL:-2s} --max-runs $${PARSAR_HTTP_RUNNER_MAX_RUNS:-100}

dev-all:
./scripts/dev-all.sh

Expand All @@ -226,9 +220,6 @@ dev-all:
smoke:
./scripts/smoke.sh

e2e-http-agent:
./scripts/e2e-http-agent.sh

e2e-feishu-gateway:
./scripts/e2e-feishu-gateway.sh

Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@

Parsar is a team-first platform for dispatching, managing, and auditing AI coding agents. Send tasks from the tools your team already uses — chat, web UI, API — and get results back where they started: a thread, a PR, a webhook.

Supported agent runtimes:

- **Claude Code**
- **Piagent**
- **Codex**
- More to come — the runtime layer is pluggable.
Agent execution goes through the independently deployed Agents API Core, whose
qualified profiles include **Claude Code**, **Codex**, and **MiniMax Code**. Parsar
keeps its own database for members, business assets, permissions and collaboration.

### Why Parsar

- **Team-first.** Shared queues, run history, and permissions — not single-player agent loops.
- **Pluggable runtimes.** Claude Code today, Codex tomorrow, your in-house agent next week.
- **Independent execution.** Core owns models, runtime environments and execution; Parsar uses its public Agents API.
- **Pluggable surfaces.** Feishu / Lark ships today; Slack, Discord, and webhooks on the roadmap.
- **Auditable.** Every run is persisted: prompt, diff, logs, exit code.
- **Self-hosted.** Your code, your secrets, your machine. No telemetry.
Expand All @@ -54,8 +51,10 @@ make docker-build
./install.sh --image parsar:dev
```

The default Compose stack starts PostgreSQL, the Parsar web control plane,
and a shared agent runtime together.
The default Compose stack starts PostgreSQL and the Parsar web control plane.
Deploy Core separately and configure a distinct Core project credential for each
workspace using the [product integration guide](docs/deploy/product-core.md).
Asset management works independently; Agent execution requires this connection.

## Contributing

Expand Down
176 changes: 0 additions & 176 deletions apps/web/src/components/admin/DevicePicker.tsx

This file was deleted.

Loading
Loading