@letterstory/cli
旋转和管理信件 幽灵的博客 从你的终端。命令行是一种工具
客户端通过字母MCP端点(POST /api/mcp) -它封装了相同的工具
代理看到的清单,所以它永远不会偏离API。
安装
命令行是普通的ESM 零依赖关系 无需构建步骤(节点≥20)。
npm install -g @letterstory/cli # puts `letterstory` (and `phantom`) on your PATH
# …or run it without installing:
npx -p @letterstory/cli letterstory --help
这个 -p 不是可选的。这个包包含两个命令, letterstory 和 phantom,
NPX仅在包具有单个命令或以其命名的命令时为您推断一个命令
这个包——这里都不是真的,所以是裸的 npx @letterstory/cli 出口与
could not determine executable to run. 命名您想要的命令(letterstory 或者
phantom),然后把包裹递过去 -p.
对CLI本身有贡献吗?直接从签出处运行它:
cd cli
npm link # puts `letterstory` (and `phantom`) on your PATH, pointing at this checkout
# …or run it directly without linking:
node cli/bin/letterstory.mjs --help
更新
CLI最多每24小时检查一次npm是否有更新的发布版本(缓存) 与您的配置一起(因此大多数运行不需要额外的网络调用)并打印一行 当一个人有空的时候,轻推他:
Update available: 0.2.1 → 0.3.0. Run `npm install -g @letterstory/cli@latest` to upgrade.
立即升级:
npm install -g @letterstory/cli@latest
集 LETTERSTORY_NO_UPDATE_CHECK=1 完全禁用检查(例如在CI中)。
phantom -同样的命令行,幻影故事品牌
phantom 幽灵品牌的演示和演示入口点是相同的二进制文件吗
命令,相同的权限,相同的护栏 letterstory,只是一个不同的打印名称:
phantom deploy create --name "My Blog" --theme gazette
# 👻 phantom — deploy and manage Phantomstory blogs from your terminal
没有单独的实现来保持同步: bin/phantom.mjs 设置一个嫉妒变量
在导入之前 lib/cli.mjs,它交换横幅和命令提示字符串和
,否则运行与的完全相同的代码路径 letterstory.
进行身份验证
有两种方法-选择适合您运行CLI的方法。
通过浏览器登录 (默认值-最适合在您自己的机器上进行交互使用):
letterstory login
# opens your browser to https://app.letterstory.com, or override with --url
它运行一个基于浏览器的OAuth 2.1流(PKCE,环回重定向- RFC 8252)
帐户。它返回一个完全访问会话和一个刷新令牌,所以没有API密钥
预先铸造预先铸造或观察令牌保存到 ~/.letterstory/config.json (模式600)和
自动刷新。运行 letterstory logout 撤销会话并忘记它。
或者使用静态API密钥 (对于CI/自动化,或者当您想要向下访问时):
您需要一个Letter API密钥(以。开头) ls_;遗产 lb_ 键仍然工作)与 phantom:read 和
phantom:write 功能-薄荷一个在应用程序下 设置→API密钥
(https://app.letterstory.com/settings?tab=api-keys)。
添加 phantom:domain 如果您打算购买自定义域名也是如此。
letterstory login --key ls_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# points at https://app.letterstory.com by default; override with --url
凭证解析自 --key/--url 国旗,然后 LETTERSTORY_API_KEY /
LETTERSTORY_API_URL,然后 ~/.letterstory/config.json (写的 login,模式600)。
运行 letterstory whoami (别名 status)随时确认哪个密钥/url(或OAuth会话)
解决并查看您的公司简介。运行 letterstory config 要查看解析后的url和
不进行网络调用的凭据源。
幻影的故事-收集信件主办作为一个独立的出版物
幻影是我们托管的一个网站,它呈现了你的一个收藏;它从不携带你的
公司的名字。幻影是在site实时测量的(phantom balance),而不是帖子。
# provision a site and follow it until it's live (then it configures itself in the background:
# strategy, visuals, writing kernel, cadence, topic map)
letterstory phantom new --name "Saved Query" --config '{"cadence":{"posts_per_week":6}}'
# Phantom 7c19c7… provisioning — following…
# … provisioning · deploy
# … provisioning · connect
# Live at https://saved-query-7c19c7.letterstory-staging.com. Configuration continues in the background
letterstory phantom list
letterstory phantom get <phantom-id>
letterstory phantom config <phantom-id> # the site's file joined to its collection's
letterstory phantom config <phantom-id> --theme commons # patch the site (identity/theme rebuild it)
letterstory phantom config <phantom-id> --collection-config '{"cadence":{"posts_per_week":4}}'
letterstory phantom config <phantom-id> --configure --dry-run # what re-configuring would decide, applying nothing
letterstory phantom rebuild <phantom-id> # after publishing outside a collection run
letterstory phantom pause <phantom-id> # stop new posts and probing; the site stays live (resume to undo)
letterstory phantom resume <phantom-id>
letterstory phantom diagnostics <phantom-id> # why is my site empty?
letterstory phantom balance # sites live / granted, and the cadence cap
letterstory phantom spread-looks [--apply] # a different look per site; dry run unless --apply
letterstory phantom delete <phantom-id> --yes
通过 --no-wait 立即返回,稍后进行投票 phantom get, --no-configure
对于裸站点,或 --dry-run 在不提供任何东西的情况下查看计划。
发布到站点是一个 收集运行 关于其收藏(如下)。信自己的
推出配方从客户端域名定位推断,报头建议,第一
帖子种子-是 phantom-onboard (参见“求婚,然后登上幻影”)。
定制域
letterstory phantom domain check myblog.com # price it (no charge)
letterstory phantom domain buy <phantom-id> myblog.com --yes # buys + attaches (spends money; phantom:domain)
letterstory phantom domain connect <phantom-id> myblog.com # attach one you already own
内容
letterstory posts list [--limit <n>] [--collection <uuid>]
letterstory posts show <article-id>
letterstory posts new --title "…" --collection <uuid> --body "…" [--article-id <uuid>] # or --file <path|->; --article-id updates that article instead of creating one
letterstory posts new --title "…" --collection <uuid> --body "…" --context "Internal data from 120 accounts: disputes fell 38%." # your own data: stated in the post with your attribution
letterstory posts update <article-id> --title "…" --summary "…" --tag seo --tag ai # only what you pass changes; --body/--file for the HTML body
letterstory posts edit <article-id> --instruction "Tighten the intro" # AI rewrite, saved as your edit
letterstory posts mentions <article-id> # re-apply the brand-mention & competitor policy
letterstory posts history <article-id>
letterstory posts restore <article-id> <version> # comes back as the newest version
letterstory posts export <article-id> --format pdf --out post.pdf # or --format md (prints the Markdown)
letterstory posts comments <article-id>
letterstory posts comments add <article-id> --body "Source?" --quote "grew 40%"
letterstory posts comments update <article-id> <comment-id> --resolve # or --reopen, --body "…"
letterstory posts comments resolve-ai <article-id> <comment-id> # AI makes the change the comment asks for
letterstory reviewers invite <article-id> --email [email protected] --name "Sam" # a guest reviewer: link + PIN by email
letterstory posts publish <article-id>
letterstory posts unpublish <article-id>
letterstory posts delete --id <uuid> [--id <uuid> ...] # permanent; content, history, and any published copy are all removed
letterstory published list [--limit <n>] [--collection <uuid>] [--format html|md]
letterstory published show --slug my-post-slug [--format html|md] # or --id <uuid>
集合——内容引擎,一扇门
集合是具有ONE-FILE配置(标识、内容、节奏、
发布,目标,测量)产生和发布关于节奏的帖子。
collection run 生成一个帖子:源→写→闸→发布→(托管)重建。
letterstory collection list # public_id = the HTTP door's address
letterstory collection overview # site, state, posts, in Google, AI reads per collection
letterstory collection new --name "Launches" --config-file cfg.json
letterstory collection config <id> # print the one file
letterstory collection config <id> --config '{"targets":{"enabled":true,"tier":"ramping"}}' # patch it
# one post, followed to the end (20–60 min); stops at the gate under manual approval
letterstory collection run --collection <id> --spoke <topic-id>
letterstory collection run --collection <id> --topic "…" --approval manual --no-wait
letterstory collection run --collection <id> --at 2026-10-01T09:00:00Z # a future slot
letterstory collection run-status <run-id> # status, steps, constraints, verification
letterstory collection runs --collection <id> --status ready
letterstory collection approve <run-id> --now
letterstory collection cancel <run-id>
letterstory collection inventory <id> # every piece; each finished draft's publish-on-its-own time
letterstory collection links <id> # internal-link refresh: on/off, posts due
letterstory collection links <id> --refresh # run the next batch now
letterstory collection delete <id> --yes
# the legacy verbs still work under `collections`
letterstory collections update <id> --cadence-target 4 --cadence-period week
letterstory collections assign <article-id> <collection-id>
letterstory collections activate <id> --cadence 6 --approval autopilot
letterstory collections autopen <id> --kernel-family gazette
直接运行将花费该系列每周的一个节奏时段(它的节奏) posts_per_week,
被组织的节奏帽所限制),并且每周被拒绝一次——从不默默地排队
花;计划者自己的位置是按照设计花掉的预算。同一扇门
HTTP: POST /api/collection/ingest/{public_id} (202 + poll_url), GET …/runs/{run_id},
POST …/runs/{run_id}/approve.
登陆页面
登陆页是一个链接加上描述那里生活的内容的上下文。集合与
启用了自动提及功能(在集合设置中切换),将相关的登陆页面编织到
他们写的文章。将URL传递为 --link - - - - - - --url 全球旗帜是这样的吗
覆盖API基URL。
letterstory landings list
letterstory landings get <landing-id>
letterstory landings create --link https://example.com/dataset --context "Our 2026 benchmark dataset. Cite it when an article discusses response-time or CSAT metrics."
letterstory landings create --link https://example.com/report --file ./context.md # context from a file (or --file - for stdin)
letterstory landings update <landing-id> --context "Updated context"
letterstory landings delete <landing-id> --yes
流
运行一篇文章的编辑传递,检查它,并管理完成webhook:
letterstory flows list
letterstory flows run <flow-id> <article-id>
letterstory flows status <run-id>
letterstory flows webhook get
letterstory flows webhook set --url https://hooks.example.com/x --secret s3cr3t
letterstory flows webhook set --url none # disable it
连接器
将完成的文章发布到外部CMS或文档目标;
letterstory connectors list
letterstory connectors publish <article-id> --to webflow --target <target-uuid>
letterstory connectors status --connector webflow --publish-id <id>
策略与入职
letterstory strategy company get
letterstory strategy company set --name "Acme" --domain acme.com --manifesto "…"
letterstory strategy positioning get
letterstory strategy positioning set --topic seo --topic ai --stance "…" --clear-avoid
letterstory strategy positioning set --company-kind devtools --stage seed --motion product-led --category "AI visibility" # the company model; `none` clears a field
letterstory strategy competitors list
letterstory strategy competitors add "Rival Co" rival.com
letterstory strategy sitemap --collection <uuid> --url https://x.com/sitemap.xml
letterstory onboarding status
letterstory onboarding step --complete connect_domain
什么需要你-收集的“需要你”脱衣,从终端
条形图中的所有东西要么在倒计时后自行应用,要么等待你的 决定;同样的阅读和决定在这里。
letterstory suggestions list <collection-id> # strategy cards + when each applies itself
letterstory suggestions dismiss proposal <id> # reject one inside its window
letterstory collection inventory <collection-id> # finished drafts + when each publishes on its own
letterstory collection links <collection-id> # internal links due for a refresh
# proposed edits to live posts: a mention an AI citation earned, or fresher internal links
letterstory revisions list --collection <collection-id>
letterstory revisions accept <revision-id> # every change; live where we publish
letterstory revisions reject <revision-id> --change <change-id> --note "not this one"
产品——一个组织,许多产品
语境是分层的 组织→提供→征集. 供品是组织想要的任何东西
(“使用Lettershred”)。每一层只存储它所覆盖的内容
省略字段继承,和 --reset <field> 让一个人回到继承。的立场,避免
话题和被屏蔽的提及 添加 跨层(集合的姿态引导提示);
优先课题(--topic) 取代 继承列表,因此产品永远不会选择它的
兄弟姐妹的焦点。
letterstory offerings list
letterstory offerings create lettershred --name Lettershred --link https://lettershred.com \
--one-liner "Removes AI watermarks from text" --stance "Detection is an arms race" --topic "AI watermarks"
letterstory offerings update <offering-id> --reset priority_topics # inherit the org's focus again
letterstory offerings competitor <offering-id> --competitor <competitor-domain-id> --stance avoid
# A collection publishes as its primary offering and may mention the others it lists.
letterstory offerings set-collection <collection-id> --primary <offering-id> --also <other-id>:0.5
letterstory offerings set-collection <collection-id> --none # the org itself again
# Why is this collection writing what it's writing? (every field + the layer that set it)
letterstory offerings collection <collection-id>
letterstory offerings collection-context <collection-id> --stance "…" --avoid "pricing" --framing "…"
# The planner picks an offering per topic; override one pick (or --offering none to clear).
letterstory offerings topic <topic-id> --offering <offering-id>
一次性域登录
一个简单的公司领域,一个完全配置的组织,作为一个持久的工作 组合现有的引擎:主博客(从其站点地图导入或连接) CMS,内容区域,主题图,SEO,系列,公司GEO探测,标题),组织视觉 从站点推断,主博客的增强流程配置(新帖子被增强; 导入的帖子保持发布状态),一个已配置+已配置+已播种的幻影 实际撰写和发布的帖子,以及Seers在合适时的建议模式。 作业从回读结束:它等待(默认为2h)种子帖子发布和 第一个地球同步轨道探测器着陆,然后报告着陆的是什么。
# On the org behind your key (its registered domain is the source):
letterstory phantom-onboard domain --about "payroll for platform teams" --posts 3 --watch
letterstory phantom-onboard domain --sitemap https://acme.com/sitemap.xml --seers skip --no-visuals
letterstory phantom-onboard domain --attach <job-id> --watch # watch a job started elsewhere
letterstory phantom-onboard domain --status # the org's latest domain onboarding
# Staff: the key exchange (create the org first) needs a STAFF key with org:create —
# mint your OWN, don't share one. --watch makes the whole recipe ONE command: the
# freshly-minted org key is used only in this process's memory to poll to completion.
LETTERSTORY_STAFF_API_KEY=<your staff key with org:create> \
letterstory admin create-org --domain acme.com --onboard --watch --about "payroll for platform teams"
# Without --watch, it prints the org id, a fresh ORG-scoped API key (once), and the job
# id — watch it yourself with:
# LETTERSTORY_API_KEY=<the printed key> letterstory phantom-onboard domain --attach <job-id> --watch
父任务所做的一切也是现有组织的自己的工具:
ensure_collection_enhance_flow, provision_org_visuals, propose_seers (--args '{"apply":true}')。
工作人员:问舰队一个问题
# Needs a STAFF key with the fleet:query capability. The answer is derived from
# read-only SQL across every org -- nothing here can write, and credential columns
# are unreadable, so this is safe to point at production because it cannot be
# anything else.
LETTERSTORY_STAFF_API_KEY=<your staff key with fleet:query> \
letterstory admin ask "which writing kernels are hooked up to the most clients?"
# --sql prints every query behind the answer, which is what makes a scripted answer
# checkable; --json emits the whole result (answer + steps) for a caller that wants
# the queries as data.
letterstory admin ask "which clients published nothing in the last 30 days?" --sql
这是没有头的那一半 /superadmin/ask -相同的函数,相同的模式-所以a
长时间运行的代理可以在没有浏览器的情况下按照时间表监视船队。
工作人员:客户模式和寓言
# What separates clients whose AI visibility moves (docs/architecture/client-patterns.md):
# every client against itself on share of voice, mention rate and page access, with what we
# did for it. Needs fleet:read; `run` and `ask` spend Fable tokens and need fleet:query.
letterstory admin patterns --period 30d
letterstory admin patterns chain --dimension arenaVersion --outcome cited14 # what each kernel/arena/research change did
letterstory admin patterns reports # Fable's weekly reports and runs, newest first
letterstory admin patterns report <id> # one report's markdown
letterstory admin patterns run # a report now (takes minutes)
letterstory admin patterns ask "do answer-gap posts help paying clients too?"
管理→客户端性能→模式:相同的功能,相同的模式。
工作人员:内核实验
# Needs a STAFF key with the tuning:experiment capability. A key always acts as an
# agent: it can propose, plan, note, spend and conclude, never approve a plan.
export LETTERSTORY_STAFF_API_KEY=<your staff key with tuning:experiment>
letterstory admin tuning-context --q "colons" # what the agent knows (JSON)
letterstory admin tuning kernels # every catalog kernel: live version, writer, candidates
letterstory admin tuning kernel <service-kernel-id> --version live # one version's kernel file (JSON)
letterstory admin tuning candidate <service-kernel-id> --file hazel.json --note "Echo as the writer"
letterstory admin tuning compare --title "Echo vs live" --candidates Hazel:21,Aspen:20
letterstory admin tuning comparison <id> # per-measure verdicts (better / worse / within noise / refused)
letterstory admin tuning picks <id> # the blind queue; then: admin tuning pick <id> --cell <key> --pick left|right|tie
letterstory admin tuning reading-list <id> --n 10 # your next blind pairs as links (Text A / Text B), to read off the screen; pick in the console
letterstory admin tuning pair <id> --cell <key> # one pair named: live and candidate, both texts, the measures per arm (a key reads every pair)
letterstory admin tuning bank # the eval bank: every eval (rules and drafts), instances, labels
letterstory admin tuning bank-pool <eval-id> # draw an eval's pool from our shipped runs and the human corpus
letterstory admin tuning bank-judge <eval-id> --prompt-file judge.md --mode score --threshold 4 # a judge version (or --live: the rule's own)
letterstory admin tuning bank-score <eval-id> --version 2 # score it over the pool; prints agreement on held-out labels
letterstory admin tuning bank-try <eval-id> --version 2 # the judge as a trial rule in candidates, and a comparison against live
letterstory admin tuning invite --email [email protected] # invite an editor (Pick and Eval bank only); `people`, `revoke <id>`
letterstory admin tuning assign --pick <comparison-id> --instructions "Read for the opening" # a task for every editor (--to <email> for one)
letterstory admin tuning assign --label bank-draft-x-not-y --target 50 # editors cut or keep 50 of this eval's sentences
letterstory admin tuning side-by-side <id>,<id>,<id> [--cell <key>] # several writers as one board: each one's measures against live; with --cell, every writer's text on that input
letterstory admin tuning candidates --kernels all --patch '{"writer":"echo/echo"}' --note "Echo" # the same change as a candidate of each kernel
letterstory admin tuning session-new --title "Echo round 1" --kernel Hazel --input-file brief.md --kind outline [--version 22] [--versions 23,29] # --versions: saved candidates, a trial each
letterstory admin tuning propose <session> --text "Echo with rarity on; live with the shred after" --create # trials from words, over the dials
letterstory admin tuning trial-run <trial> --repeats 2 # runs advance on the server; poll `admin tuning session <id> --texts`
letterstory admin tuning trial-save <trial> --note "…" # a trial as a candidate version (never live); then `admin tuning compare`
letterstory admin tuning promote <experiment-id> --versions <service-kernel-id>:21 # from a concluded "ship" decision
letterstory admin experiments list --q colons # what we've tried
letterstory admin experiments list --primitive write --stage rarity # what we learned about one stage
letterstory admin experiments new "A different writer, voice rewritten, rarity rewrite off" --primitive write # an investigation in Write's notebook
letterstory admin experiments new "We use too many colons" --as "claude-code"
letterstory admin experiments update <id> --plan-file plan.json --budget 120
# ...a person approves the plan on the investigation's page (approval gates spending a budget; a person's
# investigation needs none and is concluded straight away)...
letterstory admin experiments spend <id> 54
letterstory admin tuning-import lab/results/colons/publish/<brief>.json --experiment <id>
letterstory admin experiments conclude <id> --decision drop \
--conclusion "Colons fell 60%; P(machine) did not move; quality held." \
--evidence lab:"kernels lab/results/colons/report.md" --stages rules
内核调优实验选项卡后面的分类账 (文档/建筑/ kernel-experiment-agent。Md):每个问核的问题, 它是如何被测试的,我们学到了什么,为什么。
员工:计划食谱
# Needs a STAFF key with recipes:read (reads) and recipes:write (writes): mint it on
# /superadmin/recipes → "Your agent's key". Recipes are global: one library behind every
# account's Plan. The same routes and functions as that page.
export LETTERSTORY_STAFF_API_KEY=<your staff key with recipes:read,recipes:write>
letterstory admin recipes vocab # what a recipe can say: tabs, fields, moves, outcomes, kinds, primitives
letterstory admin recipes export --out recipes.json # the library as a file
letterstory admin recipes import recipes.json --dry-run # what would be created / changed / retired
letterstory admin recipes import recipes.json # write it (matched by id, else tab and name)
letterstory admin recipes save --tab build --name "Docs it already writes" --look-at "…" --when-to-use "…" --company-types devtools
letterstory admin letterpress settings # the one judgement's weights per ask; per lens its mode (off / shadow / live) and bar
letterstory admin letterpress flip fix shadow # run the one judgement beside today's on every Fix pass, recorded, nothing shown changes
letterstory admin letterpress set weights.fix.prior 0.3 # one weight; the version bumps, the previous body is kept
letterstory admin recipes stats # per tab and recipe: shown, dismissed, and why
letterstory admin recipes save <id> --disable # retire one (delete <id> --yes removes it)
员工:CRM管道
# Needs a STAFF key with crm:read (reads) and crm:write (writes). The same routes the
# crm.letter.dev front end calls with a staff JWT; any /api/superadmin/crm/* route takes
# the key as x-staff-api-key (GET → crm:read, anything else → crm:write).
export LETTERSTORY_STAFF_API_KEY=<your staff key with crm:read,crm:write>
letterstory admin crm signals --status new # the Inbound feed (unmatched signals)
letterstory admin crm record --source bookface --kind message \
--title "Asked about phantoms on Bookface" --name "Jane Doe" --company Acme --domain acme.com
# Re-running that is a no-op: with no --external-id the intake derives an idempotency key from
# the signal's content, so a retried agent loop cannot fill the feed with the same observation.
# Pass --external-id when the source has a stable id (a thread id, a tweet id), or to record that
# an otherwise identical signal happened AGAIN.
letterstory admin crm record --source twitter --kind social_engagement \
--title "Liked our launch tweet" --name "Pat" --linkedin https://linkedin.com/in/pat
letterstory admin crm signal <signal-id> qualify # link/create the account
letterstory admin crm signal <signal-id> dismiss # the easy delete (kept, marked)
letterstory admin crm add "Acme" --domain acme.com # quick-add; an existing account says "already exists as <name> (<domain>)"
letterstory admin crm accounts --stage demo_scheduled # with likelihood
letterstory admin crm score <account-id> # recompute; prints the factors
letterstory admin crm slack-channels [--all] # Watchdog channels + the account each is linked to
letterstory admin crm link-slack <account-id> C0123ABC # the CRM's watch-only Slack link (`none` unlinks)
letterstory admin crm import leads.csv --dry-run # bulk-import leads: what would be created/matched
letterstory admin crm import leads.csv --tag "YC W26" # …and for real (dedupes by domain, then company name)
letterstory admin crm capture thread.png --context "this is for tryordinal.com" --dry-run
# a screenshot → a lead: what it read, which account
letterstory admin crm capture thread.png --context "this is for tryordinal.com" # …and for real
letterstory admin crm capture --text-file notes.txt # pasted text or notes work the same way
letterstory admin crm capture thread.png --retry # sent before, some entries didn't save: write only what's missing
# One-click onboarding of a won client (key needs crm:write + fleet:onboard + org:create)
letterstory admin crm onboard <account-id> --domain acme.com \
--site "Where fintech compliance is heading" --site "" \
--slack [email protected] --invite [email protected]:admin --invite [email protected]
letterstory admin crm onboarding <account-id> # step-by-step progress (sites refreshed)
letterstory admin crm retry-onboarding <onboarding-id> # re-run only the failed steps
letterstory admin crm onboard-plan <account-id> # what the calls say: sites, Slack/app people, paid?
letterstory admin crm payment-link <account-id> # Stripe Payment Link at the deal amount (billing:write)
letterstory admin crm payment-link <account-id> --plan growth # with Lago signups on: a card-only start link, Lago bills the plan
onboard 运行org→链接→幻影网站→Slack频道→清单→应用邀请→
在一个呼叫阶段。每个站点都是真实的(不是测试的)舰队构建; --site "" 让引擎
从客户端的主页上推断出它的节奏。 --disclose 2 (或 --disclose all)转向赞助商
该网站的披露(“安全模式”),以及 --disclose-note "…" 记录客户的话
作为理由; onboard-plan 标记呼叫请求的站点。 onboard-plan 读取该帐户的通话记录
(最新优先,每组调用缓存; --refresh 重读),并说明有多少个网站,每个
是关于邀请谁,以及他们是否付了钱。 payment-link 在账户的组织上盖章
Stripe订阅,所以通过它支付绑定并标记自己支付的账户。与
Lago在(LETTERBRACE_LAGO_SIGNUP),它是我们的开始链接:客户端保存一个
卡,Lago收费计划(--plan按交易金额定价的债券违约; --ratio, --why
至于 admin billing lago provision),并且不进行Stripe订阅。该帐户需要一个组织。
每个触发点,Cal.com预订,Circleback录音,Letterhome晚宴回复,RB2B
访问次数,以及代理在这里记录的-通过一个入口(ingestSignal,
src / lib / crm / signals-intake。Ts),所以代理的信号与网络钩子的完全相同
就像两个网络钩子一样。合格的种类(预约、通话录音、聚餐、留言、表单)环节
或者创建账户;不合格的(访问,喜欢)只附属于一个存在
帐户,否则在入站提要中等待。
求婚,然后登上幻影
舰队向导的“计划”和“命名”显示为两个命令:选择节拍,然后选择名称,
在任何东西被创造出来之前。既不保存也不花费(域检查)
只读)。将提案保存为JSON;选定的计划经过了 --plan-file + --plan-id,
所以它的方向和它的内容区域被固定在网站上完全被批准。
# Step one: the beat. Omit the domain to use your org's own.
letterstory phantom-onboard propose acme.com --json > proposal.json
letterstory phantom-onboard propose acme.com --about "bank regulators on agentic AI" # variations on a beat
# Step two: the name — candidate mastheads for ONE plan, each with its own priced domains.
letterstory phantom-onboard mastheads acme.com --plan-file proposal.json --plan-id plan-2
jq '.topicPlans[1]' proposal.json | letterstory phantom-onboard mastheads acme.com --plan-file -
# Then onboard with the plan (direction + pillars), the masthead and, if any, the domain.
letterstory phantom-onboard acme.com --plan-file proposal.json --plan-id plan-2 \
--name "The Compliance Wire" --domain compliancewire.com --domain-mode buy_now --real
# (drives plan_phantom; the seeded posts are collection runs — poll them with `collection run-status`)
propose 读取客户端的主页并返回不同的编辑角度(topicPlans),
单个后备计划,客户的现有出版物与重叠警告,和组织的
定制的域名空间。 mastheads 返回从不包含客户端自身名称的名称。没有
--plan-file, phantom-onboard <domain> 仍然只从主页规划。
检查计划,然后应用 那 计划好,然后交回来 --accept-plan. 一个光秃秃的
入职人员会计算两次计划——一次是你读的演练,一次是在工作中——然后
第二个报头提案不需要与第一个提案匹配,因此提交到URL中的名称
不会是你批准的那个。 --accept-plan 钉住它,暗示着 --accept,并跳过
第二个主页。
letterstory phantom-onboard acme.com --json > plan.json # dry run: read it, edit nothing
letterstory phantom-onboard acme.com --accept-plan plan.json
jq '.plan' plan.json | letterstory phantom-onboard acme.com --accept-plan -
内容系列
系列是一种覆盖义务,而不是关键词赌注:“看起来像这样的内容”, 每件申报物品一邮。系列提供与主题集群相同的计划器队列。
letterstory series list
letterstory series create --name "Secrets, tool by tool" \
--description "One practical secrets guide per IaC tool." \
--coverage "Pulumi,Terraform,Ansible" --template <key>
letterstory series backfill <series-id> --collection <uuid>
竞技场和编写内核
两个不同的步骤,按这个顺序。一个 竞技场 -一群敌对的研究特工-
阅读实时网络,并在你通过的时候写一个有来源的、经过事实核查的提纲
--article,否则重新开始运行);一个 编写内核 根据简报写草稿
它是给定的,不能自己检索。都需要几分钟,所以都是先开始后投票:
# 1. Research the topic — hosted on a post (outline written into it) or standalone
letterstory arena run --article <uuid> --topic "payroll solutions" \
--source https://example.com/a --must-include "Pricing" --depth fleshed_out
letterstory arena run --topic "payroll solutions" --no-wait # standalone; prints the run id
letterstory arena run-status <run-id> # phases, sources, outline, verification
letterstory arena cancel <run-id>
letterstory arena balance # arena runs left (direct runs only)
# …with --gate, the run pauses for you to pick the angle:
letterstory arena run --article <uuid> --gate
letterstory arena run-status <run-id> # status: awaiting_direction + direction_options
letterstory arena direction <run-id> --choice 1
letterstory arena direction <run-id> --custom "Lead with the hidden costs"
letterstory arena direction <run-id> --skip # let the agents decide
letterstory arena run --topic "payroll solutions" --direction "Lead with the hidden costs" # no gate, no vote
# Watching runs (what an agent monitoring the account polls):
letterstory arena runs --status awaiting_direction # the gates waiting on you
letterstory arena runs --since 2026-10-02T00:00:00Z --limit 50
letterstory arena runs --before <next_cursor> # the next (older) page
letterstory arena latest --article <uuid> # the post's latest run, whoever started it
# What research decided each site is — and your call on one (research never overrides it):
letterstory arena roles --rival # competitors research found that you never listed
letterstory arena role set reviewsite.com --role context
letterstory arena role set rival.com --role company --company "Rival" --rival
letterstory arena role reset rival.com # hand it back to research
# Arenas are callable endpoints with one-file defaults (the org's default arena is "Letter"):
letterstory arena list
letterstory arena endpoint create --name "Docs research" --defaults '{"depth":"barebones"}'
letterstory arena endpoint config <arena-id> [--file cfg.json]
letterstory arena endpoint update <arena-id> --name "Docs research v2" # creator or org admin only
letterstory arena endpoint delete <arena-id> --yes
# The research agent as ONE versioned file (like a kernel file; schema at /api/schema/arena):
letterstory arena file <arena-id> > arena.json # the file the arena runs now
letterstory arena file <arena-id> --patch '{"rules":{"context-figures":"measure"}}' --note "try it"
letterstory arena file <arena-id> --file arena.json # save a whole file as the next version
letterstory arena file <arena-id> --file arena.json --candidate # save beside live; runs nothing yet
letterstory arena promote <arena-id> <version> --yes # ship a candidate, or roll back
letterstory arena versions <arena-id> # your copy's versions and our releases
letterstory arena pin <arena-id> <version-id|none> # pin one of our releases, or follow live
letterstory arena offer <arena-id> [--accept] # our newer version, over your own changes
# Ledes: a prospect's context in, ready-to-send opening lines out (chosen from a
# hand-approved library, never generated; the top choice is flagged). Synchronous.
letterstory lede create --name "Clay outbound table"
letterstory lede run <endpoint-id> --first-name Jane --company Acme --company-url acme.com --years 3
letterstory lede run <endpoint-id> --email [email protected] --tone direct --candidates 3
letterstory lede run <endpoint-id> --company Acme --default-lede "Came across {{company}} this week."
letterstory lede runs --limit 20
letterstory lede balance
letterstory lede endpoint config <endpoint-id> [--file cfg.json]
# 2. Have a kernel write the draft
letterstory kernel list
letterstory kernel write <endpoint-id> --article <uuid> [--kernel <uuid>] [--file brief.md]
letterstory kernel status <kernel-job-id>
kernel run (和 submit_kernel_run 它背后的工具在2026-09-27被移除。它的一个
的工作是 kernel write <endpoint-id> --article <uuid>:没有 --body/--file 它从
文章本身的内容,和 kernel status 仍在调查它开始的工作。它的
--brief/--brief-file 标志没有替换:输入是 --body/--file,
不是内容的指导进入 --directives.
独立内核端点
kernel write 和 kernel polish 敲开独立的门:散文回来了,什么都没有
保存到一篇文章中,它是用内核运行积分而不是人工智能使用门来衡量的。
letterstory kernel endpoint create --name "Writer"
letterstory kernel endpoint delete <endpoint-id> --yes
letterstory kernel write <endpoint-id> --file outline.md \
--read-as outline --person first --author "Ada" --shredder <endpoint-id>
# Follows the run and prints the ARTICLE when it lands. --no-wait returns the run id instead.
分解
letterstory shredder run <endpoint-id> --file post.md --format markdown
# Queues, follows the job, prints the finished DOCUMENT. Exits non-zero if the job lands
# as error or degraded, so a script can branch on it without parsing the payload.
letterstory shredder run <endpoint-id> --file post.md --no-wait # just queue it
letterstory shredder job <job-id> # poll it yourself
# The shredder as ONE versioned file (like a kernel file; schema at /api/schema/shredder):
letterstory shredder file <endpoint-id> > shredder.json # the file the endpoint shreds with
letterstory shredder file <endpoint-id> --patch '{"rewriters":{"excludeWriterFamily":true}}'
letterstory shredder file <endpoint-id> --file s.json --candidate # save beside live; shreds nothing yet
letterstory shredder promote <endpoint-id> <version> --yes # ship a candidate, or roll back
letterstory shredder versions <endpoint-id> # your copy's versions and our releases
letterstory shredder pin <endpoint-id> <version-id|none> # pin one of our releases, or follow live
letterstory shredder offer <endpoint-id> [--accept] # our newer version, over your own changes
letterstory shredder families [--hours 6] # how each rewriter family is doing
每15-20秒进行一次循环投票。 LETTERSTORY_POLL_INTERVAL_MS 覆盖该-集
它 0 在CI中,这样测试就不会以实际间隔等待。
collection run --topic "…" --collection <uuid> 运行主题→草稿→发布→重建
端到端,用 collection run-status <job-id> 跟随它。
加强
在作者之后的传递——视觉效果、内部链接、外部链接(引用)、 元数据-作为每个集合(模型和设置)的一个版本文件,每次运行记录。
letterstory enhance run <article-id> --pass internal_links # run one pass on a post now
letterstory enhance runs --article <article-id> # what each pass did (also --auto-pen, --outcome skipped)
letterstory enhance get <run-id> # one run: version, models, what it added, cost
letterstory enhance file <collection-id> > enhancer.json # the file the collection's passes run
letterstory enhance file <collection-id> --patch '{"internalLinks":{"maxPerPost":3}}'
letterstory enhance versions <collection-id> # your copy's versions and our releases
letterstory enhance pin <collection-id> <version-id|none> # pin one of our releases, or follow live
letterstory enhance offer <collection-id> [--accept] # our newer version, over your own changes
letterstory autopen run --article <id> --skip finish,metadata # leave passes out of one run
组织配置
将一个组织的整个配置作为一个JSON包(export_org_config;文档/建筑/ org-config。Md):设置,原语和数据,按名称键控,活动原语文件,无运行或凭据。
letterstory org export > acme.json # the bundle — the same document MCP and the API return
letterstory org export --sections primitives.kernels --sections data.collections
letterstory org export --split acme/ # one file per record, for keeping config in git
letterstory org join acme/ > acme.json # rebuild the identical bundle from the directory
letterstory org fields data.collections # what each setting means: label, path, how it's edited, its gate
letterstory org diff acme.json # what applying the bundle would change: + add, ~ change, - only in the org
letterstory org apply acme.json --dry-run # what apply would write; then drop --dry-run to apply
letterstory org apply acme.json --prune --yes # also delete records the bundle lacks
letterstory org git connect acme/config --path letterstory/org.json # keep the config in GitHub: each new commit is planned and posted to Slack
letterstory org git connect acme/config --mode apply # …or applied (deletes only with --prune)
letterstory org git status # the connected repo and its last sync
letterstory org git sync [--force] # sync now instead of waiting for the 15-minute poll
预言家——事件驱动的信号
一、 先见 查看外部源(GitHub repo,一个Notion工作区,一个规范URL,一个
新闻或监管查询),并将其检测到的内容转换为标题建议——或者,在
auto Mode,直接进入草稿。需要 seer:read / seer:write 功能
(template:read / template:write 对于模板组)。
letterstory seers providers # the self-describing config catalog — start here
letterstory seers list
letterstory seers create --name "Ship notes" --collection <uuid> --provider github_pr \
--config '{"owner":"letterstory","repo":"letterbrace"}'
letterstory seers update <seer-id> --mode auto --interval 60
letterstory seers run <seer-id> # poll + produce now (minutes; spends AI budget)
letterstory seers events <seer-id> # detected signals, dedup aliases, relevance verdicts
letterstory seers dismiss <seer-id> <event-id>
letterstory seers headlines [--collection <uuid>] # the seer-sourced suggestion feed
letterstory seers held # drafts parked pending human review
letterstory seers release <article-id> # …or: seers discard <article-id>
可重复的设置-入职路径。 export 将组织的观察者写为
清单; apply 是幂等的, name-keyed 从一个(它永远不会删除;
在组织中,但在清单中没有的先知被列为额外人员,并单独留下):
letterstory seers export --file seers.json
letterstory seers apply --file seers.json --dry-run # print the create/update/ok plan
letterstory seers apply --file seers.json # apply it
连接-两个提供程序都是无头连接(不需要浏览器):
letterstory seers connections # GitHub + Notion status
letterstory seers connect github --token <pat> # org-wide token; unlocks private repos
letterstory seers connect notion # no token: prints how to mint one + which pages to share
letterstory seers connect notion --token ntn_xxx # store a Notion internal-integration secret
连接的概念。 概念使用 内部集成 a的直接类似物 GitHub PAT),所以它是完全可脚本化的:
- 创建一个 notion.so / my-integrations → 新集成→内部,与 阅读内容 能力。
- 复制 内部集成秘密 (
ntn_…/secret_…)。 - 在Notion中,打开每个页面/数据库,观察者应该观察→ •••→连接→ 添加您的集成。 一个概念集成只看到与它显式共享的页面 -这一步是必需的,或者预言家连接但什么也检测不到。
letterstory seers connect notion --token ntn_…
应用程序的浏览器OAuth流(Seers选项卡→Connect Notion)是一个等效的替代方案,而不是必需的。
剩下的空白。
seers run同步执行服务器端(最多5分钟) web-scan提供者);目前还没有“先开始后投票”的变体。和create配置需要 raw JSON -seers providers是服务器验证所依据的模式引用。
内容模板(组合结构观察者绑定的途径) config.template_key):
letterstory templates list # custom + read-only built-ins
letterstory templates create --name "Release notes" --angle "What shipped and why" \
--blocks-file blocks.json
letterstory templates update <template-id> --angle "…" # unset fields keep their values
letterstory templates delete <template-id> --yes # bound seers fall back to defaults
原始组合(一个命名的kernel/shredder/template/seer引用包)
docs/formats/compositions.md;不是原始的,没有端点或运行。需要
composition:read / composition:write):
letterstory compositions list
letterstory compositions create --name "Regulation-watch site kit" \
--content '{"kernel_family":"Cedar","shred":true,"template_key":"tmpl_howto"}' \
--phantom '{"theme":"gazette"}' \
--seer '{"name":"AI regulation watch","provider":"regulation_change","mode":"auto","config":{"query":"AI regulation"}}'
letterstory compositions resolve comp_9f1a2b3c4d5e # preview, read-only — costs nothing
letterstory compositions update <composition-id> --clear-seer
letterstory compositions delete <composition-id> --yes # non-destructive to phantoms already built from it
letterstory phantom create --name "EU AI Act Weekly" --composition '{"key":"comp_9f1a2b3c4d5e"}'
封面图片
哪个图像模型绘制帖子的封面是CLI决定的,而不仅仅是ui决定的。 variants
粉丝一个标题出来多达四个模型和手回预览每个模型;
select 提交你想要的代码:
letterstory covers models # image models connected to this org
letterstory covers variants --article <uuid> --model bloom --model openai
letterstory covers select --article <uuid> --url <variant-url> --provider bloom
# …or skip the comparison and let the server pick, using the collection's cover template:
letterstory covers generate <article-id> [--regenerate] [--stock-only]
--ref-url <url> (可重复的)条件看现有的图像-配对
extract_blog_reference_images 来匹配你镜像的站点。每个变种需要一个
图像生成,这就是为什么扇出限制在四个模型。
的见解
搜索控制台性能、全网范围、每个职位或顶级职位:
letterstory insights site [--period 14d|30d|90d] [--collection <uuid>]
letterstory insights post <article-id> [--period 14d|30d|90d]
letterstory insights top [--period 14d|30d|90d] [--collection <uuid>] [--limit <n>] [--sort clicks|impressions]
AI可见性和页面访问-测量选项卡的读取,脚本和代理:
# The Measure Overview: how often AI answers name you and cite your pages (rates
# with 95% intervals and gated trends), share of voice, search for your site and
# the phantom network kept apart, and each ranking target's standing. --part
# (repeatable) returns only those blocks: audience, ai, shareOfVoice, pageAccess,
# search, actions, targets — `ai` is the slow one on a large org.
letterstory insights summary [--period 14d|30d|90d] [--part <block>]...
# GEO → Competitors: every tracked brand's share of mentions (one per brand per
# answer) on the window, whether each is moving (the same question on the same
# engine in both windows — the only up/down read), the question × engine cells
# behind it, the line per engine, each question's top rival, and every dated
# change under the number. --period sets the windows: 14d → last 2 complete
# weeks vs the 2 before, 30d → 4 vs 4, 90d → 13 vs 13.
letterstory insights competitors [--period 14d|30d|90d]
# The AI Visibility Bank: which questions named you, cited your pages, or both (a
# breakthrough). All time unless --period; --source picks the phantom network
# (default), your marketing site, or the whole portfolio; --phantom narrows to
# specific phantom sites (repeatable); --answers caps receipts per question.
letterstory insights bank [--source phantoms|marketing|all] [--phantom <uuid>]... [--period 14d|30d|90d] [--answers <n>]
# Page access: AI answer engines, search crawlers and confirmed human readers on
# your phantom sites; --collection narrows to the site(s) a collection publishes.
letterstory insights access [--period 14d|30d|90d] [--collection <uuid>]
出站电子邮件-邮件,序列,前景
冷邮件堆栈:发送 邮递 (我们拥有的域名上真正的谷歌邮箱), 序列
(从它们发送的多步骤流,带有一个审查队列)和 前景 (你写信给谁)。写
这里可以发送电子邮件或花钱,所以他们拒绝未知的旗帜,而不是忽略它们。范围:
mailer:read / mailer:manage / mailer:provision, sequence:read / sequence:write,
prospect:read / prospect:write (写范围是仅管理键)。
# Mailers
letterstory mail vercel-key set --token-file - --team team_AbC123 # optional: buy domains on YOUR Vercel team (token on stdin)
letterstory mail registrant --first-name Dana --last-name Lee --email [email protected] --phone "(415) 555-0100" \
--address "1 Main St" --city Oakland --state CA --zip 94607 --country "United States" # WHOIS owner; any phone format
letterstory mailers quote acme-mail.com # price it first: nothing is bought
letterstory mailers launch acme-mail.com --mailer "hello:Hello Team" --forward-to [email protected] --yes
letterstory mailers domains # every domain: setup job, mailers, warmup
letterstory mailers list [--domain acme.com] # status + daily send limit
letterstory mailers domain <owned-domain-id> # provisioning stage, DNS, mailers on it
letterstory mailers retry <owned-domain-id> # resume a failed setup from the step it stopped at
letterstory mailers messages <mailer-id> [--folder inbox|sent|all] [--limit 25] # envelopes
letterstory mailers message <mailer-id> <uid> --folder inbox # one message, plain-text body
letterstory mailers forward <mailer-id> --to [email protected] # or --clear
letterstory mailers warmup start|pause <mailer-id> # 14+ days; ready once the warmup score reaches 85
letterstory mailers limit <mailer-id> 40 # 0..500; refused while warming
letterstory mailers retire <mailer-id> # disable; history kept
letterstory mailers retire <mailer-id> --release-mailbox --yes # also delete the hosted mailbox (irreversible)
letterstory mailers suppressions [list] [--reason bounce] [--limit 100]
letterstory mailers suppressions add [email protected] --reason manual --note "asked to stop"
letterstory mailers suppressions remove [email protected] # only 'manual' entries; opt-outs stay
# Org-level mail settings
letterstory mail connections # connected mailboxes, key + postal address status
letterstory mail postal-address "123 Main St, Portland, OR 97201" # CAN-SPAM footer
# Sequences (approving or enrolling SENDS)
letterstory sequences list | get <id> | create | update <id> | pause <id> | resume <id>
letterstory sequences enroll <id> --list <list-id> # or --email [email protected] ...
letterstory sequences review list | approve <item-id> | skip <item-id> | edit <item-id> --subject "…"
letterstory sequences links create --days 2 # no-login phone review link, shown once
letterstory sequences update <id> --test-mode # internal accounts only: walks as live, sends nothing
# Dispatches (the review desks a sequence queues to)
letterstory dispatches list | create --name "Founders" | rename <id> --name "VIPs" | delete <id> --yes
# Prospects
letterstory prospects lists | ls --list <list-id> | get <id> | import --csv-file leads.csv --list-name "Q4"
letterstory prospects source --description "heads of growth at seed-stage fintech" --list-name "Fintech"
letterstory prospects openers <list-id> --new-group "Fintech openers" # print an opening line per row
letterstory prospects columns add "Cake image" | columns delete <column-id> --yes
letterstory prospects delete <prospect-id>... --yes
连接自带Gmail邮箱需要一个浏览器(谷歌同意),因此在
应用程序; letterstory mail connections 显示连接的内容。
别的
每个字母工具都是可访问的,而不仅仅是那些具有专用命令组的工具:
letterstory whoami # or: status — verify your key + who it's for
letterstory tools list # list all tools (bare `tools` also works)
letterstory tools show list_articles # one tool's capability + full argument schema
letterstory call list_articles --args '{"limit":5}'
letterstory call ingest_article --args '{"title":"…","content":"…"}'
# `tool` is the same idea with schema-coerced arguments instead of raw JSON:
letterstory tool list_articles --arg limit=5 --arg collection_id=c1
letterstory tool ingest_article --json-args '{"title":"…"}' --arg content="…"
cat article.json | letterstory tool ingest_article --stdin
letterstory mcp # print MCP server config for an agent
letterstory mcp --print-key # inline the real key instead of a placeholder
全球旗帜
| 国旗 | 意义 |
|---|---|
--json | 机器可读的输出 |
--quiet | 抑制新命令组上的成功对话(--json 意味着它) |
--verbose | 记录HTTP请求/响应到stderr |
--no-color | 因兼容性而被接受;这个CLI已经打印了纯文本 |
--dry-run | 在 deploy/blogs create,或裸露 deploy打印会发生什么,不要调用API |
--url | 为一个调用重写API基URL |
--key | 覆盖一次调用的API密钥 |
--help | 显示使用 |
--version | 打印命令行版本 |