clay-run/agent-plugins/signals

Claude Code and agent skill by clay-run/agent-plugins

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Clay Signals — watches that detect real-world changes (job changes, new hires, promotions, funding news, job postings, topic intent) and write them as events onto a table or an audience. Use for any request about a workspace''s signals: which ones exist, what one watches or writes to, whether one is running, turning one on or off, and why one is or is not producing events.

Install

npx vskill@latest install clay-run/agent-plugins/signals

SKILL.md

Clay Signals

A signal watches a set of records and emits an event when something changes in the real world — someone changes job, a company posts a role or raises a round. It has two halves, and telling them apart is the first thing to get right.

Resolve the population before discovery. For a historical question, use the request and context to distinguish existing workspace records from net-new prospects; ask if unclear before exploring either surface. For existing records, read the audiences skill's queries.md and query captured events directly. List triggers when managing watches, not as a prerequisite for historical queries. An empty trigger inventory or summary field does not establish that captured events are absent; check history before proposing a new watch.

RecordId prefixWhat it is
Trigger definitiontd_…The runnable unit: name, run status, filter, output.
Signalsig_…The underlying watch that trigger definitions share.

`id` in CLI output is the trigger definition (`td_…`), and it is the only id these commands accept. signal.id is the other record; passing it to clay signals get is a not_found. Everything a user calls "a signal" — its name, whether it is on, what it writes to — lives on the trigger definition.

Web intent is out of scope. Read Current limitations at the bottom before telling a user something cannot be done: it lists every gap with what to do instead.

The commands

bash
clay signals list # every signal in the workspace
clay signals get <triggerDefinitionId> # one signal, with its filter, schedule, and error
clay signals create --type T --input JSON # new signal of a supported type
clay signals update <triggerDefinitionId> # rename, re-schedule, re-filter, change per-type settings
clay signals pause <triggerDefinitionId> # stop signal running, and stop it spending
clay signals resume <triggerDefinitionId> # run signal again on its existing schedule
clay signals delete <triggerDefinitionId> # remove signal but keeping the events it captured
clay signals search-topics --query Q --entity-type person|company # topicIds for a topic intent signal

Excluding web intent makes list rows one per signal, so they are safe to count. Narrow with jq:

bash
clay signals list | jq -r '.data[] | "\(.id) \(.signal.type) \(.runStatus)"'
clay signals list | jq '[.data[] | select(.runStatus == "Errored") | .id]'

Read clay signals list --help and clay signals get --help for the exact output shapes; they are the contract.

pause and resume return the signal with runStatus already updated, so no confirming call is needed. They write nothing but the status: schedule, filter, and destination are untouched, and setting a status a signal already has changes nothing, so a retry after a network failure is safe.

Only an Active or Paused signal can be toggled. Any other runStatus — Errored, Disabled, Testing, Preview — is refused.

Pausing is the credit lever. A paused signal stops checking and stops spending — reach for it when a signal costs more than it is worth, rather than suggesting deletion.

Reach for `pause` before `delete`. Pausing already stops the signal running and stops it spending, and it is reversible. Nothing undoes a delete: recreating the signal means rebuilding it in the app and starting from a fresh baseline, so the first weeks of coverage are lost again. Confirm with the user before deleting something they may only want stopped, and show them get output first.

Identify a write target by id, not by name. get returns input — the same targeting the list row carries — so read the signal back and check what it actually watches before pausing or deleting it. Names are not unique and are not reliable selectors; see the ALL warning under Signals on audiences for the specific way name-matching goes wrong on audience signals.

Deleting keeps the data. The destination table and its rows survive, as do the signal activities already on audience entities — a delete removes the watch, not the history. It is also not idempotent: a second delete of the same id returns not_found, which here means "already gone or never existed", so do not read it as confirmation.

Creating and updating a signal

`clay signals create --help` is the list of creatable types and the authority on each one's `--input` shape. It is generated from the supported set, so it is never out of date; anything absent from it is an app job, and passing such a type says so by name rather than failing obscurely. The same goes for clay signals update --help and what that type lets you change.

Types differ in what they take. The watch — a table view, or audience segments — is common to all of them, but the settings beside it are not: one type takes search filters, another a set of topic providers. Never carry an --input shape from one type to another; read the shape for the type in hand, and prefer copying a working signal of that same type:

bash
clay signals get td_abc123 | jq '.signal.inputs' # copy this, edit it, feed it back

Never guess a vocabulary value — fetch it. Several --input fields take a fixed set of exactly-spelled values that a misspelling silently turns into "matches nothing": news topics, job-post seniority and employment_type, new-hire seniority levels and company size/revenue buckets. Those closed sets are enumerated in full in clay signals create --help, under each type's --input shape — read the values there rather than recalling them. The two vocabularies that page cannot enumerate: topic intent topicIds, which clay signals search-topics resolves (see Topic intent types below), and new-hire job_functions, which is resolved per workspace — prefer job_title_keywords over it.

Check for a duplicate first. Nothing stops two signals of the same type watching the same records, and each is charged in full. clay signals list and compare signal.type against input before creating another.

Resolve audience ids, never names. --input's segmentIds are ids from clay audiences list --entity-type companies|people. See the ALL warning under Signals on audiences — matching words in a segment name is how the wrong signal gets written.

A table-watching signal needs three ids, and only two have a command. clay tables list gives tableId, clay tables columns list <tableId> gives the fieldId for the identifier field. There is no command for viewId — read it off the table's URL in the app, or off input.table.viewId of an existing signal on the same table:

bash
clay signals list | jq -r '.data[] | select(.input.table.id == "t_abc123") | .input.table.viewId'

A created signal is Paused. It neither runs nor spends until clay signals resume <id>. That order is deliberate: read it back, confirm input is what you meant, then resume. Pass --activate only when the watched set and its identifier coverage have already been checked, because a check that has run cannot be taken back.

Price the signal before choosing a cadence. Which of the two billing models a type uses decides whether cadence matters at all — see Two billing models under Common issues. For a per-record-checked type, cadence multiplies the bill and a large watched view on a fast cadence is among the most expensive things a workspace can run; narrow the watched view before slowing the cadence. Omitted, --schedule takes that type's own default, which is not the same across types — and some types accept only a subset of the cadences (topic intent checks weekly at the fastest, matching how often its providers refresh); the --type values in create --help list each type's set.

Some types are created with a default filter. Omitting --filter takes it, matching the app — job change and promotion start at confidence >= 90, which is why a new signal can look healthy and still emit less than expected. Passing --filter replaces the default rather than adding to it.

`--filter` and a type's own `filters` are two different things, and confusing them is the main way a signal ends up watching for the wrong thing.

  • `--filter` decides which _detected_ events fire. One flag, the same on every type, and

what get returns as filter.

  • `filters`, a key inside --input on the types that have one, is the search that decides

what the signal looks for in the first place — which hires count for a new-hire signal, which postings for a job-post signal, which articles for a news signal. It lives in signal.inputs.filters.

A search filters document replaces rather than merges, and the search schemas are large and heavily defaulted: a key you leave out is set back to its default, not left as it was. So edit a real one rather than composing one from memory:

bash
clay signals get td_abc123 | jq '.signal.inputs.filters' # copy this, edit it, feed it back

Topic intent types have their own gate and their own vocabulary trap. PersonTopicIntent and CompanyTopicIntent are gated separately from the rest of signals, so create can fail with exit 3 on a workspace where every other type works. Their setting is providerConfigs — which intent providers to ask, and which of each provider's topics to watch — and its topicIds come from each provider's own catalog (opaque ids, except bombora's, which are the topic names spelled exactly).

Resolve `topicIds` with `clay signals search-topics` — never guess them, and never copy them off another signal. A guessed id validates and then matches nothing, and another signal's ids encode _its_ topics, not the ones this user asked for. Describe what the user wants to detect in plain language and take the ids from the result, per provider:

bash
clay signals search-topics --query 'sales intelligence tools' --entity-type company

Each result maps one topic to its id in every provider's catalog (matches.<provider>[].id); use each id only in a providerConfigs entry for that same provider. Pass the entity type matching the signal type — a person search excludes person-restricted topics and returns no bombora ids, because bombora is company-only.

A provider config without topicIds watches every topic that provider tracks, not none — and every topic is charged per record on every run, so an omitted topic list is a cost decision, not a blank.

Which providers a topic intent signal uses is also fixed at creation, unlike its topics: update can change the topicIds and tiers inside each config, but adding or dropping a provider is refused because each one keeps its own detection baseline. Choose the provider set deliberately at create time — changing it later means a new signal.

A failed table-watching create leaves something behind, and recovery depends on where it failed. The destination is set up before the signal is validated, and nothing cleans either up. Read the error to tell the two apart before retrying:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
143
Repository forks
22
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/clay-run/agent-plugins/signals/badge)](https://verified-skill.com/skills/clay-run/agent-plugins/signals)

Something wrong with this skill or its page? Tell us.