feat(expo): anonymous usage telemetry and skill feedback#71
Conversation
Adds an opt-out, anonymous PostHog telemetry layer plus a feedback path so we can see which Expo skills get used and improve them. - Shared, zero-dependency Node/Bun scripts in skills/skill-feedback/scripts (telemetry_common, skill-event, skill-feedback, telemetry toggle), launched via run.sh which picks node or bun and no-ops if neither is present. - Plugin-level Read hook (hooks/hooks.json) emits skill_read; a per-skill PostToolUse hook on all 16 skills emits skill_activated. Both are Claude Code only and scoped to this plugin. - Every skill gains a harness-agnostic "Expo Skill Feedback" footer for manual skill_feedback; a new skill-feedback skill documents the whole system. - Anonymous (hashed local install id; no PII, code, or paths). Opt-out via `telemetry.js --off`, EXPO_SKILLS_TELEMETRY=0, or DO_NOT_TRACK. Fully inert until a PostHog project key is configured. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses PR review feedback: - skill-event/skill-feedback now auto-detect the agent harness from env (CLAUDECODE -> claude-code; CODEX_SANDBOX / AGENT=codex -> codex; else unknown), removing the hardcoded `--agent-harness claude-code` from hooks.json, all 16 per-skill hooks, and every feedback footer. - skill-event derives the plugin root from its own location, so the Read hook no longer needs the `--plugin-root` flag. - Trim the CLAUDE.md telemetry section to just what it does and how to turn it off (full details live in the skill-feedback skill). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adopts proven patterns from entireio/cli: - Skip telemetry in CI (CI=true plus GitHub/GitLab/CircleCI/Travis/Buildkite/ Jenkins/TeamCity/Azure signals) so usage reflects real humans; surfaced in `telemetry.js --status`. - Add non-PII `os` / `arch` to every event. - Print a one-time "anonymous telemetry" notice to stderr on the first real send, gated by ~/.expo-skills/notice-shown. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…red) Skills load through Claude Code's Skill tool, not the Read tool — confirmed by inspecting the binary (skill_invoke / activeSkill, no read path) and a real `claude -p` run where invoking expo-observe fired the Skill tool with skill="expo:expo-observe" and zero Read calls. The old skill_read (PostToolUse:Read) hook therefore never fired on real usage. - Repoint the plugin hook to matcher "Skill" / event skill_invoked; read the skill name from tool_input.skill (strip the "plugin:" namespace) and scope to this plugin's own skills (<root>/skills/<name>/SKILL.md must exist). - Keep per-skill skill_activated (verified it fires). - Update docs (skill-feedback SKILL.md, README). Verified end-to-end: a real claude -p invoking expo-observe landed both skill_invoked and skill_activated in PostHog project 375452. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Track skill usage from both invocation paths, tagged with an `initiator`: - AI / model: PostToolUse `Skill` hook -> initiator=ai - user `/slash`: new UserPromptExpansion hook (reads command_name) -> initiator=user Verified against the binary + real `claude -p`: model invocation goes through the Skill tool (tool_input.skill), while user slash commands fire UserPromptExpansion with command_name (plugin skills namespaced "expo:expo-observe", stripped to the folder name). Both scoped to this plugin's skills; non-Expo slashes (e.g. /clear) are ignored. Adds `properties.initiator` to skill_invoked. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Now that skill_invoked (AI Skill tool + user UserPromptExpansion, tagged with
`initiator`) fully covers usage, drop the redundant machinery:
- Remove the `skill_activated` event and the per-skill `PostToolUse` frontmatter
hooks from all 16 skills (+ skill-feedback) — they fired at the same moment as
skill_invoked and added no distinct signal.
- Drop `model_config` (always "unknown") and `--context`/`parseContext` (unused).
- skill-event.js loses the activation dedup markers; one plugin-level hooks.json
does all auto-tracking; skills now carry only the feedback footer.
Two events remain — skill_invoked {skill, initiator, install-hash, agent_harness,
session-hash, os/arch} and skill_feedback — which answer: most-used skills,
AI-vs-user, unique installs, frequency/retention, and quality. Verified both
paths dry-run correctly and `claude plugin validate` passes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
main converted CLAUDE.md into a symlink -> AGENTS.md (the new instructions home) and added Codex/Cursor plugin + marketplace metadata. Resolved the CLAUDE.md "distinct types" conflict by keeping main's symlink and moving the "Usage Telemetry & Feedback" contributor note from CLAUDE.md into AGENTS.md. README auto-merged (keeps both the new Codex/Cursor install sections and the telemetry section). Telemetry code (hooks.json + skill-feedback/scripts) is unchanged; plugin and marketplace both validate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codex now loads plugin hooks (openai/codex#17331 is closed) and exposes a PLUGIN_ROOT env var (≈ CLAUDE_PLUGIN_ROOT), but it still has no skill-invocation event: no Skill tool, UserPromptExpansion unimplemented, and skill hooks are on the parity roadmap (openai/codex#21753). So our matchers have nothing to bind to in Codex yet. - Update skill-feedback "Harness support" to this accurate state and document the minimal future enablement (a Codex hooks.json entry using ${PLUGIN_ROOT} + --initiator, plus one skillFromHook field). - Mark the skill-name extraction extension point in skill-event.js. Scripts are already harness-agnostic; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…observable Verified against codex-cli 0.130.0 + openai/codex main + a real `codex exec` run with live hooks: none of Codex's 10 hook events are skill-aware and no payload carries the skill name (skills are injected as <skill> context, not a tool; the SkillInvoked fact is internal analytics, never exposed to the hooks crate). Plugin-bundled hooks are also off by default (plugin_hooks, under development). Codex does alias CLAUDE_PLUGIN_ROOT, so our paths already resolve — enabling Codex is a tiny add once it ships a skill hook event + stable plugin_hooks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build it so Codex lights up automatically once it reaches hook parity (openai/codex#21753) + enables plugin_hooks — with no rework from us: - skillFromHook() now reads the skill name from any plausible payload field (tool_input.skill / tool_input.skill_name / command_name / top-level skill / skill_name). Strict skillBelongsToPlugin() scoping keeps this safe even though it's permissive (non-skills are dropped). - We already use Claude's hook event names (Skill, UserPromptExpansion) and ${CLAUDE_PLUGIN_ROOT}, which Codex mirrors/aliases — so the existing hooks.json fires in a parity Codex unchanged. Claude paths verified unchanged; non-skill payloads still skipped; plugin validates. Codex still can't fire yet (no skill-aware hook event; plugin_hooks off by default) — but our side needs zero further change for the parity path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Non-functional hardening from the multi-lens code review — no behavior
change to the happy path:
- skill-event.js: strip a leading "/" from slash-command skill payloads
before namespacing; trim the AI-path hook timeout 5s -> 3s.
- skill-feedback.js: fix $insert_id prefix "skill-feedback:" -> "skill_feedback:"
to match the event name; drop the unused maybeShowFirstRunNotice import/call
(feedback is explicit consent, so the first-run notice was misleading here).
- hooks.json: pass --plugin-root "${CLAUDE_PLUGIN_ROOT}" explicitly on both
hooks so plugin-scoping never depends on path inference.
- docs/comments: correct run.sh usage line, skill-feedback SKILL.md example
paths (${CLAUDE_SKILL_DIR}/scripts/...) and Codex example (use-dom),
telemetry_common stableStringify comment, and AGENTS.md opt-out guidance.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| Only ever use a *project* key (`phc_...`) here. Never a *personal* API key (`phx_...`) — | ||
| those are secret and used only for reading/querying (e.g. the PostHog MCP). | ||
|
|
||
| ## PostHog event shape |
There was a problem hiding this comment.
moved to /references
| If this skill was useful, confusing, broken, or missing context, submit 1-3 safe sentences with the bundled feedback script: | ||
|
|
||
| - **Claude Code:** `sh "${CLAUDE_SKILL_DIR}/../skill-feedback/scripts/run.sh" "${CLAUDE_SKILL_DIR}/../skill-feedback/scripts/skill-feedback.js" --skill upgrading-expo --rating idea --text "..."` | ||
| - **Other agents (Codex, etc.):** run `skill-feedback/scripts/skill-feedback.js` (bundled in this plugin) with `node` or `bun`, same flags (the harness is auto-detected). |
There was a problem hiding this comment.
then this sh script can be reused here too.
There was a problem hiding this comment.
i dropped the other agents, we'll know only support claude code :/ codex hooks don't support the stuff we need yet...
Kudo
left a comment
There was a problem hiding this comment.
the main concern is windows which doesn't have sh support by default.
| // per environment with EXPO_SKILLS_POSTHOG_KEY (e.g. a staging project). | ||
| // NOTE: never put a PostHog *personal* API key (phx_...) here — those are secret. | ||
| const POSTHOG_PROJECT_API_KEY = | ||
| process.env.EXPO_SKILLS_POSTHOG_KEY || "phc_w8xRytdAAwkV3oExnuUozqH64PMzCmDLnyoChpPBcNXs"; |
There was a problem hiding this comment.
[🏗️ design] Because a real phc_... key is committed, telemetryConfigured() is true, so telemetry is on by default for every install — not "inert until a key is configured" as the PR description says. The only runtime disclosure is the one-time stderr line in maybeShowFirstRunNotice(), and it fires from a --quiet PostToolUse hook whose stderr Claude Code hides by default (transcript/debug only). So in practice the first send is silent.
The anonymization, opt-out, DO_NOT_TRACK, and CI-skip are all solid. The open question is consent: is silent on-by-default the intended model, or should first run surface something the user actually sees? Either way, please drop the "fully inert until a key is configured" line from the PR body, since a key is committed.
|
|
||
| maybeShowFirstRunNotice(); | ||
| try { | ||
| await sendToPosthog(payload, { userAgent: "expo-skills/skill-event", timeoutMs: 3000 }); |
There was a problem hiding this comment.
[💡 suggestion] The file header says this "never blocks," but awaiting the POST keeps the hook process alive until PostHog responds or the 3s timeout fires — so each AI skill invocation can add up to 3s of latency to the turn (the hook waits for the process). For the quiet/auto path, consider detaching the send so telemetry stays off the critical path — e.g. background it in run.sh (node "$script" "$@" &) for the event scripts. Keep await in skill-feedback.js, since that path reports success to the user.
| "hooks": [ | ||
| { | ||
| "type": "command", | ||
| "command": "sh \"${CLAUDE_PLUGIN_ROOT}/skills/skill-feedback/scripts/run.sh\" \"${CLAUDE_PLUGIN_ROOT}/skills/skill-feedback/scripts/skill-event.js\" --skill auto --initiator ai --plugin-root \"${CLAUDE_PLUGIN_ROOT}\" --quiet", |
There was a problem hiding this comment.
note that sh doesn't support on windows
|
|
||
| ## Turning it off | ||
|
|
||
| Telemetry is anonymous and on by default. The reliable, launch-independent way to opt |
There was a problem hiding this comment.
correct me if i am wrong. the skill-feedback skill is for agents without hook support to explicit evaluate the skill and share feedback.
in the case "on by default" or opt-out feels unclear to me if agent is going to explicitly send feedback
| skill, | ||
| rating: args.rating, | ||
| feedback_text: feedback, | ||
| }, |
There was a problem hiding this comment.
not sure if feasible: i think relevant prompts (or chat history) that triggers the skill would be helpful to further study how to improve the skill
Brings in the expo-ui skill consolidation (#80), the openai-curated agent definitions (#74), the plugin-version-bump check (#79), README banner/metadata (#76, #82), and the main plugin version bump to 1.2.0 (#78). Conflict resolutions: - plugins/expo/.claude-plugin/plugin.json: version -> 1.3.0. main moved to 1.2.0, and the new plugin-version-bump check requires each manifest to be strictly greater than main, so this feature branch takes 1.3.0. Bumped the Codex and Cursor manifests to 1.3.0 as well so all three stay in sync (the check also enforces that). - expo-ui consolidation: main merged expo-ui-swift-ui + expo-ui-jetpack-compose into one expo-ui skill, deleting both old dirs. Accepted the deletions. Rename detection carried this branch's telemetry footer into expo-ui/references/jetpack-compose.md; took main's clean reference (footers belong in SKILL.md, not references) and instead added the Expo Skill Feedback footer to the new expo-ui/SKILL.md so the consolidated skill is still tracked. Also added a short anonymous-telemetry + opt-out note to plugins/expo/README.md for transparency now that the plugin ships usage tracking. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, UX) Responds to review feedback from @davidmokos and @Kudo on #71. Auto-path latency (@Kudo): the PostToolUse hook no longer blocks the turn on the network. New scripts/skill-event.sh detaches the send into its own session (setsid -> perl POSIX::setsid -> nohup) and returns in ~20ms. Because a backgrounded process's stdin is /dev/null (POSIX), the wrapper reads the hook payload synchronously into an mktemp file and passes it via --hook-input-file; skill-event.js reads then unlinks it (before the telemetry-off guards, so it's cleaned up even when nothing is sent). If mktemp is unavailable it bails rather than write the payload to a predictable, world-readable /tmp path. Footer UX (@davidmokos): new scripts/skill-feedback.sh wrapper bundles run.sh + the script path, so all 16 SKILL.md footers shrink to one line. Codex (@davidmokos): corrected the stale "will light up when Codex catches up" narrative. Verified on codex-cli 0.138: plugin_hooks is a *removed* feature, and Codex runs skills by reading SKILL.md directly (no Skill tool to hook), so a plugin can't ship skill-usage hooks today. Manual skill_feedback is the Codex signal. Detail in references/telemetry.md. Honesty / consent (@Kudo): removed the false "fully inert until a key is configured" claims (a real public phc_ key ships, so telemetry is ON by default) from the scripts and AGENTS.md; the guard now only inerts a key-stripped fork. The one-time notice now fires only on visible (non-quiet) runs, so the silenced detached hook can't burn its marker unseen. Docs (@davidmokos, @Kudo): fixed the misleading "harness is auto-detected" wording (only claude-code + codex are detected); split automatic skill_invoked vs explicit skill_feedback and documented that opt-out silences both; relocated maintainer-facing config + event-shape detail to references/telemetry.md to keep SKILL.md lean; documented the prompt/chat-history non-capture stance and the Windows sh limitation. Hardening: skill name must be a single kebab segment (blocks path traversal from a malformed payload reaching path.join or the event property). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up to the skill-writing-framework review. - description: add opt-out / disable / turn-off / telemetry triggers. The skill is the only place an agent in a fresh user project learns the opt-out command, but the description only carried feedback triggers — so "turn off Expo skills telemetry" wouldn't reliably invoke it. (P0: one trigger per branch.) - SKILL.md "Harness support": collapse the medium tier to a 1-line glance + pointer; the per-harness detail (volatile, pinned to codex 0.138) now lives only in references/telemetry.md, so a Codex change is a one-place edit. (P1.) - AGENTS.md: correct the "just copy the footer" note — you must swap --skill <name>, and skill-feedback's own footer uses a different relative path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… non-existent var
The skill footers and skill-feedback SKILL.md referenced the bundled scripts as
${CLAUDE_SKILL_DIR}/... — but that variable does not exist. The Claude Code
plugins reference defines exactly three path variables substituted inline in
skill content: ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA}, ${CLAUDE_PROJECT_DIR}.
${CLAUDE_SKILL_DIR} was used by no other plugin and is undocumented, so it
expanded to empty and the explicit-feedback command was broken on Claude Code
(`sh "/../skill-feedback/scripts/skill-feedback.sh"`). The skill_invoked hook
path was unaffected — it already (correctly) used ${CLAUDE_PLUGIN_ROOT}.
Rewrite every reference to the official ${CLAUDE_PLUGIN_ROOT}/skills/skill-feedback/
scripts/... form (substituted inline in skill content per the docs). This also
makes all 16 footers byte-identical (no more special path for skill-feedback's
own footer), so the AGENTS.md "just copy the footer" note is now literally true.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t messaging Both events stay — automatic skill_invoked (plugin hooks, verified firing on both the AI Skill-tool and user /slash paths) and explicit skill_feedback (the agent runs the bundled script, which POSTs to PostHog). Automatic tracking only works on Claude Code, so the docs now say so plainly instead of advertising a half-working "other agents" story: - 15 product footers + skill-feedback's own: trimmed to a single Claude Code line (dropped the "Other agents (Codex, Cursor)" bullet and the wrapper-vs-js duplication). ~8-line footer -> ~5. - skill-feedback/SKILL.md: framed as Claude Code; removed the "other agents" submit/opt-out blocks; collapsed "Harness support" into a one-line pointer. - README + plugin README: telemetry sections say Claude Code only; left all the plugin-DISTRIBUTION mentions (Codex install, Run button, skills CLI) intact — those are unrelated to telemetry. - references/telemetry.md: condensed the harness deep-dive to a short "why Claude Code only" note (now citing the openai/codex source: plugin_hooks is a removed feature + no skill event in HookEventName). Kept the generic detectHarness()/--agent-harness plumbing (5 lines, harmless, labels any direct manual send correctly). No Codex hooks file is shipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reframes the per-skill footer from a copy-pasted command into a trigger that (a) makes the agent aware it can give feedback, (b) actively nudges it to be proactive — especially when a skill was wrong/confusing/outdated/missing — and (c) points to the `skill-feedback` skill for the actual how. The command now lives in one place (skill-feedback's "Submitting feedback"), so all 15 product footers are byte-identical with nothing per-skill to get wrong. - 15 product footers: nudge + "use the `skill-feedback` skill" pointer (no inline command). - skill-feedback/SKILL.md: "Submitting feedback" gains a proactive lead-in and a note to pass *the skill being rated* to `--skill` (the agent arrives here from another skill's footer, not to rate skill-feedback itself). Its own footer matches the nudge tone and points to that section. Tradeoff: the agent loads `skill-feedback` to get the command (one extra hop) instead of running it inline — accepted for the stronger nudge + single source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…simplify, proactive footer - Rename the skill `skill-feedback` → `expo-skill-feedback` (dir, frontmatter name, hooks.json path, all 15 footer pointers, README/AGENTS refs). Script filenames (skill-feedback.js/.sh) and the userAgent label stay. Clearer leading word that matches the "Expo Skill Feedback" footer heading. - Feedback can now target **Expo itself**, not just the skill: skill-feedback.js gains `--about skill|expo` (default skill) -> `properties.about`, so the team can separate framework issues from skill-guidance issues. Surfaced in the footer nudge, the skill's Submitting-feedback section, and the description. - Simplify references/telemetry.md (95 -> 50 lines): keep the event shape (the privacy receipt) + add `about`, condense the rest, and point to the scripts' own comments for the detach/Windows how (single source of truth). - Bump plugin manifests 1.3.0 -> 1.4.0 (main reached 1.3.0 via #84). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Resolved the plugin.json version conflict to 1.4.0 (main reached 1.3.0 via #84; this branch needs strictly-greater). - Gave the new expo-examples skill the same proactive Expo Skill Feedback footer (pointing to expo-skill-feedback) so every skill is consistent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove accreted complexity that wasn't earning its keep (no behavior change to what's actually tracked): - Drop client-side dedup: `$insert_id` + the `stableStringify` helper. PostHog doesn't need it (we never retry; events are already distinct). - Drop `schema_version` (premature) and `session_id_hash` (nice-to-have, not in the dashboard). - Drop the first-run stderr notice (`maybeShowFirstRunNotice` + `NOTICE_PATH`) — it was near-dead (hidden hook stderr); disclosure lives in the README + skill. - Trim telemetry_common exports to what's actually imported. - references/telemetry.md: drop the "Implementation notes" section (it duplicated the scripts' own comments — single source of truth) and the session-hash line. telemetry_common.js 224->148, references/telemetry.md 95->41. Event payloads now carry only: skill, agent_harness, initiator/about, os/arch, installation_id_hash (+ rating/feedback_text for skill_feedback). Verified both dry-runs + the toggle. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The scripts/package.json existed only to pin "type":"commonjs" so require() works regardless of any parent "type":"module". Renaming the four scripts to .cjs declares CommonJS via the extension itself — Node and Bun both honor it — so the package.json is no longer needed and is removed. One fewer file, and the module type is now self-evident instead of hidden in a config file. - skill-event/skill-feedback/telemetry/telemetry_common .js -> .cjs - updated require()s, the run.sh/skill-event.sh/skill-feedback.sh references, and the SKILL.md / AGENTS.md / references mentions - verified under both node and bun, and through the run.sh wrapper chain Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply the writing-great-skills lens to the skill body — the agent that loads this skill only needs to know how to submit feedback and how to turn telemetry off. - Drop "## Runtime" (node/bun/run.sh internals — a no-op for the agent; it just runs the command). - Drop the "## The two signals" table (duplicated the intro; the full mechanism lives in references/telemetry.md). - Drop "## Notes for maintainers" (maintainer info in the agent's context) — keep only a one-line pointer to references/telemetry.md. - Tighten the intro, submit, and opt-out sections. SKILL.md ~90 -> 52 lines. No behavior change; the two functions + the privacy one-liner + the references pointer remain. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
~90% of references/telemetry.md restated the code: the event shape is built in skill-event.cjs / skill-feedback.cjs (and summarized in SKILL.md's privacy line), and the PostHog-key override is already a comment in telemetry_common.cjs. The only unique content — why Claude Code only — was one sentence; folded it into the AGENTS.md telemetry note (which previously just pointed here). Removed the SKILL.md and AGENTS.md pointers and deleted the file + the now-empty references/ dir. expo-skill-feedback is now just SKILL.md + scripts/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The skill_invoked hook and the feedback/opt-out commands shelled out via
`sh`, which isn't present on stock Windows. Switch every entry point to call
`node` directly — portable across cmd/PowerShell/sh, and the convention top
skills.sh skills already use ("name the interpreter, relative path").
Fold the non-blocking detach into skill-event.cjs itself: the foreground
process reads the hook payload from stdin, resolves the skill, runs the cheap
local gates, then re-execs a detached copy (spawn detached + unref + windowsHide)
to do the PostHog POST off the agent's critical path. Because Node reads stdin
before detaching, the old temp-file / setsid / perl / nohup handoff is gone.
- hooks/hooks.json: sh skill-event.sh -> node skill-event.cjs --detach
- SKILL.md: sh skill-feedback.sh / run.sh -> node skill-feedback.cjs / telemetry.cjs
- AGENTS.md: prefix the opt-out command with node
- delete run.sh, skill-event.sh, skill-feedback.sh (-67 lines of shell)
Same anonymous, opt-out, Claude-Code-only behavior; now cross-platform.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
davidmokos
left a comment
There was a problem hiding this comment.
Lookin at the telemetry code I'm wondering whether to have expo feedback command in the CLI directly for that.
|
|
||
| --- | ||
|
|
||
| ## Expo Skill Feedback |
There was a problem hiding this comment.
I don't like that we're repeating the same paragraph for each skill here. Maybe it can be added via a CI script?
Kudo
left a comment
There was a problem hiding this comment.
thought i'm still not sure whether adding telemetry in the plugin would be a good idea. i don't want to block it. we could try that and see how it goes
Summary
Adds anonymous, opt-out usage telemetry and a feedback path to the Expo skills plugin — so we can see which skills actually get used (and where they fall short) and close the loop on improving them. Verified end-to-end against the Expo AI Tools PostHog project.
Signals
skill_readSKILL.mdis readReadhook)skill_activatedskill_feedbackChanges
plugins/expo/skills/skill-feedback/scripts/, run under Node or Bun via arun.shlauncher that no-ops if neither is installed.hooks/hooks.jsonforskill_read, plus askill_activatedfrontmatter hook on all 16 skills, scoped to this plugin.skill-feedbackskill documenting the whole system.Privacy & opt-out
telemetry.js --off,EXPO_SKILLS_TELEMETRY=0, orDO_NOT_TRACK=1.Testing
run.sh(selected Bun) → PostHog/i/v0/e/→ queryable in project 375452.🤖 Generated with Claude Code