@x-otto/cli 0.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +120 -0
  2. package/bin/otto.js +61 -0
  3. package/dist/auth-command-CXAB3_hs.js +11 -0
  4. package/dist/auth-command-CXAB3_hs.js.map +1 -0
  5. package/dist/build-id-BX4QHzM0.js +3 -0
  6. package/dist/build-id-BX4QHzM0.js.map +1 -0
  7. package/dist/bundled-extensions/plugin-otto-wire-protocols/otto-plugin.json +8 -0
  8. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/meta.json +1 -0
  9. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/plugin.cjs +60023 -0
  10. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin.ts +64 -0
  11. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-messages.ts +916 -0
  12. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-usage.ts +81 -0
  13. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-completions.ts +158 -0
  14. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-responses.ts +575 -0
  15. package/dist/bundled-extensions/plugin-skill-inductor/otto-plugin.json +8 -0
  16. package/dist/bundled-extensions/plugin-skill-inductor/plugin-dist/meta.json +1 -0
  17. package/dist/bundled-extensions/plugin-skill-inductor/plugin-dist/plugin.cjs +52781 -0
  18. package/dist/bundled-extensions/plugin-skill-inductor/plugin.ts +77 -0
  19. package/dist/bundled-extensions/plugin-skill-inductor/src/candidate-detector.ts +210 -0
  20. package/dist/bundled-extensions/plugin-skill-inductor/src/candidate-digest.ts +146 -0
  21. package/dist/bundled-extensions/plugin-skill-inductor/src/candidate-store.ts +87 -0
  22. package/dist/bundled-extensions/plugin-skill-inductor/src/episode-store.ts +122 -0
  23. package/dist/bundled-extensions/plugin-skill-inductor/src/episode.ts +125 -0
  24. package/dist/bundled-extensions/plugin-skill-inductor/src/extraction-prompt.ts +97 -0
  25. package/dist/bundled-extensions/plugin-skill-inductor/src/inductor-service.ts +183 -0
  26. package/dist/bundled-extensions/plugin-skill-inductor/src/similarity.ts +58 -0
  27. package/dist/command-dispatcher-BgStVcCF.js +13 -0
  28. package/dist/command-dispatcher-BgStVcCF.js.map +1 -0
  29. package/dist/config-migration-DatflIxs.js +21 -0
  30. package/dist/config-migration-DatflIxs.js.map +1 -0
  31. package/dist/daemon-COESl-zU.js +21 -0
  32. package/dist/daemon-COESl-zU.js.map +1 -0
  33. package/dist/daemon-base-YOWgYYN7.js +3 -0
  34. package/dist/daemon-base-YOWgYYN7.js.map +1 -0
  35. package/dist/debug-CiosFwme.js +34 -0
  36. package/dist/debug-CiosFwme.js.map +1 -0
  37. package/dist/discover-with-bundled-CznLjkkw.js +3 -0
  38. package/dist/discover-with-bundled-CznLjkkw.js.map +1 -0
  39. package/dist/doctor-C84-hhEr.js +30 -0
  40. package/dist/doctor-C84-hhEr.js.map +1 -0
  41. package/dist/doctor-attach-_zeIJewx.js +42 -0
  42. package/dist/doctor-attach-_zeIJewx.js.map +1 -0
  43. package/dist/doctor-cdp-K_mIFRfA.js +5 -0
  44. package/dist/doctor-cdp-K_mIFRfA.js.map +1 -0
  45. package/dist/doctor-heap-Rr2nNvcw.js +11 -0
  46. package/dist/doctor-heap-Rr2nNvcw.js.map +1 -0
  47. package/dist/doctor-ps-OL3FGQYu.js +8 -0
  48. package/dist/doctor-ps-OL3FGQYu.js.map +1 -0
  49. package/dist/extension-Bhzoel6s.js +169 -0
  50. package/dist/extension-Bhzoel6s.js.map +1 -0
  51. package/dist/extension-plugin-CnF6O_zK.js +7 -0
  52. package/dist/extension-plugin-CnF6O_zK.js.map +1 -0
  53. package/dist/extension-plugin-DWcakwRx.js +2 -0
  54. package/dist/extension-v-liRnUX.js +2 -0
  55. package/dist/feedback-BES_6ebi.js +21 -0
  56. package/dist/feedback-BES_6ebi.js.map +1 -0
  57. package/dist/feedback-BRbLUn9u.js +2 -0
  58. package/dist/feishu-setup-D6vnuNLw.js +6 -0
  59. package/dist/feishu-setup-D6vnuNLw.js.map +1 -0
  60. package/dist/index.d.ts +6 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +20 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/install-DlVJRHRT.js +11 -0
  65. package/dist/install-DlVJRHRT.js.map +1 -0
  66. package/dist/install-WCcQ9k9M.js +2 -0
  67. package/dist/mcp-DbTYT7hB.js +12 -0
  68. package/dist/mcp-DbTYT7hB.js.map +1 -0
  69. package/dist/migrate-boDXhEyV.js +14 -0
  70. package/dist/migrate-boDXhEyV.js.map +1 -0
  71. package/dist/model-auth-C27iG6Jq.js +3 -0
  72. package/dist/model-auth-C27iG6Jq.js.map +1 -0
  73. package/dist/model-auth-C4bsWvvn.js +2 -0
  74. package/dist/observe-CVg-MRM2.js +32 -0
  75. package/dist/observe-CVg-MRM2.js.map +1 -0
  76. package/dist/parse-cli-tFDOeVU1.js +3 -0
  77. package/dist/parse-cli-tFDOeVU1.js.map +1 -0
  78. package/dist/persistenced-CCwHu1Ww.js +36 -0
  79. package/dist/persistenced-CCwHu1Ww.js.map +1 -0
  80. package/dist/proxy-BvdBsB1O.js +2 -0
  81. package/dist/proxy-evg7ZvoD.js +3 -0
  82. package/dist/proxy-evg7ZvoD.js.map +1 -0
  83. package/dist/ps-DKrluEuy.js +9 -0
  84. package/dist/ps-DKrluEuy.js.map +1 -0
  85. package/dist/registry-B3nfN62q.js +2 -0
  86. package/dist/registry-D0NONjLv.js +6 -0
  87. package/dist/registry-D0NONjLv.js.map +1 -0
  88. package/dist/remote-persistence-server-B_hONoVR.js +35 -0
  89. package/dist/remote-persistence-server-B_hONoVR.js.map +1 -0
  90. package/dist/run-attach-Ci5jYyCa.js +3 -0
  91. package/dist/run-attach-Ci5jYyCa.js.map +1 -0
  92. package/dist/serve-pVR6UIT9.js +21 -0
  93. package/dist/serve-pVR6UIT9.js.map +1 -0
  94. package/dist/service-client-BLNeugM9.js +3 -0
  95. package/dist/service-client-BLNeugM9.js.map +1 -0
  96. package/dist/time-travel-ZozuPPI-.js +21 -0
  97. package/dist/time-travel-ZozuPPI-.js.map +1 -0
  98. package/dist/version-C0qM-qJM.js +3 -0
  99. package/dist/version-C0qM-qJM.js.map +1 -0
  100. package/package.json +61 -0
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # @x-otto/cli
2
+
3
+ ## 模块定位
4
+
5
+ Otto 命令行入口,解析参数并分发到 Print / JSON / Interactive 运行模式与子命令。
6
+
7
+ ## 使用方式
8
+
9
+ ```bash
10
+ # Print 模式(单次执行)
11
+ otto "fix the bug" -p
12
+
13
+ # Interactive 模式(REPL,默认)
14
+ otto -i
15
+
16
+ # JSON 模式
17
+ otto "summarize this file" --json
18
+
19
+ # 指定模型
20
+ otto "explain this" -m claude-sonnet-4
21
+
22
+ # 启用调试
23
+ otto -i --inspect
24
+
25
+ # 子命令
26
+ otto doctor # 环境诊断
27
+ otto config # 配置迁移
28
+ otto auth # 认证管理
29
+ otto extension # 插件管理(install / list / update / remove / trust)
30
+ otto serve # 启动 HTTP/WS service
31
+ otto persistenced # 独立持久化存储服务
32
+ otto observe # 观测面板
33
+ otto debug # 调试面板
34
+ otto time-travel # 时间旅行(checkpoints / restore / fork / replay)
35
+ otto mcp # MCP server OAuth 管理
36
+ otto ps # 进程列表
37
+ otto migrate # 数据/配置导入导出
38
+ otto feedback # 反馈管理
39
+ ```
40
+
41
+ ## 参数
42
+
43
+ | 参数 | 说明 |
44
+ |------|------|
45
+ | `-p` / `--print` | Print 模式 |
46
+ | `-i` / `--interactive` | Interactive 模式 |
47
+ | `--json` | JSON 模式 |
48
+ | `-m` / `--model` | 指定模型 |
49
+ | `-c` / `--config` | 配置文件路径 |
50
+ | `-d` / `--project` | 工作目录 |
51
+ | `-v` / `--verbose` | 详细日志 |
52
+ | `-q` / `--quiet` | 仅 error 日志 |
53
+ | `--continue` | 继续上次会话 |
54
+ | `--inspect[=port]` | 启用调试(默认 9229) |
55
+ | `--max-tool-turns` | 单回合最大工具调用数 |
56
+ | `--max-tool-turn-extensions` | 触顶后压缩续跑扩展次数 |
57
+ | `--session-url` | 远程持久化 URL |
58
+ | `--session-token` | 远程持久化 Bearer token |
59
+ | `--id` | 显式 workspace ID |
60
+ | `--help` / `--version` | 帮助 / 版本 |
61
+
62
+ ## 安装
63
+
64
+ ```bash
65
+ pnpm add @x-otto/cli
66
+ ```
67
+
68
+ 或从仓库构建:
69
+
70
+ ```bash
71
+ pnpm --filter @x-otto/cli build
72
+ node packages/cli/bin/otto.js
73
+ ```
74
+
75
+ 全局安装(dev):
76
+
77
+ ```bash
78
+ pnpm --filter @x-otto/cli build
79
+ pnpm --global link packages/cli
80
+ ```
81
+
82
+ ## API
83
+
84
+ | 导出 | 类型 | 说明 |
85
+ |---|---|---|
86
+ | `runCli` | `() => Promise<number>` | 主执行入口,返回退出码 |
87
+
88
+ ## 目录概览
89
+
90
+ ```
91
+ bin/
92
+ otto # 二进制入口(#!/usr/bin/env node)
93
+ src/
94
+ cli.ts # 主执行入口(SUB_COMMANDS 注册表)
95
+ parse-cli.ts # 参数解析(parseCLI)
96
+ types.ts # 核心类型
97
+ index.ts # 顶层执行 + runCli 导出
98
+ auth-command.ts # auth 子命令
99
+ build-id.ts # 构建元信息
100
+ commands/ # 子命令模块(~49 文件)
101
+ i18n/ # 国际化类型
102
+ modes/ # 运行模式辅助
103
+ session-contract/ # 会话契约
104
+ tests/ # 14 个测试文件
105
+ ```
106
+
107
+ ## 开发命令
108
+
109
+ ```bash
110
+ pnpm --filter @x-otto/cli build
111
+ pnpm --filter @x-otto/cli typecheck
112
+ pnpm --filter @x-otto/cli clean
113
+ ```
114
+
115
+ ## 关联包
116
+
117
+ `@x-otto/agent`、`@x-otto/ai`、`@x-otto/coding`、`@x-otto/env`、`@x-otto/hooks`、`@x-otto/mcp`、
118
+ `@x-otto/memory`、`@x-otto/persistence`、`@x-otto/interchange`、`@x-otto/remote-persistence-server`、
119
+ `@x-otto/runtime`、`@x-otto/schedule`、`@x-otto/service`、`@x-otto/session`、`@x-otto/session-contract`、
120
+ `@x-otto/setting`、`@x-otto/shared`、`@x-otto/tools`、`@x-otto/trace-view`、`@x-otto/tui`
package/bin/otto.js ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ // otto CLI 入口——P0 内存治理终局修复:显式钉死 V8 old-space 堆上限为 4096MB(4GiB),
3
+ // 不再依赖 V8 对物理内存的启发式推算(Docker 实测:>16GB 物理内存后 heap_size_limit 不再
4
+ // 继续放大,本机 48GB 与一台 16GB 机器拿到的默认值完全一致,均为 4144MB——大内存机器并未
5
+ // 获得应有的更大堆预算)。容量心智模型:16GB 机器可干净并发 4 个 otto 进程(4×4GB=16GB)。
6
+ //
7
+ // --max-old-space-size 是 V8 启动期 flag,运行时 v8.setFlagsFromString() 无法生效(已实测验证:
8
+ // 老生代堆大小在进程启动时即初始化完成)。必须在 node 启动前经 execArgv 传入,故本文件做一次性
9
+ // 自我 respawn(检测 process.execArgv 是否已带该 flag,未带则重新 spawn 自身并注入)。
10
+ //
11
+ // 重启幂等性:RFC-115/RFC-085 的内存治理/--exit --restart 陪跑重启(cli.ts)用
12
+ // `spawn(process.execPath, [...process.argv.slice(1), ...])`,`process.argv[1]` 恒为本文件路径——
13
+ // 每次重启都会重新进入本文件、重新执行本 respawn 检测,故重启后的新进程同样带着正确的堆上限,
14
+ // 不会因为陪跑重启丢失(node flag 在 execArgv 而非 argv,不会被 argv.slice(1) 意外透传/复制,
15
+ // 必须靠本文件的检测逻辑主动重新注入)。
16
+ //
17
+ // 可覆盖:OTTO_MAX_OLD_SPACE_MB 环境变量(运维在容器/内存受限环境下调整)。
18
+ import { spawn } from 'node:child_process'
19
+ import { fileURLToPath } from 'node:url'
20
+
21
+ // P0 内存治理(2026-07-18 长跑驻留事故):NODE_ENV 未设置时默认 production。
22
+ // 依据:react/index.js 按 NODE_ENV 条件加载 development/production 构建;development 构建的
23
+ // react-reconciler 组件性能追踪(logComponentRender)对每次组件 render 调用 performance.measure(),
24
+ // 而 Node 的 user-timing 缓冲无界累积、无人消费——实测 17h 长跑进程累积 246 万条 PerformanceMeasure,
25
+ // 驻留 2GB+(heapUsed 2210MB,clearMeasures 后 175MB),是"运行时内存单调爬升逼近 4GB 堆上限"的
26
+ // 直接根因。production 构建零 performance.measure 调用(已 grep 核实),从源头消除。
27
+ // 显式设置 NODE_ENV=development 的调试场景不受影响(仅未设置时兜底)。
28
+ if (!process.env.NODE_ENV) {
29
+ process.env.NODE_ENV = 'production'
30
+ }
31
+
32
+ const DEFAULT_MAX_OLD_SPACE_MB = 4096
33
+
34
+ function resolveMaxOldSpaceMb() {
35
+ const raw = process.env.OTTO_MAX_OLD_SPACE_MB
36
+ if (!raw) return DEFAULT_MAX_OLD_SPACE_MB
37
+ const parsed = Number(raw)
38
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_MAX_OLD_SPACE_MB
39
+ }
40
+
41
+ const maxOldSpaceMb = resolveMaxOldSpaceMb()
42
+ const flag = `--max-old-space-size=${maxOldSpaceMb}`
43
+ const alreadySet = process.execArgv.some((a) => a.startsWith('--max-old-space-size='))
44
+
45
+ if (alreadySet) {
46
+ await import('./../dist/index.js')
47
+ } else {
48
+ const child = spawn(
49
+ process.execPath,
50
+ [flag, ...process.execArgv, fileURLToPath(import.meta.url), ...process.argv.slice(2)],
51
+ { stdio: 'inherit', env: process.env },
52
+ )
53
+ child.on('exit', (code, signal) => {
54
+ process.exitCode = code ?? (signal ? 1 : 0)
55
+ })
56
+ child.on('error', (err) => {
57
+ console.error(`[otto] Failed to respawn with ${flag}: ${err.message}`)
58
+ process.exitCode = 1
59
+ })
60
+ }
61
+
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import{createApp as e}from"@x-otto/coding";import{createDefaultAuthStore as t}from"@x-otto/ai";import{createInterface as n}from"node:readline/promises";async function r(n,i={}){if(!i.authStore&&i.bootstrap){let t=e({workspaceDir:i.bootstrap.workspaceDir,projectConfigPath:i.bootstrap.projectConfigPath,logger:{name:`otto-auth`,level:i.bootstrap.verbose?`debug`:`info`,destination:`stderr`}});try{return await t.start(),await r(n,{...i,authStore:t.authStore,bootstrap:void 0})}finally{await t.stop()}}let s=i.stdout??(e=>process.stdout.write(e)),l=i.stderr??(e=>process.stderr.write(e)),u=i.authStore??t({watchForExternalChanges:!1}),[d,f]=n;switch(d){case`login`:return a(u,f,{stdout:s,stderr:l,prompt:i.prompt});case`logout`:return o(u,f,{stdout:s,stderr:l});case`status`:case void 0:return c(u,{stdout:s});default:return l(`otto auth: unknown action '${d}'. Use login | status | logout.\n`),1}}function i(e){return e.oauth.list().map(e=>e.id)}async function a(e,t,r){let a=i(e);if(a.length===0)return r.stderr(`otto auth login: no OAuth-capable providers available yet.
3
+ Install a provider plugin first — run \`otto\` (interactive) for guided setup,
4
+ or: otto extension install anthropic-provider
5
+ `),1;if(!t)return r.stderr(`otto auth login: missing provider. One of: ${a.join(`, `)}\n`),1;let o=e.oauth.get(t);if(!o)return r.stderr(`otto auth login: unknown provider '${t}'. One of: ${a.join(`, `)}\n`),r.stderr(`Hint: plugin providers (cursor, anthropic, …) need the plugin installed with provider capability granted.
6
+ otto extension install --link extensions/plugin-cursor --yes
7
+ # user-scope install auto-trusts; then otto auth login cursor
8
+ `),1;let s=r.prompt?void 0:n({input:process.stdin,output:process.stdout}),c=r.prompt??(e=>s.question(e)),l=new AbortController,u=()=>l.abort();process.on(`SIGINT`,u);try{let n={onAuth:e=>{r.stdout(`\nOpen this URL in your browser to authorize:\n ${e.url}\n`),e.code&&r.stdout(`Code: ${e.code}\n`),e.instructions&&r.stdout(`${e.instructions}\n`)},onPrompt:async e=>{let t=e.placeholder?` (${e.placeholder})`:``;return(await c(`${e.message}${t}: `)).trim()},onManualCode:async e=>{let t=c(`
9
+ Paste the code here: `).then(e=>e.trim(),()=>``);return e?e.aborted?``:Promise.race([t,new Promise(t=>{e.addEventListener(`abort`,()=>t(``),{once:!0})})]):t},onProgress:e=>r.stdout(`${e}\n`),signal:l.signal};return await e.login(t,n),r.stdout(`\n✓ Logged in to ${o.name}.\n`),0}catch(e){return r.stderr(`\notto auth login failed: ${e.message}\n`),1}finally{process.off(`SIGINT`,u),s?.close()}}async function o(e,t,n){if(!t)return n.stderr(`otto auth logout: missing provider. One of: ${e.listProviders().join(`, `)}\n`),1;let r=await e.hasCredential(t);return await e.logout(t),n.stdout(r?`✓ Logged out of ${t}.\n`:`${t} was not logged in.\n`),0}const s={oauth:`OAuth`,api_key:`API key (stored)`,env:`API key (env)`};async function c(e,t){t.stdout(`Authentication status:
10
+ `);for(let n of e.listProviders()){let r=await e.getAuthSource(n),i=r?s[r]:`not configured`;t.stdout(` ${n.padEnd(16)} ${i}\n`)}return 0}export{r as runAuthCommand};
11
+ //# sourceMappingURL=auth-command-CXAB3_hs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-command-CXAB3_hs.js","names":[],"sources":["../src/auth-command.ts"],"sourcesContent":["import { createInterface } from 'node:readline/promises'\n\nimport { createApp } from '@x-otto/coding'\nimport { createDefaultAuthStore } from '@x-otto/ai'\nimport type { AuthStore, OAuthLoginOptions } from '@x-otto/ai'\n\n/**\n * `otto auth login|status|logout` 子命令(M8-07)。\n *\n * 驱动 AuthStore.login 的 onAuth/onPrompt/onManualCode 回调:\n * - Anthropic(usesCallbackServer=false)→ loopback(54545) 优先自动回填,\n * 端口占用时回退托管回调 + 用户回贴 code(onManualCode 必须提供);\n * - loopback provider(OpenAI/Codex,usesCallbackServer=true)→ 浏览器重定向自动完成。\n * - 插件 OAuth(cursor/anthropic 等)→ 须 bootstrap App 装载插件后再查 oauth 表(RFC-130 M131-1)。\n */\nexport interface AuthBootstrapOptions {\n workspaceDir: string\n projectConfigPath?: string\n verbose?: boolean\n}\n\nexport interface AuthCommandDeps {\n authStore?: AuthStore\n /** 未注入 authStore 时,经 App.start() 装载插件 OAuth(对齐 TUI `/auth`)。 */\n bootstrap?: AuthBootstrapOptions\n stdout?: (s: string) => void\n stderr?: (s: string) => void\n /** 单行读取器(注入便于测试);未提供时按需创建 readline。 */\n prompt?: (question: string) => Promise<string>\n}\n\nexport async function runAuthCommand(args: string[], deps: AuthCommandDeps = {}): Promise<number> {\n if (!deps.authStore && deps.bootstrap) {\n const app = createApp({\n workspaceDir: deps.bootstrap.workspaceDir,\n projectConfigPath: deps.bootstrap.projectConfigPath,\n logger: {\n name: 'otto-auth',\n level: deps.bootstrap.verbose ? 'debug' : 'info',\n destination: 'stderr',\n },\n })\n try {\n await app.start()\n return await runAuthCommand(args, {\n ...deps,\n authStore: app.authStore,\n bootstrap: undefined,\n })\n } finally {\n await app.stop()\n }\n }\n\n const stdout = deps.stdout ?? ((s) => process.stdout.write(s))\n const stderr = deps.stderr ?? ((s) => process.stderr.write(s))\n // watchForExternalChanges:false —— `otto auth *` 是一次性命令,跑完即退出,不需要跨进程凭据\n // 实时同步(那是给 TUI/serve 长驻进程用的)。AuthStore 的 fs.watch 句柄本身已 unref(不阻塞\n // 事件循环清空,见 auth-store.ts setupWatcher 注释),此处显式关闭仍是更准确的语义表达——\n // 避免为一个秒退的脚本无谓建立/拆除一个不会被用到的 watcher。\n const authStore = deps.authStore ?? createDefaultAuthStore({ watchForExternalChanges: false })\n\n const [action, provider] = args\n\n switch (action) {\n case 'login':\n return authLogin(authStore, provider, { stdout, stderr, prompt: deps.prompt })\n case 'logout':\n return authLogout(authStore, provider, { stdout, stderr })\n case 'status':\n case undefined:\n return authStatus(authStore, { stdout })\n default:\n stderr(`otto auth: unknown action '${action}'. Use login | status | logout.\\n`)\n return 1\n }\n}\n\nfunction loginableProviders(authStore: AuthStore): string[] {\n return authStore.oauth.list().map((p) => p.id)\n}\n\nasync function authLogin(\n authStore: AuthStore,\n provider: string | undefined,\n io: { stdout: (s: string) => void; stderr: (s: string) => void; prompt?: (q: string) => Promise<string> },\n): Promise<number> {\n const providers = loginableProviders(authStore)\n // UX(round 6):零 provider 插件时 providers 为空数组——\"One of: \"后面是空串,\n // 用户面对死端。指回引导路径而不是展示空名单。\n if (providers.length === 0) {\n io.stderr(\n 'otto auth login: no OAuth-capable providers available yet.\\n' +\n 'Install a provider plugin first — run `otto` (interactive) for guided setup,\\n' +\n 'or: otto extension install anthropic-provider\\n',\n )\n return 1\n }\n if (!provider) {\n io.stderr(`otto auth login: missing provider. One of: ${providers.join(', ')}\\n`)\n return 1\n }\n\n const oauth = authStore.oauth.get(provider)\n if (!oauth) {\n io.stderr(`otto auth login: unknown provider '${provider}'. One of: ${providers.join(', ')}\\n`)\n io.stderr(\n 'Hint: plugin providers (cursor, anthropic, …) need the plugin installed with provider capability granted.\\n' +\n ' otto extension install --link extensions/plugin-cursor --yes\\n' +\n ' # user-scope install auto-trusts; then otto auth login cursor\\n',\n )\n return 1\n }\n\n const rl = io.prompt ? undefined : createInterface({ input: process.stdin, output: process.stdout })\n const ask = io.prompt ?? ((q: string) => rl!.question(q))\n\n const controller = new AbortController()\n const onSigint = (): void => controller.abort()\n process.on('SIGINT', onSigint)\n\n try {\n const options: OAuthLoginOptions = {\n onAuth: (info) => {\n io.stdout(`\\nOpen this URL in your browser to authorize:\\n ${info.url}\\n`)\n if (info.code) {\n io.stdout(`Code: ${info.code}\\n`)\n }\n if (info.instructions) {\n io.stdout(`${info.instructions}\\n`)\n }\n },\n onPrompt: async (p) => {\n const suffix = p.placeholder ? ` (${p.placeholder})` : ''\n return (await ask(`${p.message}${suffix}: `)).trim()\n },\n // loopback 回调先完成时经 signal 放行。readline 本身无法中断,由 finally 的\n // rl.close() 收尾——close 会 reject 悬挂的 question,故 catch 归一为空串防 unhandled。\n onManualCode: async (signal?: AbortSignal) => {\n const question = ask('\\nPaste the code here: ').then(\n (s) => s.trim(),\n () => '',\n )\n if (!signal) return question\n if (signal.aborted) return ''\n return Promise.race([\n question,\n new Promise<string>((resolve) => {\n signal.addEventListener('abort', () => resolve(''), { once: true })\n }),\n ])\n },\n onProgress: (m) => io.stdout(`${m}\\n`),\n signal: controller.signal,\n }\n\n await authStore.login(provider, options)\n io.stdout(`\\n✓ Logged in to ${oauth.name}.\\n`)\n return 0\n } catch (error) {\n io.stderr(`\\notto auth login failed: ${(error as Error).message}\\n`)\n return 1\n } finally {\n process.off('SIGINT', onSigint)\n rl?.close()\n }\n}\n\nasync function authLogout(\n authStore: AuthStore,\n provider: string | undefined,\n io: { stdout: (s: string) => void; stderr: (s: string) => void },\n): Promise<number> {\n if (!provider) {\n io.stderr(\n `otto auth logout: missing provider. One of: ${authStore.listProviders().join(', ')}\\n`,\n )\n return 1\n }\n\n const had = await authStore.hasCredential(provider)\n await authStore.logout(provider)\n io.stdout(had ? `✓ Logged out of ${provider}.\\n` : `${provider} was not logged in.\\n`)\n return 0\n}\n\nconst SOURCE_LABEL: Record<string, string> = {\n oauth: 'OAuth',\n api_key: 'API key (stored)',\n env: 'API key (env)',\n}\n\nasync function authStatus(\n authStore: AuthStore,\n io: { stdout: (s: string) => void },\n): Promise<number> {\n io.stdout('Authentication status:\\n')\n for (const provider of authStore.listProviders()) {\n const source = await authStore.getAuthSource(provider)\n const label = source ? SOURCE_LABEL[source] : 'not configured'\n io.stdout(` ${provider.padEnd(16)} ${label}\\n`)\n }\n return 0\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ const e=4526,t=`a8e82a1b2`;export{e as n,t};
3
+ //# sourceMappingURL=build-id-BX4QHzM0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-id-BX4QHzM0.js","names":[],"sources":["../src/build-id.ts"],"sourcesContent":["// auto-generated by scripts/gen-build-id.mjs — DO NOT EDIT\nexport const BUILD_ID = 4526\nexport const BUILD_BRANCH = 'dev'\nexport const BUILD_HASH = 'a8e82a1b2'\n"],"mappings":";AACA,MAAa,EAAW,KAEX,EAAa"}
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "plugin-otto-wire-protocols",
3
+ "name": "Otto Wire Protocols",
4
+ "version": "1.0.0",
5
+ "description": "Three standard wire protocol implementations (anthropic-messages/openai-responses/openai-completions) — physically migrated out of the framework core (RFC-148). Provides runtime support for any declarative or code-based provider plugin that declares one of these wireApi values.",
6
+ "capabilities": ["wire-protocol"],
7
+ "engines": { "otto": ">=1.0.0" }
8
+ }
@@ -0,0 +1 @@
1
+ {"apiVersion":1,"compilerVersion":"0.1.0-alpha.1","sourceHash":"e97f72fbd868bbdee36970393ffb5542f61cfb1e55a3209496b5c2569aeb913c"}