@heliohq/helio 0.1.2
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/bin/helio +3 -0
- package/dist/commands/assistant/chat.js +6435 -0
- package/dist/commands/assistant/chat.js.map +1 -0
- package/dist/commands/assistant/connect/lark.js +6257 -0
- package/dist/commands/assistant/connect/lark.js.map +1 -0
- package/dist/commands/assistant/connect/slack.js +6322 -0
- package/dist/commands/assistant/connect/slack.js.map +1 -0
- package/dist/commands/assistant/connect/wechat.js +6258 -0
- package/dist/commands/assistant/connect/wechat.js.map +1 -0
- package/dist/commands/assistant/create.js +6190 -0
- package/dist/commands/assistant/create.js.map +1 -0
- package/dist/commands/assistant/delete.js +6176 -0
- package/dist/commands/assistant/delete.js.map +1 -0
- package/dist/commands/assistant/disconnect.js +6302 -0
- package/dist/commands/assistant/disconnect.js.map +1 -0
- package/dist/commands/assistant/list.js +6192 -0
- package/dist/commands/assistant/list.js.map +1 -0
- package/dist/commands/assistant/messages.js +6488 -0
- package/dist/commands/assistant/messages.js.map +1 -0
- package/dist/commands/assistant/send.js +6468 -0
- package/dist/commands/assistant/send.js.map +1 -0
- package/dist/commands/assistant/skills/add.js +6296 -0
- package/dist/commands/assistant/skills/add.js.map +1 -0
- package/dist/commands/assistant/skills/list.js +6258 -0
- package/dist/commands/assistant/skills/list.js.map +1 -0
- package/dist/commands/assistant/skills/remove.js +6288 -0
- package/dist/commands/assistant/skills/remove.js.map +1 -0
- package/dist/commands/auth/login.js +6327 -0
- package/dist/commands/auth/login.js.map +1 -0
- package/dist/commands/auth/logout.js +6174 -0
- package/dist/commands/auth/logout.js.map +1 -0
- package/dist/commands/auth/status.js +6205 -0
- package/dist/commands/auth/status.js.map +1 -0
- package/dist/commands/channel/chat.js +6341 -0
- package/dist/commands/channel/chat.js.map +1 -0
- package/dist/commands/channel/create.js +6199 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/delete.js +6178 -0
- package/dist/commands/channel/delete.js.map +1 -0
- package/dist/commands/channel/list.js +6207 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/channel/members/add.js +6235 -0
- package/dist/commands/channel/members/add.js.map +1 -0
- package/dist/commands/channel/members/index.js +6198 -0
- package/dist/commands/channel/members/index.js.map +1 -0
- package/dist/commands/channel/members/remove.js +6237 -0
- package/dist/commands/channel/members/remove.js.map +1 -0
- package/dist/commands/channel/messages.js +6261 -0
- package/dist/commands/channel/messages.js.map +1 -0
- package/dist/commands/channel/send.js +6171 -0
- package/dist/commands/channel/send.js.map +1 -0
- package/dist/commands/claude.js +11928 -0
- package/dist/commands/claude.js.map +1 -0
- package/dist/commands/codex.js +11928 -0
- package/dist/commands/codex.js.map +1 -0
- package/dist/commands/config/init.js +6186 -0
- package/dist/commands/config/init.js.map +1 -0
- package/dist/commands/config/profile/create.js +6207 -0
- package/dist/commands/config/profile/create.js.map +1 -0
- package/dist/commands/config/profile/delete.js +6183 -0
- package/dist/commands/config/profile/delete.js.map +1 -0
- package/dist/commands/config/profile/list.js +6204 -0
- package/dist/commands/config/profile/list.js.map +1 -0
- package/dist/commands/config/show.js +6187 -0
- package/dist/commands/config/show.js.map +1 -0
- package/dist/commands/marketplace/info.js +6325 -0
- package/dist/commands/marketplace/info.js.map +1 -0
- package/dist/commands/marketplace/list.js +6288 -0
- package/dist/commands/marketplace/list.js.map +1 -0
- package/dist/commands/task/assign.js +6254 -0
- package/dist/commands/task/assign.js.map +1 -0
- package/dist/commands/task/claim.js +6244 -0
- package/dist/commands/task/claim.js.map +1 -0
- package/dist/commands/task/create.js +6249 -0
- package/dist/commands/task/create.js.map +1 -0
- package/dist/commands/task/done.js +6244 -0
- package/dist/commands/task/done.js.map +1 -0
- package/dist/commands/task/list.js +6281 -0
- package/dist/commands/task/list.js.map +1 -0
- package/dist/commands/task/reject.js +6244 -0
- package/dist/commands/task/reject.js.map +1 -0
- package/dist/commands/task/review.js +6244 -0
- package/dist/commands/task/review.js.map +1 -0
- package/dist/commands/task/show.js +6250 -0
- package/dist/commands/task/show.js.map +1 -0
- package/dist/commands/task/unclaim.js +6244 -0
- package/dist/commands/task/unclaim.js.map +1 -0
- package/dist/commands/update.js +6229 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/help.js +6168 -0
- package/dist/help.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/channel-helper.js +11893 -0
- package/dist/lib/channel-helper.js.map +1 -0
- package/dist/pty/broker-transport.js +10271 -0
- package/dist/pty/broker-transport.js.map +1 -0
- package/dist/pty/client.js +7312 -0
- package/dist/pty/client.js.map +1 -0
- package/dist/pty/clipboard.js +39 -0
- package/dist/pty/clipboard.js.map +1 -0
- package/dist/pty/errors.js +57 -0
- package/dist/pty/errors.js.map +1 -0
- package/dist/pty/protocol.js +18 -0
- package/dist/pty/protocol.js.map +1 -0
- package/dist/pty/screen-renderer.js +492 -0
- package/dist/pty/screen-renderer.js.map +1 -0
- package/dist/pty/terminal.js +24 -0
- package/dist/pty/terminal.js.map +1 -0
- package/dist/pty/transport.js +2 -0
- package/dist/pty/transport.js.map +1 -0
- package/dist/types/qrcode-terminal.d.js +2 -0
- package/dist/types/qrcode-terminal.d.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pty/screen-renderer.ts"],"sourcesContent":["import xtermHeadless from '@xterm/headless';\n\nconst Terminal = xtermHeadless.Terminal;\n\n/**\n * ScreenRenderer supports two modes:\n *\n * 1. Vterm mode (default): agent data -> xterm buffer -> cell-by-cell render to stdout\n * 2. Passthrough mode (HELIO_PASSTHROUGH=1): raw agent data -> stdout, xterm for cursor tracking only\n *\n * Vterm mode avoids escape sequence interleaving issues at the cost of higher CPU.\n * Passthrough mode is native speed but needs incomplete-escape detection for overlay.\n */\nexport class ScreenRenderer {\n private term: InstanceType<typeof Terminal>;\n private writeBuffer: { writeSync(data: string, isUtf8?: boolean): void };\n // xterm internal API — depends on @xterm/headless ^5.5.0 internals\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private core: any;\n private overlayTimer: ReturnType<typeof setImmediate> | null = null;\n private pendingOverlay = '';\n private incompleteEsc = false;\n private vterm: boolean;\n private lastFrame: string[] = [];\n private cols: number;\n private rows: number;\n private renderTimer: ReturnType<typeof setTimeout> | null = null;\n /** Render batch delay in ms — matches Ink's 16ms (60fps) throttle to prevent\n * partial-frame rendering when TUI frameworks send rapid incremental updates. */\n private static readonly RENDER_BATCH_MS = 16;\n /** Last seen baseY — when it changes the viewport shifted and lastFrame must be invalidated. */\n private lastBaseY = 0;\n /** Last observed content height (last non-blank row + 1). Used to detect\n * dialog dismiss events where content shrinks significantly. */\n private lastContentHeight = 0;\n /** Callback fired when content height drops significantly (e.g., dialog dismissed).\n * The PTYClient uses this to send a resize trick to force Ink to relayout. */\n onContentShrink: (() => void) | null = null;\n private scrollOffset = 0; // 0 = bottom (live), >0 = scrolled up\n private scrollCursorY = 0; // cursor row within viewport (0-indexed)\n private scrollCursorX = 0; // actual display col (clamped to content)\n private scrollDesiredX = 0; // remembered col for up/down navigation\n\n constructor(cols: number, rows: number) {\n this.cols = cols;\n this.rows = rows;\n this.vterm = !process.env['HELIO_PASSTHROUGH'];\n this.term = new Terminal({ cols, rows, scrollback: 10000, allowProposedApi: true });\n this.core = (this.term as unknown as Record<string, unknown>)['_core'];\n this.writeBuffer = this.core._writeBuffer;\n\n // Detect alternate screen buffer switches (\\x1b[?1049h / \\x1b[?1049l).\n // Invalidate lastFrame so the next render is a full redraw.\n this.term.parser.registerCsiHandler({ prefix: '?', final: 'h' }, (params) => {\n if (params[0] === 1049) this.lastFrame = [];\n return false; // let xterm handle normally\n });\n this.term.parser.registerCsiHandler({ prefix: '?', final: 'l' }, (params) => {\n if (params[0] === 1049) this.lastFrame = [];\n return false;\n });\n }\n\n /**\n * Relay terminal query responses from xterm to the agent PTY.\n * Also intercepts queries xterm can't answer (OSC 10 foreground color)\n * and provides default responses to prevent agent startup delays.\n */\n setupResponseRelay(sendToAgent: (data: string) => void): void {\n // xterm auto-responds to DA, DSR etc. Relay those to agent.\n this.term.onData((data: string) => {\n sendToAgent(data);\n });\n\n // OSC 10 (foreground color query) — xterm doesn't respond.\n // Provide a default response to prevent agent timeout.\n this.term.parser.registerOscHandler(10, (data: string) => {\n if (data === '?') {\n // Respond with default foreground color (white)\n sendToAgent('\\x1b]10;rgb:ffff/ffff/ffff\\x1b\\\\');\n }\n return false; // let other handlers also process\n });\n }\n\n write(data: string | Uint8Array, statusBarEsc: string): void {\n const str = typeof data === 'string' ? data : new TextDecoder().decode(data);\n this.writeBuffer.writeSync(str, false);\n\n // New data arrives — snap to bottom if scrolled back\n if (this.scrollOffset > 0) {\n this.scrollOffset = 0;\n this.lastFrame = [];\n }\n\n if (this.vterm) {\n this.pendingOverlay = statusBarEsc;\n if (!this.renderTimer) {\n this.renderTimer = setTimeout(() => {\n this.renderTimer = null;\n this.vtermRender();\n }, ScreenRenderer.RENDER_BATCH_MS);\n }\n } else {\n // Passthrough mode: direct stdout + deferred overlay\n process.stdout.write(data);\n this.incompleteEsc = this.endsWithIncompleteEsc(str);\n\n if (statusBarEsc) {\n this.pendingOverlay = statusBarEsc;\n if (!this.overlayTimer) {\n this.overlayTimer = setImmediate(() => {\n this.overlayTimer = null;\n if (!this.incompleteEsc) {\n this.flushOverlay();\n }\n });\n }\n }\n }\n }\n\n /** Vterm render (legacy, no scroll). */\n vtermRender(): void {\n const buf = this.term.buffer.active;\n let output = '';\n\n // Invalidate frame cache when viewport shifts due to scrollback growth\n if (buf.baseY !== this.lastBaseY) {\n this.lastFrame = [];\n this.lastBaseY = buf.baseY;\n }\n\n for (let y = 0; y < this.rows; y++) {\n const line = buf.getLine(buf.baseY + y);\n if (!line) {\n // No line in buffer — clear if previously rendered\n if (this.lastFrame[y] !== undefined) {\n output += `\\x1b[${y + 1};1H\\x1b[2K`;\n delete this.lastFrame[y];\n }\n continue;\n }\n\n const rendered = this.renderLine(line);\n if (this.lastFrame[y] === rendered) continue;\n this.lastFrame[y] = rendered;\n\n output += `\\x1b[${y + 1};1H\\x1b[2K${rendered}`;\n }\n\n // Track content height to detect dialog dismiss (content shrinks significantly).\n let contentHeight = 0;\n for (let y = this.rows - 1; y >= 0; y--) {\n const line = buf.getLine(buf.baseY + y);\n if (line && line.translateToString(true).length > 0) {\n contentHeight = y + 1;\n break;\n }\n }\n // If content was using >60% of viewport and dropped to <40%, a dialog was dismissed.\n // Fire callback so PTYClient can trigger a resize to force Ink relayout.\n const prevHeight = this.lastContentHeight;\n this.lastContentHeight = contentHeight;\n const shrinkThreshold = this.rows * 0.6;\n const shrunkTo = this.rows * 0.4;\n if (prevHeight > shrinkThreshold && contentHeight < shrunkTo && this.onContentShrink) {\n // Defer to avoid re-entrancy\n setTimeout(() => this.onContentShrink?.(), 50);\n }\n\n // Overlay + cursor\n const cx = buf.cursorX;\n const cy = buf.cursorY;\n const cursorHidden = this.core?.coreService?.isCursorHidden ?? false;\n const cursorSuffix = cursorHidden ? '\\x1b[?25l' : '\\x1b[?25h';\n output += this.pendingOverlay;\n output += `\\x1b[${cy + 1};${cx + 1}H${cursorSuffix}`;\n\n if (output) {\n process.stdout.write(output);\n }\n }\n\n private renderLine(\n line: NonNullable<ReturnType<typeof this.term.buffer.active.getLine>>,\n ): string {\n let result = '';\n let prevSgr = '';\n\n const cell = line.getCell(0);\n if (!cell) return line.translateToString(true);\n\n for (let x = 0; x < this.cols; x++) {\n line.getCell(x, cell);\n if (!cell) break;\n if (cell.getWidth() === 0) continue;\n\n const sgr = this.cellSGR(cell);\n if (sgr !== prevSgr) {\n result += '\\x1b[0m' + sgr;\n prevSgr = sgr;\n }\n\n result += cell.getChars() || ' ';\n }\n\n result += '\\x1b[0m';\n return result;\n }\n\n private cellSGR(\n cell: NonNullable<\n ReturnType<NonNullable<ReturnType<typeof this.term.buffer.active.getLine>>['getCell']>\n >,\n ): string {\n let sgr = '';\n if (cell.isBold()) sgr += '\\x1b[1m';\n if (cell.isDim()) sgr += '\\x1b[2m';\n if (cell.isItalic()) sgr += '\\x1b[3m';\n if (cell.isUnderline()) sgr += '\\x1b[4m';\n if (cell.isInverse()) sgr += '\\x1b[7m';\n if (cell.isStrikethrough()) sgr += '\\x1b[9m';\n\n if (cell.isFgPalette()) {\n const fg = cell.getFgColor();\n if (fg < 8) sgr += `\\x1b[${30 + fg}m`;\n else if (fg < 16) sgr += `\\x1b[${90 + fg - 8}m`;\n else sgr += `\\x1b[38;5;${fg}m`;\n } else if (cell.isFgRGB()) {\n const fg = cell.getFgColor();\n sgr += `\\x1b[38;2;${(fg >> 16) & 0xff};${(fg >> 8) & 0xff};${fg & 0xff}m`;\n }\n\n if (cell.isBgPalette()) {\n const bg = cell.getBgColor();\n if (bg < 8) sgr += `\\x1b[${40 + bg}m`;\n else if (bg < 16) sgr += `\\x1b[${100 + bg - 8}m`;\n else sgr += `\\x1b[48;5;${bg}m`;\n } else if (cell.isBgRGB()) {\n const bg = cell.getBgColor();\n sgr += `\\x1b[48;2;${(bg >> 16) & 0xff};${(bg >> 8) & 0xff};${bg & 0xff}m`;\n }\n\n return sgr;\n }\n\n private flushOverlay(): void {\n if (!this.pendingOverlay) return;\n const buf = this.term.buffer.active;\n const cx = buf.cursorX;\n const cy = buf.cursorY;\n const cursorHidden = this.core?.coreService?.isCursorHidden ?? false;\n const cursorSuffix = cursorHidden ? '\\x1b[?25l' : '\\x1b[?25h';\n process.stdout.write(\n `\\x1b[?25l${this.pendingOverlay}\\x1b[${cy + 1};${cx + 1}H${cursorSuffix}`,\n );\n }\n\n writeSilent(data: string | Uint8Array): void {\n const str = typeof data === 'string' ? data : new TextDecoder().decode(data);\n this.writeBuffer.writeSync(str, false);\n }\n\n renderStatusBar(statusBarEsc: string): void {\n const buf = this.term.buffer.active;\n const cx = buf.cursorX;\n const cy = buf.cursorY;\n const cursorHidden = this.core?.coreService?.isCursorHidden ?? false;\n const cursorSuffix = cursorHidden ? '\\x1b[?25l' : '\\x1b[?25h';\n process.stdout.write(\n `\\x1b[?25l${statusBarEsc}\\x1b[${cy + 1};${cx + 1}H${cursorSuffix}`,\n );\n }\n\n private endsWithIncompleteEsc(str: string): boolean {\n const lastEsc = str.lastIndexOf('\\x1b');\n if (lastEsc === -1) return false;\n\n const tail = str.substring(lastEsc);\n if (tail.length === 1) return true;\n if (tail[1] === '[') {\n for (let i = 2; i < tail.length; i++) {\n const c = tail.charCodeAt(i);\n if (c >= 0x40 && c <= 0x7e) return false;\n }\n return true;\n }\n if (tail[1] === ']') {\n if (tail.includes('\\x1b\\\\') || tail.includes('\\x07')) return false;\n return true;\n }\n return false;\n }\n\n /** Enter scroll mode: freeze viewport at current position, show cursor. */\n enterScrollMode(): void {\n const buf = this.term.buffer.active;\n this.scrollOffset = 0;\n this.scrollCursorY = buf.cursorY;\n this.scrollCursorX = buf.cursorX;\n this.scrollDesiredX = buf.cursorX;\n const totalLines = buf.baseY + this.rows;\n const currentLine = buf.baseY + this.scrollCursorY + 1;\n const pos = `${currentLine}/${totalLines}`;\n const sep = '\\u2500'.repeat(this.cols);\n let output = '';\n const pad = ' '.repeat(this.cols);\n output += `\\x1b[${this.rows + 1};1H${pad}\\x1b[${this.rows + 1};1H\\x1b[90m${sep}\\x1b[0m`;\n output += `\\x1b[${this.rows + 2};1H${pad}\\x1b[${this.rows + 2};1H\\x1b[7m [\\u2191\\u2193/hjkl] move [w/b] word [0/$] line [g/G] top/end [q/Esc] exit \\x1b[0m`;\n output += `\\x1b[${this.rows + 2};${this.cols - pos.length - 1}H\\x1b[43;30m ${pos} \\x1b[0m`;\n output += `\\x1b[${this.scrollCursorY + 1};${this.scrollCursorX + 1}H\\x1b[?25h`;\n process.stdout.write(output);\n }\n\n /** Scroll up by n lines. Returns true if scrolled. */\n scrollUp(n: number): boolean {\n const buf = this.term.buffer.active;\n const maxScroll = buf.baseY;\n const newOffset = Math.min(this.scrollOffset + n, maxScroll);\n if (newOffset === this.scrollOffset) return false;\n this.scrollOffset = newOffset;\n this.lastFrame = [];\n this.renderScrolled();\n return true;\n }\n\n /** Scroll down by n lines. Returns true if scrolled. */\n scrollDown(n: number): boolean {\n const newOffset = Math.max(this.scrollOffset - n, 0);\n if (newOffset === this.scrollOffset) return false;\n this.scrollOffset = newOffset;\n this.lastFrame = [];\n if (this.scrollOffset === 0) {\n return true;\n }\n this.renderScrolled();\n return true;\n }\n\n /** Move cursor up in scroll mode. Scrolls viewport if needed. */\n moveCursorUp(n: number): void {\n this.scrollCursorY -= n;\n if (this.scrollCursorY < 0) {\n const overflow = -this.scrollCursorY;\n this.scrollUp(overflow);\n this.scrollCursorY = 0;\n }\n const lineLen = this.getScrollLineLength(this.scrollCursorY);\n this.scrollCursorX = Math.min(this.scrollDesiredX, Math.max(lineLen - 1, 0));\n this.renderScrolled();\n }\n\n /** Move cursor left. Wraps to end of previous line at col 0. */\n moveCursorLeft(n: number): void {\n for (let i = 0; i < n; i++) {\n if (this.scrollCursorX > 0) {\n this.scrollCursorX--;\n } else if (this.scrollCursorY > 0 || this.scrollOffset > 0) {\n this.scrollCursorY--;\n if (this.scrollCursorY < 0) {\n this.scrollOffset = Math.min(this.scrollOffset + 1, this.term.buffer.active.baseY);\n this.scrollCursorY = 0;\n this.lastFrame = [];\n }\n const lineLen = this.getScrollLineLength(this.scrollCursorY);\n this.scrollCursorX = Math.max(lineLen - 1, 0);\n }\n }\n this.scrollDesiredX = this.scrollCursorX;\n this.renderScrolled();\n }\n\n /** Move cursor right. Wraps to start of next line at end of content. */\n moveCursorRight(n: number): void {\n for (let i = 0; i < n; i++) {\n const lineLen = this.getScrollLineLength(this.scrollCursorY);\n if (this.scrollCursorX < lineLen - 1) {\n this.scrollCursorX++;\n } else {\n this.scrollCursorY++;\n if (this.scrollCursorY >= this.rows) {\n const overflow = this.scrollCursorY - this.rows + 1;\n this.scrollOffset = Math.max(this.scrollOffset - overflow, 0);\n this.scrollCursorY = this.rows - 1;\n this.lastFrame = [];\n }\n this.scrollCursorX = 0;\n }\n }\n this.scrollDesiredX = this.scrollCursorX;\n this.renderScrolled();\n }\n\n /** Move cursor down in scroll mode. Scrolls viewport if needed. */\n moveCursorDown(n: number): void {\n this.scrollCursorY += n;\n if (this.scrollCursorY >= this.rows) {\n const overflow = this.scrollCursorY - this.rows + 1;\n this.scrollDown(overflow);\n this.scrollCursorY = this.rows - 1;\n }\n const lineLen = this.getScrollLineLength(this.scrollCursorY);\n this.scrollCursorX = Math.min(this.scrollDesiredX, Math.max(lineLen - 1, 0));\n this.renderScrolled();\n }\n\n /** Get content length of a viewport row in scroll mode. */\n private getScrollLineLength(viewportY: number): number {\n const buf = this.term.buffer.active;\n const viewStart = buf.baseY - this.scrollOffset;\n const line = buf.getLine(viewStart + viewportY);\n if (!line) return 0;\n return line.translateToString(true).length;\n }\n\n /** Get text content of a viewport row in scroll mode. */\n private getScrollLineText(viewportY: number): string {\n const buf = this.term.buffer.active;\n const viewStart = buf.baseY - this.scrollOffset;\n const line = buf.getLine(viewStart + viewportY);\n if (!line) return '';\n return line.translateToString(true);\n }\n\n private static readonly WORD_SEPARATORS = new Set(\n ' \\t`~!@#$%^&*()-=+[{]}\\\\|;:\\'\",.<>/?'.split(''),\n );\n\n /** Move cursor to the start of the previous word (vim b / Alt+Left). */\n moveCursorPrevWord(): void {\n const seps = ScreenRenderer.WORD_SEPARATORS;\n let x = this.scrollCursorX;\n let y = this.scrollCursorY;\n let text = this.getScrollLineText(y);\n\n x--;\n if (x < 0) {\n if (y > 0 || this.scrollOffset > 0) {\n y--;\n if (y < 0) {\n this.scrollUp(1);\n y = 0;\n }\n text = this.getScrollLineText(y);\n x = Math.max(text.length - 1, 0);\n } else {\n x = 0;\n }\n }\n\n while (x >= 0 && seps.has(text[x] ?? ' ')) {\n x--;\n if (x < 0) {\n if (y > 0 || this.scrollOffset > 0) {\n y--;\n if (y < 0) {\n this.scrollUp(1);\n y = 0;\n }\n text = this.getScrollLineText(y);\n x = Math.max(text.length - 1, 0);\n } else {\n x = 0;\n break;\n }\n }\n }\n\n while (x > 0 && !seps.has(text[x - 1] ?? ' ')) {\n x--;\n }\n\n this.scrollCursorX = Math.max(x, 0);\n this.scrollCursorY = y;\n this.scrollDesiredX = this.scrollCursorX;\n this.renderScrolled();\n }\n\n /** Move cursor to the start of the next word (vim w / Alt+Right). */\n moveCursorNextWord(): void {\n const seps = ScreenRenderer.WORD_SEPARATORS;\n let x = this.scrollCursorX;\n let y = this.scrollCursorY;\n let text = this.getScrollLineText(y);\n const maxY = this.rows - 1;\n\n while (x < text.length && !seps.has(text[x] ?? ' ')) {\n x++;\n }\n\n while (true) {\n if (x < text.length && !seps.has(text[x] ?? ' ')) break;\n if (x >= text.length) {\n y++;\n if (y > maxY) {\n this.scrollDown(1);\n y = maxY;\n }\n text = this.getScrollLineText(y);\n x = 0;\n if (text.length === 0) continue;\n if (!seps.has(text[0] ?? ' ')) break;\n }\n x++;\n }\n\n this.scrollCursorX = Math.min(x, Math.max(text.length - 1, 0));\n this.scrollCursorY = y;\n this.scrollDesiredX = this.scrollCursorX;\n this.renderScrolled();\n }\n\n /** Whether there's content in scrollback to view. */\n hasScrollback(): boolean {\n return this.term.buffer.active.baseY > 0;\n }\n\n /** Whether we're scrolled back (not showing live content). */\n get isScrolledBack(): boolean {\n return this.scrollOffset > 0;\n }\n\n /** Render from scrollback buffer at current offset. */\n private renderScrolled(): void {\n const buf = this.term.buffer.active;\n const viewStart = buf.baseY - this.scrollOffset;\n const totalLines = buf.baseY + this.rows;\n const currentLine = viewStart + this.scrollCursorY + 1;\n let output = '';\n\n const pad = ' '.repeat(this.cols);\n for (let y = 0; y < this.rows; y++) {\n const line = buf.getLine(viewStart + y);\n const rendered = line ? this.renderLine(line) : '';\n output += `\\x1b[${y + 1};1H${pad}\\x1b[${y + 1};1H${rendered}`;\n }\n\n const pos = `${currentLine}/${totalLines}`;\n const sep = '\\u2500'.repeat(this.cols);\n output += `\\x1b[${this.rows + 1};1H${pad}\\x1b[${this.rows + 1};1H\\x1b[90m${sep}\\x1b[0m`;\n output += `\\x1b[${this.rows + 2};1H${pad}\\x1b[${this.rows + 2};1H\\x1b[7m [\\u2191\\u2193/hjkl] move [w/b] word [0/$] line [g/G] top/end [q/Esc] exit \\x1b[0m`;\n output += `\\x1b[${this.rows + 2};${this.cols - pos.length - 1}H\\x1b[43;30m ${pos} \\x1b[0m`;\n output += `\\x1b[${this.scrollCursorY + 1};${this.scrollCursorX + 1}H\\x1b[?25h`;\n process.stdout.write(output);\n }\n\n /** Force full redraw on next render (e.g. after sidebar toggle). */\n invalidate(): void {\n this.lastFrame = [];\n let clear = '';\n for (let y = 0; y < this.rows; y++) {\n clear += `\\x1b[${y + 1};1H\\x1b[2K`;\n }\n process.stdout.write(clear);\n }\n\n resize(cols: number, rows: number): void {\n this.cols = cols;\n this.rows = rows;\n this.term.resize(cols, rows);\n this.lastFrame = [];\n }\n\n dispose(): void {\n if (this.overlayTimer) clearImmediate(this.overlayTimer);\n if (this.renderTimer) clearTimeout(this.renderTimer);\n process.stdout.write('\\x1b[?25h');\n this.term.dispose();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequire as __createRequire } from 'module'; const require = __createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/pty/terminal.ts
|
|
4
|
+
function isTerminal() {
|
|
5
|
+
return process.stdin.isTTY === true;
|
|
6
|
+
}
|
|
7
|
+
function enableRawMode() {
|
|
8
|
+
const wasRaw = process.stdin.isRaw;
|
|
9
|
+
process.stdin.setRawMode(true);
|
|
10
|
+
return () => {
|
|
11
|
+
process.stdin.setRawMode(wasRaw ?? false);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function getSize() {
|
|
15
|
+
const cols = process.stdout.columns ?? 80;
|
|
16
|
+
const rows = process.stdout.rows ?? 24;
|
|
17
|
+
return { cols, rows };
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
enableRawMode,
|
|
21
|
+
getSize,
|
|
22
|
+
isTerminal
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/pty/terminal.ts"],"sourcesContent":["/**\n * Terminal helpers for raw mode, size detection, etc.\n * Node.js equivalents of Go's golang.org/x/term functions.\n */\n\nexport function isTerminal(): boolean {\n return process.stdin.isTTY === true;\n}\n\nexport function enableRawMode(): () => void {\n const wasRaw = process.stdin.isRaw;\n process.stdin.setRawMode(true);\n return () => {\n process.stdin.setRawMode(wasRaw ?? false);\n };\n}\n\nexport function getSize(): { cols: number; rows: number } {\n const cols = process.stdout.columns ?? 80;\n const rows = process.stdout.rows ?? 24;\n return { cols, rows };\n}\n"],"mappings":";;;AAKO,SAAS,aAAsB;AACpC,SAAO,QAAQ,MAAM,UAAU;AACjC;AAEO,SAAS,gBAA4B;AAC1C,QAAM,SAAS,QAAQ,MAAM;AAC7B,UAAQ,MAAM,WAAW,IAAI;AAC7B,SAAO,MAAM;AACX,YAAQ,MAAM,WAAW,UAAU,KAAK;AAAA,EAC1C;AACF;AAEO,SAAS,UAA0C;AACxD,QAAM,OAAO,QAAQ,OAAO,WAAW;AACvC,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,SAAO,EAAE,MAAM,KAAK;AACtB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@heliohq/helio",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Helio CLI - human-facing entry for Helio.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
7
|
+
"homepage": "https://helio.im",
|
|
8
|
+
"bin": {
|
|
9
|
+
"helio": "./bin/helio"
|
|
10
|
+
},
|
|
11
|
+
"files": ["bin/", "dist/"],
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=22"
|
|
17
|
+
},
|
|
18
|
+
"oclif": {
|
|
19
|
+
"commands": "./dist/commands",
|
|
20
|
+
"bin": "helio",
|
|
21
|
+
"topicSeparator": " ",
|
|
22
|
+
"helpClass": "./dist/help",
|
|
23
|
+
"plugins": []
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsc --build --watch",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"lint": "eslint src/",
|
|
32
|
+
"prepublishOnly": "pnpm build && pnpm test"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@bufbuild/protobuf": "^2.11.0",
|
|
36
|
+
"@clack/prompts": "^0.9.1",
|
|
37
|
+
"@heliohq/helio-sdk": "file:../../helio-sdk",
|
|
38
|
+
"@heliohq/shared": "file:../shared",
|
|
39
|
+
"@oclif/core": "^4.3.0",
|
|
40
|
+
"@xterm/headless": "^5.5.0",
|
|
41
|
+
"open": "^10.1.0",
|
|
42
|
+
"qrcode-terminal": "^0.12.0",
|
|
43
|
+
"yaml": "^2.7.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@eslint/js": "^10.0.1",
|
|
47
|
+
"@types/node": "^22.13.0",
|
|
48
|
+
"eslint": "^9.39.4",
|
|
49
|
+
"prettier": "^3.5.0",
|
|
50
|
+
"tsup": "^8.5.1",
|
|
51
|
+
"typescript": "^5.8.0",
|
|
52
|
+
"typescript-eslint": "^8.58.0",
|
|
53
|
+
"vitest": "^3.1.0"
|
|
54
|
+
}
|
|
55
|
+
}
|