From haiku
Polls CRM, ticketing, and comms providers for events since last poll to suggest new intents, advance await gates, and sync state changes.
npx claudepluginhub gigsmart/haiku-method --plugin haikuThis skill is limited to using the following tools:
`haiku:triggers` — Poll providers for events that should create intents or advance gates.
Tests ClaudeTracker's hooks integration end-to-end by sending 21 hook events via PowerShell script through HookBridge and verifying delivery in logs and notifications.
Configures polling mechanisms for API integrations with step-by-step guidance, production-ready code, configurations, and best practices for third-party APIs, webhooks, and SDKs.
Creates, validates, and refines Claude Code plugin hooks for workflow automation. Supports command hooks (shell scripts), prompt hooks (LLM decisions), event matching, decision schemas, and production safety validation.
Share bugs, ideas, or general feedback.
haiku:triggers — Poll providers for events that should create intents or advance gates.
/haiku:triggers # Poll all providers, check all gates
/haiku:triggers --poll crm # Poll only the CRM provider
/haiku:triggers --poll ticketing # Poll only the ticketing provider
/haiku:triggers --check-gates # Only check await gates, don't poll for new intents
/haiku:triggers --dry-run # Show what would happen without acting
User-facing command and schedulable task. Designed to run both interactively and as a scheduled remote trigger via /schedule or Claude Desktop scheduled tasks.
This skill polls configured providers for events since the last poll and surfaces:
await gates whose conditions are now satisfied# Load providers from settings via MCP
PROVIDERS=$(haiku_settings_get { field: "providers" } || echo "{}")
LAST_POLL=$(Read ".haiku/trigger-poll.json" || echo '{"last_poll":"1970-01-01T00:00:00Z"}')
LAST_POLL_TIME=$(parse last_poll from $LAST_POLL JSON)
For each configured provider category (filtered by --poll if specified):
1. Query for deals/opportunities changed since $LAST_POLL_TIME
2. For each changed deal:
a. Check if it matches a studio trigger declaration
(e.g., sales studio declares: on deal close → suggest CS onboarding)
b. Check if it maps to an active intent's await gate
(e.g., deal stage changed → customer responded)
3. Collect events as structured findings
1. Query for tickets changed since $LAST_POLL_TIME that reference H·AI·K·U epics
2. For each changed ticket:
a. Status changes → may indicate unit completion by human
b. New comments → context for active stages
c. New sub-tickets → potential new units
3. Collect events
1. Check threads for replies to H·AI·K·U gate notifications
2. Look for confirmation patterns:
- Explicit: "done", "approved", "customer responded"
- Reaction: ✅ on the gate notification message
3. Collect events
1. Check for new/updated documents since $LAST_POLL_TIME
2. Match against active intents' input dependencies
3. Flag if an input has been updated since the stage last read it
Load trigger declarations from all studios:
for studio_dir in "$CLAUDE_PLUGIN_ROOT/studios"/*/; do
STUDIO_FILE="$studio_dir/STUDIO.md"
# Parse triggers from studio frontmatter via MCP
TRIGGERS=$(haiku_studio_get { studio: "$(basename "$studio_dir")" } | parse triggers field)
# Match against collected events
done
For each matched trigger:
--dry-run: Report what would happenauto: true, otherwise log it for the next interactive sessionFor each active intent with an await gate:
for intent_dir in .haiku/intents/*/; do
INTENT_FILE="$intent_dir/intent.md"
ACTIVE_STAGE=$(haiku_intent_get { slug, field: "active_stage" })
STUDIO=$(haiku_intent_get { slug, field: "studio" })
# Load stage review type
STAGE_METADATA=$(haiku_stage_get { intent: "$INTENT_SLUG", stage: "$ACTIVE_STAGE", field: "metadata" })
REVIEW=$(parse review field from $STAGE_METADATA)
# Check if this is an await gate
if REVIEW is "await" or REVIEW is an array containing "await"; then
# Check if the await condition is satisfied by any polled event
# The await condition is stored in intent state
AWAIT_STATE=$(Read "$intent_dir/await.json" || echo "")
if [ -n "$AWAIT_STATE" ]; then
AWAIT_EVENT=$(parse event field from $AWAIT_STATE)
AWAIT_PROVIDER=$(parse provider field from $AWAIT_STATE)
# Match against polled events from that provider
fi
fi
done
For matched await gates:
--dry-run: Report which gates would advanceFor each active intent with a ticketing/CRM provider:
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
echo "{\"last_poll\":\"$TIMESTAMP\"}" > ".haiku/trigger-poll.json"
## Trigger Poll Results
**Polled at:** {timestamp}
**Providers checked:** {list}
### New Intent Suggestions
| Source | Event | Suggested Studio | Template |
|--------|-------|-----------------|----------|
| CRM: Acme Corp deal closed | Stage: Closed Won | customer-success | new-customer-onboarding |
### Gate Advancements
| Intent | Stage | Gate | Event |
|--------|-------|------|-------|
| acme-proposal | proposal | await | Customer replied via email |
### State Sync
| Intent | Change | Source |
|--------|--------|--------|
| feature-x | unit-03 marked Done in Jira | ticketing |
This skill is designed to run as a scheduled task:
/schedule every 30m /haiku:triggers
When running scheduled (no interactive TTY):
auto: true.haiku/state/pending-triggers.jsonWhen running interactively:
| Scenario | Behavior |
|---|---|
| No providers configured | Skip polling, report "no providers" |
| Provider MCP not available | Skip that provider, report which were skipped |
| Rate limit hit | Back off, record partial poll timestamp |
| Event matches multiple triggers | Present all matches, let user choose |