npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tasklens/vue

v0.1.0

Published

TaskLens Vue 3 组件层:AgentTaskPanel / ApprovalGate / RunLog / RunReplay + useRun / useRunStream(零运行时依赖,不含 Vue)

Downloads

14

Readme

@tasklens/vue

TaskLens 的 Vue 3 组件层。 把 Agent 的每一步、每次工具调用、每次人工审批,变成用户看得懂的界面。

  • Vue 原生优先:<script setup lang="ts"> 写法,完整 props / slots / emits 类型推导
  • 零运行时依赖(除 @tasklens/protocol);vue 是 peerDependency,不会打进产物
  • SSR 安全(Nuxt 3 可用),首屏可用 @tasklens/server 的快照
  • 主题走 CSS 变量,不强制 Tailwind
pnpm add @tasklens/vue @tasklens/protocol
# 想用 createRun() 埋点再加:pnpm add @tasklens/core
// 样式只需引入一次
import '@tasklens/vue/style.css'

三档接入(换档只换数据来源,不换界面)

档 1 · Agent 跑在浏览器里(零后端)

<script setup lang="ts">
import { createRun } from '@tasklens/core'
import { AgentTaskPanel } from '@tasklens/vue'

const run = createRun({ goal: '给 20 位未激活用户发激活邮件' })
// run.plan() / run.stepStart() / run.tool() / run.requestApproval() …
</script>

<template>
  <AgentTaskPanel :run="run" />
</template>

档 2 · Agent 跑在 Node 里,浏览器通过 SSE 观看

<AgentTaskPanel
  :stream-url="`/api/tasklens/runs/${runId}/stream`"
  :decide="submitDecision"
  :retry-step="retryStep"
/>

断线重连、Last-Event-ID 续传、按 id 去重、乱序纠正都在组件内部完成 —— 你只给一个 URL 和两个回调。

档 0 · 粘一份 JSON 就出面板(零后端、零 key、零规范)

<script setup lang="ts">
import { RunReplay } from '@tasklens/vue'

// 手写的、别人导出的、缺字段的 —— 直接丢进去就行
const events = [
  { type: 'run:start', goal: '整理本周销售线索' },
  { type: 'plan', steps: ['抓取线索', '去重打分', '生成报告'] },
  { type: 'step:start', stepId: 'step_1' },
  { type: 'tool:call', stepId: 'step_1', name: 'fetch_leads', args: { range: '7d' } },
  { type: 'tool:result', ok: true, result: { count: 128 }, ms: 1840 },
  { type: 'step:done', stepId: 'step_1' },
]
</script>

<template>
  <RunReplay :events="events" auto-play :speed="2" />
</template>

这是整个设计里最重要的一条产品判断:手里只有一段 Agent 日志的人, 应该立刻看到完整面板,而不是先被告知"请先读懂信封规范"。

RunReplay 的 events 故意声明为 unknown:档 0 的数据类型在编译期不可能准确。 内部走 toRunEvents() 补全信封与无歧义载荷 (tool_call → tool:call、steps 传字符串数组、tool:result 与最近的调用配对、 缺 id/seq/at 自动生成、缺 run:start 自动补一条……)。

但改了什么一定会告诉你 —— 面板上方会出现一条提示(下例是真实渲染结果):

! 已自动补全 6 行                                    [查看改动]
  envelope-filled  6 处  第 1–6 行   id / runId / seq / at / schemaVersion / callId
  plan-strings     1 处  第 2 行     steps
  call-id-filled   1 处  第 4 行     callId
  call-id-paired   1 处  第 5 行     callId

列表按 code 归并(不是逐条展开):档 0 的常态是"每一行都要补信封", 逐条列会变成几千行噪音,归并后每个 code 只占一行。

静默补全是最危险的一种"好用":面板看着正常,用户就永远不知道自己的日志本来有问题。 不需要这个提示时,自己先调 toRunEvents() 把 events 传进来即可(已经是合法事件就不提示)。

修不好的行不会消失:它们被降级成"格式异常事件"折叠在时间线末尾, 原始 JSON 一眼可查 —— 不丢、不猜、不白屏。

组件

| 组件 | 作用 | | --- | --- | | AgentTaskPanel | 主面板:目标 + 状态 + 时间线 + 步骤 + 工具调用 + 底部统计 | | ApprovalGate | 审批卡片:摘要 / 结构化预览 / 风险等级 / 批准 · 修改后批准 · 拒绝 | | RunLog | 可折叠原始日志(入参、出参、耗时、token、错误原文) | | RunReplay | 事件数组回放器(play / pause / restart / stepForward / seek,支持 v-model:progress) | | 展示组件 | PanelHeader PanelFooter ApprovalBanner TaskTimeline StepItem ToolCallItem PreviewBlock JsonBlock StatusBadge RiskBadge EmptyState UnknownEventItem —— 都可单独使用 |

AgentTaskPanel 主要 props

| prop | 说明 | | --- | --- | | run / events / streamUrl | 三选一,对应上面三档 | | decide / retryStep | 决策与重试回传通道;不传 = 只读 | | readonly | 显式强制只读 | | renderers | 自定义工具渲染器(按工具名注册) | | title / locale / theme / colorScheme | 展示层 | | collapsible / defaultCollapsed / showFooter | 形态 | | virtualThreshold | 超过该条数启用虚拟滚动 | | by | 决策人标识(随决策回传,用于审计) | | streamOptions | SSE 调优(退避序列、注入 EventSource 工厂) |

Slots:header-actions / step-pending / footer-actions。 Emits:decide / retry-step / export / connection-change / update:collapsed。 Expose:state / events / focusApproval(id) / reconnect()。

id 在 Vue 3.4 + SSR 下建议显式传入(面板 DOM id 前缀;自动计数器的服务端与客户端取值可能不一致)。

审批组件的只读语义

ApprovalGate 的 decide 不传即只读 —— 不会发出任何请求,按钮不会假装成功。 接入方后端无法闭环时请显式保持只读:点了没反应,比功能少更伤信任。

主题

/* 放在 @tasklens/vue/style.css 之后 */
:root {
  --tl-color-primary: oklch(0.52 0.19 320);
  --tl-color-bg: #fafafa;
  --tl-radius-md: 10px;
}

源码分发(不装包)

不想引依赖?npx tasklens add agent-task-panel 把 .vue 源码直接拷进你的仓库,之后随你怎么改。 详见 tasklens CLI。

许可

MIT © 李学丹 · 仓库与完整文档