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

context-awareness

画面遷移や選択中の項目をエージェントに伝え、表示内容に応じた操作や案内を実装・調整するためのスキルです。

原文原文の説明を見る

How the agent knows what the user is looking at. Use when exposing UI state to the agent, implementing view-screen or navigate actions, wiring navigation state, or debugging agent context issues.

BuilderIO/agent-nativeスター 7,522(GitHub 7,522 + cccskills 0)

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • 現在の画面をエージェントに伝えたいとき
  • 画面遷移コマンドを実装したいとき
  • 選択状態の同期を調べたいとき

日本語での紹介

できること

アプリの画面状態をエージェントへ伝える仕組みを設計します。画面遷移ごとにビュー名や選択中のIDなどを記録し、エージェントが現在の画面を把握してから操作する流れを説明します。URL上の検索条件、テキストなどの選択状態、画面の詳細を返すview-screen、画面を移動させるnavigateの連携も扱います。

こんなときに便利

エージェントに「どの項目ですか」と毎回聞かせず、利用者が開いているメールや選択範囲に沿って操作させたいときに役立ちます。新しい画面を追加した際の状態同期や、タブ間で選択がずれる問題の調査にも向いています。

使い方の例

  • 「現在の画面と選択状態をエージェントに渡してください」
  • 「このアプリで使えるnavigateの処理を実装してください」
  • 「エージェントが古い画面情報を使う原因を調べてください」

注意点

タブ単位の同期にはフレームワークが提供するタブIDを使います。ナビゲーション状態には大きなファイルや画面データを保存せず、IDや意味のある状態に限ります。共有可能な検索条件はURLクエリに保持します。

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

含まれるファイル(1)

  • SKILL.md10.8 KB

SKILL.md(原文)

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

Context Awareness

Rule

The agent must always know what the user is currently viewing. The UI writes navigation state on every route change. The agent reads it before acting.

Why

Without context awareness, the agent is blind. It asks "which email?" when the user is staring at one. It cannot act on the current selection, cannot provide relevant suggestions, and cannot modify what the user sees. Context awareness is what makes the agent feel like a collaborator rather than a disconnected chatbot.

The Core Patterns

1. Navigation State (navigation key)

The UI writes a navigation key to application-state on every route change. This tells the agent the semantic screen state: view, open IDs, active tab, and focused object.

UI side — useNavigationState, an app-owned hook (not a framework import) that every template ships at app/hooks/use-navigation-state.ts. It is a thin wrapper around the framework primitive useAgentRouteState, handling both directions: writing navigation on route change and consuming the agent's navigate command.

// app/hooks/use-navigation-state.ts
import { useAgentRouteState } from "@agent-native/core/client/navigation";
import { TAB_ID } from "@/lib/tab-id";

export function useNavigationState() {
  useAgentRouteState({
    browserTabId: TAB_ID,
    requestSource: TAB_ID,
    getNavigationState: ({ pathname, searchParams }) => ({
      view: pathname === "/" ? "home" : pathname.slice(1),
      // Optional semantic alias. Raw query params are already exposed in
      // <current-url> and controllable with set-search-params.
      label: searchParams.get("label"),
    }),
    getCommandPath: (command: any) => command.path ?? "/",
  });
}

TAB_ID comes from the framework's getBrowserTabId() (see the scaffolded app/lib/tab-id.ts; never redefine it). The server resolves tab-scoped application_state writes and page-local WebMCP calls (X-Agent-Native-Browser-Tab) against this same id, so a hand-rolled random id silently breaks selection sync for hidden and background tabs.

Agent side — read before acting:

import { readAppState } from "@agent-native/core/application-state";

const navigation = await readAppState("navigation");
// e.g. { view: "thread", threadId: "abc123", subject: "Re: Q3 Planning" }

What to include in navigation state:

  • view — the current page/section (e.g., "inbox", "form-builder", "dashboard")
  • Item IDs — the selected/open item (e.g., threadId, formId, issueKey)
  • Semantic aliases — label names, active tabs, focused row, or stable filter names the agent should reason about
  • Any durable selection — focused item, selected text range, active tab

Raw URL query params are already synced by the framework to __url__ and shown to the built-in agent as <current-url>. Keep shareable filters in URL state, then use view-screen to summarize important query params as activeFilters when helpful.

Keep application_state values small. Do not store pasted files, base64 images, recording chunks, screenshots, or other large blobs in navigation or app-state keys; upload them and store only a URL or storage handle.

Selection state

The editor writes the user's current selection to tab-scoped app state under selection whenever it changes: writeClientAppState("selection", { kind: "text", id: <artifact id>, elementId?, range?: { start, end }, text?: <short excerpt>, capturedAt }, { requestSource: TAB_ID }) — stable ids and a short label, never the whole document. view-screen reads it and returns selection plus the exact next call, e.g. nextRequiredAction: "update-slide" with nextArgs: { slideId, edits: [{ find: selection.text, replace: "…", expectedMatches: 1 }] }. External agents act on that hint directly; only when selection is null should the agent ask which item.

2. Current URL (__url__ key)

AgentPanel automatically writes __url__ with { pathname, search, hash, searchParams }. The built-in agent sees it as a <current-url> block in every turn.

Use this for URL-reachable filters and search state. The agent can update it with the built-in set-search-params and set-url-path tools; do not duplicate the whole query string into navigation.

3. The view-screen Script

Every template should have a view-screen script. It reads navigation state, the current URL if filters matter, and selection state. It fetches the relevant data from existing domain actions, shared data helpers, or Drizzle queries, and returns a snapshot of what the user sees. Do not add REST wrappers just so view-screen can read app data. This is the agent's eyes.

// actions/view-screen.ts
import { readAppState } from "@agent-native/core/application-state";

export default async function main() {
  const navigation = await readAppState("navigation");
  const url = (await readAppState("__url__")) as {
    searchParams?: Record<string, string>;
  } | null;
  const screen: Record<string, unknown> = { navigation };

  if (url?.searchParams) {
    screen.activeFilters = url.searchParams;
  }

  // Fetch data based on what the user is viewing
  if (navigation?.view === "inbox") {
    const emails = await fetchEmailList(navigation.label);
    screen.emailList = emails;
  }
  if (navigation?.threadId) {
    const thread = await fetchThread(navigation.threadId);
    screen.thread = thread;
  }

  const selection = await readAppState("selection");
  if (selection) {
    screen.selection = selection;
    screen.nextRequiredAction = "update-email";
  }

  console.log(JSON.stringify(screen, null, 2));
}

Navigation state is auto-injected into every user message as a <current-screen> block, so the agent always has basic context without calling any tool. The view-screen action is still useful when you need a richer snapshot (e.g., fetching the full email thread or form data for the current view).

4. The navigate Script

The agent writes a one-shot navigate command to application-state. The UI reads it, performs the navigation, and deletes the entry.

Agent side:

import { writeAppState } from "@agent-native/core/application-state";

// Navigate the user to a specific thread
await writeAppState("navigate", { view: "inbox", threadId: "abc123" });

UI side — use useAgentRouteState, shown above. It polls command keys, dedupes _writeId, deletes consumed commands, and applies app-local routing.

When a destination has a real URL, let the navigate command carry that local path (plus semantic fields when useful) and have the UI prefer path before falling back to semantic routing. Keep app navigation single-channel: do not also write __set_url__ for the same navigation. __set_url__ belongs to the framework URL tools (set-url-path, set-search-params) and URL-only filter changes. If a command can arrive while a chat stream is rendering, prefer navigate(path, { replace: true, flushSync: true }) over a view-transition wrapper so the URL and visible route commit together.

Jitter Prevention

When the agent writes to application-state via script helpers (writeAppState), the write is tagged with requestSource: "agent". The UI uses the ignoreSource option on useDbSync() with a per-tab ID so it ignores its own writes while still picking up changes from agents, other tabs, and scripts.

Client code can use useAgentRouteState, useSemanticNavigationState, setClientAppState, writeClientAppState, readClientAppState, and deleteClientAppState from @agent-native/core/client instead of hand-written fetch calls. Pass { requestSource: TAB_ID } on UI writes when pairing with useDbSync({ ignoreSource: TAB_ID }); pass { keepalive: true } for short-lived writes such as selection cleanup during unload.

// app/root.tsx
import { TAB_ID } from "@/lib/tab-id";

useDbSync({
  queryClient,
  ignoreSource: TAB_ID,  // ignore events from this tab's own writes
});

The UI sends its tab ID via X-Request-Source header on PUT/DELETE requests. The server stores this as the event's requestSource. When processing sync events, the UI filters out events matching its own ignoreSource value. This prevents the UI from refetching data it just wrote.

Gold-Standard Example: Mail Template

The mail template demonstrates these patterns working together:

Navigation state shape:

{ "view": "inbox", "threadId": "thread-123", "focusedEmailId": "msg-456", "label": "important" }

view-screen output:

  • Reads navigation state
  • Reads __url__ if URL query filters matter
  • Fetches email list matching current view/filter state
  • Fetches thread messages if a thread is open
  • Returns everything as a single JSON snapshot

navigate command:

  • { "view": "starred" } — switch to starred view
  • { "view": "inbox", "threadId": "thread-123" } — open a specific thread
  • For pure query-filter changes, use set-search-params

Do

  • Use the auto-injected <current-screen> block for basic context — call view-screen only when you need richer data
  • Include semantic route state in the navigation key (view, item IDs, active tab, focused row)
  • Keep shareable filters in URL query params so <current-url> and set-search-params work
  • Update view-screen when adding new features — it should return data for every view
  • Use useAgentRouteState or useSemanticNavigationState for UI-side navigation sync and command consumption
  • Use the one-shot navigate command pattern for app navigation; include a same-origin path when the target URL is known
  • Tag agent writes with requestSource: "agent" (the script helpers do this automatically)

Don't

  • Don't assume the user is on a specific page — always check navigation state
  • Don't hardcode navigation paths in scripts — read the current state and branch
  • Don't write to the navigation key from the agent — it belongs to the UI. Use navigate instead.
  • Don't write both navigate and __set_url__ for one app navigation; competing consumers can make the browser URL change before React Router commits the page.
  • Don't ignore the <current-screen> block — it tells you where the user is
  • Don't duplicate whole URL query strings into navigation when <current-url> already exposes them
  • Don't store fetched data in navigation state — it holds IDs and semantic UI state only. The view-screen script fetches the actual data.

Related Skills

  • adding-a-feature — Context awareness is area 4 of the four-area checklist
  • real-time-sync — How useDbSync delivers app-state changes to the UI
  • actions — How to create the view-screen and navigate actions
  • storing-data — Application-state is one of the core SQL stores

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

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

同じリポジトリのスキル

a2a-assets

無料概要あり

複数のアプリやMCPホストからブランド画像・動画を生成、調整、書き出し、挿入する作業を支援します。ライブラリ選択や修正依頼も扱います。

  • スライド用のブランド画像を作りたいとき
  • 既存素材をフィードバックに合わせて直したいとき
  • 動画素材を生成して書き出したいとき
BuilderIO/agent-native7,5222026年10月26日 更新

account-health

無料概要あり

特定の顧客企業について、契約と製品利用の数値を照らし合わせ、根拠や不足情報を明記した健全性レポートをまとめます。

  • 顧客の健全性を確認したいとき
  • 契約席数と実利用を比べたいとき
  • 更新前に利用状況を整理したいとき
BuilderIO/agent-native7,5222026年10月26日 更新

actions

無料概要あり

アプリの操作をエージェントと画面の両方から呼び出せるアクションとして実装し、API連携や画面のデータ取得を一貫した形で追加するスキルです。

  • 新しいアプリ操作を追加したいとき
  • 外部APIと連携したいとき
  • 画面からデータを取得したいとき
BuilderIO/agent-native7,5222026年10月26日 更新

adding-a-feature

無料概要あり

新機能をUI・エージェント用アクション・説明資料・画面状態の4領域でそろえ、利用者とエージェントのどちらからも一貫して使えるようにするチェックリストです。

  • 新機能追加の作業範囲を整理したいとき
  • UIとエージェント操作をそろえたいとき
  • 画面状態の同期漏れを防ぎたいとき
BuilderIO/agent-native7,5222026年10月26日 更新

adhoc-analysis

無料概要あり

複数のデータソースを照合して、傾向や指標、根拠をまとめた分析結果を作成します。必要に応じて、再実行できるダッシュボードとして保存できます。

  • 商談と通話記録を照合したいとき
  • 顧客の利用状況を横断して調べたいとき
  • 繰り返し更新できる分析を保存したいとき
BuilderIO/agent-native7,5222026年10月26日 更新

admin-surfaces

無料概要あり

Analyticsの管理画面で、機能フラグの状態確認と切り替え、ダッシュボード利用状況の調査、接続先アプリのデータベース管理を行います。

  • アプリごとの機能フラグを確認・変更したいとき
  • ダッシュボードの所有者や利用状況を調べたいとき
  • 接続済みアプリのテーブルを管理したいとき
BuilderIO/agent-native7,5222026年10月26日 更新

BuilderIO のスキルをすべて見る

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