← 开源
oneshot-agent

oneshot-gtm

GTM agent for technical founders. Pay-per-result. Two surfaces: terminal CLI + local web dashboard.

ApplicationsProductivityTypeScript
在 GitHub 打开
增长势头
+024 小时新增 Star0.0%
692
Star
18
Fork
3
贡献者
创建于 2026-04-23 · 更新于 2026-10-16 · 今日第 14931 名
主要开发者
README

oneshot-gtm

Outbound for founders who have not earned scale yet. It finds people, you approve them, it writes, you send.

oneshot-gtm.com · docs · what a signed receipt is

bunx oneshot-gtm-server     # the dashboard, no clone

https://github.com/user-attachments/assets/bba2fb2d-35c3-4171-a358-fd3a987c24bc

How it works

  • Finders watch public signals: a launch, a funding round, a new licence, a starred repo.
  • A gate judges each person against your ICP and rejects who does not fit. You can overrule it.
  • You approve rows in a queue. Approval sends nothing.
  • Each message opens with an offer specific to their firm, written from research and your product brief, in your voice. You send one, or run a batch. See the prospect offer.
  • Cadences follow up. A reply on any channel stops them.

Every paid call leaves a signed receipt, so spend per reply is a record and not an estimate.

It runs on your machine: a CLI and a local dashboard over one SQLite ledger. OneShot supplies the actions (research, enrichment, email, LinkedIn, SMS, voice, letters) and bills per call. You bring the LLM key. The licence is MIT. Read the prompts, fork the plays.

What it will not let you do

Most outbound tools assume product-market fit and optimise sends. Most founders using them do not have it yet. So the limits are in the code.

  • A first touch never asks a stranger for a meeting. It says one useful thing and asks one line back, or nothing.
  • Every draft passes a lint for machine writing. A flagged draft is held.
  • A new mailbox sends 10 a day and earns 10 more each week, up to 50. Once the day's quota is used, nothing more sends until midnight.
  • The handoff commands check your replies and deals before a scale move, and say so when it is too early.

Setup

curl -fsSL https://bun.sh/install | bash        # Bun is the runtime

git clone https://github.com/oneshot-agent/oneshot-gtm
cd oneshot-gtm && bun install

bun run cli -- init                             # profile and keys
bun run cli -- doctor                           # health check
bun run --cwd apps/web build                    # build the dashboard once
bun run cli -- ui                               # http://127.0.0.1:3030

init asks who you are and what you sell. Every field is optional: a blank one skips its beat in the draft, it is never invented. Your first workspace walks the dashboard path from an empty install to a reviewed draft. Prompt inputs maps each field to the drafts it reaches, and a voice card makes them sound like you.

bunx oneshot-gtm-server runs the dashboard without a clone. Both paths need Bun; the code uses bun:sqlite and fails under plain Node. bun run cli -- --help lists every command, and the CLI reference documents each flag.

Where targets come from

A finder is a source with a schedule and a spend cap: Show HN, funding news, accelerator cohorts, job changes, open roles, GitHub stars, event guest lists, business registries, public tenders, any page that lists companies. All of them start off. Turn on the ones your buyers show up in, apply an industry pack, or bring your own list. Finders has the table, the gates and the research each row gets.

The plays

A play is one motion: who it is for, what happened to them, what the first message says and how it follows up. Pick by the buyer's situation. Email and LinkedIn go out when you send. X, Reddit and Hacker News drafts are posted by you, then marked sent. Choosing a play lists each one with what it needs and what it produces.

Sending

Mail goes out through a pool of your own mailboxes and OneShot domains. A prospect always hears from the address that wrote first. Sending has the caps, the duplicate guard and reply handling.

LinkedIn

Connect your account once on Setup. Invites, messages and replies go through OneShot's API from that account, never a browser bot. LinkedIn has the limits and the guard that runs before each invite.

Direct mail

A physical letter as an optional cadence step. Each one is proofed and approved by hand; no bulk action sends mail. See direct mail.

Background monitoring as a service

Finders poll while the dashboard runs. ui --install-service keeps it running across restarts, and config spend-ceiling caps what a day of finder runs and drains may spend. See background monitoring.

Workspaces

One workspace is one product: one voice, one ICP, one ledger, one sender pool. A second product gets a second workspace.

bun run cli -- workspace create acme
bun run cli -- --workspace acme init
bun run cli -- --workspace acme ui

Workspaces share one database of people, paid lookups and contact history, so two products do not cold-email the same person in the same week. See workspaces.

Architecture

   apps/cli        apps/server       apps/web        surfaces
   commander       Bun.serve + SSE   Vite + React
        \               |               /
   packages/*      core · intel · plays · find · prompts · doctor · shared-types
                        |
   @oneshot-agent/sdk   email · LinkedIn · SMS · voice · research · enrichment · receipts
  • State. ~/.oneshot-gtm/ledger.sqlite is the source of truth for the CLI and the dashboard. ONESHOT_GTM_HOME moves it. Data storage lists every file and how to back it up.
  • Secrets. ~/.oneshot-gtm/.env, mode 600.
  • Server. Single user, bound to 127.0.0.1. The only routes meant for other systems are two webhooks.
  • Data. Lookups resolve through OneShot's data vendors.
  • Stack. Bun, TypeScript, Vitest, oxlint and oxfmt, Vite, React, TanStack, Tailwind. Plain async/await throughout.

What stays out of Git is in repository boundaries.

Development

bun install
bun run typecheck                  # tsc across apps and packages
bun run lint                       # oxlint
bun run fmt                        # oxfmt, also formats Markdown
bun --bun run test                 # vitest under Bun
bun run --cwd apps/web build       # apps/web/dist
bun run --cwd apps/server build    # the published server bundle

The --bun flag matters: bun:sqlite does not exist under Node. Tests set ONESHOT_GTM_HOME to a temp directory and never touch your ledger. STATUS.md carries the current test totals. Docs upkeep is in maintaining the docs.

Watching what's happening

Each install writes ~/.oneshot-gtm/events.jsonl: one line per LLM call, gate decision, finder event and swallowed error. It never leaves the machine.

tail -F ~/.oneshot-gtm/events.jsonl | jq -c '{t:.ts, k:.kind, ctx:.ctx}'            # everything, condensed
tail -F ~/.oneshot-gtm/events.jsonl | jq -c 'select(.kind|startswith("llm."))'      # LLM calls
tail -F ~/.oneshot-gtm/events.jsonl | jq -c 'select(.kind=="icp.decision")'         # topic gate
tail -F ~/.oneshot-gtm/events.jsonl | jq -c 'select(.kind=="icp.person_decision")'  # person gate
tail -F ~/.oneshot-gtm/events.jsonl | jq -c 'select(.level=="error" or .level=="warn")'
DEBUG=oneshot:* oneshot-gtm find watch --once                                       # mirror to stderr

The file rotates at about 10 MB into three older generations. Use tail -F; tail -f loses the file at rotation.

Telemetry

Anonymous and on by default. One command turns it off:

oneshot-gtm config telemetry off        # or ONESHOT_GTM_TELEMETRY=0

It sends one event per command: the command name, flag names, outcome, duration, versions, OS, LLM provider and a random install id. Nothing about prospects, prompts, replies, receipts or your wallet. TELEMETRY.md is the field list.

Status and scope

STATUS.md says what is verified against the live API and what is thin. ROADMAP.md says what is not built and what never will be: it will not run an SDR for you, manage your DNS, hold your customer data, lock you to one LLM or go multi-user.

License

MIT. See LICENSE. Shipped something with it? There is a badge.

Built by free.butter. The lead pipeline behind it runs there.

排名相邻
同类项目