[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80484":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":15,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":16,"starSnapshotCount":16,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},80484,"langship.sh","open-gitagent\u002Flangship.sh","open-gitagent","The platform for shipping, governing AI agents — framework-agnostic, multi-runtime, GitOps-native, self-hosted.","https:\u002F\u002Fwww.langship.sh\u002F",null,"Go",78,9,67,3,0,6,11,"Apache License 2.0",false,"main",[],"2026-06-12 02:04:03","\u003Cdiv align=\"center\">\n\n# Langship\n\n**Any framework. Any runtime.**\n\nOpen-source, self-hosted **deployment · governance · operations** for agent apps.\nOne pipeline definition → Kubernetes, AWS Bedrock AgentCore, or Vertex AI Agent\nEngine — same governance everywhere. Works with LangGraph, LangChain, LlamaIndex,\nCrewAI, AutoGen, or raw-SDK agents. No framework lock-in.\n\n[langship.sh](https:\u002F\u002Flangship.sh) · [github.com\u002Fopen-gitagent\u002Flangship.sh](https:\u002F\u002Fgithub.com\u002Fopen-gitagent\u002Flangship.sh) · [CLI](.\u002Flangship-cli\u002F) · Apache 2.0\n\n\u003C\u002Fdiv>\n\n---\n\n- [What you get](#what-you-get)\n- [5 minutes to a green run](#5-minutes-to-a-green-run)\n- [Architecture](#architecture)\n- [Repo map](#repo-map)\n- [The `langship` CLI](#the-langship-cli)\n- [Concepts](#concepts)\n- [Nodes](#nodes)\n- [Reference — env vars & make targets](#reference)\n- [Contributing & community](#contributing--community)\n- [License](#license)\n\n---\n\n## What you get\n\n| | |\n|---|---|\n| **Pipelines as graphs** | Drag-and-drop CI\u002FCD nodes — Trigger → Build → Scan\u002FSAST → Eval → Policy → Approval → Deploy → Promote → Rollback. n8n-shaped JSON on disk; YAML in git is the source of truth. |\n| **Governance is a node** | Approvals, policy checks, eval gates, PII\u002Fsecret scans are first-class, reorderable steps in the graph — not middleware you can't see. |\n| **Any runtime, one pipeline** | Same definition deploys to K8s, Bedrock AgentCore, or Vertex Agent Engine. (Today the Deploy node ships to **Bedrock AgentCore** end-to-end; K8s \u002F Vertex are stubbed.) |\n| **Durable by construction** | Restate journals every node (`restate.Run(\"node:\u003Cname>\", fn)`) — crash-safe replay, awakeable-based human approvals (timeout → auto-reject). |\n| **GitOps promotion** | A Promote node opens\u002Fmerges a PR `fromBranch → toBranch` on the agent's repo; the merge fires the next environment's pipeline. Promotion is an auditable event. |\n| **Real OCI builds** | BuildKit solves your Dockerfile against the cloned repo, pushes to GHCR or any registry (private-repo PAT support). Mirror to N registries with the Push node. |\n| **Operate, don't just deploy** | Live SSE log streams + canvas-overlay status rings; per-node logs archived to S3-compatible storage. |\n| **Self-hosted, end-to-end** | Your cloud credentials, agent code, and run history never leave your network. Secrets AES-GCM sealed at rest. |\n| **CLI-first** | `langship` — agents, envs, pipelines, creds, runs from your terminal. `git push` to ship. |\n\n---\n\n## 5 minutes to a green run\n\n**0. Start everything.** Base compose bundles every service `flow` needs —\n`mongo, restate, buildkitd, registry, minio, flow, web`.\n\n```sh\ndocker compose up\n```\n\n| | URL |\n|---|---|\n| UI | http:\u002F\u002Flocalhost:3000 |\n| API | http:\u002F\u002Flocalhost:8090 |\n| Restate | `:8081` ingress · `:9070` admin |\n| BuildKit | `tcp:\u002F\u002F127.0.0.1:1234` |\n| Registry | `127.0.0.1:5050` (host port; buildkitd pushes to `registry:5000` internally) |\n| MinIO | `127.0.0.1:9000` (S3 API) · `:9001` console (`minio` \u002F `minio12345`) |\n\n> If a sibling stack already owns one of those host ports, stop it or override the\n> mapping in a `compose.override.yml`.\n\n**1. Install the CLI and point it at the API.**\n\n```sh\npip install -e .\u002Flangship-cli          # optional: pip install pyyaml  (for -o yaml)\nlangship login --api-url http:\u002F\u002Flocalhost:8090\n```\n\n**2. Register an agent (a git repo) and push a pipeline.**\n\n```sh\nlangship agents create --repo https:\u002F\u002Fgithub.com\u002Fyou\u002Fyour-agent --pat ghp_...\nlangship pipelines push examples\u002Fhello.json        # prints the new pipeline id\n```\n\n**3. Wire it into an environment, follow it, run it.**\n\n```sh\nlangship envs create dev -d \"Auto-deploy on push\"\nlangship envs add-pipeline dev \u003CpipelineId>\nlangship agents follow-env \u003CagentId> dev\nlangship agents trigger \u003CagentId>                  # → prints execution id(s)\n```\n\n**4. Watch it run.**\n\n```sh\nlangship runs logs \u003CexecutionId> -f                # live SSE stream\n# or open the UI: http:\u002F\u002Flocalhost:3000\u002Fexecutions\u002Fview?id=\u003CexecutionId>\n```\n\nThat's the loop: `agent → env → pipeline → trigger → durable run → status`.\n\n### Hot-reload dev (three terminals)\n\n```sh\n# 1) backing services only\ndocker compose up -d mongo restate            # + buildkitd\u002Fregistry from the overlay\n\n# 2) Go API with air — rebuilds on .go change\nmake watch                                    # or `make serve` for a stable binary\n\n# 3) Next dev server with HMR; \u002Fapi proxies to :8090\nmake dev\n```\n\n`make watch` pre-exports env defaults matching the compose host ports — override\nany at the CLI, e.g. `make watch MINIO_ENDPOINT=...`. Set `FLOW_SECRET_KEY` in\nyour shell before touching anything credential\u002Fenvironment-related (the API\nrefuses credential writes without it).\n\n---\n\n## Architecture\n\nThree layers, all run by you:\n\n```\n            ┌──────────────────────────────────────────────────────────┐\n  CLI ──────►  API \u002F control plane   (Go — pkg\u002Fapi)                     │\n  UI  ──────►   REST + SSE · agents\u002Fenvs\u002Fpipelines\u002Fcreds\u002Fruns · webhooks │\n            └─────────────┬────────────────────────────────────────────┘\n                          │ RunAsync\n            ┌─────────────▼────────────────────────────────────────────┐\n            │  Orchestration   (Restate cluster + worker)              │\n            │  DAG walk (pkg\u002Forchestrator) → executors (pkg\u002Fexecutors) │\n            │  every node = restate.Run(\"node:\u003Cname>\", fn)            │\n            └─────────────┬────────────────────────────────────────────┘\n                          │\n            ┌─────────────▼────────────────────────────────────────────┐\n            │  Data:  MongoDB  (pipelines · runs · agents · creds ·    │\n            │                   environments)                          │\n            │         MinIO \u002F S3  (archived per-node logs, artifacts)  │\n            │         Postgres  — Restate's backing store ONLY         │\n            │         pkg\u002Fsecrets  — AES-GCM seal\u002Fopen (FLOW_SECRET_KEY)│\n            └──────────────────────────────────────────────────────────┘\n                          ▲\n            GitHub webhook │  \u002Fwebhooks\u002Fgithub\u002F{id}  (HMAC-verified)\n                           │  push → branch filter → dispatch run(s)\n```\n\nA run's lifecycle: webhook (or `langship agents trigger`) → the dispatcher walks\nthe agent's followed environments, applies each pipeline's branch filter, stamps\n`agentId \u002F environment \u002F fromBranch` into the trigger payload, and calls\n`orchestrator.RunAsync` → the DAG walker runs nodes in topological order, each\nwrapped in `restate.Run` → terminal status written back to Mongo `runs` → SSE\nclients (`\u002Fapi\u002Fexecutions\u002F{id}\u002Fstream`) get `node_started \u002F node_log \u002F\nnode_completed \u002F node_error \u002F done` events live.\n\n> **Why these choices** — Restate gives crash-safe journaling + awakeables (human\n> approval that survives a restart) for free; Mongo is the app store; Postgres is\n> *only* Restate's persistence and is never touched by app code; BuildKit does\n> real OCI builds without a Docker daemon. See [aude.md](.\u002Faude.md) for the full\n> rationale.\n\n---\n\n## Repo map\n\n```\ncmd\u002Fflow\u002F            the `flow` server binary (API + Restate worker entry point)\npkg\u002F\n  api\u002F               REST + SSE handlers (agents, envs, pipelines, creds, runs, webhooks)\n  orchestrator\u002F      DAG walk; Approval is special-cased out of restate.Run (it\n                     calls restate.Set\u002FClear directly)\n  engine\u002F            execution context, ExecutionEvent, the executor lookup\n  executors\u002F         node implementations + the registry:\n                       trigger · build · push · sast · imagescan · approval ·\n                       promote · deploy · (test\u002Feval\u002Fpolicy\u002Frollback stubs)\n  awsdeploy\u002F         AWS Bedrock AgentCore adapter — STS AssumeRole, idempotent\n                     ECR + IAM bootstrap, control-plane SigV4, endpoint wait\n  github\u002F            REST helpers — webhook install\u002Fverify, PRs, merges\n  storage\u002F           Mongo-backed stores: pipelines, runs, agents, credentials,\n                     environments\n  secrets\u002F           AES-GCM SealString\u002FOpenString keyed off FLOW_SECRET_KEY\nweb\u002F                 Next.js 15 UI (static export) — canvas, runs, agents,\n                     environments, credentials\nlangship-cli\u002F        the `langship` Python CLI (Typer \u002F Rich \u002F httpx)\nexamples\u002F            sample pipeline JSON\n```\n\n---\n\n## The `langship` CLI\n\nThe daily driver for agent devs; the bootstrap surface for platform engineers.\n\n```sh\npip install -e .\u002Flangship-cli                # + pip install pyyaml  for -o yaml\nlangship login --api-url http:\u002F\u002Flocalhost:8090   # saved to ~\u002F.langship\u002Fconfig.toml\n\n# the loop\nlangship agents create --repo https:\u002F\u002Fgithub.com\u002Fyou\u002Fagent --pat ghp_...\nlangship pipelines push prod.yaml --id \u003CpipelineId>     # create-or-update from a file\nlangship envs create prod -d \"Strict gates\"\nlangship envs add-pipeline prod \u003CpipelineId>\nlangship envs reorder prod \u003Cpid1> \u003Cpid2> \u003Cpid3>          # promotion order\nlangship agents follow-env \u003CagentId> prod\nlangship agents trigger \u003CagentId>\nlangship runs logs \u003CexecutionId> -f\n\n# credentials (server needs FLOW_SECRET_KEY)\nlangship creds create prod-aws --type aws \\\n  --aws-region us-east-1 --aws-account 123456789012 \\\n  --aws-role-arn arn:aws:iam::123456789012:role\u002FFlowDeployRole\n```\n\nCommand groups: `agents`, `envs`, `pipelines`, `creds`, `runs` — each with\n`--help`. `-o json` \u002F `-o yaml` on list\u002Fget commands. `LANGSHIP_API_URL` \u002F\n`LANGSHIP_TOKEN` override the saved config. Full reference:\n[`langship-cli\u002FREADME.md`](.\u002Flangship-cli\u002FREADME.md).\n\n---\n\n## Concepts\n\n- **Agent** — a registered git repo (URL + PAT). One-click GitHub webhook\n  install; `\u002Fwebhooks\u002Fgithub\u002F{id}` verifies the HMAC signature and dispatches runs\n  on push. An agent **follows environments** (`agent.environments[]`); triggering\n  it runs the pipelines of every followed env. Agents may carry per-agent\n  credential overrides.\n- **Environment** — a named, **ordered list of pipelines** (the promotion\n  sequence; reorderable). Global. Purely a sequencing container — per-deploy\n  config lives on the nodes, not the env. `dev` \u002F `staging` \u002F `prod` \u002F custom.\n- **Pipeline** — a DAG of nodes built on the canvas (n8n-shape JSON underneath),\n  stored in Mongo, loaded fresh per run. The Trigger node carries `fromBranch` \u002F\n  `toBranch`; a per-pipeline branch filter decides which pipelines run for a given\n  push.\n- **Credential** — a named record (`aws` \u002F `gcp` \u002F `kv`) in a global pool, with\n  optional per-agent overrides. Secret fields are AES-GCM sealed at rest with\n  `FLOW_SECRET_KEY`. Deploy \u002F Push look one up by name.\n- **Run** — one execution of a pipeline. Restate journals each node. Terminal\n  status is written back to Mongo's `runs` collection. The dispatcher stamps\n  `agentId`, `environment`, and `fromBranch` into the trigger payload; each node\n  emits a `__\u003Cnode>` summary object on its output items.\n- **Live view** — `\u002Fexecutions\u002Fview?id=…` subscribes to\n  `\u002Fapi\u002Fexecutions\u002F{id}\u002Fstream` (SSE) for `node_started`, `node_completed`,\n  `node_error`, **`node_log`**, and `done` events; the canvas overlays status\n  rings on each node.\n\n---\n\n## Nodes\n\n| Node | What it does |\n|---|---|\n| **Trigger** | Entry point; carries `fromBranch` \u002F `toBranch` for the branch filter + Promote. |\n| **Build** | Clones the agent repo (`fromBranch`), builds an OCI image via BuildKit (`mode: docker`) or runs `\u002Fbin\u002Fsh -c \u003Ccommand>` in the clone (`mode: shell`). GHCR auth uses the agent's PAT (`write:packages`); `localhost:*` \u002F `registry:*` are anonymous + insecure. Streams BuildKit's plain-mode progress as `node_log` events. |\n| **Push** | Mirrors the built image to one or more registries (go-containerregistry's `crane`). |\n| **SAST \u002F ImageScan** | Sibling-container scanners — trivy \u002F semgrep \u002F gitleaks \u002F SonarCloud \u002F grype — over the source \u002F image. Configurable severity threshold and fail-on-finding. |\n| **Approval** | Pauses on a Restate awakeable until resumed via `POST \u002Fapi\u002Fexecutions\u002F{id}\u002Fresume` (UI or `langship`). `method: ui \\| quorum \\| auto`; optional `timeoutSeconds` → auto-reject. Two outputs: approved (0) \u002F rejected (1). |\n| **Promote** | Opens or merges a PR `fromBranch → toBranch` on the agent's repo via the GitHub API — idempotent (re-finds an existing PR). Modes: `open-pr` \u002F `merge` \u002F `merge-pr`. Emits `__promote` with the PR number \u002F URL. The merge fires the next env's pipeline. |\n| **Deploy** | Deploys the upstream Push image to **AWS Bedrock AgentCore** (`target: agentcore`; k8s \u002F vertex are stubs). Looks up an `aws` credential by name, assumes the cross-account role, idempotently provisions the ECR repo + the shared `agentcore-runtime-role` IAM role, creates\u002Fupdates the runtime, waits for the endpoint to be `READY`, and emits `__deploy` with the public invoke URL. |\n| **Test \u002F Eval \u002F Policy \u002F Rollback** | Stubbed for now — visible on the canvas, no-op executors. |\n\nAdding a node? See the \"Adding a node executor\" section in\n[CONTRIBUTING.md](.\u002FCONTRIBUTING.md).\n\n---\n\n## Reference\n\n### Env vars (the `flow` process — `.\u002Fbin\u002Fflow serve`, `make watch`, or compose)\n\n| Var | Default | Notes |\n|---|---|---|\n| `FLOW_ADDR` | `:8090` | API listen address |\n| `FLOW_CORS_ORIGINS` | `*` (compose: `http:\u002F\u002Flocalhost:3000`) | CSV allowlist |\n| `FLOW_PUBLIC_URL` | (empty) | Externally-reachable base URL for webhook callback URLs. Set to your `cloudflared` tunnel for GitHub webhooks. |\n| `FLOW_SECRET_KEY` | (unset → credential writes refused) | Master key for AES-GCM sealing of credentials\u002Fsecrets. Any string; hashed to 32 bytes. **Losing it makes sealed data unrecoverable.** |\n| `MONGO_URI` | (required; compose: `mongodb:\u002F\u002Flocalhost:27017`) | |\n| `MONGO_DB` | `flow` | |\n| `RESTATE_INGRESS_URL` | `http:\u002F\u002Flocalhost:8081` | |\n| `RESTATE_ADMIN_URL` | `http:\u002F\u002Flocalhost:9070` | |\n| `RESTATE_SERVICE_ADDR` | `:9080` | Service-endpoint listen addr |\n| `RESTATE_DEPLOYMENT_URI` | `http:\u002F\u002Fhost.docker.internal:9080` | How Restate reaches us; compose overrides to `http:\u002F\u002Fflow:9080` |\n| `BUILDKIT_HOST` | `tcp:\u002F\u002F127.0.0.1:1234` | BuildKit gRPC; compose: `tcp:\u002F\u002Fbuildkitd:1234` |\n| `MINIO_ENDPOINT` \u002F `MINIO_ACCESS_KEY` \u002F `MINIO_SECRET_KEY` \u002F `MINIO_BUCKET` \u002F `MINIO_USE_SSL` | `127.0.0.1:9000` \u002F `minio` \u002F `minio12345` \u002F `flow-logs` \u002F `false` | Archived per-node log storage |\n\nCLI env: `LANGSHIP_API_URL`, `LANGSHIP_TOKEN` (override `~\u002F.langship\u002Fconfig.toml`).\n\n### Make targets\n\n| | |\n|---|---|\n| `make build` | build the web bundle then the Go binary (`bin\u002Fflow`) |\n| `make build-go` | Go binary only (expects `web\u002Fdist` to exist) |\n| `make serve` | `build-go` then `.\u002Fbin\u002Fflow serve` — stable binary |\n| `make watch` | Go API with `air` (rebuilds on `.go` change), env defaults pre-exported |\n| `make dev` | Next dev server with HMR (`\u002Fapi` proxies to `:8090`) |\n| `make web` | build the Next static export |\n| `make test` \u002F `make vet` \u002F `make tidy` | `go test .\u002F...` \u002F `go vet .\u002F...` \u002F `go mod tidy` |\n\n---\n\n## Contributing & community\n\n- **Issues & discussion** — [github.com\u002Fopen-gitagent\u002Flangship.sh\u002Fissues](https:\u002F\u002Fgithub.com\u002Fopen-gitagent\u002Flangship.sh\u002Fissues) for bugs and feature requests. Search first.\n- **Contributing** — [CONTRIBUTING.md](.\u002FCONTRIBUTING.md): dev setup, what to run before a PR, conventions, how to add a node executor. Contributions accepted under Apache 2.0.\n- **Code of conduct** — [CODE_OF_CONDUCT.md](.\u002FCODE_OF_CONDUCT.md) (Contributor Covenant). Report concerns to \u003Ckhush@lyzr.ai>.\n- **Security** — **do not** file public issues for vulnerabilities. See [SECURITY.md](.\u002FSECURITY.md) — report privately to \u003Ckhush@lyzr.ai>.\n\n## License\n\n[Apache 2.0](.\u002FLICENSE)\n","Langship 是一个用于部署、治理AI代理的开源平台，支持多框架、多运行时，并且是GitOps原生和自托管的。它采用Go语言编写，通过统一的管道定义即可在Kubernetes、AWS Bedrock AgentCore或Vertex AI Agent Engine上进行部署与治理，无需担心框架锁定问题。其核心功能包括基于图的CI\u002FCD流水线、可重排布的治理节点如审批和策略检查、以及针对不同运行环境的一致性治理流程等。此外，Langship还提供了持久化设计、GitOps晋升机制、真实OCI构建支持以及从终端操作的能力。适合需要灵活选择开发框架与运行环境同时保持高效治理的企业级AI应用开发场景使用。",2,"2026-06-11 04:00:56","CREATED_QUERY"]