跳到正文
cccskills
免费在 GitHub 公开中文介绍

agent-work

本指南介绍如何将代理创建或编辑的资源登记为可追溯的 Work 记录和卡片,涵盖版本历史、去重、技能提供方结果、命令行扫描、文件与任务登记,以及共享会话的访问规则。

原文查看原文说明

Use for the Agent Work output registry: registration, deduplication, cards, skill providers, CLI scanners and Work types.

lobehub/lobehub星标 83,502(GitHub 83,502 + cccskills 0)

实测评分 未实测

查看安装方法

适用场景

  • 将代理结果记录为会话卡片
  • 检测命令行创建或编辑的资源
  • 避免重复登记 Work
  • 设计共享会话的访问范围

中文介绍

功能

本指南介绍 Work 登记机制,用于记录代理创建或修改的资源。Work 可以代表 GitHub 拉取请求或议题、Linear 议题、文档、文件或任务。它会显示在产生该结果的助手消息下方;后续操作会为同一资源记录增加版本。

资源身份和去重规则包括 (resourceType, resourceId) 组合,以及用于登记事件去重的唯一 (workId, toolCallId)。指南还说明如何规范化 GitHub、Linear 等提供方返回的结构化结果,如何扫描已保存的命令行命令及其输出以识别创建或编辑的资源,以及如何登记文件、任务和文档。材料也介绍共享会话的访问范围,以及如何通过兼容性门控避免向不支持的客户端发送较新的 Work 类型。

适用场景

添加工具提供方、命令行扫描器或 Work 卡片类型时,可以参考本指南。它也适用于希望之后查看代理操作结果的开发者,可帮助考虑重复登记、共享会话访问权限,以及已删除资源在不同视图中的显示方式。

使用示例

  • “请添加将 GitHub 创建结果登记为 Work 的路径。”
  • “请检查从命令行输出识别拉取请求的扫描器。”
  • “请说明如何隔离共享会话中 Work 的读取和写入。”

注意事项

没有特别事项。

本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。

文档检查

AI 根据 SKILL.md 的内容检查了需要注意的操作和使用前提。评分只依据实际运行的结果(实测对比)。

安全性发送数据、删除文件、执行命令等是否有说明
B部分不足说明共享访问隔离和失败关闭,但也会登记命令行结果。
安装难易度所需工具和 API 密钥是否少且有说明
B部分不足依赖提供方集成和数据库模型,但未提供安装步骤。

不计入评分。 由 AI(OpenAI Codex)于 2026年10月26日 评估。仅供参考,安装前请同时查看原文。

如果您认为评估有误,请申请复核

请写明哪一项有误以及原因。无需登录。我们会对照 SKILL.md 重新评估,并在此处更新结果。

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

包含的文件(1)

  • SKILL.md15.8 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Agent Works

A Work is a durable record of something an agent produced or touched — a GitHub PR/issue, a Linear issue, an entity file (pptx/xlsx/docx/pdf), a document, a task. Works render as cards under the assistant message that produced them and accumulate versions across operations, so the same PR edited twice shows one card with history.

Two tables (packages/database/src/schemas/work.ts):

  • works — one row per resource. Identity/dedup key: (resourceType, resourceId) within the user/workspace scope and the share scope (see below). currentVersionId soft-references the latest version.
  • work_versions — one row per registration event. Dedup: unique (workId, toolCallId), so a retried registration with the same real tool call id is a no-op. Versions carry provenance (source message, producing tool) and operation-level cumulativeCost / cumulativeUsage.

Type registry

packages/database/src/models/work/registry.ts is the single registry of Work types (document / external / file / task): WORK_TYPE_ADAPTERS is satisfies Record<WorkType, WorkTypeAdapter>, so a type added to @lobechat/types without an adapter is a compile error.

Read-path compatibility gate: OPT_IN_WORK_TYPES (currently {'file'}) hides newer types from clients that did not opt in (includeFileWorks). Released Electron clients lag by weeks and crash on unknown type descriptors (descriptor.getIcon on undefined), so a request without the opt-in receives exactly the pre-file set. Any NEW Work type must ship behind the same kind of opt-in.

The gate has two kinds of emission points, and both must honor the client's declaration:

  • Pulled reads (message.getMessages, work.* lists, shareChat.getMessages): the client service passes includeFileWorks: true on the request.
  • Pushed payloads (the uiMessages snapshots and message_patch revisions built by AgentRuntimeService.queryUiMessages): no request carries the opt-in, so the starting client declares the file_works stream feature and the run stores it as state.host.acceptsFileWorks; approval continuations and group members inherit it. A pushed path that skips this check drops the card until the user reloads the page.

Access scope (Agent Share visitors)

A share visitor's run executes as the creator, so owner scope alone cannot separate its Works. Every Work read and write takes a WorkAccessScope (packages/types/src/work.ts): ordinary sees only rows without share provenance; agentShare sees only rows stamped in works.metadata.agentShare with exactly that share/topic/visitor.

  • workOwnership applies the scope on every path, so a new query built on it inherits the fence. Do not query works without it.
  • Any registration path reachable from a visitor run (skill results, completion scans, anchor stamping) must build its WorkModel with the run's scope via resolveRunWorkAccessScope. A visitor run without a topic yields null: skip registration (fail closed) rather than registering unscoped into the creator's lists.
  • The resource unique indexes include the visitor topic id, so the creator and each visitor topic keep separate rows for the same external resource.
  • Visitor read payloads drop the creator's userId / workspaceId and gate spend on showModelInfo (toVisitorMessage).

Orphaned Works (backing resource deleted)

works.resourceId has no FK, and deleting a document, task, or file never cascades into its Work (LOBE-13917). Deleting the Work would also drop its version history and its project and goal references. Each read surface handles orphans itself:

  • Resource-page galleries hide orphans. These are listByWorkspace surfaces: /resource, /resource/works, and the project dashboard. They filter orphans out with resourceLiveFilter (packages/database/src/models/work/internal.ts). A task or document must still exist and not be trashed. A file Work's current-version fileId must point to a files row that exists and is not trashed. Restoring the resource brings the card back. Any new gallery-style Work list must apply the same filter.
  • Conversation surfaces keep the card. These are listByConversation and the cards under messages; the conversation did produce the Work. resourceDeleted drives a click-time prompt (useResourceDeletedPrompt) that lets the user remove it.

Registration write paths

Four write paths, two timing classes:

PathWhenWhere
Skill structured tools + sandbox runCommand (github / linear)at tool executionWorkModel.handleSkillToolResult, called from server toolExecution and the client executor (registerClientWorkFromIntent.ts on the legacy non-gateway runtime)
Shell Work scan (hetero codex/claude-code + device lobe-local-system)at operation completionapps/server/src/services/workRegistration/shellWorkRegistration.ts via registerWorksForOperation
File Work scan (sandbox entity files)at operation completionapps/server/src/services/workRegistration/registerWorksForOperation.ts
Task / document worksat creation by their owning featureWorkModel.registerTask / registerDocument

Execution-time: skill providers

SKILL_TOOL_RESULT_NORMALIZERS in packages/database/src/models/work/index.ts maps WorkSkillProvider (github, linear; vocabulary in packages/types/src/work.ts) to a normalizer. Both satisfies a Record<WorkSkillProvider, …>, so provider list and normalizer map cannot drift.

A normalizer turns one tool result into ExternalToolWorkOperation | null — null means "not Work-worthy", which is the common case and never an error.

Completion-time: the shell Work scan framework

Heterogeneous CLI agents (codex, claude-code) and the device lobe-local-system tool run CLIs like gh through their own shell surfaces, which never pass the skill-tool hook. registerWorksForOperation recovers their Works at completion from the persisted command text + stdout. Layering:

registerWorksForOperation (registerWorksForOperation.ts)
  ├─ collectOperationRecords         one pass over the operation tree, shared by both scans
  ├─ registerShellWorks              (shellWorkRegistration.ts — the ENGINE, command-agnostic)
  │    ├─ SHELL_COMMAND_SOURCES      identifier→apiName scoping of shell surfaces
  │    ├─ success gate               plugin error / state.success===false / state.error → skip
  │    ├─ extract {command, exitCode, output}   from arguments / state / message content
  │    └─ shellWorkScanners/         one file per CLI family
  │         ├─ types.ts              ShellWorkScanner = { matches, name, register }
  │         ├─ github.ts             matches: includes('gh ') → workModel.registerShellGithubResult
  │         └─ index.ts              SHELL_WORK_SCANNERS registry
  └─ file Work scan                  aggregate per-path fold + sandbox export pipeline (NOT a scanner)

Command parsing is split the same way: packages/database/src/models/work/shellCommandParsing.ts holds the command-agnostic layer (POSIX-ish tokenizer, control-operator segmenting, codex /bin/zsh -lc wrapper expansion — parseShellCommandSegments), while githubToolResult.ts holds only the gh-specific parseGhSegment + field mapping.

Cost granularity: execution-time vs completion-time

cumulativeCost / cumulativeUsage are per-version SNAPSHOTS ("spend up to this version"), never deltas — summing them across versions double-counts on every path.

  • Execution-time registrations (skill providers) snapshot right after UsageCounter.accumulateTool for that call, so create + edit + edit within one run carries an INCREASING series (e.g. $0.30 → $0.70 → $1.20) and step deltas are recoverable.
  • Completion-time registrations (shell scan, file scan) attach one OPERATION-LEVEL figure — the completing run's terminal total plus terminal child-op totals — to EVERY version registered that round: the scan only has persisted command text + stdout, no per-call intermediate snapshots (hetero CLI usage is aggregated per step by the trace recorder, not per tool call). The same create + edit + edit therefore yields three versions all carrying $1.20, indistinguishable per step.
  • Cross-operation is independent: a later run editing the same resource appends a version with THAT run's total only.

Why file Works are not a scanner: their unit is a file path folded across ALL records (multi-edit merge, renames, last-edit provenance), the registration is a heavy IO pipeline (idempotency probe → sandbox export → upload → version → redeploy, bounded concurrency), hetero records are deliberately EXCLUDED (the file lives on the executing device, not the exportable sandbox), and the version key is the synthetic op:${operationId} instead of a real toolCallId. Shoehorning that into ShellWorkScanner would break the interface. If a second aggregate-style scan ever appears, extract an aggregate layer then.

Display anchor & completion marker

A Works card renders only under an assistant message stamped with metadata.work.rootOperationId (the "anchor"). Who stamps it:

  • In-process runs: callLlmFinalizer stamps the round's final assistant message.
  • Hetero runs never pass that executor, so registerWorksForOperation stamps the anchor itself when the shell scan registered anything — using the completion's assistantMessageId, falling back to the parentId of the last registered tool message (hetero single-step runs persist no final-assistant pointer at all; see heteroFinish).

The whole scan returns {attempted, failed} and the completion backstop (CompletionLifecycle) writes its idempotency marker only when failed === 0. Anything that must be retried — a thrown registration, a {success: false} anchor stamp, an unresolvable anchor — counts into failed. Registration is retry-safe end to end (probe short-circuits, (workId, toolCallId) guard backs it up), so counting a failure is always the right move.

Key decisions (from the Work PRs)

  • Only successful create/edit results become Works (LOBE-10967). Read-only queries, comments, merges/closes, and branch/repo operations are excluded — gh pr view printing an entity URL must NOT register.
  • owner/repo#number is the canonical github identity, not node_id: the gh CLI surface never returns node_id, and the same entity touched via REST tools and CLI must land on one Work row.
  • stdout is the source of truth for identity on the CLI path (gh … create/edit prints the entity URL); the command's edit target is the fallback. The LAST gh create/edit segment of a chained command owns the trailing URL.
  • Persisted URLs are http(s)-allowlisted (sanitizeExternalUrl): gh stdout / tool results are member-controlled and the URL reaches shell.openExternal on desktop.
  • The tokenizer is deliberately hand-rolled (no shell-quote dep): a real parser would expand what must stay literal, and the worst failure mode is skipping a bookkeeping registration.
  • Error-terminated runs skip the completion scan (same success gate as file Works): a gh create that succeeds before a later terminal failure registers no Work that round. Accepted — bounded cost, missing card only.
  • Hetero Works register after the terminal snapshot (agent_runtime_end publishes before completeOperation), so a hetero-created card appears on the next refetch, not in the terminal snapshot. Accepted for now.
  • PRs pushed via codex's own GitHub integration are not covered — no shell record exists; text-mention parsing was rejected as too false-positive-prone.

Extension recipes

New skill provider (structured tools), e.g. Notion:

  1. packages/types/src/work.ts — extend WORK_SKILL_PROVIDERS + WORK_PROVIDER_RESOURCE_TYPES (+ resource-type unions).
  2. packages/database/src/models/work/<provider>ToolResult.ts — write the normalizer; mirror linearToolResult.ts.
  3. packages/database/src/models/work/index.ts — add it to SKILL_TOOL_RESULT_NORMALIZERS (the satisfies forces this).
  4. Pick a stable cross-surface resourceId (the github lesson: choose the identity every surface can produce).

New shell CLI scanner, e.g. linear CLI or vercel deploy:

  1. Add a normalizer in packages/database/src/models/work/ reusing parseShellCommandSegments, plus a WorkModel.registerShell<X>Result facade method.
  2. Add apps/server/src/services/workRegistration/shellWorkScanners/<name>.ts with { matches, name, register } — matches stays a cheap substring check.
  3. Append it to SHELL_WORK_SCANNERS in shellWorkScanners/index.ts. The engine needs zero changes.
  4. Pin the parsing edge cases in packages/database/src/models/work/__tests__/ (wrapper unwrap, chained segments, failed/read-only commands must not register).

New Work type (new card kind):

  1. @lobechat/types — extend WorkType and related unions.
  2. packages/database/src/models/work/ — new adapter module + WORK_TYPE_ADAPTERS entry (compile-enforced).
  3. Client — add the type descriptor for the card UI.
  4. Add the type to the read-path opt-in gate (OPT_IN_WORK_TYPES pattern) — released clients throw on unknown types; never ship a new type into the legacy result set.

File map

ConcernPath
Schemapackages/database/src/schemas/work.ts
Type registry + read gatepackages/database/src/models/work/registry.ts
WorkModel facade + provider normalizer mappackages/database/src/models/work/index.ts
gh CLI + structured github normalizerpackages/database/src/models/work/githubToolResult.ts
Command-agnostic shell parsingpackages/database/src/models/work/shellCommandParsing.ts
Completion scan orchestrator (file + shell + anchor)apps/server/src/services/workRegistration/registerWorksForOperation.ts
Shell scan engineapps/server/src/services/workRegistration/shellWorkRegistration.ts
Desktop-local run scan (client-reported)apps/server/src/services/workRegistration/localRunWorkRegistration.ts
Per-CLI scannersapps/server/src/services/workRegistration/shellWorkScanners/
Client (non-gateway) registrationsrc/store/chat/agents/registerClientWorkFromIntent.ts

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

acceptance

免费有简介

通过实际操作产品验证交付内容,记录用户可查看的证据,并发布验收报告。可检查已有验证计划或创建检查项,选择合适的操作界面,并使用 `lh` CLI 发布结果。

  • 实际检查更改后的产品行为
  • 收集截图或其他验证证据
  • 编写验证计划和报告
lobehub/lobehub8.4万2026年10月26日 更新

add-model-provider

免费有简介

本技能指导在 LobeHub 中接入 AI 模型提供商,涵盖运行时、模型信息、设置、品牌展示、文档和验收,并帮助判断新增模型是否需要新的提供商集成。

  • 为 LobeHub 接入新的 AI 模型提供商
  • 更新提供商设置说明或介绍
  • 判断添加模型是否需要新的提供商集成
lobehub/lobehub8.4万2026年10月26日 更新

add-setting-env

免费有简介

本技能指导如何用服务器端环境变量设置用户偏好默认值,涵盖变量校验、服务器配置、写入用户状态,以及更新 `.env.example` 和自托管文档。

  • 通过环境变量设置用户偏好默认值
  • 将设置接入服务器配置和用户状态
  • 更新环境变量示例及文档
lobehub/lobehub8.4万2026年10月26日 更新

agent-runtime-hooks

免费有简介

说明如何在智能体执行步骤、工具调用、人工审批、上下文压缩和子智能体调用时注册钩子。钩子可观察事件、模拟本地工具结果,也可通过 Webhook 按配置策略允许或拒绝工具调用。

  • 记录智能体步骤和错误
  • 测试时模拟工具结果
  • 通过 Webhook 允许或拒绝工具调用
lobehub/lobehub8.4万2026年10月26日 更新

agent-signal

免费有简介

此技能用于为智能体设计事件驱动的后台工作流,划分来源、信号、动作和策略的职责,并处理异步交接、去重、执行范围、完成记录与运行观测。

  • 添加事件触发的后台任务
  • 将工作移出对话请求
  • 防止动作重复执行
lobehub/lobehub8.4万2026年10月26日 更新

agent-testing-bot

免费有简介

本技能在 macOS 桌面聊天应用中测试机器人频道:打开应用、进入频道或联系人、发送消息、等待回复并截图。支持 Discord、Slack、Telegram、微信、飞书和 QQ;iMessage 使用 BlueBubbles 桥接。

  • 检查真实 Discord 频道中的机器人回复
  • 测试 Slack 或 Telegram 的对话流程
  • 记录 macOS 应用中的操作结果
lobehub/lobehub8.4万2026年10月26日 更新

查看 lobehub 的全部技能

报告此技能的问题