yc-cli
Operator's guide to the YC CLI (`yc`) for the Gini batch demo — scoped to the yc commands the demo actually uses: the validated browser-forward login flow (tmux + browser_connect) and investor research against Bookface. Assumes yc is installed but NOT logged in yet. Load before staging or running the demo.
git clone --depth 1 https://github.com/Open-Curiosity/gini-agent /tmp/yc-cli && cp -r /tmp/yc-cli/skills/integrations/yc-cli ~/.claude/skills/yc-cliSKILL.md
# YC CLI (`yc`) — demo operator's guide
`yc` is the Y Combinator CLI; it talks to **Bookface** over an authenticated
API. In our demo it's the **investor-research source** behind Step 5: pulling a
fund's track record (check size, YC conversion, recent deals) from the terminal.
This guide covers only the parts the demo touches.
## 0. Install + PATH (do this first)
Before using `yc`, check whether it's installed and decide whether to install
it — you (the agent) own this judgment; don't blindly run an install.
1. **Check if it's available.** Put the usual install locations on PATH first,
since the binary often isn't there in a non-interactive shell, then look:
```bash
export PATH="$HOME/.yc/bin:$HOME/.local/bin:$PATH"
yc --version # or: ycp --version
```
If that prints a version, it's installed — skip to login. If it errors with
"command not found", continue.
2. **Confirm it's genuinely missing, not just off PATH.** A bare `yc` can fail
just because PATH wasn't set. Before installing, verify the binary truly
isn't on disk (e.g. check `~/.yc/bin/yc` and `~/.local/bin/yc`). Only if it's
actually absent do you install.
3. **Install only when missing:**
```bash
curl -fsSL https://bookface.ycombinator.com/cli/install.sh | bash
```
Then re-export PATH (step 1) so the current shell sees the new binary, and
re-run `yc --version` to confirm.
Notes:
- If an existing `yc` command was detected at install time, the CLI may be
installed as **`ycp`** instead — try `ycp` if `yc` is absent.
- Non-interactive SSH shells don't source `~/.zshrc`, so set the
`export PATH=...` line at the top of any script before calling `yc`.
## 1. The optimal login flow (VALIDATED — use this)
We are NOT logged in yet. This is the flow we rehearsed to convergence — it's
the demo's Step 5 trust beat: the agent forwards its browser to the user, the
user signs in on their own device, the agent never sees the password. `yc login`
spins a local callback listener on `localhost:19876`; the agent's forwarded
browser can't reach that localhost, so we keep `yc login` alive in **tmux** and
let the CLI catch the callback directly while the user signs in.
> **Keep tmux backstage — do NOT mention it to the user.** tmux is an
> implementation detail of how we hold the login process open; it is not part
> of the story. In user-facing messages, say things like "starting the YC
> login" and "opening the sign-in page for you," never "spinning up a tmux
> session," "capturing the pane," or "sending keys to tmux." Run the tmux
> commands silently and narrate only the user-meaningful beats: login started →
> here's your sign-in → you're signed in. Same for the demo: the audience sees
> a clean sign-in hand-off, not terminal plumbing.
**4 steps, no redundancy:**
1. **Parallel logout** — clear both the CLI and the YC browser session:
```bash
yc logout
```
and in the same turn `browser_navigate` to the YC logout/session-clear URL so
the next sign-in is fresh (no silent reuse of an existing Google session).
2. **tmux + grab the OAuth URL in one shot.** Long URLs wrap in the pane, so
capture with `-J` (join wrapped lines) or you'll get a truncated URL:
```bash
tmux kill-session -t yclogin 2>/dev/null; tmux new-session -d -s yclogin
tmux send-keys -t yclogin 'export PATH="$HOME/.yc/bin:$HOME/.local/bin:$PATH"; yc login' Enter
sleep 2
tmux capture-pane -t yclogin -p -J | grep -o 'https://[^ ]*'
```
3. **`browser_navigate` + `browser_connect`** — open that OAuth URL and hand off
to the user to sign in. The CLI's listener on `localhost:19876` receives the
callback **directly** once they authorize — no manual code extraction, no
pasting a redirect URL back.
4. **Confirm:**
```bash
tmux capture-pane -t yclogin -p -J | grep -i successful
yc me # should print the founder + company, e.g. "Gini Agent (S26)"
```
Why tmux: a bare `yc login` over a non-interactive shell dies when the call
returns; tmux keeps the process alive to catch the callback. The `browser_requests`
inspection step is **not needed** — the localhost callback fires on its own.
### Fallbacks (only if the above stalls)
- `yc login --device` — prints a URL + code; user authenticates on another
device. Cleanest when browser-forward is flaky, but it's NOT what we rehearsed.
- `yc login --manual` — prints the auth URL, takes the redirect URL pasted back.
- Token lives in `~/.yc/credentials.json` and refreshes automatically. If
`yc me` already shows the right founder, do NOT re-run login.
## 2. The investor lookup (the yc beat of the demo)
Feeds Step 5. Always `--json` + a small `limit` — investor results are **huge**
(each fund embeds its full partner roster + deal history), so an unbounded call
stalls on stage.
```bash
yc search "<fund name>" --type investors # human: columns id,link,type,users,investments
yc tools run search --input '{"entity":"investors","query":"<fund>","limit":3}' # structured — PREFER live
```
- Pin the **exact query and fund name** during staging; confirm clean fields
(check size, conversion, recent deals). The "accurate, not fragile" check.
- Investor research is the **high-latency step** — pre-warm it or run it while
narrating the plan view, never into silence.
- Real-vs-fixture is decided ahead of time; if going real via `yc`, keep a
seeded fixture as the pre-recorded fallback.
## 2a. Investor profile — required output format
When the user asks for an **investor profile**, gather the data with the three
commands below, then present it in EXACTLY the markdown format that follows.
### Data-gathering commands
```bash
# 1. Identity, bio, education, followers (profile tool, by user_id)
yc tools run profile --input '{"action":"get","user_id":{user_id}}'
# 2. Ratings, stats, tags, and portfolio company IDs
yc search "{investor_name}" --type investors --json
# 3. Bulk batch breakdown (IDs extracted from command 2's results)
ycHow to dogfood and verify a Gini behavior change by driving a real chat turn as a real user would. Use when verifying that the agent reaches for a tool or path on its own — a behavioral steer, a new tool, an INSTRUCTIONS.md change, or a dispatch/provider/memory/skill change — or before claiming a steer "works". Enforces bare, uncoached prompts so the test measures the default, not instruction-following.
Delegate coding work to Claude Code CLI for repository edits, reviews, and multi-turn implementation sessions.
Delegate coding work to the OpenAI Codex CLI for repository changes, reviews, and focused fixes.
Gini's self-knowledge: how Gini configures, extends, and operates on its own state via /api/* and registered tools. Load when the user asks Gini about its own capabilities or asks Gini to modify its own configuration.
Manage Apple Notes via memo CLI: create, search, edit.
Apple Reminders via remindctl: add, list, complete.
Move bytes between Gini upload space, external URLs, and workspace files. Used by every attachment / file-upload / file-download flow regardless of the target system (Linear, GitHub, S3, Notion, etc.).
File a locally-captured, already-redacted Gini crash report as a GitHub issue, with the user's consent. Reads the pending crash queue and delegates the actual filing to the github-issues skill.