@x-otto/cli 0.0.1-alpha.23 → 0.0.1-alpha.25

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.
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{r as e}from"./feedback-D14OTV5B.js";export{e as runFeedbackCommand};
@@ -1 +0,0 @@
1
- {"version":3,"file":"persistence-CTXa-OyC.js","names":["DEFAULT_PORT","DEFAULT_HOST","printHelp"],"sources":["../src/commands/persistenced.ts","../src/commands/remote-persistence-server.ts","../src/commands/persistence.ts"],"sourcesContent":["import { startPersistenced, PERSISTENCED_DEFAULT_PORT } from '@x-otto/service'\n\nimport { waitForShutdown } from './daemon-base'\n\nexport interface PersistencedDeps {\n stdout?: (s: string) => void\n stderr?: (s: string) => void\n signal?: AbortSignal\n}\n\n/** 复用 @x-otto/service 的族内单源默认端口,消除双源漂移。 */\nconst DEFAULT_PORT = PERSISTENCED_DEFAULT_PORT\nconst DEFAULT_HOST = '127.0.0.1'\n\nexport async function runPersistencedCommand(\n args: string[],\n deps: PersistencedDeps = {},\n): Promise<number> {\n const stdout = deps.stdout ?? ((s) => process.stdout.write(s))\n const stderr = deps.stderr ?? ((s) => process.stderr.write(s))\n\n if (args[0] === 'help' || args[0] === '--help') {\n printHelp(stdout)\n return 0\n }\n\n let dir: string | undefined\n let port = DEFAULT_PORT\n let host = DEFAULT_HOST\n let token: string | undefined\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg === '--dir' || arg === '-d') {\n dir = args[++i]\n } else if (arg === '--port' || arg === '-p') {\n const raw = args[++i]\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n stderr(`otto persistenced: invalid --port value: ${raw ?? '(missing)'}\\n`)\n return 1\n }\n port = n\n } else if (arg === '--host' || arg === '-h') {\n host = args[++i] ?? DEFAULT_HOST\n } else if (arg === '--token' || arg === '-t') {\n token = args[++i]\n }\n }\n\n if (!dir) {\n stderr('otto persistenced: --dir is required\\n')\n return 1\n }\n\n if (!token) {\n stderr('otto persistenced: --token is required\\n')\n return 1\n }\n\n try {\n const { url } = await startPersistenced({ dir, port, host, token })\n\n stdout(`persistenced listening on ${url}\n storage: ${url}/api/storage/:namespace\n events: ${url}/api/events/:namespace (SSE)\n sync: ${url}/api/sync/:namespace\n health: ${url}/health\n stop: Ctrl-C\n`)\n\n await waitForShutdown(deps.signal)\n stdout('persistenced shutting down\\n')\n return 0\n } catch (error) {\n stderr(\n `otto persistenced: ${error instanceof Error ? error.message : String(error)}\\n`,\n )\n return 1\n }\n}\n\nfunction printHelp(stdout: (s: string) => void): void {\n stdout(`otto persistenced — 独立持久化存储服务(SQLite + HTTP API)\n\n用法:\n otto persistenced --dir <path> --token <token> [--port <n>] [--host <ip>]\n\n选项:\n --dir, -d <path> 数据目录(SQLite db 文件存放位置,必填)\n --token, -t <token> Bearer token(所有 /api/* 请求必须携带,必填)\n --port, -p <n> 监听端口(默认 ${DEFAULT_PORT})\n --host, -h <ip> 监听地址(默认 ${DEFAULT_HOST},0.0.0.0 = 公网暴露)\n\n示例:\n otto persistenced --dir /var/lib/otto/storage --token \"\\$TOKEN\"\n otto persistenced --dir ./data --port 3002 --token dev-secret\n\n端点:\n GET /health 健康检查\n GET /api/storage/:namespace 列出文档 ID / 分页列表\n GET /api/storage/:namespace/:id 读取文档\n PUT /api/storage/:namespace/:id 写入文档\n DELETE /api/storage/:namespace/:id 删除文档\n GET /api/events/:namespace SSE 变更推送\n POST /api/sync/:namespace/push 批量写入(离线同步)\n GET /api/sync/:namespace/pull 增量拉取\n`)\n}\n\n","import { REMOTE_PERSISTENCE_DEFAULT_PORT, type ServerConfig } from '@x-otto/remote-persistence-server'\n\nimport { waitForShutdown } from './daemon-base'\n\nexport interface RemotePersistenceServerDeps {\n stdout?: (s: string) => void\n stderr?: (s: string) => void\n signal?: AbortSignal\n}\n\n/** 复用 @x-otto/remote-persistence-server 的族内单源默认端口,消除双源漂移。 */\nconst DEFAULT_PORT = REMOTE_PERSISTENCE_DEFAULT_PORT\nconst DEFAULT_HOST = '127.0.0.1'\n\nexport async function runRemotePersistenceServerCommand(\n args: string[],\n deps: RemotePersistenceServerDeps = {},\n): Promise<number> {\n const stdout = deps.stdout ?? ((s) => process.stdout.write(s))\n const stderr = deps.stderr ?? ((s) => process.stderr.write(s))\n\n if (args[0] === 'help' || args[0] === '--help') {\n printHelp(stdout)\n return 0\n }\n\n let dir: string | undefined\n let port = DEFAULT_PORT\n let host = DEFAULT_HOST\n let token: string | undefined\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg === '--dir' || arg === '-d') {\n dir = args[++i]\n } else if (arg === '--port' || arg === '-p') {\n const raw = args[++i]\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 1 || n > 65535) {\n stderr(\n `otto remote-persistence-server: invalid --port value: ${raw ?? '(missing)'}\\n`,\n )\n return 1\n }\n port = n\n } else if (arg === '--host' || arg === '-h') {\n host = args[++i] ?? DEFAULT_HOST\n } else if (arg === '--token' || arg === '-t') {\n token = args[++i]\n }\n }\n\n if (!dir) {\n stderr('otto remote-persistence-server: --dir is required\\n')\n return 1\n }\n\n if (token === undefined) {\n stderr(\n 'otto remote-persistence-server: --token is required (use --token \"\" to disable auth for dev only)\\n',\n )\n return 1\n }\n\n const { startServer } = await import('@x-otto/remote-persistence-server')\n\n try {\n const config: ServerConfig = { dataDir: dir, port, authToken: token }\n const { url, server, store } = await startServer(config, { host })\n\n stdout(`remote-persistence-server listening on ${url}\n sessions: ${url}/sessions\n health: ${url}/health\n stop: Ctrl-C\n`)\n\n await waitForShutdown(deps.signal)\n stdout('remote-persistence-server shutting down\\n')\n await new Promise<void>((resolve) => server.close(() => resolve()))\n store.close()\n return 0\n } catch (error) {\n stderr(\n `otto remote-persistence-server: ${error instanceof Error ? error.message : String(error)}\\n`,\n )\n return 1\n }\n}\n\nfunction printHelp(stdout: (s: string) => void): void {\n stdout(`otto remote-persistence-server — 最小化远程持久化服务(Hono + SQLite,5 REST 端点)\n\n用法:\n otto remote-persistence-server --dir <path> --token <token> [--port <n>] [--host <ip>]\n\n选项:\n --dir, -d <path> 数据目录(SQLite db 文件存放位置,必填)\n --token, -t <token> Bearer token(所有 /sessions/* 请求必须携带,必填)\n --port, -p <n> 监听端口(默认 ${DEFAULT_PORT})\n --host, -h <ip> 监听地址(默认 ${DEFAULT_HOST},0.0.0.0 = 公网暴露)\n\n示例:\n otto remote-persistence-server --dir ./data --token dev-secret\n otto remote-persistence-server --dir /var/lib/otto/storage --port 3002 --token \"\\$TOKEN\"\n\n端点(:wsKey 为客户端工作区分区段,本服务 accept-and-ignore,按 token 派生 userId 分区):\n GET /health 健康检查(无需认证)\n GET /sessions/:wsKey 列出会话 ID(需要 Bearer token)\n GET /sessions/:wsKey/:id 读取会话快照\n PUT /sessions/:wsKey/:id 写入/更新会话快照\n DELETE /sessions/:wsKey/:id 删除会话快照\n\n对端客户端:\n 另一台机器上的 Otto CLI:\n otto --session-url http://<host>:<port>/sessions --session-token <token>\n`)\n}\n","/**\n * `otto persistence` 子命令 —— 持久化服务族(local / remote)的薄路由。\n *\n * RFC-369 M4:persistence 收编 persistenced(local)与 remote-persistence-server(remote)\n * 为子命令。旧入口 `otto persistenced` / `otto remote-persistence-server` 作为别名保留,\n * 内部分别转发到本命令的 `local` / `remote` 子路径。\n */\nimport { runPersistencedCommand, type PersistencedDeps } from './persistenced'\nimport {\n runRemotePersistenceServerCommand,\n type RemotePersistenceServerDeps,\n} from './remote-persistence-server'\n\n/**\n * persistence 路由的 deps —— 是 PersistencedDeps 与 RemotePersistenceServerDeps 的并集\n * (两者结构相同:stdout? / stderr? / signal?,并集保持兼容)。\n */\nexport type PersistenceDeps = PersistencedDeps & RemotePersistenceServerDeps\n\nexport async function runPersistenceCommand(\n args: string[],\n deps: PersistenceDeps = {},\n): Promise<number> {\n const stdout = deps.stdout ?? ((s) => process.stdout.write(s))\n\n const [subCommand, ...rest] = args\n\n switch (subCommand) {\n case 'local':\n return runPersistencedCommand(rest, deps)\n case 'remote':\n return runRemotePersistenceServerCommand(rest, deps)\n default:\n stdout(`otto persistence — 持久化服务族(local / remote)\n\n用法:\n otto persistence local [...flags] 启动独立持久化服务(storage + events + sync)\n otto persistence remote [...flags] 启动最小化远程持久化服务(5 REST 端点)\n\n子命令说明:\n local 等价于旧 otto persistenced(SQLite + HTTP API,storage/events/sync)\n remote 等价于旧 otto remote-persistence-server(Hono + SQLite,5 REST 端点)\n\n通用选项(详见各子命令 --help):\n --dir, -d <path> 数据目录(必填)\n --token, -t <token> Bearer token(必填)\n --port, -p <n> 监听端口(各子命令有各自默认端口)\n --host, -h <ip> 监听地址(默认 127.0.0.1,0.0.0.0 = 公网暴露)\n\n注:旧命令 otto persistenced / otto remote-persistence-server 仍可用(别名转发)。\n`)\n return 0\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"serve-Dbn3THez.js","names":[],"sources":["../src/commands/serve.ts"],"sourcesContent":["import type { AddressInfo } from 'node:net'\nimport { resolve } from 'node:path'\nimport { SERVICE_PORT } from '@x-otto/env'\nimport { createHostApp } from '../create-host-app'\nimport { createCodingService } from '@x-otto/service'\nimport type { AppContext } from '@x-otto/coding'\n\nimport { waitForShutdown } from './daemon-base'\n\nexport interface ServeDeps {\n stdout?: (s: string) => void\n stderr?: (s: string) => void\n /** 全局 CLI 选项透传(与 `otto run` 同源装配)。 */\n projectDir?: string\n configPath?: string\n modelId?: string\n verbose?: boolean\n /** 测试注入:替代生产装配的 app(结构 = AppContext + start/stop)。 */\n app?: AppContext & { start(): Promise<void>; stop(): Promise<void> }\n /** 测试注入:优雅退出信号(生产 = SIGINT/SIGTERM)。 */\n signal?: AbortSignal\n}\n\nexport async function runServeCommand(args: string[], deps: ServeDeps = {}): Promise<number> {\n const stdout = deps.stdout ?? ((s) => process.stdout.write(s))\n const stderr = deps.stderr ?? ((s) => process.stderr.write(s))\n\n if (args[0] === 'help' || args[0] === '--help') {\n printHelp(stdout)\n return 0\n }\n\n let port: number\n let inspect: boolean\n let staticDir: string | undefined\n let token: string | undefined\n try {\n ;({ port, inspect, staticDir, token } = parseServeArgs(args))\n } catch (error) {\n stderr(`otto serve: ${error instanceof Error ? error.message : String(error)}\\n`)\n return 1\n }\n\n const app =\n deps.app ??\n createHostApp({\n logger: {\n name: 'otto-serve',\n level: deps.verbose ? 'debug' : 'info',\n destination: 'stderr',\n },\n // `--inspect` 必须下传:`AppOptions.inspect` 是 `buildInspectDevtools` 的唯一开关\n // (devtools-setup.ts:19 `if (!inspect) return { devtools: null }`)。此前 serve 解析了\n // 该 flag、也据它打印\"调试器已启用\"提示,却从未传给 createApp —— 于是 `app.devtools`\n // 恒为 null,`/api/debugger/*` 全部 503、DebugBridge 也不会被构造。即 `otto serve\n // --inspect` 实际从不启用调试器(提示与事实相反)。\n inspect,\n workspaceDir: deps.projectDir,\n projectConfigPath: deps.configPath,\n modelId: deps.modelId,\n })\n\n try {\n await app.start()\n } catch (error) {\n stderr(`otto serve: failed to start app: ${error instanceof Error ? error.message : String(error)}\\n`)\n return 1\n }\n\n // --token 同时启用 HTTP Bearer(apiToken)与 WS ?token=(wsAuthToken);页面用 URL `?token=` 对上。\n const service = createCodingService(app, {\n port,\n host: '127.0.0.1',\n staticDir,\n apiToken: token,\n wsAuthToken: token,\n // RFC-335 M2:由 `otto daemon start` 下传,使 AuthorityDescriptor.instanceId 与\n // daemon state 记录一致(客户端据此确认\"连上的 authority 就是 state 里那个 daemon\")。\n // 前台直接 `otto serve` 时缺省,由 service 自行生成。\n authorityId: process.env['OTTO_AUTHORITY_ID'] || undefined,\n })\n\n try {\n await service.start()\n } catch (error) {\n stderr(`otto serve: failed to listen on port ${port}: ${error instanceof Error ? error.message : String(error)}\\n`)\n await app.stop()\n return 1\n }\n\n const actualPort = (service.httpServer.address() as AddressInfo).port\n // 不把 token 明文打进 stdout(会落 scrollback/CI 日志)——只提示需附加 ?token=。\n const webHint = token ? ' (打开时附加 ?token=<你的 token>)' : ''\n stdout(`otto service listening on http://127.0.0.1:${actualPort}${token ? ' (auth: token required)' : ''}\n${staticDir ? ` web: http://127.0.0.1:${actualPort}/${webHint} (静态页面同源托管 ${staticDir})\\n` : ''} panels: otto observe summary <session-id>\n otto time-travel checkpoints <session-id>\n otto debug breakpoints list${inspect ? '' : ' (debugger disabled — restart with `otto serve --inspect`)'}\n stop: Ctrl-C\n`)\n\n await waitForShutdown(deps.signal)\n\n stdout('otto serve: shutting down...\\n')\n await service.stop()\n await app.stop()\n return 0\n}\n\nfunction parseServeArgs(args: string[]): {\n port: number\n inspect: boolean\n staticDir?: string\n token?: string\n} {\n let port = SERVICE_PORT\n let inspect = false\n let staticDir: string | undefined\n let token: string | undefined\n\n // 取下一个值;缺失或形如 --flag(误把下个选项当值)即报错,避免静默吞掉选项。\n const takeValue = (i: number, name: string): string => {\n const raw = args[i + 1]\n if (raw === undefined || raw.startsWith('--')) {\n throw new Error(`${name} requires a value`)\n }\n return raw\n }\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg === '--port' || arg === '-p') {\n const raw = takeValue(i, '--port')\n i++\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 0 || n > 65535) {\n throw new Error(`invalid --port value: ${raw}`)\n }\n port = n\n } else if (arg === '--inspect') {\n inspect = true\n } else if (arg === '--static') {\n staticDir = resolve(takeValue(i, '--static'))\n i++\n } else if (arg === '--token') {\n token = takeValue(i, '--token')\n i++\n }\n // 其它(含全局 flag --verbose/--model 等,经 ctx.args 透传进来)忽略——\n // 不能 throw,否则 `otto serve --verbose` 会误伤(全局 flag 由 parseCLI 已解析)。\n }\n\n return { port, inspect, staticDir, token }\n}\n\nfunction printHelp(stdout: (s: string) => void): void {\n stdout(`otto serve — 启动 HTTP/WS service(观测/调试/时间旅行面板的对端)\n\n用法:\n otto serve [--port <n>] [--inspect] [--static <dir>] [--token <t>]\n\n选项:\n --port, -p <n> 监听端口(默认 ${SERVICE_PORT},可经 OTTO_SERVICE_PORT 覆盖;0 = 随机)\n --inspect 启用调试器(断点/暂停面板需要)\n --static <dir> 同源托管一个已构建的前端目录(SPA),页面与 /api、/ws 同端口免 CORS\n --token <t> 启用鉴权:HTTP /api/* 需 Bearer,WS 需 ?token=;页面用 URL ?token=<t> 对上\n\n面板命令默认连 http://127.0.0.1:${SERVICE_PORT}(可 --remote 覆盖)\n`)\n}\n"],"mappings":";gOAuBA,eAAsB,EAAgB,EAAgB,EAAkB,EAAE,CAAmB,CAC3F,IAAM,EAAS,EAAK,SAAY,GAAM,QAAQ,OAAO,MAAM,EAAE,EACvD,EAAS,EAAK,SAAY,GAAM,QAAQ,OAAO,MAAM,EAAE,EAE7D,GAAI,EAAK,KAAO,QAAU,EAAK,KAAO,SAEpC,OADA,EAAU,EAAO,CACV,EAGT,IAAI,EACA,EACA,EACA,EACJ,GAAI,EACA,uCAAsC,EAAe,EAAK,QACrD,EAAO,CAEd,OADA,EAAO,eAAe,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,IAAI,CAC1E,EAGT,IAAM,EACJ,EAAK,KACL,EAAc,CACZ,OAAQ,CACN,KAAM,aACN,MAAO,EAAK,QAAU,QAAU,OAChC,YAAa,SACd,CAMD,UACA,aAAc,EAAK,WACnB,kBAAmB,EAAK,WACxB,QAAS,EAAK,QACf,CAAC,CAEJ,GAAI,CACF,MAAM,EAAI,OAAO,OACV,EAAO,CAEd,OADA,EAAO,oCAAoC,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,IAAI,CAC/F,EAIT,IAAM,EAAU,EAAoB,EAAK,CACvC,OACA,KAAM,YACN,YACA,SAAU,EACV,YAAa,EAIb,YAAa,QAAQ,IAAI,mBAAwB,IAAA,GAClD,CAAC,CAEF,GAAI,CACF,MAAM,EAAQ,OAAO,OACd,EAAO,CAGd,OAFA,EAAO,wCAAwC,EAAK,IAAI,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAAC,IAAI,CACnH,MAAM,EAAI,MAAM,CACT,EAGT,IAAM,EAAc,EAAQ,WAAW,SAAS,CAAiB,KAejE,OAZA,EAAO,8CAA8C,IAAa,EAAQ,4BAA8B,GAAG;EAC3G,EAAY,+BAA+B,EAAW,GAFtC,EAAQ,6BAA+B,GAEU,eAAe,EAAU,KAAO,GAAG;;wCAE9D,EAAU,GAAK,+DAA+D;;EAEpH,CAEA,MAAM,EAAgB,EAAK,OAAO,CAElC,EAAO;EAAiC,CACxC,MAAM,EAAQ,MAAM,CACpB,MAAM,EAAI,MAAM,CACT,EAGT,SAAS,EAAe,EAKtB,CACA,IAAI,EAAO,EACP,EAAU,GACV,EACA,EAGE,GAAa,EAAW,IAAyB,CACrD,IAAM,EAAM,EAAK,EAAI,GACrB,GAAI,IAAQ,IAAA,IAAa,EAAI,WAAW,KAAK,CAC3C,MAAU,MAAM,GAAG,EAAK,mBAAmB,CAE7C,OAAO,GAGT,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GACjB,GAAI,IAAQ,UAAY,IAAQ,KAAM,CACpC,IAAM,EAAM,EAAU,EAAG,SAAS,CAClC,IACA,IAAM,EAAI,OAAO,EAAI,CACrB,GAAI,CAAC,OAAO,UAAU,EAAE,EAAI,EAAI,GAAK,EAAI,MACvC,MAAU,MAAM,yBAAyB,IAAM,CAEjD,EAAO,OACE,IAAQ,YACjB,EAAU,GACD,IAAQ,YACjB,EAAY,EAAQ,EAAU,EAAG,WAAW,CAAC,CAC7C,KACS,IAAQ,YACjB,EAAQ,EAAU,EAAG,UAAU,CAC/B,KAMJ,MAAO,CAAE,OAAM,UAAS,YAAW,QAAO,CAG5C,SAAS,EAAU,EAAmC,CACpD,EAAO;;;;;;6BAMoB,EAAa;;;;;2BAKf,EAAa;EACtC"}