本文へ移動
cccskills
無料GitHub で公開日本語紹介

agent-work

エージェントが作成・更新した課題やファイルなどをWorkとして登録し、重複を防ぎながらカード表示や履歴、CLI結果の検出につなげる仕組みを扱います。

原文原文の説明を見る

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

lobehub/lobehubスター 83,506(GitHub 83,506 + cccskills 0)

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • エージェントの成果をカードで記録したいとき
  • CLIの作成・編集結果を検出したいとき
  • Workの重複登録を防ぎたいとき
  • 共有会話のアクセス範囲を設計したいとき

日本語での紹介

できること

エージェントが作成・編集したPR、課題、文書、ファイルなどをWorkとして記録し、会話内のカードや履歴につなぐ仕組みを扱います。同じリソースは種類とIDで識別し、登録イベントはツール呼び出しIDで重複を防ぎます。GitHubやLinearなどのスキル結果を正規化する方法、CLI実行のコマンドと出力から作成・編集結果を検出するスキャナー、ファイル・タスクの登録経路、カード表示位置の付与も説明します。共有会話では所有者だけでなく共有範囲を含むアクセス境界を設け、対応していない古いクライアントに新しいWork種別を返さないための仕組みも扱います。

こんなときに便利

エージェントの操作結果を後から一覧・追跡できるようにしたい開発者向けです。新しいツール提供元やCLIスキャナー、カード種別を追加するとき、重複登録や共有範囲、削除済みリソースの表示を検討する場面で役立ちます。

使い方の例

  • 「GitHubの作成結果をWorkとして登録する経路を追加してください」
  • 「CLI出力からPR作成を検出するスキャナーの構成を確認してください」
  • 「共有会話でWorkの読み書きを分離する方法を整理してください」

注意点

特記事項はありません。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

資料チェック

SKILL.md の記述から、注意が要る操作と導入の前提を AI が確認しました。点数は実際に動かした結果(実行検証)だけで付けています。

安全面送信・削除・コマンド実行などの扱いが明示されているか
B一部不足共有アクセスの境界やfail closedは明示されるが、CLI結果の登録も行う。
導入のしやすさ必要なツールや API キーが少ないか、書かれているか
B一部不足GitHub・LinearやDBモデルなどの前提は示されるが導入手順はない。

点数には入れていません。 2026年10月26日 時点で AI(OpenAI Codex)が判定しました。目安なので、入れる前に原文も確認してください。

評価が違うと思ったら、見直しを依頼する

どの項目が、なぜ違うと思うかを書いてください。ログインは不要です。内容を SKILL.md と照らし合わせて評価を作り直し、この欄に反映します。

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

含まれるファイル(1)

  • SKILL.md15.8 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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

無料概要あり

実際の製品を操作して、利用者が確認できる動作証拠を集め、検証計画に沿った受け入れレポートとして公開するスキルです。

  • 変更後の製品動作を実地で検証したいとき
  • 画面キャプチャなどの証拠を集めたいとき
  • 検証計画とレポートを作成したいとき
lobehub/lobehub8.4万2026年10月26日 更新

add-model-provider

無料概要あり

LobeHubにAIモデルプロバイダーを追加し、実行時連携からモデル表示、設定、ブランド表記、文書化、動作確認まで進めるスキルです。

  • 新しいAIモデルプロバイダーを追加したいとき
  • プロバイダーの設定手順や説明文を更新したいとき
  • 既存プロバイダーへのモデル追加要件を見極めたいとき
lobehub/lobehub8.4万2026年10月26日 更新

add-setting-env

無料概要あり

ユーザー設定の初期値をサーバー側の環境変数で切り替えるため、型定義や設定の組み立て、ユーザーストアへの反映、環境変数の例と説明書きを追加する手順です。

  • 設定の初期値を環境変数で変えたいとき
  • 設定項目をサーバー設定に追加したいとき
  • 環境変数の例と説明を更新したいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-runtime-hooks

無料概要あり

エージェント実行中の各段階をフックで監視し、ツール呼び出しの模擬・制御や人の承認、圧縮、サブエージェント処理に介入する仕組みを扱います。

  • エージェントの実行状況を記録したいとき
  • ツール結果をテスト用に模擬したいとき
  • Webhookでツール実行を許可・拒否したいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-signal

無料概要あり

イベントを起点にエージェントのバックグラウンド処理を組み立て、ソース・シグナル・アクション・ポリシーの役割分担や非同期連携を実装するためのスキルです。

  • イベント起点の処理を追加したいとき
  • バックグラウンド処理を非同期化したいとき
  • 重複実行を防ぐ仕組みを整えたいとき
lobehub/lobehub8.4万2026年10月26日 更新

agent-testing-bot

無料概要あり

DiscordやSlackなどの実際のチャットアプリでボットにメッセージを送り、応答を画面で確認する受け入れテストを行うスキルです。

  • 実際のDiscordでボット応答を確かめたいとき
  • SlackやTelegramの会話経路をテストしたいとき
  • macOSアプリ上の操作結果を画面で記録したいとき
lobehub/lobehub8.4万2026年10月26日 更新

lobehub のスキルをすべて見る

このスキルの問題を報告する