@letterstory/cli

中文文档
0.175.18发布于 2026/11/01UNLICENSEDES Module零依赖

从您的终端启动和管理Letter虚拟博客。

中文使用文档
文档目录33 节
  1. 安装
  2. 更新
  3. phantom -同样的命令行,幻影故事品牌
  4. 进行身份验证
  5. 幻影的故事-收集信件主办作为一个独立的出版物
  6. 定制域
  7. 内容
  8. 集合——内容引擎,一扇门
  9. 登陆页面
  10. 流
  11. 连接器
  12. 策略与入职
  13. 什么需要你-收集的“需要你”脱衣,从终端
  14. 产品——一个组织,许多产品
  15. 一次性域登录
  16. 工作人员:问舰队一个问题
  17. 工作人员:客户模式和寓言
  18. 工作人员:内核实验
  19. 员工:计划食谱
  20. 员工:CRM管道
  21. 求婚,然后登上幻影
  22. 内容系列
  23. 竞技场和编写内核
  24. 独立内核端点
  25. 分解
  26. 加强
  27. 组织配置
  28. 预言家——事件驱动的信号
  29. 封面图片
  30. 的见解
  31. 出站电子邮件-邮件,序列,前景
  32. 别的
  33. 全球旗帜

@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),所以它是完全可脚本化的:

  1. 创建一个 notion.so / my-integrations → 新集成→内部,与 阅读内容 能力。
  2. 复制 内部集成秘密 (ntn_… / secret_…)。
  3. 在Notion中,打开每个页面/数据库,观察者应该观察→ •••→连接→ 添加您的集成。 一个概念集成只看到与它显式共享的页面 -这一步是必需的,或者预言家连接但什么也检测不到。
  4. 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打印命令行版本

版本与发布记录

@letterstory/cli 共发布 274 个版本,首次发布于 2026/07/20;过去 12 个月发布了 274 个版本。

版本发布日期距今
0.175.18latest2026/11/011 天前
0.175.172026/11/012 天前
0.175.162026/11/012 天前
0.175.152026/11/012 天前
0.175.142026/11/012 天前
0.175.132026/11/012 天前

关于 @letterstory/cli 的常见问题

@letterstory/cli 是什么?

从您的终端启动和管理Letter虚拟博客。

如何安装 @letterstory/cli?

在项目目录运行 npm install @letterstory/cli,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 phantom、letterstory,可以用 npx phantom 直接运行。

@letterstory/cli 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/letterstory__cli 是否存在。

@letterstory/cli 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@letterstory/cli 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@letterstory/cli 可以商用吗?

@letterstory/cli 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@letterstory/cli 还在维护吗?

最新版本 0.175.18 发布于 2026/11/01(1 天前);至今共发布 274 个版本,其中过去 12 个月发布了 274 个;首次发布于 2026/07/20。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。