Skip to content

turso 迁回本仓后,CLI 的 URL→driver 解析仍对 libsql:// 抛 UnsupportedDriverError —— runtime 的 provisioning 却把 turso 排在偏好第一位,两处口径相反 #5602

Closed

Description

@os-zhuang

发现于:#4645 Phase A(@objectstack/driver-turso 迁入 packages/drivers/driver-turso)。Phase A 只做迁移,没有动任何接线;这个单记的是迁移暴露出来的口径分叉,需要维护者裁定要不要接。

现状(迁移后实测)

同一个仓库里,两处对 turso 的态度相反:

A. runtime 把 turso 当默认首选

  • packages/runtime/src/http-dispatcher.ts:1520 —— 环境 provisioning 的偏好顺序:turso → memory → 任意其他已注册 driver
  • 同文件 :1495 —— POST /cloud/environments 的 driver 参数示例即 memory | turso
  • packages/objectql/src/engine.ts:4086 —— turso 专属的瞬时 fetch failed 重试

B. CLI 的 URL 推断明文拒收 turso

  • packages/cli/src/utils/storage-driver.ts resolveStorageDefinition() 对 driverType === 'turso' || 'libsql' 抛 UnsupportedDriverError
  • packages/cli/src/commands/serve.ts 把它当 fatal 重抛,boot 直接 exit 1
  • inferDriverTypeFromUrl() 仍然把 libsql:// / *.turso.io 归类成 turso(注释写明是故意的:归类了才能响亮拒收,而不是静默掉回 SQLite)

拒收本身是对的、也是有来历的(#3276 那类 declared ≠ enforced:CLI 广告了 memory/turso 却没有分派分支,两者都静默变成 SQLite-in-memory)。在 driver 不在本仓的年代,"不在开源分发里"就是拒收的完整理由。现在这个理由没了,接线与否变成一个真正的选择。

Phase A 已做的(仅限真话修复,不改行为):把拒收信息里"ships with the ObjectStack cloud / enterprise distribution, not the open-core CLI"这句已经失真的话,改成"不是 CLI 从 URL 构造的 driver";content/docs/data-modeling/drivers.mdx、self-hosting.mdx、environment-variables.mdx 三处"开源框架不支持 Turso"同样改成"URL 不推断,需显式注册"。抛错行为一字未改,storage-driver.test.ts 的四条 pin 全绿。

需要裁定的是接线本身

选项 代价 说明
A. 维持现状(libsql:// 继续响亮拒收,只能显式注册) 零 CLI 不新增对 driver 包的依赖;libsql:// 用户必须写 stack config。runtime 的 provisioning 偏好顺序与 CLI 的 URL 推断本来就是两条路径,不接线不算矛盾——只是读起来像。
B. 接进 URL 推断(libsql:// → TursoDriver) CLI 新增一条对 @objectstack/driver-turso 的依赖(进而拖上 @libsql/client),或走可选动态 import + 缺包时响亮报错 与 runtime 把 turso 排第一的口径对齐;os start --database libsql://...(start.ts:54 的 example 里已经这么写了)真的能跑。

注意 packages/cli/src/commands/start.ts:54 的 examples 里已经写着
start --database libsql://my-db.turso.io --database-auth-token $TURSO_TOKEN ——
照抄这条 example 今天会 exit 1。无论裁定哪个选项,这条 example 都得跟着处理(B 则它成真,A 则它得删或改写)。

⛔ 不要在没有裁定的情况下顺手接:给 CLI 加一条 driver 依赖是公共契约面的变化(安装体积、可选 peer 的形状、libsql:// 从"响亮失败"变成"能连")。

Activity

  1. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    on Aug 5, 2026
  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    分诊:needs-user-decision + domain:cli(预挂)。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    决策分析(drivers 车道 PM,2026-08-06,应维护者要求)。正文两选项(A 维持拒收 / B 接进 URL 推断)按三轴:

    • 实际业务需求:turso 是 runtime provisioning 的偏好第一位、云产品的既定远程后端方向,且 start.ts:54 自己的 example 就写着 --database libsql://… —— 产品自己宣示的黄金路径今天 exit 1。这不是投机能力面,是已声明能力的兑现;但也要如实说:今天没有实测的「CLI 用户被 libsql:// 挡住」的工单,拉动来自产品内部一致性而非外部用户。
    • 项目长远合理性:拒收的历史理由(「driver 不在开源分发里」)已随 driver-turso 住在闭源 cloud 仓,却是开源 runtime 点名偏好的默认 driver — 建议把核心迁回本仓 #4645 消亡;维持 A 意味着永久保留一条与 runtime 口径相反的边界,且必须删掉自己的 example 与四处文档措辞(Phase A 已把它们从「不支持」软化为「不推断」— A 是把软化钉死)。B 让 declared = enforced。
    • 防 AI 写错:B 优 —— AI 照 example 写命令真的能跑;A 留着一个「文档示例必然失败」的陷阱,恰是教 AI 学会错误模式的温床。

    成本的关键在 B 的形态:@objectstack/driver-turso 拖 @libsql/client(含原生绑定),做 CLI 的硬依赖会显著加重 npx create-objectstack 类安装面。

    建议

    B-lite:接线,但走可选依赖 + 动态 import。 libsql:// / *.turso.io 识别后动态 import('@objectstack/driver-turso');包缺席时响亮失败,错误信息给出精确安装命令(不静默回退 SQLite —— #3276 的教训保持)。CLI 声明 optional peer,安装体积默认不变;workspace / 云镜像内包本就在场,example 直接成真。start.ts 的 example 加一行「需安装 driver 包」注记。

    若您裁 A(维持拒收):则 example 必须删除或改写为显式注册形态,四处文档从「不推断」进一步收紧为「不支持 URL 直连」,并接受与 runtime 偏好序的永久口径分叉 —— 这些代价请一并确认。

    两案均不阻塞任何在飞工作;裁定后实施属 domain:cli 车道(CLI 包),drivers 侧无改动。


    Generated by Claude Code

  4. added
    pm:queueReady for the PM dispatch loop
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    on Aug 6, 2026
  5. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    裁决落地:维护者 2026-08-06 拍板 — 按 B-lite 执行(PM 会话原话:「同意你的建议」,针对上一条分析的建议段)。

    裁定内容:libsql:// / *.turso.io 接进 CLI 的 URL 推断,形态为可选依赖 + 动态 import:

    已挂 pm:queue 转入队列(跨座位转移:落点 packages/cli,归 domain:cli 车道;domain:* 标签待分诊座位按例补,本评论即 source line:Part of 本单自身,裁决锚点在此)。


    Generated by Claude Code

  6. baozhoutao commented on Aug 6, 2026

    @baozhoutao
    Contributor

    决策输入补充


    Generated by Claude Code

  7. baozhoutao commented on Aug 6, 2026

    @baozhoutao
    Contributor

    截断修复指令(cli 车道 PM,会话 session_01DWUR56YsttL5sTF72Q75TQ):上一条 03:05Z 的「决策输入补充」评论正文为空 —— 疑似被 GitHub 消毒截断(裸 <x> 会吞掉其后全部内容),其作者会话(前任 cli PM,03:07Z 已注销)无法重贴。若该补充含对 B-lite 裁决的实质修正,请知情者(维护者或原作者后继)重贴全文;本单派发暂缓一轮等该修复,若无人补正,将按 01:05Z 已记录的 B-lite 裁决原样派发(可选依赖 + 动态 import,响亮失败不回退,optional peer,example 注记,pin 与四处文档同步)。


    Generated by Claude Code

  8. self-assigned this
    on Aug 6, 2026
  9. baozhoutao commented on Aug 6, 2026

    @baozhoutao
    Contributor

    认领:PM 循环第 3 轮(cli 车道)
    会话:session_01DWUR56YsttL5sTF72Q75TQ
    分支:claude/issue-5602-cli-libsql-url-inference
    Worktree:objectstack-issue-5602
    域:domain:cli
    文件面:packages/cli(utils/storage-driver.ts、commands/start.ts example、commands/serve.ts 如需、对应测试、package.json optional peer 声明)+ content/docs 三页措辞(drivers.mdx / self-hosting.mdx / environment-variables.mdx)+ changeset;⛔ 不改 packages/drivers/driver-turso(drivers 车道,仅动态 import 消费)

    执行依据:维护者 2026-08-06 01:05Z 已拍 B-lite(裁决评论在本 thread);03:05Z 那条被截断的「决策输入补充」修复窗口已过、无人补正,按已记录裁决原样执行。churn:PR #5789(schema-migrate/migrate 命令文件,已在合并队列)与本单文件面不相交;#5618 Phase A 动过 storage-driver.ts 与三页文档,以最新 origin/main 为准。


    Generated by Claude Code

  10. baozhoutao commented on Aug 6, 2026

    @baozhoutao
    Contributor

    验收:ACCEPT(cli 车道 PM,session_01DWUR56YsttL5sTF72Q75TQ,2026-08-06 06:4xZ)→ PR #5819

    转 ready + 挂 auto-merge 入队;MERGED 后 cli 线接续 #5429(等 #5673 先行,两者同落 doctor.ts)。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

pm:dispatchedDispatched to a dev agent by /pm-dispatchpm:queueReady for the PM dispatch loop

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions