npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@quq/keline-cli

v0.1.0

Published

客来茵后端查询 CLI(以只读为主,含定向发券写命令),供客户侧 AI Agent 经 Skill 调用

Readme

keline-cli

给客来茵后端接口做薄封装的命令行工具(以只读为主,含定向发券写命令 coupon send)。本文档面向调用方——编排本 CLI 的 Skill / AI Agent 作者——不是安装教程,也不是项目接手者文档(那些在 docs/)。

init 外,每条命令执行完毕后 stdout 恰好输出一个 JSON 对象(信封),不含任何日志或提示文本;诊断信息一律走 stderr。init 是全 CLI 唯一面向人的命令,被成功路由后输出人类可读文本而非信封(其命令行解析层的失败——如未知选项——仍走信封,边界见下文「命令速查」的 init 条目)。

契约

输出信封

成功:

{"ok": true, "data": <结果>, "error": null}

失败:

{"ok": false, "data": null, "error": {"code": "<稳定错误码>", "message": "<说明>", "details": <诊断信息或 null>}}

okdataerror 三键恒在,缺省侧显式为 null(不是省略该键)。请求帮助(--help)与版本号(--version)同样走这个信封,data 是帮助/版本号文本,不会有裸文本直接出现在 stdout 上。

退出码

| 退出码 | 含义 | 调用方应做的事 | |---|---|---| | 0 | 成功 | 正常消费 data | | 1 | 非用法问题(上游/网络/CLI 内部故障) | 不等于「可重试」,见下方按 error.code 分支 | | 2 | 用法或配置错误(error.code 恒为 E_USAGE) | 修正调用参数,重试无意义 |

退出码 1 MUST NOT 被当作「可重试」的统一信号E_AUTH 同样是退出码 1,而它重试无用,唯一补救是更换凭证。调用方 MUST 按 error.code 分支,而不是按退出码统一处置。

稳定错误码

| error.code | 含义 | 调用方应做的事 | |---|---|---| | E_USAGE | 调用方用法或配置错误 | 按 error.details 修正参数 | | E_AUTH | 凭证无效、过期或权限不足 | 更换凭证,重试无用 | | E_UPSTREAM | 后端返回业务失败 | 依 error.details 中的后端原始码与消息判断,不盲目重试 | | E_NETWORK | 网络故障或超时 | 可按自身策略重试 | | E_INTERNAL | CLI 自身未预期的错误 | 重试无用,应上报 |

后端内部错误码不会直接暴露为 error.code——调用方无需了解、也不应依赖后端内部枚举。

配置

两项后端配置(地址与凭证)从固定路径的配置文件读取,唯一来源——CLI 不再读取任何环境变量。

| 项 | 说明 | |---|---| | 路径 | $XDG_CONFIG_HOME/keline/config.jsonXDG_CONFIG_HOME 未设置、为空串、纯空白,或不是绝对路径时,仅在 HOME 为有效绝对路径时回落为 ~/.config/keline/config.json;两者均无效则路径不可解析(普通命令报 E_USAGEdetails.pathnullinit 在任何交互前拒绝执行) | | 格式 | 顶层为 JSON 对象,字段 baseUrl(后端地址,必填)与 apiKey(后端凭证,必填);字段缺失、为空串、纯空白或非字符串均视同未配置 | | 前置约定 | 部署前须先运行 keline init——它交互式收集这两项配置、做形态校验后发一次真实请求验证链路可用,通过后才写入配置文件。跑通 init 即代表链路已验证可用 |

配置文件缺失、不可读、内容不合法,或 baseUrl/apiKey 未配置时,命令以 E_USAGE、退出码 2 失败,不发出任何请求,error.message 含指引运行 keline init 的提示。

命令速查

本 CLI 目前共提供 15 条命令,覆盖门店、报表、客户、产品/服务项目、操作单、订单、发券七个维度,以及初始化命令 init。参数、必填性与默认值均以下方各命令的 --help 实测为准;如与本文档不一致,以 --help 为准并请提交 issue。

⚠️ 「返回观察形状」列是后端通常返回的形状,不是 CLI 的保证:本 CLI 对绝大多数命令只承诺透传的忠实性,不承诺 data 的具体结构——后端以成功码返回 null 或对象时会被原样透传,不会被伪造成空数组。调用方应对形状不符做防御。唯一例外是 customer getcustomer inactive:前者的七键聚合结构、后者的差集结果都是 CLI 自己组装的,可作契约性描述。

| 命令 | 位置参数 | 必填选项 | 可选选项(默认值) | 后端端点 | 返回观察形状 | |---|---|---|---|---|---| | keline store list | 无 | 无 | 无 | GET /store/listAll | 数组(后端通常形状,非 CLI 保证) | | keline report scope | 无 | --month | --store-id(可选,省略即不收窄门店范围) | GET /businessReport/listStoreAndStaff | 数组(门店→员工树节点,后端通常形状,非 CLI 保证) | | keline report monthly | 无 | --month | --store-id(可选,省略即企业整体) | GET /businessMonthlyReport/getReport | 单条报表对象(后端通常形状,非 CLI 保证) | | keline report daily | 无 | --date | --store-id(可选,省略即企业整体) | GET /businessDailyReport/getReport | 单条报表对象(后端通常形状,非 CLI 保证) | | keline report item-order | 无 | --month | --store-id(可选,省略即企业整体)、--page(默认 1)、--size(默认 20,上限 200) | GET /businessReport/pageItemOrder | 分页外壳对象(后端通常形状,非 CLI 保证) | | keline report item-consume | 无 | --month | --store-id(可选,省略即企业整体)、--page(默认 1)、--size(默认 20,上限 200) | GET /businessReport/pageServiceConsume | 分页外壳对象(后端通常形状,非 CLI 保证) | | keline customer list | 无 | 无 | --itinerary(可选,旅程名,取值集合运行时查询)、--keyword(可选,匹配昵称或姓名;手机号按尾号方向匹配——前缀不命中、过短不参与)、--page(默认 1)、--size(默认 20,上限 200) | GET /customer/page | 分页外壳对象(后端通常形状,非 CLI 保证) | | keline customer get | id(必填) | 无 | 无 | GET /customer/${id}GET /customer-portrait/${id}GET /customer-portrait/preference/${id}GET /customer-portrait/efficacy/${id}GET /customer-portrait/project/${id}GET /customerServiceRecord/pageGET /order/page | CLI 自有的固定七键聚合对象(profile/tags/preference/efficacy/project/latestService/lastVisitByConsumption),CLI 自身承诺的结构,不是透传形状 | | keline customer stats | 无 | 无 | 无 | GET /customerStatistics/customerWorkbenches | 统计对象(后端通常形状,非 CLI 保证) | | keline customer inactive | 无 | --days | --with-last-visit(可选,默认关闭;每位未到店客户至少 2 次额外请求) | GET /customer/pageGET /customerServiceRecord/pageGET /order/page | CLI 自有的差集结果对象(since/total/list),CLI 自身承诺的结构,不是透传形状 | | keline product list | 无 | --type | --keyword(可选)、--page(默认 1)、--size(默认 20,上限 200) | GET /product/page | 分页外壳对象(后端通常形状,非 CLI 保证) | | keline coupon send | 无 | --body | 无 | POST /activityConfig/addActivity(会在后端创建活动数据,不可撤销;请求超时后须先人工确认活动是否已创建,勿直接重发) | 后端固定返回 data:null(后端通常形状,非 CLI 保证) | | keline sheet list | 无 | --date | --store-id(可选,范围取决于凭证登录类型,见口径约束 1)、--page(默认 1)、--size(默认 20,上限 200) | GET /operationSheet/page | 分页外壳对象(后端通常形状,非 CLI 保证) | | keline order list | 无 | --date | --order-type(可选,逗号分隔,省略即不按类型筛选)、--store-id(可选,省略即全企业)、--page(默认 1)、--size(默认 20,上限 200) | GET /order/page | 分页外壳对象(后端通常形状,非 CLI 保证) | | keline init | 无 | 无 | 无 | 无后端业务端点(落盘前会以一次只读请求做活体校验,见下方说明) | 人类可读文本,不受三键信封约束——全 CLI 唯一面向人的命令 |

示例:

keline store list
{"ok": true, "data": [{"id": "1234567890123456789", "storeName": "示例门店"}], "error": null}

customer get 是唯一带位置参数的命令,且必须来自本 CLI 自身 customer list 的返回结果(见口径约束 7):

keline customer get 1234567890123456789

customer inactive:列出「今天减 N 天」至今天(含两端)内没有到店记录的客户(消费口径近似,见口径约束 14):

keline customer inactive --days 30

product list:核实用户口述的服务项目/产品名称,取得可用于组装品项券的 id 与卡类型支持范围:

keline product list --type service --keyword 艾灸

coupon send:读取一份 JSON 请求体,创建专享礼包活动定向发券(唯一的写命令,见口径约束 15);--body 取文件路径或 -(标准输入):

keline coupon send --body body.json

body.json 的最小合法请求体(品项券,服务项目):

{
  "activityName": "回店礼",
  "startTime": "now",
  "customerPhoneList": ["13800000001"],
  "giftList": [
    {
      "productType": 1,
      "periodValidity": 30,
      "serviceProductList": [{ "id": "2031909916478136322", "num": 1, "cardType": 1 }]
    }
  ]
}

一份专享礼包至多一项品项券,全部产品与服务项目合在这一项里;品项券每人固定 1 张,不接受 totalNum,要多次或多盒调整品项的 num;优惠券可用 totalNum 指定每人份数。

辅助请求

提供 --store-id 时,CLI 会先发一次门店存在性校验请求;提供 --itinerary 时,CLI 会先发一次旅程名翻译请求;coupon send 的请求体含品项券时,CLI 会先对其中每个去重后的产品/服务项目 id 各发一次 GET /product/{id} 确认其存在、启用、类型与卡类型受支持。这些请求自身失败时,错误码为 E_AUTH / E_NETWORK / E_UPSTREAM(退出码 1),不会被表述为「参数错误」(E_USAGE);品项确认查询唯有后端业务码 1001 会被判为「品项不存在」(E_USAGE、退出码 2),其余非零码一律 E_UPSTREAM

调用方 MUST 按 error.code 分支处理,而不是把退出码 1 一律当作「可重试」:E_AUTH 要换凭证,重试无用;E_NETWORK 可重试;E_UPSTREAMdetails 判断。否则一次后端不可达会被误当成「我传错了门店 id」,反复修改一个本来正确的值;或者一次凭证过期被无人值守的 Agent 无限重试。

口径约束

以下约束是既有决策已认定为「不这么写就会让调用方说出错误事实」的硬约束,不是使用建议。

| # | 约束 | 若缺失会发生什么 | |---|---|---| | 1 | sheet list 不提供 --store-id 时,查询范围取决于凭证登录类型:管理员/系统凭证下为全企业,员工凭证会被后端静默收窄为该员工所属门店。 | 调用方按无条件全企业汇报,实际只拿到了单店数据。 | | 2 | 服务操作单没有任何金额字段,不是开单;「今天谁开单了、多少钱」只能由 order list 回答。 | 调用方拿操作单条数当开单数、拿操作单列表当营收依据上报。 | | 3 | order list 的金额需由调用方自行累加各条的 paymentAmount,并按 totalElements 判断是否需要翻页;MUST NOT 用日报的营业收入字段(如 incomeAmount)冒充下单金额——该口径不含线上订单支付额。 | 只取第一页即汇报总额,金额静默少算;或拿营业收入冒充下单金额,得到一个看不出异常的错误数字。 | | 4 | 「到店」存在两种不可混用的口径:customer statstodayArrivalCustomerNumber 只统计「预约且到店」,不含未预约直接进店的客户。 | 把「预约且到店」的人数当作全口径到店人数汇报。 | | 5 | 品项数据没有「已售卖次数」,只有金额;report item-order 每项仅含品项名与金额。 | 承诺一个后端不提供的能力,向使用者答出一个编造的次数。 | | 6 | 客户侧的时间维度查询有限:2026-08-18 曾裁定完全不做,2026-09-12 推翻该裁决,接受消费口径近似(ADR-0001)——customer getlastVisitByConsumptioncustomer inactive 只计券核销/门店订单/客户消耗三类服务记录,以及门店/门店手工/券核销三类已支付订单;到店只咨询、回访而未消费的不计入。「近 x 天刚流失」仍不可回答——后端无旅程变更时间的查询出口。 | 把「最近一次消费」说成「最近一次到店」,或把只咨询过的客户列为未到店;或声称能回答「刚流失」。 | | 7 | customer get <id> 的 id MUST 来自本 CLI 自身 customer list 的返回结果,MUST NOT 使用外部来源的 id——后端存在跨企业越权读取风险。 | 外部来源的 id 会读到别家企业的客户数据。 | | 8 | report scope 返回的不是企业员工花名册,而是该期间有报表数据的门店与员工。 | 把本月没出业绩的员工当成不存在的员工。 | | 9 | 「今天谁开单了、多少钱」的订单类型口径是 --order-type 2,3(门店 + 门店手工)。 | 不传类型会把线上订单与券核销一并计入,得到一个口径不符却看不出异常的金额。 | | 10 | 品项数据要做全局排序或取 top N,必须先翻完所有页——CLI 每页上限 200,totalElements 是判断是否还有下一页的依据。 | 只对第一页排序,会漏掉真正的全局 top。 | | 11 | 订单返回中,付款金额字段名是 paymentAmount、商品列表字段名是 orderGoodsList,MUST 按原拼写读取。 | 键名写错,拿到 undefined 并当作零。 | | 12 | sheet list 同样不自动翻页:调用方 MUST 按 totalElements 逐页取回。 | 只取默认第一页,把最多 20 条当成了当天全部操作单。 | | 13 | order list 只返回已支付订单(状态口径由 CLI 固定,不可调整)。 | 把结果表述为「当天全部订单」,而未支付/已取消/已关闭的并不在内。 | | 14 | customer inactive 是 CLI 在全量扫描上计算的差集:--days N 的窗口为今天减 N 天至今天、含两端(Asia/Shanghai,共 N + 1 个自然日),扫描期间刚发生的到店可能未被计入;--with-last-visit 的成本为未到店人数 × 2 次以上请求,默认关闭。 | 把「3 天未到店」当成精确实时集合;或对全体客户默认开启补查打出数以千计的请求。 | | 15 | 发券(coupon send)的手机号与品项 id MUST 来自本 CLI 自身的查询结果(手机号取自 customer list / customer inactive / customer get,品项 id 取自 product list):后端对匹配不到的手机号静默忽略,产品详情端点不按企业过滤。coupon send 是本 CLI唯一的写命令,会在后端创建活动并按发放时间发券,不可撤销;请求超时后 MUST 先人工确认活动是否已创建,MUST NOT 直接重发。定时发放请至少提前一分钟以上,临近时刻请直接用 now。 | 手误的号码没人收到券且无报错;外来的品项 id 生成一张引用别家项目的券;把发券当查询反复重试造成重复发券。 | | 16 | 服务项目的 serviceCardSupportListproduct list 返回项)是该项目支持的卡类型编号数组(1 次卡 / 2 月卡 / 3 季卡 / 4 半年卡 / 5 年卡 / 6 两年卡,如 [1, 2]);品项券中服务项目的 cardType MUST 取自其中。 | 给一个只支持次卡的项目发月卡券,券无法核销。 | | 17 | 一份专享礼包(coupon send至多一张品项券,全部产品与服务项目合在这一张里,每人固定一张;要让客户得到多次或多盒,调的是券内品项的 num,不是发多张品项券(品项券不接受 totalNum)。优惠券不受此限,可用 totalNum 指定每人份数。 | 在对话里承诺「每人发 3 张艾灸券」,请求被 E_USAGE 拒绝后才发现兑现不了;或把多个品项拆成多张品项券,同样被拒。 |

组合示例

以下跨命令的编排、翻页与业务汇总均由调用方(Skill)完成,CLI 不做跨命令的循环或汇总(见口径约束 3、10、12)。

唯一的例外是 customer getcustomer inactive:前者内部聚合的八个来源(profile/tags/preference/efficacy/project/latestService/lastVisitServiceRecord/lastVisitOrder,见命令速查)是 CLI 自己组装的固定结构,不是「Skill 该做的编排」——档案被后端拆在多个端点上这件事本身就是后端知识,而不是一项业务决策,因此收在 CLI 内一次性做掉;调用方不需要、也不应对这些请求自行重复编排。后者的差集计算同理:「哪些表证明客户到过店」也是后端知识,不留给调用方拼装(见口径约束 14)。

今日经营总结report daily + sheet list + order list,注意操作单没有金额,金额来自订单):

keline report daily --date 2026-08-18
keline sheet list --date 2026-08-18
keline order list --date 2026-08-18 --order-type 2,3

⚠️ 以上三行只演示单次请求的命令形式,不是可直接得出总结的完整流程。 sheet listorder list 都不自动翻页(口径约束 3、12):取回响应后必须读 totalElements,若大于本次已取回的条数,递增 --page 继续请求同一条命令,直到累计取回条数达到 totalElements 为止,再汇总操作单条数、累加订单的 paymentAmount。当天记录不超过一页(默认 20 条)时,以上三行恰好就是完整流程;一旦超过,只跑一次就当作总结会静默漏报操作单、少算订单金额——这正是本文档要防止的那类失效,示例本身不能带头犯。

各门店月度经营对比(先取门店列表,再逐店查询——CLI 没有「一次返回各门店多条」的接口):

keline store list
keline report monthly --month 2026-08 --store-id 1234567890123456789

按旅程排查客户并取档案(id 必须来自 customer list 的返回结果):

keline customer list --itinerary 流失 --keyword 138
keline customer get 1234567890123456789

customer list 同样不自动翻页(默认每页 20 条):如需该筛选条件下的完整匹配列表而不只是前几条,需按 totalElements--page 翻页取全,做法与上面订单/操作单的翻页相同。