Skip to content

Add evolving teaching skills with local learning loop#101

Open
octavi42 wants to merge 15 commits into
farzaa:mainfrom
octavi42:feature/teaching-skills-upstream
Open

Add evolving teaching skills with local learning loop#101
octavi42 wants to merge 15 commits into
farzaa:mainfrom
octavi42:feature/teaching-skills-upstream

Conversation

@octavi42

Copy link
Copy Markdown

Summary

  • Adds evolving teaching skills: after successful tutoring sessions, Clicky writes reusable local SKILL.md files under ~/.clicky/skills/ (inspired by Hermes Agent, adapted for screen-native teaching)
  • Read path: matched skills are injected into the voice response system prompt when the frontmost app and transcript align
  • Write path: skills are created or patched after multi-step help + user confirmation (e.g. "got it, thanks")
  • Curator: time-based stale/archive lifecycle, optional LLM merge/patch passes, user pin/delete/restore
  • UI: teaching skills toggle + preview in the menu bar panel, full skills library view ("View all")
  • E2E: headless regression suite (teaching-skills.sh, skills-library.sh) with mock worker + GitHub Actions on macos-15

Demo success: "I taught Clicky how to walk me through TextEdit save yesterday — today it remembers and points better on the first try."

Test plan

  • ./tests/e2e/run-all.sh passes locally (write + read-path + patch + library restore)
  • Run TeachingSkillTests from Xcode
  • Manual: hold Control+Option, ask for multi-step screen help, confirm with "got it thanks"
  • Manual: repeat the same question in the same app — response should reference saved skill content
  • Manual: open panel → Teaching Skills → View all → pin/delete/restore a skill
  • CI: E2E Teaching Skills workflow passes on this PR

Notes

This PR is intentionally scoped to teaching skills only — niche discovery and personal vault are planned as follow-up PRs.

octavi42 added 7 commits May 29, 2026 17:25
Clicky now learns from successful tutoring sessions, injects matched skills into prompts, and includes a mock-worker E2E test for the read/write loop.
Derive skill names from the primary question, persist cross-session topic history, verify read-path injection via Phase B relaunch, and run the full harness locally and on macos-14 GitHub Actions.
E2E workflow runs teaching-skills.sh without niche-discovery tests.
Hermes-style loop: stable (app, task) identity, target-app resolution from
session text, patch-first synthesis, and E2E Phase C — so refinements update
one skill instead of spawning duplicates mid-tutorial.
Input Monitoring gates the CGEvent tap instead of Accessibility, and ClickyWorkerBaseURL routes Claude, TTS, and AssemblyAI through the Cloudflare Worker so manual testing matches main.
Ship the full skills library view, LLM curator passes, shared E2E helpers,
skills-library regression script, and teaching-only launch hooks without
niche or vault dependencies.
Drop niche and full-stack scripts from the upstream PR branch so CI
matches the scoped feature set.
@danielbusnz

Copy link
Copy Markdown

hi, if you would like to work on a more recent fork of this project, reach out to me

octavi42 and others added 8 commits June 8, 2026 12:52
* Add runtime data-home isolation for parallel app instances.

Introduce ClickyPaths/ClickyDefaults/ClickyLaunchArguments so the app's
data home (~/.clicky), UserDefaults suite, and global push-to-talk can be
redirected per instance via -CLICKY_HOME / -CLICKY_DEFAULTS_SUITE /
-CLICKY_DISABLE_GLOBAL_PTT (or the CLICKY_HOME env var). This lets multiple
worktree builds run side by side without clobbering each other's skills,
preferences, or fighting over the global hotkey. Routes skill and topic
stores through ClickyPaths, threads CLICKY_HOME through the E2E harness, and
adds unit coverage plus a @mainactor fix so the test target compiles.

* Make input-monitoring preflight nonisolated to fix Xcode 16.4 build.

GlobalPushToTalkShortcutMonitor.start() runs in a nonisolated context and
calls WindowPositionManager.hasInputMonitoringPermission(), which Xcode 16.4
(used by CI) rejects as a cross-actor call. The helper only reads live TCC
state via a pure C preflight, so marking it nonisolated is safe and unblocks
the CI build on both Xcode 16.4 and 17.
ScreenCaptureKit routes through screencaptureui on macOS Tahoe and shows
floating screenshot thumbnails during voice sessions. Switch companion
capture to CGWindowListCreateImage (via a runtime dlsym wrapper), suppress
and dismiss leftover thumbnail UI for the app lifetime, and harden
permission refresh so dev builds reflect live TCC state after granting in
System Settings. Also fixes a CGWindowID crash when window numbers are out
of UInt32 range.
new-worktree.sh creates a branch worktree with its own CLICKY_HOME,
UserDefaults suite, and optional push-to-talk disable, and patches that
worktree's Xcode scheme so multiple Clicky instances can run side by side
without sharing ~/.clicky or fighting over the global hotkey.
Save session JSON under ~/.clicky/sessions when a voice session ends via
confirm phrase, 30s idle, or panel close. Includes 7-day retention cleanup,
SessionStore unit tests, and cross-suite test isolation for ClickyPaths.
maybeWriteTeachingSkill's in-flight task ended with an unconditional
sessionTrace.removeAll(). Since synthesis is async, it could fire after a
new session had already started and wipe its turns before persistence.
Only clear the trace when it still matches the synthesized snapshot.
- Keep the in-memory trace and re-arm the idle timer when sessionStore.save
  throws, so a transient I/O error retries instead of dropping the capture.
- Arm the 30s idle boundary after TTS playback completes rather than in
  recordSessionExchange, so a long spoken reply no longer fires the timer
  mid-speech and splits one conversation into two persisted sessions.
If the 30s idle timer fires while the assistant is mid-speech, re-arm
instead of finalizing so a long spoken reply cannot split one
conversation into two persisted sessions.
Persist voice sessions to disk on session boundary

@danielbusnz danielbusnz left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants