メインコンテンツまでスキップ

選択コンテキスト

ユーザーが Zotero でアイテムを選択すると、プラグインは構造化された**選択コンテキスト(SelectionContext)**を構築する。これはユーザーが何を選択したか、および各選択アイテムがどの種別に属するかを記述する。このコンテキストは buildRequest フックの入力基盤として機能する。

選択種別

選択されたアイテム種別の組み合わせに基づき、selectionContext.selectionType は以下のいずれかの値を返す。

種別説明
"parent"すべての選択アイテムが親アイテム(トップレベルアイテム)
"child"すべての選択アイテムが子アイテム(非トップレベルアイテム)
"attachment"すべての選択アイテムが添付ファイル
"note"すべての選択アイテムがノート
"mixed"選択アイテムが複数の種別の混在
"none"アイテムが選択されていない

コンテキストの構造

selectionContext = {
selectionType: "parent", // 選択種別
items: {
parents: [ /* 親アイテムのリスト */ ],
children: [ /* 子アイテムのリスト */ ],
attachments: [ /* 添付ファイルのリスト */ ],
notes: [ /* ノートのリスト */ ],
},
summary: {
parentCount: 2,
childCount: 0,
attachmentCount: 0,
noteCount: 0,
},
warnings: [], // 警告メッセージ
sampledAt: "2026-01-15T...", // コンテキスト作成日時
}

各アイテム種別には豊富なコンテキスト情報が含まれる。

親アイテム(ParentContext)

親アイテムは Zotero ライブラリ内のトップレベルアイテムである(例:学術論文、書籍、ウェブページなど)。各親アイテムコンテキストには以下が含まれる。

{
item: Zotero.Item, // アイテムオブジェクト
id: number, // アイテム ID
title: string, // タイトル
attachments: [ // このアイテムの子添付ファイル
{ type, filePath, mimeType, dateAdded, ... }
],
notes: [ // このアイテムの子ノート
{ id, content, ... }
],
tags: string[], // タグリスト
collections: string[], // 含まれるコレクション
children: [ // その他の子アイテム
{ id, type, ... }
],
}

添付ファイル(AttachmentContext)

添付ファイルはアイテムのファイル添付である(PDF、Markdown など)。各添付ファイルコンテキストには以下が含まれる。

{
item: Zotero.Item, // 添付ファイルアイテムオブジェクト
id: number, // アイテム ID
filePath: string, // ローカルファイルパス
fileName: string, // ファイル名
mimeType: string, // MIME タイプ(例:"application/pdf")
dateAdded: Date, // 追加日
parentItem: { // 所有者の親アイテム
id: number,
key: string,
libraryID: number,
},
tags: string[],
collections: string[],
}

ノート(NoteContext)

{
item: Zotero.Item,
id: number,
content: string, // ノート内容(HTML)
parentItem: { id, key, libraryID },
tags: string[],
}

フックでの選択コンテキストの利用

選択された添付ファイルの取得

export function buildRequest({ selectionContext, runtime }) {
const attachments = selectionContext.items.attachments;

return {
kind: "skillrunner.job.v1",
create: { skill_id: "my-skill" },
input: {
files: attachments.map((attachment) => ({
path: runtime.helpers.getAttachmentFilePath(attachment),
name: runtime.helpers.getAttachmentFileName(attachment),
})),
},
};
}

選択された親アイテムとその子コンテンツの取得

export function buildRequest({ selectionContext, runtime }) {
const parents = selectionContext.items.parents;

for (const parent of parents) {
const title = parent.item.getField("title");
const attachments = parent.attachments; // この親アイテム配下の添付ファイル
const notes = parent.notes; // この親アイテム配下のノート
}

// ...
}

選択種別を確認して動作を決定する

export function preflight({ selectionContext }) {
const { selectionType } = selectionContext;

if (selectionType === "none") {
// アイテムが選択されていない。スキップ
return { kind: "skip", reason: "no selected items" };
}

if (selectionType === "attachment") {
// ユーザーが添付ファイルのみを選択。添付ファイル処理ロジックを使用
} else if (selectionType === "parent") {
// ユーザーが親アイテムのみを選択。最初の該当添付ファイルを展開
}

return { kind: "continue", context: { selectionType } };
}

添付ファイルのフィルタリング

一般的な添付ファイルのフィルタリングには宣言的な validateSelection を使用します:

{
"validateSelection": {
"select": { "policy": "pdf-attachment" },
"require": {
"counts": { "attachments": 1 },
"allowMixed": false
}
}
}

解決済みのユニットに依存するランタイムのみの判断には、preflight でスキップまたは続行します:

export function preflight({ selectionContext, runtime }) {
const { helpers } = runtime;

const hasPdf = selectionContext.items.attachments.some(
a => helpers.isPdfAttachment(a)
);

if (!hasPdf) {
return { kind: "skip", reason: "no PDF attachments" };
}

return { kind: "continue" };
}

アイテム未選択時の Workflow

inputs.unit: "workflow" かつ trigger.requiresSelection: false の場合、Workflow はアイテムを選択せずにトリガーできる。この場合、selectionContext.selectionType"none" になり、items 内のすべての配列が空になる。このモードはグローバル操作の作成(例:「トピック合成の作成」)に適する。

宣言的な選択検証

Workflow がすでに結果を持つアイテムをスキップする、または特定種別の入力をフィルタリングするだけであれば、JavaScript フックを書かずに宣言的な validateSelection フィールドを使用できる。

{
"validateSelection": {
"select": { "policy": "literature-source" },
"exclude": [
{ "kind": "generated-notes-all", "noteKinds": ["digest"] }
]
}
}

完全なドキュメントはマニフェストの作成を参照。

選択のガイド: 可能な限り宣言的な validateSelection を使用すること — JavaScript ゼロ、メンテナンスゼロで済む。複雑な選択ロジックは buildRequest フックで実装できる。

次のステップ