@x-otto/cli 0.0.1-alpha.49 → 0.0.1-alpha.50
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.
- package/dist/{auth-command-D1T16ed-.js → auth-command-BYaFM76w.js} +2 -2
- package/dist/{auth-command-D1T16ed-.js.map → auth-command-BYaFM76w.js.map} +1 -1
- package/dist/backend-handler-DUafuNWw.js +3 -0
- package/dist/backend-handler-DUafuNWw.js.map +1 -0
- package/dist/build-id-DjE6eVpQ.js +3 -0
- package/dist/build-id-DjE6eVpQ.js.map +1 -0
- package/dist/bundled-extensions/plugin-feedback/otto-plugin.json +24 -0
- package/dist/bundled-extensions/plugin-feedback/panels/feedback.tsx +348 -0
- package/dist/bundled-extensions/plugin-feedback/panels/panel-host-globals.d.ts +67 -0
- package/dist/bundled-extensions/plugin-feedback/panels-dist/feedback.mjs +257 -0
- package/dist/bundled-extensions/plugin-feedback/plugin-dist/meta.json +1 -0
- package/dist/bundled-extensions/plugin-feedback/plugin-dist/plugin.cjs +11304 -0
- package/dist/bundled-extensions/plugin-feedback/plugin.ts +198 -0
- package/dist/bundled-extensions/plugin-feedback/src/coding-adapter.ts +183 -0
- package/dist/bundled-extensions/plugin-feedback/src/coding-lister.ts +26 -0
- package/dist/bundled-extensions/plugin-feedback/src/github-lister.ts +230 -0
- package/dist/bundled-extensions/plugin-feedback/src/issue-aggregator.ts +109 -0
- package/dist/bundled-extensions/plugin-feedback/src/issue-submitter.ts +241 -0
- package/dist/bundled-extensions/plugin-feedback/src/platform-resolver.ts +76 -0
- package/dist/bundled-extensions/plugin-feedback/src/pulse-survey-sink.ts +114 -0
- package/dist/bundled-extensions/plugin-feedback/src/resolved-sink.ts +163 -0
- package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/meta.json +1 -1
- package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/plugin.cjs +605 -725
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-messages.ts +4 -22
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-completions.ts +5 -5
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-responses.ts +3 -15
- package/dist/command-dispatcher-BLT8IO4K.js +18 -0
- package/dist/command-dispatcher-BLT8IO4K.js.map +1 -0
- package/dist/create-host-app-CbJ8ptv-.js +3 -0
- package/dist/{create-host-app-BXQ8bU-B.js.map → create-host-app-CbJ8ptv-.js.map} +1 -1
- package/dist/{daemon-base-Y1XI61JY.js → daemon-base-D015ew5y.js} +1 -1
- package/dist/{daemon-base-Y1XI61JY.js.map → daemon-base-D015ew5y.js.map} +1 -1
- package/dist/{doctor-DXBLkbkP.js → doctor-EndB-ycb.js} +3 -3
- package/dist/{doctor-DXBLkbkP.js.map → doctor-EndB-ycb.js.map} +1 -1
- package/dist/{doctor-attach-DEMuyBOk.js → doctor-attach-DEoE7eFx.js} +2 -2
- package/dist/{doctor-attach-DEMuyBOk.js.map → doctor-attach-DEoE7eFx.js.map} +1 -1
- package/dist/{doctor-cdp-CnJUVNOB.js → doctor-cdp-Cj9IFpEP.js} +1 -1
- package/dist/{doctor-cdp-CnJUVNOB.js.map → doctor-cdp-Cj9IFpEP.js.map} +1 -1
- package/dist/{doctor-heap-Eu3LZj-F.js → doctor-heap-SIxiRvL8.js} +2 -2
- package/dist/{doctor-heap-Eu3LZj-F.js.map → doctor-heap-SIxiRvL8.js.map} +1 -1
- package/dist/{doctor-ps-JBgCH77n.js → doctor-ps-DNVOF6yY.js} +2 -2
- package/dist/{doctor-ps-JBgCH77n.js.map → doctor-ps-DNVOF6yY.js.map} +1 -1
- package/dist/extension-CoJqqktf.js +2 -0
- package/dist/extension-Dpn8gltG.js +179 -0
- package/dist/extension-Dpn8gltG.js.map +1 -0
- package/dist/feedback-QcONRnO3.js +30 -0
- package/dist/feedback-QcONRnO3.js.map +1 -0
- package/dist/feedback-backend-methods-BNm38ddr.js +3 -0
- package/dist/feedback-backend-methods-BNm38ddr.js.map +1 -0
- package/dist/{feishu-setup-5ZoxtH0J.js → feishu-setup-DbAq_BRH.js} +1 -1
- package/dist/feishu-setup-DbAq_BRH.js.map +1 -0
- package/dist/{ftue-doctor-recovery-8FeDBFOc.js → ftue-doctor-recovery-CKTMnxM8.js} +1 -1
- package/dist/{ftue-doctor-recovery-8FeDBFOc.js.map → ftue-doctor-recovery-CKTMnxM8.js.map} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/install-CEPczuet.js +11 -0
- package/dist/install-CEPczuet.js.map +1 -0
- package/dist/install-CG6b6fox.js +2 -0
- package/dist/interactive-schedule-Bv__2Kwc.js +3 -0
- package/dist/interactive-schedule-Bv__2Kwc.js.map +1 -0
- package/dist/{mcp-Cm4-OhXI.js → mcp-DjReRjuu.js} +1 -1
- package/dist/{mcp-Cm4-OhXI.js.map → mcp-DjReRjuu.js.map} +1 -1
- package/dist/{mcp-server-Dpza3yn2.js → mcp-server-Rr__aWO7.js} +3 -3
- package/dist/mcp-server-Rr__aWO7.js.map +1 -0
- package/dist/{migrate-RlBJqJnB.js → migrate-BBi3Txu2.js} +1 -1
- package/dist/{migrate-RlBJqJnB.js.map → migrate-BBi3Txu2.js.map} +1 -1
- package/dist/{observe-Dxfud-t7.js → observe-BqLCpmFD.js} +2 -2
- package/dist/{observe-Dxfud-t7.js.map → observe-BqLCpmFD.js.map} +1 -1
- package/dist/parse-cli-Db8pF_Ya.js +3 -0
- package/dist/parse-cli-Db8pF_Ya.js.map +1 -0
- package/dist/{persistence-CRFhOYx6.js → persistence-BvLRnpfi.js} +2 -2
- package/dist/{persistence-CRFhOYx6.js.map → persistence-BvLRnpfi.js.map} +1 -1
- package/dist/{plugin-assembly-check-DEozmcJ7.js → plugin-assembly-check-BntT5W6H.js} +1 -1
- package/dist/{plugin-assembly-check-DEozmcJ7.js.map → plugin-assembly-check-BntT5W6H.js.map} +1 -1
- package/dist/{proxy-evg7ZvoD.js → proxy-CFZDVIwI.js} +1 -1
- package/dist/proxy-CFZDVIwI.js.map +1 -0
- package/dist/proxy-CkSf8ziQ.js +2 -0
- package/dist/{ps-DiKCLKbs.js → ps-BVKv6rAo.js} +1 -1
- package/dist/{ps-DiKCLKbs.js.map → ps-BVKv6rAo.js.map} +1 -1
- package/dist/{registry-BdCcwyGy.js → registry-BUvu-es1.js} +4 -4
- package/dist/registry-BUvu-es1.js.map +1 -0
- package/dist/registry-DYHR-ONu.js +2 -0
- package/dist/{run-attach-DDpMk2_N.js → run-attach-X35puJ_n.js} +2 -2
- package/dist/{run-attach-DDpMk2_N.js.map → run-attach-X35puJ_n.js.map} +1 -1
- package/dist/schedule-Ke0jwatM.js +5 -0
- package/dist/schedule-Ke0jwatM.js.map +1 -0
- package/dist/serve-K6BOT5K_.js +21 -0
- package/dist/serve-K6BOT5K_.js.map +1 -0
- package/dist/{service-client-Cr4sxDVM.js → service-client-cfUUP4EE.js} +1 -1
- package/dist/{service-client-Cr4sxDVM.js.map → service-client-cfUUP4EE.js.map} +1 -1
- package/dist/{version-BrSIyY6s.js → version-DrCy32wR.js} +2 -2
- package/dist/{version-BrSIyY6s.js.map → version-DrCy32wR.js.map} +1 -1
- package/package.json +16 -13
- package/dist/build-id-DxfuzdUE.js +0 -3
- package/dist/build-id-DxfuzdUE.js.map +0 -1
- package/dist/command-dispatcher-DTOPjtZP.js +0 -21
- package/dist/command-dispatcher-DTOPjtZP.js.map +0 -1
- package/dist/create-host-app-BXQ8bU-B.js +0 -3
- package/dist/create-host-app-DG58-vRA.js +0 -2
- package/dist/extension-CTyrcdT1.js +0 -2
- package/dist/extension-DVEml5IN.js +0 -179
- package/dist/extension-DVEml5IN.js.map +0 -1
- package/dist/feedback-DvWUvSc4.js +0 -21
- package/dist/feedback-DvWUvSc4.js.map +0 -1
- package/dist/feedback-DzPLfcfN.js +0 -2
- package/dist/feishu-setup-5ZoxtH0J.js.map +0 -1
- package/dist/install-DlVJRHRT.js +0 -11
- package/dist/install-DlVJRHRT.js.map +0 -1
- package/dist/install-WCcQ9k9M.js +0 -2
- package/dist/mcp-server-Dpza3yn2.js.map +0 -1
- package/dist/parse-cli-BvcxTK88.js +0 -3
- package/dist/parse-cli-BvcxTK88.js.map +0 -1
- package/dist/proxy-BvdBsB1O.js +0 -2
- package/dist/proxy-evg7ZvoD.js.map +0 -1
- package/dist/registry-BOX7DaxS.js +0 -2
- package/dist/registry-BdCcwyGy.js.map +0 -1
- package/dist/serve-Ke0nwN9Y.js +0 -21
- package/dist/serve-Ke0nwN9Y.js.map +0 -1
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{OTTO_HOME as e}from"@x-otto/env";import{resolve as t}from"node:path";import{readFileSync as n,readdirSync as r}from"node:fs";import{parseCron as i}from"@x-otto/schedule";let a;function o(e){a=e}const s=async(e,t)=>{let n=a;if(!n){t.tui.info.showToast(`Schedule`,`Schedule system not available`);return}let r=e[0];switch(r){case void 0:return c(t);case`list`:return l(n,t);case`add`:return d(e.slice(1),n,t);case`remove`:return f(e[1],n,t);case`run`:return p(e[1],n,t);case`enable`:return h(e[1],!0,n,t);case`disable`:return h(e[1],!1,n,t);case`logs`:return g(e[1],t);case`cancel`:return m(e[1],t);default:t.tui.info.showToast(`Schedule`,`/schedule ${r} — unknown subcommand. Use: add|list|remove|run|enable|disable|cancel|logs`)}};async function c(e){let t=(e.app.getPluginPanelRegistrations?.()??[]).find(e=>e.pluginId===`plugin-schedule`);if(!t){e.tui.info.showToast(`Schedule`,`Schedule panel not installed — run "otto extension install plugin-schedule"`);return}e.tui.modal.openModal({kind:`pluginPanel`,panelInfo:{title:t.title,modulePath:t.modulePath,exportName:t.exportName,pluginId:t.pluginId},onClose:()=>{}})}async function l(e,t){let n=e.list(),r=e.isFireOwner()?[]:e.fireOwnerFailureReason()===`network-error`?[`[read-only — could not reach the remote schedule service; check network/persistenced connectivity]`]:[`[read-only — another terminal holds the fire-ownership lease for this workspace]`];if(n.length===0){t.tui.info.showToast(`Schedule`,r.length>0?`No scheduled tasks. ${r[0]}`:`No scheduled tasks`);return}let i=[];for(let e of n){let t=e.lastFireFailed?`✕`:e.enabled?`◉`:`○`,n=e.recurring?e.cronExpression:`one-shot`,r=new Date(e.nextFireAt).toLocaleString(),a=e.lastFireFailed&&e.lastFireError?` (failed: ${e.lastFireError})`:``;i.push(`${t} ${e.id} ${e.name}${a}`),i.push(` ${n} next: ${r}`)}t.tui.messages.pushMessage({role:`command_echo`,command:`/schedule`,status:r.length>0?`warn`:`ok`,summary:r.length>0?r[0]:`${n.length} 个已排定任务`,detail:i.join(`
|
|
3
|
+
`)}),t.tui.panes.togglePane?.(`schedulePane`)}function u(e){if(e.length>=5){let t=e.slice(0,5).join(` `);try{return i(t),{cron:t,prompt:e.slice(5).join(` `)}}catch{}}return{cron:e[0]??``,prompt:e.slice(1).join(` `)}}async function d(e,t,n){if(e.length<2){n.tui.info.showToast(`Schedule`,`/schedule add [--once] [--session] <cron 5 fields> <prompt>`);return}let r=!1,i,a=[...e],o=a.indexOf(`--once`);o!==-1&&(r=!0,a.splice(o,1));let s=a.indexOf(`--session`);if(s!==-1&&(i=`session`,a.splice(s,1)),a.length<2){n.tui.info.showToast(`Schedule`,`Opening schedule panel in create mode`),c(n);return}let{cron:l,prompt:d}=u(a);try{let e=t.add({name:d.slice(0,40),prompt:d,cronExpression:l,recurring:!r,origin:`user`,target:i}),a=r?`one-shot`:`recurring`,o=new Date(e.nextFireAt).toLocaleString(),s=e.target===`session`?` [fires into this conversation]`:``;n.tui.info.showToast(`Schedule`,`${e.id}: ${e.name} (${a})${s} next: ${o}`)}catch(e){n.tui.info.showToast(`Schedule`,`Failed: ${e instanceof Error?e.message:String(e)}`)}}async function f(e,t,n){if(!e){n.tui.info.showToast(`Schedule`,`/schedule remove <id>`);return}let r=t.remove(e);n.tui.info.showToast(`Schedule`,r?`Removed ${e}`:`Schedule "${e}" not found`)}async function p(e,t,n){if(!e){n.tui.info.showToast(`Schedule`,`/schedule run <id>`);return}try{t.runNow(e),n.tui.info.showToast(`Schedule`,`Triggering ${e}...`)}catch(e){n.tui.info.showToast(`Schedule`,`Failed: ${e instanceof Error?e.message:String(e)}`)}}async function m(e,t){let n=a;if(!n){t.tui.info.showToast(`Schedule`,`Schedule system not available`);return}if(!e){t.tui.info.showToast(`Schedule`,`/schedule cancel <id>`);return}let r=n.cancel(e);r.ok?t.tui.info.showToast(`Schedule`,`Canceled "${e}"`):t.tui.info.showToast(`Schedule`,`Cannot cancel "${e}": ${r.reason??`unknown`}`)}async function h(e,t,n,r){if(!e){r.tui.info.showToast(`Schedule`,`/schedule ${t?`enable`:`disable`} <id>`);return}let i=n.update(e,{enabled:t});r.tui.info.showToast(`Schedule`,i?`Schedule ${e} ${t?`enabled`:`disabled`}`:`Schedule "${e}" not found`)}async function g(i,a){let o=t(e,`schedule-logs`),s;try{s=r(o)}catch{a.tui.info.showToast(`Schedule`,`No schedule logs found`);return}if(i&&(s=s.filter(e=>e.startsWith(i+`-`))),s.length===0){a.tui.info.showToast(`Schedule`,i?`No logs for schedule "${i}"`:`No schedule logs found`);return}s.sort().reverse();let c=s.slice(0,5),l=[];for(let e of c)try{let r=n(t(o,e),`utf-8`).trim(),i=e.indexOf(`-`),a=i>0?e.slice(0,i):e;l.push(`${a} ${r}`)}catch{l.push(`${e} (unreadable)`)}let u=s.length-c.length;u>0&&l.push(`... and ${u} more entries`),a.tui.messages.pushMessage({role:`command_echo`,command:`/schedule logs`,summary:`${s.length} 条日志文件`,detail:l.join(`
|
|
4
|
+
`)})}export{o as n,s as t};
|
|
5
|
+
//# sourceMappingURL=schedule-Ke0jwatM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-Ke0jwatM.js","names":[],"sources":["../src/commands/handlers/schedule.ts"],"sourcesContent":["/**\n * /schedule 命令:周期性 Agent Job 管理(增删改查/手动执行)。\n */\n\nimport { readdirSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\n// RFC-161 M2:SchedulerService 已迁至 @x-otto/schedule,直连新真源。\nimport type { SchedulerService } from '@x-otto/schedule'\nimport { parseCron } from '@x-otto/schedule'\nimport { OTTO_HOME } from '@x-otto/env'\n\nimport type { CliContext } from '../../command-dispatcher'\n\n/** RFC-426 M3:/schedule 定时任务管理——app 仅 getPluginPanelRegistrations(打开面板)+ tui。 */\nexport type ScheduleCtx = Pick<CliContext, 'tui'> & {\n app: Pick<CliContext['app'], 'getPluginPanelRegistrations'>\n}\n\n// ── Module-level scheduler ref ──\n\nlet schedulerRef: SchedulerService | undefined\n\nexport function setScheduleService(s: SchedulerService | undefined): void {\n schedulerRef = s\n}\n\n// ── Main handler ──\n\nexport const handleSchedule = async (args: string[], ctx: ScheduleCtx): Promise<void> => {\n const scheduler = schedulerRef\n if (!scheduler) {\n ctx.tui.info.showToast('Schedule', 'Schedule system not available')\n return\n }\n\n const sub = args[0]\n switch (sub) {\n case undefined:\n // RFC-229 M2: open the schedule plugin panel\n return handleOpenPanel(ctx)\n case 'list':\n return handleList(scheduler, ctx)\n case 'add':\n return handleAdd(args.slice(1), scheduler, ctx)\n case 'remove':\n return handleRemove(args[1], scheduler, ctx)\n case 'run':\n return handleRun(args[1], scheduler, ctx)\n case 'enable':\n return handleToggle(args[1], true, scheduler, ctx)\n case 'disable':\n return handleToggle(args[1], false, scheduler, ctx)\n case 'logs':\n return handleLogs(args[1], ctx)\n case 'cancel':\n return handleCancel(args[1], ctx)\n default:\n ctx.tui.info.showToast('Schedule', `/schedule ${sub} — unknown subcommand. Use: add|list|remove|run|enable|disable|cancel|logs`)\n }\n}\n\n// ── Subcommand handlers ──\n\n// open panel (RFC-229 M2: when /schedule is called without subcommand)\n//\n// 2026-07-25 终局修复:不再用 resolveOttoRepoRoot() 猜测 extensions/plugin-schedule/panels-dist/\n// 的磁盘路径——该函数向上找 `.git` 定位仓库根,只在本仓开发环境有效,`@x-otto/cli` 一旦真正\n// 发布到 npm(生产分发只含 `dist/`,无 `.git`),该函数恒返回 undefined,面板永远打不开。\n// schedule 现已物化为独立 npm 包 `@x-otto/plugin-schedule-panel`(对齐 browser-use/mobile-use 等既有\n// 内置扩展形态),走 `otto extension install schedule` 标准安装流程软链进 `~/.otto/plugins/\n// schedule`,面板路径改为查已注册的 `PanelRegistration`(`app.getPluginPanelRegistrations()`,\n// 内部用真实插件目录 `p.dir` 拼接,不依赖任何路径猜测)。\nasync function handleOpenPanel(ctx: ScheduleCtx): Promise<void> {\n const panel = (ctx.app.getPluginPanelRegistrations?.() ?? []).find(\n (p) => p.pluginId === 'plugin-schedule',\n )\n if (!panel) {\n ctx.tui.info.showToast(\n 'Schedule',\n 'Schedule panel not installed — run \"otto extension install plugin-schedule\"',\n )\n return\n }\n ctx.tui.modal.openModal({\n kind: 'pluginPanel',\n panelInfo: {\n title: panel.title,\n modulePath: panel.modulePath,\n exportName: panel.exportName,\n pluginId: panel.pluginId,\n },\n onClose: () => {},\n } as any)\n}\n\nasync function handleList(scheduler: SchedulerService, ctx: ScheduleCtx): Promise<void> {\n const tasks = scheduler.list()\n // RFC-169 D3d: surface read-only state — the user can see the shared task list but\n // this process isn't the one that will fire them (another terminal holds the lease).\n // F2 (RFC-169 终局 review 2026-07-15): distinguish \"another terminal genuinely holds the\n // lease\" from \"we couldn't reach the remote lease service at all\" — showing the wrong\n // specific reason is worse than a vague one; a network-error hint tells the user to check\n // connectivity instead of hunting for a nonexistent second terminal.\n const readOnlyHint = scheduler.isFireOwner()\n ? []\n : scheduler.fireOwnerFailureReason() === 'network-error'\n ? ['[read-only — could not reach the remote schedule service; check network/persistenced connectivity]']\n : ['[read-only — another terminal holds the fire-ownership lease for this workspace]']\n\n if (tasks.length === 0) {\n ctx.tui.info.showToast('Schedule', readOnlyHint.length > 0 ? `No scheduled tasks. ${readOnlyHint[0]}` : 'No scheduled tasks')\n return\n }\n const lines: string[] = []\n for (const t of tasks) {\n const status = t.lastFireFailed ? '✕' : t.enabled ? '◉' : '○'\n const cron = t.recurring ? t.cronExpression : 'one-shot'\n const next = new Date(t.nextFireAt).toLocaleString()\n const failedHint = t.lastFireFailed && t.lastFireError ? ` (failed: ${t.lastFireError})` : ''\n lines.push(`${status} ${t.id} ${t.name}${failedHint}`)\n lines.push(` ${cron} next: ${next}`)\n }\n ctx.tui.messages.pushMessage({\n role: 'command_echo',\n command: '/schedule',\n status: readOnlyHint.length > 0 ? 'warn' : 'ok',\n // readOnlyHint 优先展示(降级功能提醒,比\"N 个已排定任务\"更需要用户先看到)。\n summary: readOnlyHint.length > 0 ? readOnlyHint[0] : `${tasks.length} 个已排定任务`,\n detail: lines.join('\\n'),\n })\n ctx.tui.panes.togglePane?.('schedulePane')\n}\n\n/**\n * 从 token 化的命令行参数里解算 cron 表达式与 prompt(纯函数,单测覆盖)。\n *\n * 背景(2026-08-14 真 PTY 验收发现):cron 的自然书写是 5 个空格分隔字段\n * (`0 0 1 1 *`),但命令分词后散成 5 个独立 token——此前 handleAdd 只取\n * `positional[0]` 当 cron,用户自然写法必然报 \"expected 5 fields, got 1 (0)\",\n * 且用法提示从未提过引号包裹,等于自然语法全废。tokenizer 虽支持引号\n * (`\"0 0 1 1 *\"` 合成单 token),但把负担推给用户是 UX 缺陷而非答案。\n *\n * 解算规则(贪心、确定性):\n * - 前 5 个 token 拼接后能通过 parseCron 校验 → 认作 cron,其余归 prompt\n * (自然写法 `add --once 0 0 1 1 * probe` 命中此支);\n * - 否则沿用单 token 形态(引号包裹的完整表达式,或用户输入本就非法——\n * 由 scheduler.add 的 parseCron 报错兜底,错误文案不变)。\n */\nexport function splitCronArgs(positional: readonly string[]): { cron: string; prompt: string } {\n if (positional.length >= 5) {\n const joined = positional.slice(0, 5).join(' ')\n try {\n parseCron(joined)\n return { cron: joined, prompt: positional.slice(5).join(' ') }\n } catch {\n // 前 5 token 不构成合法 cron → 单 token 形态(引号包裹)继续。\n }\n }\n return { cron: positional[0] ?? '', prompt: positional.slice(1).join(' ') }\n}\n\nasync function handleAdd(args: string[], scheduler: SchedulerService, ctx: ScheduleCtx): Promise<void> {\n if (args.length < 2) {\n ctx.tui.info.showToast('Schedule', '/schedule add [--once] [--session] <cron 5 fields> <prompt>')\n return\n }\n\n let once = false\n // RFC-357 D3 (M2): --session opts a user-created task into firing back into the\n // current conversation (via followUp) instead of dispatching an isolated worktree job.\n let target: 'job' | 'session' | undefined\n const positional = [...args]\n const onceIdx = positional.indexOf('--once')\n if (onceIdx !== -1) {\n once = true\n positional.splice(onceIdx, 1)\n }\n const sessionIdx = positional.indexOf('--session')\n if (sessionIdx !== -1) {\n target = 'session'\n positional.splice(sessionIdx, 1)\n }\n\n if (positional.length < 2) {\n // RFC-229 M4: open the panel in create view mode\n ctx.tui.info.showToast('Schedule', 'Opening schedule panel in create mode')\n void handleOpenPanel(ctx)\n return\n }\n\n const { cron: cronExpr, prompt } = splitCronArgs(positional)\n\n try {\n const task = scheduler.add({\n name: prompt.slice(0, 40),\n prompt,\n cronExpression: cronExpr,\n recurring: !once,\n origin: 'user',\n target,\n })\n const kind = once ? 'one-shot' : 'recurring'\n const next = new Date(task.nextFireAt).toLocaleString()\n const targetNote = task.target === 'session' ? ' [fires into this conversation]' : ''\n ctx.tui.info.showToast('Schedule', `${task.id}: ${task.name} (${kind})${targetNote} next: ${next}`)\n } catch (err) {\n ctx.tui.info.showToast('Schedule', `Failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n}\n\nasync function handleRemove(id: string | undefined, scheduler: SchedulerService, ctx: ScheduleCtx): Promise<void> {\n if (!id) {\n ctx.tui.info.showToast('Schedule', '/schedule remove <id>')\n return\n }\n const removed = scheduler.remove(id)\n ctx.tui.info.showToast('Schedule', removed ? `Removed ${id}` : `Schedule \"${id}\" not found`)\n}\n\nasync function handleRun(id: string | undefined, scheduler: SchedulerService, ctx: ScheduleCtx): Promise<void> {\n if (!id) {\n ctx.tui.info.showToast('Schedule', '/schedule run <id>')\n return\n }\n try {\n scheduler.runNow(id)\n ctx.tui.info.showToast('Schedule', `Triggering ${id}...`)\n } catch (err) {\n ctx.tui.info.showToast('Schedule', `Failed: ${err instanceof Error ? err.message : String(err)}`)\n }\n}\n\nasync function handleCancel(id: string | undefined, ctx: ScheduleCtx): Promise<void> {\n const scheduler = schedulerRef\n if (!scheduler) {\n ctx.tui.info.showToast('Schedule', 'Schedule system not available')\n return\n }\n if (!id) {\n ctx.tui.info.showToast('Schedule', '/schedule cancel <id>')\n return\n }\n const result = scheduler.cancel(id)\n if (result.ok) {\n ctx.tui.info.showToast('Schedule', `Canceled \"${id}\"`)\n } else {\n ctx.tui.info.showToast('Schedule', `Cannot cancel \"${id}\": ${result.reason ?? 'unknown'}`)\n }\n}\n\nasync function handleToggle(\n id: string | undefined,\n enabled: boolean,\n scheduler: SchedulerService,\n ctx: ScheduleCtx,\n): Promise<void> {\n if (!id) {\n ctx.tui.info.showToast('Schedule', `/schedule ${enabled ? 'enable' : 'disable'} <id>`)\n return\n }\n const ok = scheduler.update(id, { enabled })\n ctx.tui.info.showToast('Schedule', ok ? `Schedule ${id} ${enabled ? 'enabled' : 'disabled'}` : `Schedule \"${id}\" not found`)\n}\n\nasync function handleLogs(taskId: string | undefined, ctx: ScheduleCtx): Promise<void> {\n const logDir = resolve(OTTO_HOME, 'schedule-logs')\n\n let logFiles: string[]\n try {\n logFiles = readdirSync(logDir)\n } catch {\n ctx.tui.info.showToast('Schedule', 'No schedule logs found')\n return\n }\n\n if (taskId) {\n logFiles = logFiles.filter(f => f.startsWith(taskId + '-'))\n }\n\n if (logFiles.length === 0) {\n ctx.tui.info.showToast('Schedule', taskId ? `No logs for schedule \"${taskId}\"` : 'No schedule logs found')\n return\n }\n\n logFiles.sort().reverse()\n\n const recent = logFiles.slice(0, 5)\n const lines: string[] = []\n for (const filename of recent) {\n try {\n const content = readFileSync(resolve(logDir, filename), 'utf-8').trim()\n const dashIdx = filename.indexOf('-')\n const tid = dashIdx > 0 ? filename.slice(0, dashIdx) : filename\n lines.push(`${tid} ${content}`)\n } catch {\n lines.push(`${filename} (unreadable)`)\n }\n }\n\n const remaining = logFiles.length - recent.length\n if (remaining > 0) {\n lines.push(`... and ${remaining} more entries`)\n }\n\n ctx.tui.messages.pushMessage({\n role: 'command_echo',\n command: '/schedule logs',\n summary: `${logFiles.length} 条日志文件`,\n detail: lines.join('\\n'),\n })\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{t as e}from"./create-host-app-CbJ8ptv-.js";import{t}from"./daemon-base-D015ew5y.js";import{SERVICE_PORT as n}from"@x-otto/env";import{resolve as r}from"node:path";import{createCodingService as i}from"@x-otto/service";async function a(n,r={}){let a=r.stdout??(e=>process.stdout.write(e)),c=r.stderr??(e=>process.stderr.write(e));if(n[0]===`help`||n[0]===`--help`)return s(a),0;let l,u,d,f,p;try{({port:l,inspect:u,staticDir:d,token:f}=o(n))}catch(e){return c(`otto serve: ${e instanceof Error?e.message:String(e)}\n`),1}let m=r.app??e({logger:{name:`otto-serve`,level:r.verbose?`debug`:`info`,destination:`stderr`},inspect:u,workspaceDir:r.projectDir,projectConfigPath:r.configPath,modelId:r.modelId});try{await m.start()}catch(e){return c(`otto serve: failed to start app: ${e instanceof Error?e.message:String(e)}\n`),1}if(`agentJobs`in m&&typeof m.start==`function`){let{setupScheduleService:e}=await import(`./interactive-schedule-Bv__2Kwc.js`).then(e=>e.t),{FireLogger:t,DEFAULT_SCHEDULE_CONFIG:n}=await import(`@x-otto/schedule`),r=new t(n);try{let{scheduler:t}=e(m,{});p=t,r.write(`daemon-scheduler`,`headless scheduler assembled (job-only)`)}catch(e){let t=e instanceof Error?e.message:String(e);m.logger?.warn?.({err:t},`[schedule] serve headless scheduler setup failed (non-fatal)`),r.write(`daemon-scheduler`,`headless scheduler setup FAILED: ${t}`)}}let h=i(m,{port:l,host:`127.0.0.1`,staticDir:d,apiToken:f,wsAuthToken:f,authorityId:process.env.OTTO_AUTHORITY_ID||void 0});try{await h.start()}catch(e){return c(`otto serve: failed to listen on port ${l}: ${e instanceof Error?e.message:String(e)}\n`),await m.stop(),1}let g=h.httpServer.address().port;if(a(`otto service listening on http://127.0.0.1:${g}${f?` (auth: token required)`:``}
|
|
3
|
+
${d?` web: http://127.0.0.1:${g}/${f?` (打开时附加 ?token=<你的 token>)`:``} (静态页面同源托管 ${d})\n`:``} panels: otto observe summary <session-id>
|
|
4
|
+
otto time-travel checkpoints <session-id>
|
|
5
|
+
otto debug breakpoints list${u?``:" (debugger disabled — restart with `otto serve --inspect`)"}
|
|
6
|
+
stop: Ctrl-C
|
|
7
|
+
`),await t(r.signal),a(`otto serve: shutting down...
|
|
8
|
+
`),p)try{await p.stop()}catch(e){m.logger?.warn?.({err:e instanceof Error?e.message:String(e)},`[schedule] serve scheduler stop failed`)}await h.stop(),await m.stop(),process.exit(0)}function o(e){let t=n,i=!1,a,o,s=(t,n)=>{let r=e[t+1];if(r===void 0||r.startsWith(`--`))throw Error(`${n} requires a value`);return r};for(let n=0;n<e.length;n++){let c=e[n];if(c===`--port`||c===`-p`){let e=s(n,`--port`);n++;let r=Number(e);if(!Number.isInteger(r)||r<0||r>65535)throw Error(`invalid --port value: ${e}`);t=r}else c===`--inspect`?i=!0:c===`--static`?(a=r(s(n,`--static`)),n++):c===`--token`&&(o=s(n,`--token`),n++)}return{port:t,inspect:i,staticDir:a,token:o}}function s(e){e(`otto serve — 启动 HTTP/WS service(观测/调试/时间旅行面板的对端)
|
|
9
|
+
|
|
10
|
+
用法:
|
|
11
|
+
otto serve [--port <n>] [--inspect] [--static <dir>] [--token <t>]
|
|
12
|
+
|
|
13
|
+
选项:
|
|
14
|
+
--port, -p <n> 监听端口(默认 ${n},可经 OTTO_SERVICE_PORT 覆盖;0 = 随机)
|
|
15
|
+
--inspect 启用调试器(断点/暂停面板需要)
|
|
16
|
+
--static <dir> 同源托管一个已构建的前端目录(SPA),页面与 /api、/ws 同端口免 CORS
|
|
17
|
+
--token <t> 启用鉴权:HTTP /api/* 需 Bearer,WS 需 ?token=;页面用 URL ?token=<t> 对上
|
|
18
|
+
|
|
19
|
+
面板命令默认连 http://127.0.0.1:${n}(可 --remote 覆盖)
|
|
20
|
+
`)}export{a as runServeCommand};
|
|
21
|
+
//# sourceMappingURL=serve-K6BOT5K_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-K6BOT5K_.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 /** RFC-435 D2:serve headless scheduler(无人值守定时任务)。退出时 stop 释放 ownership。 */\n let appScheduler: { stop(): Promise<void> } | 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 // RFC-435 D2:serve/daemon 无人值守装配 headless SchedulerService——job/subscriber 类\n // cron 任务在交互会话关闭后仍到点执行(用户原始诉求\"每天凌晨自动维护文档\")。\n // 无 sessionRef/tui → job-only 形态(session 类任务跳过 + fire log 记录,RFC-435 D2)。\n // fail-soft:装配失败不阻断 serve 主功能(调度是附加能力,R3)。\n // 仅完整 App(createHostApp 生产路径)装配——测试注入的 AppContext 桩无 agentJobs/\n // panelBackendController 等调度依赖,跳过(T435-5 用 fake app 直接验证装配调用)。\n if ('agentJobs' in app && typeof app.start === 'function') {\n const { setupScheduleService } = await import('./interactive-schedule')\n const { FireLogger, DEFAULT_SCHEDULE_CONFIG } = await import('@x-otto/schedule')\n const serveFireLogger = new FireLogger(DEFAULT_SCHEDULE_CONFIG)\n try {\n const { scheduler } = setupScheduleService(app, {})\n // serve 生命周期:优雅退出时释放 ownership(stop),避免锁残留 5min stale 窗口。\n appScheduler = scheduler\n // D5:无人值守装配成功落盘可查(daemon 壳 stdio:'ignore',stderr 日志不可见)。\n serveFireLogger.write('daemon-scheduler', 'headless scheduler assembled (job-only)')\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error)\n app.logger?.warn?.({ err: msg }, '[schedule] serve headless scheduler setup failed (non-fatal)')\n // D5:装配失败落盘——无人值守时用户第二天必须能查到调度未起。\n serveFireLogger.write('daemon-scheduler', `headless scheduler setup FAILED: ${msg}`)\n }\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 // RFC-435 D4:先 stop scheduler(release fire ownership,避免锁残留 stale 窗口,\n // 交互会话/其他 daemon 立即可接管),再停 service/app。\n if (appScheduler) {\n try {\n await appScheduler.stop()\n } catch (error) {\n app.logger?.warn?.(\n { err: error instanceof Error ? error.message : String(error) },\n '[schedule] serve scheduler stop failed',\n )\n }\n }\n await service.stop()\n await app.stop()\n // 硬退出:service.stop()/app.stop() 可能留下孤儿 handle(worker_threads port、\n // DB pool、trace tail),吊住事件循环导致 Ctrl+C 后进程不退。与 interactive 路径\n // (cli.ts 末尾 process.exit)对齐。stdio 已同步写,无截断风险。\n process.exit(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":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import{SERVICE_URL as e}from"@x-otto/env";var t=class extends Error{constructor(e){super(`cannot reach otto service at ${e} — start it with \`otto serve\` or pass --remote <url>`),this.name=`ServiceUnreachableError`}},n=class extends Error{constructor(e,t){super(t?`${t} (HTTP ${e})`:`request failed (HTTP ${e})`),this.status=e,this.name=`ServiceRequestError`}};function r(t){let n=[...t],r=n.indexOf(`--remote`),i=e;if(r>=0){let e=n[r+1];if(!e||e.startsWith(`-`))throw Error(`--remote requires a url (e.g. --remote http://127.0.0.1:8417)`);i=e,n.splice(r,2)}return{baseUrl:i.replace(/\/$/,``),rest:n}}function i(e,r=globalThis.fetch,i={}){async function a(a,o){let s,c={"content-type":`application/json`,...i.token?{Authorization:`Bearer ${i.token}`}:{},...o?.headers};try{s=await r(`${e}${a}`,{...o,headers:c})}catch{throw new t(e)}if(!s.ok){let e=await s.json().catch(()=>({}));throw new n(s.status,typeof e.error==`string`?e.error:void 0)}let l;try{l=await s.json()}catch{throw new n(s.status,`response was not valid JSON`)}return l}return{baseUrl:e,get:e=>a(e),post:(e,t)=>a(e,{method:`POST`,body:JSON.stringify(t??{})}),put:(e,t)=>a(e,{method:`PUT`,body:JSON.stringify(t??{})}),fetchSnapshot(e){return a(`/api/sessions/${encodeURIComponent(e)}/snapshot`)},async sendPrompt(e,t){return a(`/api/chat/query`,{method:`POST`,body:JSON.stringify({message:t,sessionId:e})})}}}function a(e,t,n){return n(`otto ${e}: ${t instanceof Error?t.message:String(t)}\n`),1}export{r as a,a as i,t as n,i as r,n as t};
|
|
3
|
-
//# sourceMappingURL=service-client-
|
|
3
|
+
//# sourceMappingURL=service-client-cfUUP4EE.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-client-
|
|
1
|
+
{"version":3,"file":"service-client-cfUUP4EE.js","names":[],"sources":["../src/commands/service-client.ts"],"sourcesContent":["import { SERVICE_URL } from '@x-otto/env'\n\n/** service 进程不可达(连接被拒/DNS 失败)。命令层 catch 后输出可操作提示。 */\nexport class ServiceUnreachableError extends Error {\n constructor(baseUrl: string) {\n super(\n `cannot reach otto service at ${baseUrl} — start it with \\`otto serve\\` or pass --remote <url>`,\n )\n this.name = 'ServiceUnreachableError'\n }\n}\n\nexport class ServiceRequestError extends Error {\n constructor(\n readonly status: number,\n serverMessage: string | undefined,\n ) {\n super(serverMessage ? `${serverMessage} (HTTP ${status})` : `request failed (HTTP ${status})`)\n this.name = 'ServiceRequestError'\n }\n}\n\nexport interface ServiceClient {\n readonly baseUrl: string\n get<T>(path: string): Promise<T>\n post<T>(path: string, body?: unknown): Promise<T>\n put<T>(path: string, body?: unknown): Promise<T>\n /** RFC-335 T335-07 S3:attach 快照(含 cursor——serve 给出的 subscribe.since 起点)。 */\n fetchSnapshot(sessionId: string): Promise<SessionSnapshotDto>\n /** RFC-335 T335-07 S3:attach 首期唯一写入面——经 POST /api/chat/query 发送 prompt。 */\n sendPrompt(sessionId: string, message: string): Promise<ChatQueryResponse>\n}\n\n/** service `GET /api/sessions/:id/snapshot` 响应(service/src/types.ts:141 SessionSnapshot)。 */\nexport interface SessionSnapshotDto {\n session: {\n id: string\n status: string\n messageCount: number\n messages: Array<unknown>\n }\n authority: { hostname: string; pid: number; sessionId: string }\n cursor: number\n}\n\n/** service `POST /api/chat/query` 响应。 */\nexport interface ChatQueryResponse {\n sessionId: string\n}\n\nexport function resolveRemote(args: string[]): { baseUrl: string; rest: string[] } {\n const rest = [...args]\n const idx = rest.indexOf('--remote')\n let baseUrl = SERVICE_URL\n if (idx >= 0) {\n const url = rest[idx + 1]\n if (!url || url.startsWith('-')) {\n throw new Error('--remote requires a url (e.g. --remote http://127.0.0.1:8417)')\n }\n baseUrl = url\n rest.splice(idx, 2)\n }\n return { baseUrl: baseUrl.replace(/\\/$/, ''), rest }\n}\n\nexport interface ServiceClientOptions {\n /** `otto serve --token <t>` 时的鉴权头(Authorization: Bearer <t>)。 */\n token?: string\n}\n\nexport function createServiceClient(\n baseUrl: string,\n fetchImpl: typeof globalThis.fetch = globalThis.fetch,\n options: ServiceClientOptions = {},\n): ServiceClient {\n async function request<T>(path: string, init?: RequestInit): Promise<T> {\n let res: Response\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n ...(options.token ? { Authorization: `Bearer ${options.token}` } : {}),\n ...(init?.headers as Record<string, string> | undefined),\n }\n try {\n res = await fetchImpl(`${baseUrl}${path}`, { ...init, headers })\n } catch {\n throw new ServiceUnreachableError(baseUrl)\n }\n\n if (!res.ok) {\n const errBody = (await res.json().catch(() => ({}))) as Record<string, unknown>\n throw new ServiceRequestError(\n res.status,\n typeof errBody.error === 'string' ? errBody.error : undefined,\n )\n }\n\n let body: unknown\n try {\n body = await res.json()\n } catch {\n throw new ServiceRequestError(res.status, 'response was not valid JSON')\n }\n return body as T\n }\n\n return {\n baseUrl,\n get: (path) => request(path),\n post: (path, body) =>\n request(path, {\n method: 'POST',\n body: JSON.stringify(body ?? {}),\n }),\n put: (path, body) =>\n request(path, {\n method: 'PUT',\n body: JSON.stringify(body ?? {}),\n }),\n fetchSnapshot(sessionId: string): Promise<SessionSnapshotDto> {\n return request<SessionSnapshotDto>(`/api/sessions/${encodeURIComponent(sessionId)}/snapshot`)\n },\n async sendPrompt(sessionId: string, message: string): Promise<ChatQueryResponse> {\n return request<ChatQueryResponse>('/api/chat/query', {\n method: 'POST',\n body: JSON.stringify({ message, sessionId }),\n })\n },\n }\n}\n\nexport function reportServiceError(\n command: string,\n error: unknown,\n stderr: (s: string) => void,\n): number {\n const message = error instanceof Error ? error.message : String(error)\n stderr(`otto ${command}: ${message}\\n`)\n return 1\n}\n"],"mappings":";0CAGA,IAAa,EAAb,cAA6C,KAAM,CACjD,YAAY,EAAiB,CAC3B,MACE,gCAAgC,EAAQ,wDACzC,CACD,KAAK,KAAO,4BAIH,EAAb,cAAyC,KAAM,CAC7C,YACE,EACA,EACA,CACA,MAAM,EAAgB,GAAG,EAAc,SAAS,EAAO,GAAK,wBAAwB,EAAO,GAAG,CAHrF,KAAA,OAAA,EAIT,KAAK,KAAO,wBAgChB,SAAgB,EAAc,EAAqD,CACjF,IAAM,EAAO,CAAC,GAAG,EAAK,CAChB,EAAM,EAAK,QAAQ,WAAW,CAChC,EAAU,EACd,GAAI,GAAO,EAAG,CACZ,IAAM,EAAM,EAAK,EAAM,GACvB,GAAI,CAAC,GAAO,EAAI,WAAW,IAAI,CAC7B,MAAU,MAAM,gEAAgE,CAElF,EAAU,EACV,EAAK,OAAO,EAAK,EAAE,CAErB,MAAO,CAAE,QAAS,EAAQ,QAAQ,MAAO,GAAG,CAAE,OAAM,CAQtD,SAAgB,EACd,EACA,EAAqC,WAAW,MAChD,EAAgC,EAAE,CACnB,CACf,eAAe,EAAW,EAAc,EAAgC,CACtE,IAAI,EACE,EAAkC,CACtC,eAAgB,mBAChB,GAAI,EAAQ,MAAQ,CAAE,cAAe,UAAU,EAAQ,QAAS,CAAG,EAAE,CACrE,GAAI,GAAM,QACX,CACD,GAAI,CACF,EAAM,MAAM,EAAU,GAAG,IAAU,IAAQ,CAAE,GAAG,EAAM,UAAS,CAAC,MAC1D,CACN,MAAM,IAAI,EAAwB,EAAQ,CAG5C,GAAI,CAAC,EAAI,GAAI,CACX,IAAM,EAAW,MAAM,EAAI,MAAM,CAAC,WAAa,EAAE,EAAE,CACnD,MAAM,IAAI,EACR,EAAI,OACJ,OAAO,EAAQ,OAAU,SAAW,EAAQ,MAAQ,IAAA,GACrD,CAGH,IAAI,EACJ,GAAI,CACF,EAAO,MAAM,EAAI,MAAM,MACjB,CACN,MAAM,IAAI,EAAoB,EAAI,OAAQ,8BAA8B,CAE1E,OAAO,EAGT,MAAO,CACL,UACA,IAAM,GAAS,EAAQ,EAAK,CAC5B,MAAO,EAAM,IACX,EAAQ,EAAM,CACZ,OAAQ,OACR,KAAM,KAAK,UAAU,GAAQ,EAAE,CAAC,CACjC,CAAC,CACJ,KAAM,EAAM,IACV,EAAQ,EAAM,CACZ,OAAQ,MACR,KAAM,KAAK,UAAU,GAAQ,EAAE,CAAC,CACjC,CAAC,CACJ,cAAc,EAAgD,CAC5D,OAAO,EAA4B,iBAAiB,mBAAmB,EAAU,CAAC,WAAW,EAE/F,MAAM,WAAW,EAAmB,EAA6C,CAC/E,OAAO,EAA2B,kBAAmB,CACnD,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,UAAS,YAAW,CAAC,CAC7C,CAAC,EAEL,CAGH,SAAgB,EACd,EACA,EACA,EACQ,CAGR,OADA,EAAO,QAAQ,EAAQ,IADP,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CACnC,IAAI,CAChC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e}from"./build-id-
|
|
3
|
-
//# sourceMappingURL=version-
|
|
2
|
+
import{n as e}from"./build-id-DjE6eVpQ.js";import{createRequire as t}from"node:module";const n=t(import.meta.url);function r(){return`${n(`../package.json`).version??`0.0.0`} (build ${e})`}export{r as t};
|
|
3
|
+
//# sourceMappingURL=version-DrCy32wR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-
|
|
1
|
+
{"version":3,"file":"version-DrCy32wR.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["import { createRequire } from 'node:module'\n\nimport { BUILD_ID } from './build-id'\n\nconst require = createRequire(import.meta.url)\n\n/**\n * 版本号 + build ID。\n * 格式:`0.1.0 (build 2072)`。build ID = git rev-list --count HEAD,随每次构建自增。\n */\nexport function getVersion(): string {\n const pkg = require('../package.json') as { version?: string }\n const ver = pkg.version ?? '0.0.0'\n return `${ver} (build ${BUILD_ID})`\n}\n"],"mappings":";uFAIA,MAAM,EAAU,EAAc,OAAO,KAAK,IAAI,CAM9C,SAAgB,GAAqB,CAGnC,MAAO,GAFK,EAAQ,kBAAkB,CACtB,SAAW,QACb,UAAU,EAAS"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x-otto/cli",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,26 +18,29 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"react": "^19.2.4",
|
|
21
|
+
"zod": "4.3.6",
|
|
21
22
|
"@x-otto/agent": "0.0.1-alpha.5",
|
|
22
23
|
"@x-otto/coding": "0.0.1-alpha.19",
|
|
23
24
|
"@x-otto/ai": "0.0.1-alpha.4",
|
|
24
|
-
"@x-otto/schedule": "0.0.1-alpha.3",
|
|
25
25
|
"@x-otto/env": "0.1.0-alpha.6",
|
|
26
|
-
"@x-otto/memory": "0.0.1-alpha.3",
|
|
27
26
|
"@x-otto/mcp": "0.0.1-alpha.3",
|
|
28
|
-
"@x-otto/persistence": "0.0.1-alpha.4",
|
|
29
27
|
"@x-otto/interchange": "0.1.0-alpha.5",
|
|
30
|
-
"@x-otto/
|
|
28
|
+
"@x-otto/memory": "0.0.1-alpha.3",
|
|
29
|
+
"@x-otto/persistence": "0.0.1-alpha.4",
|
|
30
|
+
"@x-otto/plugin": "0.1.0-alpha.6",
|
|
31
31
|
"@x-otto/remote-persistence-server": "0.0.1-alpha.4",
|
|
32
|
-
"@x-otto/
|
|
32
|
+
"@x-otto/runtime": "0.0.1-alpha.10",
|
|
33
|
+
"@x-otto/schedule": "0.0.1-alpha.3",
|
|
33
34
|
"@x-otto/session-contract": "0.0.1-alpha.3",
|
|
34
|
-
"@x-otto/
|
|
35
|
-
"@x-otto/shared": "0.1.0-alpha.6",
|
|
35
|
+
"@x-otto/service": "0.0.1-alpha.3",
|
|
36
36
|
"@x-otto/setting": "0.0.1-alpha.4",
|
|
37
|
-
"@x-otto/
|
|
37
|
+
"@x-otto/shared": "0.1.0-alpha.6",
|
|
38
|
+
"@x-otto/hooks": "0.0.1-alpha.3",
|
|
39
|
+
"@x-otto/session": "0.0.1-alpha.5",
|
|
40
|
+
"@x-otto/guard": "0.0.1-alpha.1",
|
|
38
41
|
"@x-otto/tui": "0.0.1-alpha.20",
|
|
39
|
-
"@x-otto/
|
|
40
|
-
"@x-otto/
|
|
42
|
+
"@x-otto/trace-view": "0.0.1-alpha.2",
|
|
43
|
+
"@x-otto/tools": "0.0.1-alpha.4"
|
|
41
44
|
},
|
|
42
45
|
"publishConfig": {
|
|
43
46
|
"access": "public",
|
|
@@ -45,8 +48,8 @@
|
|
|
45
48
|
"tag": "alpha"
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
|
-
"
|
|
49
|
-
"
|
|
51
|
+
"@types/react": "^19.2.2",
|
|
52
|
+
"node-pty": "^1.1.0"
|
|
50
53
|
},
|
|
51
54
|
"private": false,
|
|
52
55
|
"scripts": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-id-DxfuzdUE.js","names":[],"sources":["../src/build-id.ts"],"sourcesContent":["// auto-generated by scripts/gen-build-id.mjs — DO NOT EDIT\nexport const BUILD_ID = 5124\nexport const BUILD_BRANCH = 'dev'\nexport const BUILD_HASH = '5b61b2446'\n"],"mappings":";AACA,MAAa,EAAW,KAEX,EAAa"}
|