{
  "schemaVersion": "1.0",
  "item": {
    "slug": "toggle",
    "name": "Toggle",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/aleksandar-jive/toggle",
    "canonicalUrl": "https://clawhub.ai/aleksandar-jive/toggle",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/toggle",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=toggle",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "scripts/toggle.py"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "toggle",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-04T03:54:17.196Z",
      "expiresAt": "2026-05-11T03:54:17.196Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=toggle",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=toggle",
        "contentDisposition": "attachment; filename=\"toggle-1.0.6.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "toggle"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/toggle"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/toggle",
    "agentPageUrl": "https://openagent3.xyz/skills/toggle/agent",
    "manifestUrl": "https://openagent3.xyz/skills/toggle/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/toggle/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Toggle (ToggleX) — The Context Layer",
        "body": "ToggleX gives you awareness of the user's real work activity across the web — which projects, how long, how focused, and what they left unfinished. Unlike skills that only know what the user tells you, Toggle knows what they did.\n\nThe script fetches raw JSON from the ToggleX API. You are responsible for all intelligence on top of that data: summarization, pattern detection, nudges, and automations.\n\n{baseDir} throughout this document refers to the root directory of this skill's installation (the folder containing this SKILL.md file). This is standard OpenClaw skill convention."
      },
      {
        "title": "Quick reference",
        "body": "ActionCommandFetch todaypython3 {baseDir}/scripts/toggle.pyFetch date rangepython3 {baseDir}/scripts/toggle.py --from-date YYYY-MM-DD --to-date YYYY-MM-DDFetch + save to memorypython3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memoryCron run (skip cron check)python3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory --skip-cron-check"
      },
      {
        "title": "Endpoint",
        "body": "https://ai-x.toggle.pro/public-openclaw/workflows\n\nOperated by ToggleX (https://x.toggle.pro). Your TOGGLE_API_KEY is sent as an x-openclaw-api-key header. No other data is transmitted."
      },
      {
        "title": "Getting your API key",
        "body": "Get your TOGGLE_API_KEY from:\n\nhttps://x.toggle.pro/new/clawbot-integration\n\nNever paste the key into chat. Set it in OpenClaw config:\n\n{\n  \"skills\": {\n    \"entries\": {\n      \"toggle\": {\n        \"apiKey\": \"your_key_here\"\n      }\n    }\n  }\n}\n\nOr export in shell: export TOGGLE_API_KEY=your_key_here"
      },
      {
        "title": "Interpreting the output",
        "body": "The script returns raw JSON. The top-level response looks like:\n\n{\n  \"userId\": \"...\",\n  \"startDate\": \"YYYY-MM-DD\",\n  \"endDate\": \"YYYY-MM-DD\",\n  \"totalWorkflows\": 44,\n  \"totalDays\": 1,\n  \"workflowsByDate\": {\n    \"YYYY-MM-DD\": [ ...workflow entries... ]\n  },\n  \"summary\": {\n    \"totalContextSwitches\": 0,\n    \"totalDurationMinutes\": 797\n  }\n}"
      },
      {
        "title": "Sample workflow entry",
        "body": "{\n  \"workflowId\": \"3cd901ef-b708-4869-8ce0-52364ce494e6\",\n  \"date\": \"2026-02-19\",\n  \"workflowType\": \"AI Image Generation Debugging, Toggle/OpenClaw Skill Configuration\",\n  \"workflowDescription\": \"The user began by browsing the OpenClaw GitHub repository...\",\n  \"primaryDomain\": \"github.com\",\n  \"secondaryDomains\": \"[\\\"http://127.0.0.1:18789/agents\\\",\\\"https://github.com/openclaw/openclaw\\\"]\",\n  \"productivityScore\": \"92.00\",\n  \"productivityNotes\": \"Reviewing the ClawHub documentation ensured correct skill file structure...\",\n  \"type\": \"WORK\",\n  \"startTime\": \"2026-02-19T10:49:12.253Z\",\n  \"endTime\": \"2026-02-19T11:34:27.809Z\",\n  \"duration\": 1746.629,\n  \"durationMinutes\": 29,\n  \"isBreakPeriod\": false,\n  \"isLeisure\": false,\n  \"isWork\": true,\n  \"sessionCount\": 10,\n  \"activeSessionCount\": 10,\n  \"projectTask\": {\n    \"id\": \"05f01090-...\",\n    \"name\": \"OpenClaw Environment: Gateway Configuration & Image Generation Skill Integration\",\n    \"goal\": \"Configure and validate the local OpenClaw environment...\",\n    \"isDone\": false,\n    \"context\": \"Local OpenClaw instance; GitHub repositories...\",\n    \"prompts\": [\n      \"What verification steps should I follow to confirm the config changes took effect?\",\n      \"How can I test the skill invocation through the OpenClaw chat interface?\"\n    ],\n    \"project\": {\n      \"id\": \"ab576749-...\",\n      \"name\": \"Toggle Pro AI Chat Feature Development\",\n      \"description\": \"End-to-end development of AI Chat functionality...\",\n      \"isActive\": true,\n      \"summary\": \"The project currently reports 0 of 0 tasks completed...\"\n    }\n  }\n}"
      },
      {
        "title": "Data type gotchas",
        "body": "productivityScore is a string (e.g. \"92.00\"), not a number. Parse to float before comparing against thresholds.\nsecondaryDomains is a stringified JSON array, not an actual array. Parse it with JSON.parse() if you need individual URLs.\nduration is in seconds (float). durationMinutes is a rounded integer approximation.\nprojectTask can be null — some WORK entries have no project context. Always check before accessing nested fields.\nZero-duration entries exist — some WORK entries have duration: 0 and durationMinutes: 0. These are brief interactions (e.g. a single page view). Include them in sequence analysis but don't count them as substantial sessions.\nstartTime and endTime are UTC (ISO 8601). Convert to the user's local timezone before grouping by \"today\" or \"yesterday\" or displaying times. If the user's timezone is unknown, ask once and store in state.yaml under timezone."
      },
      {
        "title": "Key fields",
        "body": "FieldDescriptiontype\"WORK\", \"BREAK\", or \"LEISURE\"workflowTypeShort label for the session (e.g. \"Build Investigation and Scripting\")workflowDescriptionDetailed narrative of what the user did. May contain raw URLs — do not echo these to the user unless asked. Summarize in your own words.primaryDomainMain website/app (e.g. \"github.com\", \"claude.ai\", \"127.0.0.1\")productivityScore\"0.00\" to \"100.00\" (string). 90+ = sharp, 70–89 = solid, below 70 = fragmentedstartTime / endTimeISO 8601 UTC timestamps. endTime may equal startTime for instantaneous actions, or be null if ongoing.durationSession length in seconds (float)durationMinutesRounded session length in minutes (int)projectTask.nameHuman-readable task descriptionprojectTask.goalWhat the user was trying to accomplishprojectTask.promptsAI-generated follow-up questions relevant to the task. Use these — if the user asks \"what should I do next on this project?\", these are high-quality suggestions directly tied to their recent work.projectTask.project.nameParent project name — use for grouping and stale-project detectionprojectTask.project.summaryRunning project summary — useful for briefings and recallsummary.totalContextSwitchesAPI-provided count of context switches for the period. Use this instead of calculating manually.summary.totalDurationMinutesTotal tracked time in minutes"
      },
      {
        "title": "Interpretation rules",
        "body": "Focus on type: \"WORK\" entries; skip BREAK unless asked; mention LEISURE briefly if present\nAlways sort entries by startTime — the API does not return entries in chronological order\nIf totalWorkflows is 0, tell the user Toggle wasn't running or captured nothing for that period\nWhen summarizing, use workflowType as the headline and workflowDescription for detail — but paraphrase the description, don't dump it raw (it contains URLs, OAuth tokens, and internal paths)"
      },
      {
        "title": "Error handling",
        "body": "The script exits with a non-zero code and prints to stderr on failure. Handle these cases:\n\nErrorLikely causeWhat to tell the userHTTP error 401Invalid or expired API key\"Your Toggle API key isn't working. Get a new one at https://x.toggle.pro/new/clawbot-integration\"HTTP error 403Insufficient permissions\"Your API key doesn't have the right permissions. Check your ToggleX integration settings.\"HTTP error 429Rate limited\"Toggle's API is rate-limiting requests. I'll try again in a few minutes.\" Implement exponential backoff: wait 1 min, then 2 min, then 5 min. Max 3 retries. Do not run the script more than once per 5 minutes.HTTP error 5xxToggleX server issue\"ToggleX servers seem to be having issues. I'll try again shortly.\"Request failed / timeoutNetwork issue\"Couldn't reach ToggleX. Check your internet connection.\"TOGGLE_API_KEY is not setMissing env var\"Your Toggle API key isn't configured yet. Set it up at https://x.toggle.pro/new/clawbot-integration and add it to your OpenClaw config.\"JSON parse errorMalformed response\"Got an unexpected response from ToggleX. Usually temporary — I'll retry.\"\n\nOn first run: If the fetch fails, do NOT proceed with the setup pitch. Diagnose the error first.\n\nOn cron runs: If a fetch fails, log the error in {baseDir}/state.yaml under last_error with a timestamp. On the next successful user interaction, mention it briefly: \"Heads up — the last background sync failed at [time]. It's working again now.\""
      },
      {
        "title": "Persist to memory",
        "body": "python3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory\n\nWrites a <!-- toggle-data-start --> / <!-- toggle-data-end --> section inside <date>.md files. One file per day. Existing content outside that section is preserved.\n\nAlways use --persist when running via cron or when the user asks to save/refresh data."
      },
      {
        "title": "Cron setup",
        "body": "The script checks cron status on every run. It reads:\n\n{baseDir}/state.yaml — if cron_disabled: true, skips the check.\n~/.openclaw/cron/jobs.json — looks for any job with \"toggle\" in its name.\n\nStatusMeaningYour actionNO_CRONNo toggle cron job existsAsk: \"Want me to auto-sync your activity? I can check every hour and keep your context fresh.\"CRON_DISABLEDJob exists but disabledAsk if they want to re-enableCRON_ERRORLast run failedShow error, help troubleshootCRON_OKHealthyNo action needed"
      },
      {
        "title": "Standard cron commands",
        "body": "These exact commands are used for all cron setup. Referenced throughout this document — define once here.\n\nHourly sync:\n\nopenclaw cron create \\\n  --name \"Toggle hourly sync\" \\\n  --schedule \"0 * * * *\" \\\n  --message \"Run: python3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory --skip-cron-check\"\n\nDaily digest (default 6 PM):\n\nopenclaw cron create \\\n  --name \"Toggle daily digest\" \\\n  --schedule \"0 18 * * *\" \\\n  --message \"Fetch today's Toggle data and generate my end-of-day digest. Run: python3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory --skip-cron-check\"\n\nAdjust the digest schedule if the user requests a different digest_time."
      },
      {
        "title": "If user declines cron",
        "body": "Write to {baseDir}/state.yaml:\n\ncron_disabled: true"
      },
      {
        "title": "State file",
        "body": "{baseDir}/state.yaml stores preferences and tracking state. You can read and write it."
      },
      {
        "title": "User preferences",
        "body": "KeyTypeDefaultDescriptioncron_disabledboolfalseSkip cron status checkdigest_enabledbooltrueWhether to generate end-of-day digestsdigest_timestring\"18:00\"When to generate the daily digest (24h format)nudge_stale_hoursint48Hours of inactivity before nudging about a stale projectfocus_alert_thresholdint30productivityScore below this triggers a context-switch alertfocus_alert_window_minint20Minutes of low-focus before alertingpattern_detection_daysint7Days of history to scan for repeated patternspattern_min_occurrencesint3Times a workflow must repeat before proposing automationtimezonestringnullUser's local timezone (e.g. \"Europe/Sofia\"). Ask once on first run if not set.prediction_enabledbooltrueWhether to proactively predict the user's next actionprediction_min_daysint5Minimum days of data before predictions activateprediction_confidence_minint3Minimum occurrences of a routine before predicting it"
      },
      {
        "title": "Tracking state (managed by you, the agent)",
        "body": "KeyTypeDescriptionlast_nudgedmapProject names → ISO timestamps of last nudge. Don't re-nudge within 24h.dismissed_projectslistProject names the user explicitly dropped. Never nudge these again.last_focus_alertstringISO timestamp of last context-switch alert. Back off 3h after alerting.focus_alert_paused_untilstringISO date. If set and today ≤ this date, skip focus alerts.proposed_patternsmapPattern description → ISO timestamp. Don't re-propose within 14 days.last_errorstringLast cron error message + timestamp. Clear after reporting to user.last_predictionstringISO timestamp of last prediction offered. Back off 2h between predictions.prediction_dismissed_untilstringISO date. If user declines predictions, pause until this date.prediction_hit_loglistLog of predictions made + whether the user followed them. Use to refine confidence."
      },
      {
        "title": "PROACTIVE BEHAVIORS",
        "body": "These are the core intelligence features. Do not wait for the user to ask. When data is available — through a cron run, a manual fetch, or persisted memory files — analyze it and act."
      },
      {
        "title": "1. Daily Digest",
        "body": "Trigger: Cron job at the user's digest_time (default 6:00 PM), OR the first interaction after end of workday if no cron is set.\n\nWhat to do:\n\nFetch today's data with --persist and --skip-cron-check\nProduce a short default digest — 3 to 4 lines max:\n\nTotal work time + session count\nTop focus area (project with most time)\nBiggest open item (most-invested project that still has recent, unfinished activity)\nOne notable stat (focus score trend vs yesterday, longest session, or summary.totalContextSwitches)\n\nDefault format — keep it tight:\n\nYour day: 5.2h across 4 sessions. Deepest focus on auth migration (2.1h, 94 focus). Stripe webhooks still open — you were 80% through. Context switches down to 3 from 6 yesterday.\n\nIf the user asks for more detail, expand to: top 3 focus areas by time, all open items, full focus stats (average score, switch count, longest session), and a tomorrow suggestion.\n\nComparing to yesterday: If yesterday's data exists in {baseDir}/../../memory/, compare total time, focus score, and context-switch count. Note trends. Skip comparison if no prior data exists."
      },
      {
        "title": "2. Stale Project Nudges",
        "body": "Trigger: Every time you fetch or read Toggle data, scan for stale projects.\n\nA project is stale when both are true:\n\nIt has more than 2 hours of total accumulated time across all days (a real project, not a one-off visit)\nIt has no activity in the last nudge_stale_hours (default: 48 hours)\n\nThat's it. Two criteria. Don't try to infer whether a project is \"completed\" — if it is, the user will dismiss the nudge and you'll record that.\n\nWhat to do:\n\nAfter any data fetch, compare current projects against persisted memory from previous days\nRead {baseDir}/../../memory/*.md files for the past 7 days\nSurface stale projects:\n\nYou haven't touched \"Landing Page Deploy\" in 3 days. Last session: 1.5h on responsive layout. Want me to pull up where you left off?\n\nRules:\n\nMaximum 2 stale nudges per interaction\nCheck last_nudged in state.yaml — skip if same project nudged within 24h\nCheck dismissed_projects — never nudge projects on this list\nIf the user says \"I dropped that\" / \"not working on it\" / \"done with that\", add to dismissed_projects"
      },
      {
        "title": "3. Context-Switch Alerts",
        "body": "Trigger: When analyzing current or recent data (last 2 hours), detect scattered behavior.\n\nAll three must be true:\n\n3+ different project.name values within a 30-minute window (use startTime to define the window)\nAverage productivityScore across those sessions is below focus_alert_threshold (default: 30)\nThis scattered pattern spans at least focus_alert_window_min minutes (default: 20)\n\nWhat to do:\n\nYou've switched between 5 different things in the last 25 minutes (focus score: 22). Want me to help you lock in on [project with most time today]?\n\nRules:\n\nCheck last_focus_alert — only alert once per 3-hour window\nCheck focus_alert_paused_until — if today ≤ that date, skip entirely\nIf user dismisses (\"I'm fine\" / \"intentionally browsing\"), set focus_alert_paused_until to tomorrow\nFrame as an offer, never a judgment"
      },
      {
        "title": "4. Pattern Detection & Automation Proposals (Agentify)",
        "body": "Trigger: When 7+ days of persisted data exist in {baseDir}/../../memory/. Run after each daily digest, or when the user asks about patterns or automations.\n\nHow to detect patterns:\n\nRead memory files for the past pattern_detection_days days (default: 7)\nFor each day, sort sessions by startTime to get the chronological sequence\nBuild sequences of (workflowType, project.name) tuples in time order\nIdentify subsequences that appear on pattern_min_occurrences+ different days (default: 3):\n\nSame projects visited in the same order (e.g. GitHub → Notion → Slack)\nSame workflowType at approximately the same time of day (±1 hour window on startTime)\n\nImportant: Do not assume the API returns entries in chronological order. Always sort by startTime before building sequences.\n\nWhat to propose:\n\nI noticed you check GitHub PR comments, then update Notion, then post in Slack — 4 times this week, ~12 min each. Want me to automate that pipeline?\n\nRules:\n\nCheck what other skills the user has installed. Only propose full automations if the required skills exist\nIf partial: \"I see you do X → Y → Z each morning. Can't automate all of it yet, but I can pre-fetch the data so it's ready.\"\nCheck proposed_patterns in state.yaml — don't re-propose the same pattern within 14 days\nIf approved, help create the appropriate cron job or workflow"
      },
      {
        "title": "5. Instant Recall — \"What Was I Looking At?\"",
        "body": "Trigger phrases:\n\n\"What was I working on [time period]?\"\n\"What was that thing I was reading on Tuesday?\"\n\"Where did I leave off on [project]?\"\n\"What was I looking at before the meeting?\"\n\"Pick up where I left off\"\n\nWhat to do:\n\nDetermine the date range from the user's question\nFetch data: python3 {baseDir}/scripts/toggle.py --from-date YYYY-MM-DD --to-date YYYY-MM-DD\nAlso check persisted memory: {baseDir}/../../memory/*.md\nUse startTime and endTime for precise timestamps in the answer\nUse workflowDescription for context about what they were doing, not just where\n\n\"Pick up where I left off\" (no other context):\nFind the most recent type: \"WORK\" session with the highest accumulated time. Describe exactly where they stopped — project, task, time, and description.\n\nTuesday afternoon (2:15–4:30 PM) you were deep in the Kalshi API docs — 1.5h across 3 sessions. Last session ended on the authentication endpoint. Focus: 87."
      },
      {
        "title": "6. Predictive Context — \"Your Agent Knows What's Next\"",
        "body": "This is the highest-value behavior. The agent doesn't just know what the user did — with enough history, it knows what they're about to do and can prepare for it.\n\nMinimum data required: prediction_min_days days of persisted memory (default: 5). Do NOT attempt predictions with less data — you'll guess wrong and lose trust. When insufficient data exists, silently skip. Never tell the user \"I don't have enough data to predict yet.\""
      },
      {
        "title": "6a. Routine Prediction — \"You usually do X right now\"",
        "body": "Trigger: On every cron-triggered fetch, OR when the user starts a new interaction. Compare the current day of week + approximate time (±1 hour) against historical patterns.\n\nHow to build routines:\n\nRead {baseDir}/../../memory/*.md for the past prediction_min_days days\nFor each day, note what project.name and workflowType the user was engaged in at each hour block\nGroup by day of week + hour: e.g. \"Monday 9 AM → PR reviews (4 of last 5 Mondays)\"\nA routine is valid when the same activity appears at the same day+hour on prediction_confidence_min or more occasions (default: 3)\n\nWhat to do when a routine is detected for the current moment:\n\nIt's Tuesday 10 AM — you usually start with PR reviews around now. Want me to pull up open PRs?\n\nCritical rules:\n\nOnly predict if the user hasn't already started doing the thing. Check the most recent session in today's data — if they're already in PR reviews, saying \"you usually do PR reviews now\" is useless. Skip it.\nMaximum 1 routine prediction per 2-hour window. Check last_prediction in state.yaml.\nIf the user follows the prediction (their next session matches), log it as a hit in prediction_hit_log. If they ignore it, log as a miss. Over time, only surface predictions with a >60% hit rate.\nIf the user says \"stop predicting\" or dismisses predictions repeatedly (3 misses in a row), set prediction_dismissed_until to 7 days from now."
      },
      {
        "title": "6b. Session Endurance Prediction — \"You're about to hit your wall\"",
        "body": "Trigger: When analyzing current data during a fetch, check if the user is in an active deep-work session.\n\nHow it works:\n\nFrom historical data, calculate the user's average deep-work session duration for the current project (or overall if not enough project-specific data)\nCheck the current active session's duration against that average\nWhen the current session reaches 90% of the average duration, offer a heads-up\n\nExample: If the user's average deep-work session on \"API Integration\" is 95 minutes and they're currently at 85 minutes:\n\nYou're 85 minutes into the API integration — around when you usually take a break. Want me to bookmark where you are so you can pick it up cleanly?\n\nRules:\n\nOnly trigger for sessions with productivityScore above 70 (actual deep work, not scattered browsing)\nOnly trigger once per session — don't nag at 90%, 95%, 100%\nIf the user keeps working past the prediction, that's fine. Don't mention it again. Log the actual duration to improve future estimates.\nNever frame it as \"you should stop.\" Frame it as \"here's a natural breakpoint if you want it.\""
      },
      {
        "title": "6c. Next-Task Prediction — \"You just finished X, you usually do Y next\"",
        "body": "Trigger: When the most recent session just ended (the user went from active to inactive, or switched to a different project), check if there's a predictable next step.\n\nHow it works:\n\nFrom historical data, build transition sequences: when the user finishes project A, what do they do next?\nA transition is valid when the same A → B sequence appears on prediction_confidence_min or more occasions\nWhen the user finishes a session that matches the \"A\" side of a known transition, suggest \"B\"\n\nExample: The user just finished a 45-minute session reviewing PRs. Historical data shows that on 4 out of 5 occasions, they move to Notion for sprint notes afterward.\n\nYou just wrapped PR reviews. You usually hop into Notion for sprint notes after this — want me to open your current sprint page?\n\nRules:\n\nOnly predict transitions that are strong (appear on 60%+ of relevant occasions)\nPair with other skills when possible: if you predict they'll go to Notion and the Notion skill is installed, offer to do something useful (open the right page, pre-load context)\nIf the user does something different, log the miss. Transitions that drop below 60% hit rate get retired silently."
      },
      {
        "title": "6d. Pre-Meeting Briefing — \"You have context for what's coming\"",
        "body": "Trigger: When calendar data is available (via another skill or the user's schedule), cross-reference upcoming events against Toggle work history.\n\nHow it works:\n\nIf a calendar skill is installed, check for meetings in the next 30 minutes\nSearch Toggle data for work sessions related to the meeting topic (match project.name or workflowDescription against the meeting title/attendees)\nIf relevant work is found, proactively brief the user\n\nExample: A calendar event \"Wallet App Sync\" is in 20 minutes. Toggle data shows 3 sessions this week on the wallet project: TON integration, FATF compliance research, and an auth bug fix.\n\nYou have \"Wallet App Sync\" in 20 minutes. This week you worked on: TON integration (2.1h), FATF compliance research (1.3h), and the auth bug fix (45 min). Want me to draft quick talking points?\n\nRules:\n\nOnly trigger if a calendar skill is available. Do not ask the user about their schedule — that defeats the purpose.\nOnly brief if there's actual Toggle data to cross-reference. An empty briefing (\"you have a meeting in 20 min\") adds no value.\nMaximum 1 briefing per meeting. Deliver it 15–30 minutes before, not 2 hours before."
      },
      {
        "title": "FIRST RUN BEHAVIOR",
        "body": "When the skill is invoked for the first time (no {baseDir}/state.yaml exists):\n\nFetch today's data to confirm the API key works\nIf the fetch fails: Diagnose using the error handling table. Do NOT proceed to setup. Help fix the connection first.\nIf the fetch succeeds: Present a brief summary, then offer setup:\n\nYour Toggle data is flowing. I can do a lot with this:\nAuto-sync — Check your activity every hour so I always have context.\nDaily digest — Summary of your day at 6 PM, no prompt needed.\nSmart nudges — Flag projects you haven't touched in a while.\nFocus alerts — Heads up when you're context-switching too much.\nPattern detection — After a week, I'll spot repeated workflows and suggest automations.\nPredictions — Once I learn your routines, I'll anticipate what you're about to do and have it ready.\nWant me to set up auto-sync and the daily digest?\n\nIf they agree, create both cron jobs (see \"Standard cron commands\" above) and write the initial state file with all preference defaults. Also ask: \"What timezone are you in?\" and store the answer in state.yaml under timezone. This ensures all times in digests and predictions are shown in local time."
      },
      {
        "title": "BEHAVIOR GUIDELINES",
        "body": "Be proactive, not annoying. Surface insights when they matter. Don't repeat yourself.\nNever announce internal operations. Don't say \"I'm analyzing your Toggle data.\" Just present the result.\nUse the data to make every other skill smarter. If the user asks you to do something and you have Toggle context, use it. Don't silo it.\nPrivacy-first language in all user-facing output. Say \"your activity shows\" or \"based on your sessions.\" Never \"I watched you\" or \"I tracked you.\"\nShort by default. Digests and nudges should be concise. Expand only when the user asks."
      }
    ],
    "body": "Toggle (ToggleX) — The Context Layer\n\nToggleX gives you awareness of the user's real work activity across the web — which projects, how long, how focused, and what they left unfinished. Unlike skills that only know what the user tells you, Toggle knows what they did.\n\nThe script fetches raw JSON from the ToggleX API. You are responsible for all intelligence on top of that data: summarization, pattern detection, nudges, and automations.\n\n{baseDir} throughout this document refers to the root directory of this skill's installation (the folder containing this SKILL.md file). This is standard OpenClaw skill convention.\n\nQuick reference\nAction\tCommand\nFetch today\tpython3 {baseDir}/scripts/toggle.py\nFetch date range\tpython3 {baseDir}/scripts/toggle.py --from-date YYYY-MM-DD --to-date YYYY-MM-DD\nFetch + save to memory\tpython3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory\nCron run (skip cron check)\tpython3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory --skip-cron-check\nEndpoint\nhttps://ai-x.toggle.pro/public-openclaw/workflows\n\n\nOperated by ToggleX (https://x.toggle.pro). Your TOGGLE_API_KEY is sent as an x-openclaw-api-key header. No other data is transmitted.\n\nGetting your API key\n\nGet your TOGGLE_API_KEY from:\n\nhttps://x.toggle.pro/new/clawbot-integration\n\n\nNever paste the key into chat. Set it in OpenClaw config:\n\n{\n  \"skills\": {\n    \"entries\": {\n      \"toggle\": {\n        \"apiKey\": \"your_key_here\"\n      }\n    }\n  }\n}\n\n\nOr export in shell: export TOGGLE_API_KEY=your_key_here\n\nInterpreting the output\n\nThe script returns raw JSON. The top-level response looks like:\n\n{\n  \"userId\": \"...\",\n  \"startDate\": \"YYYY-MM-DD\",\n  \"endDate\": \"YYYY-MM-DD\",\n  \"totalWorkflows\": 44,\n  \"totalDays\": 1,\n  \"workflowsByDate\": {\n    \"YYYY-MM-DD\": [ ...workflow entries... ]\n  },\n  \"summary\": {\n    \"totalContextSwitches\": 0,\n    \"totalDurationMinutes\": 797\n  }\n}\n\nSample workflow entry\n{\n  \"workflowId\": \"3cd901ef-b708-4869-8ce0-52364ce494e6\",\n  \"date\": \"2026-02-19\",\n  \"workflowType\": \"AI Image Generation Debugging, Toggle/OpenClaw Skill Configuration\",\n  \"workflowDescription\": \"The user began by browsing the OpenClaw GitHub repository...\",\n  \"primaryDomain\": \"github.com\",\n  \"secondaryDomains\": \"[\\\"http://127.0.0.1:18789/agents\\\",\\\"https://github.com/openclaw/openclaw\\\"]\",\n  \"productivityScore\": \"92.00\",\n  \"productivityNotes\": \"Reviewing the ClawHub documentation ensured correct skill file structure...\",\n  \"type\": \"WORK\",\n  \"startTime\": \"2026-02-19T10:49:12.253Z\",\n  \"endTime\": \"2026-02-19T11:34:27.809Z\",\n  \"duration\": 1746.629,\n  \"durationMinutes\": 29,\n  \"isBreakPeriod\": false,\n  \"isLeisure\": false,\n  \"isWork\": true,\n  \"sessionCount\": 10,\n  \"activeSessionCount\": 10,\n  \"projectTask\": {\n    \"id\": \"05f01090-...\",\n    \"name\": \"OpenClaw Environment: Gateway Configuration & Image Generation Skill Integration\",\n    \"goal\": \"Configure and validate the local OpenClaw environment...\",\n    \"isDone\": false,\n    \"context\": \"Local OpenClaw instance; GitHub repositories...\",\n    \"prompts\": [\n      \"What verification steps should I follow to confirm the config changes took effect?\",\n      \"How can I test the skill invocation through the OpenClaw chat interface?\"\n    ],\n    \"project\": {\n      \"id\": \"ab576749-...\",\n      \"name\": \"Toggle Pro AI Chat Feature Development\",\n      \"description\": \"End-to-end development of AI Chat functionality...\",\n      \"isActive\": true,\n      \"summary\": \"The project currently reports 0 of 0 tasks completed...\"\n    }\n  }\n}\n\nData type gotchas\nproductivityScore is a string (e.g. \"92.00\"), not a number. Parse to float before comparing against thresholds.\nsecondaryDomains is a stringified JSON array, not an actual array. Parse it with JSON.parse() if you need individual URLs.\nduration is in seconds (float). durationMinutes is a rounded integer approximation.\nprojectTask can be null — some WORK entries have no project context. Always check before accessing nested fields.\nZero-duration entries exist — some WORK entries have duration: 0 and durationMinutes: 0. These are brief interactions (e.g. a single page view). Include them in sequence analysis but don't count them as substantial sessions.\nstartTime and endTime are UTC (ISO 8601). Convert to the user's local timezone before grouping by \"today\" or \"yesterday\" or displaying times. If the user's timezone is unknown, ask once and store in state.yaml under timezone.\nKey fields\nField\tDescription\ntype\t\"WORK\", \"BREAK\", or \"LEISURE\"\nworkflowType\tShort label for the session (e.g. \"Build Investigation and Scripting\")\nworkflowDescription\tDetailed narrative of what the user did. May contain raw URLs — do not echo these to the user unless asked. Summarize in your own words.\nprimaryDomain\tMain website/app (e.g. \"github.com\", \"claude.ai\", \"127.0.0.1\")\nproductivityScore\t\"0.00\" to \"100.00\" (string). 90+ = sharp, 70–89 = solid, below 70 = fragmented\nstartTime / endTime\tISO 8601 UTC timestamps. endTime may equal startTime for instantaneous actions, or be null if ongoing.\nduration\tSession length in seconds (float)\ndurationMinutes\tRounded session length in minutes (int)\nprojectTask.name\tHuman-readable task description\nprojectTask.goal\tWhat the user was trying to accomplish\nprojectTask.prompts\tAI-generated follow-up questions relevant to the task. Use these — if the user asks \"what should I do next on this project?\", these are high-quality suggestions directly tied to their recent work.\nprojectTask.project.name\tParent project name — use for grouping and stale-project detection\nprojectTask.project.summary\tRunning project summary — useful for briefings and recall\nsummary.totalContextSwitches\tAPI-provided count of context switches for the period. Use this instead of calculating manually.\nsummary.totalDurationMinutes\tTotal tracked time in minutes\nInterpretation rules\nFocus on type: \"WORK\" entries; skip BREAK unless asked; mention LEISURE briefly if present\nAlways sort entries by startTime — the API does not return entries in chronological order\nIf totalWorkflows is 0, tell the user Toggle wasn't running or captured nothing for that period\nWhen summarizing, use workflowType as the headline and workflowDescription for detail — but paraphrase the description, don't dump it raw (it contains URLs, OAuth tokens, and internal paths)\nError handling\n\nThe script exits with a non-zero code and prints to stderr on failure. Handle these cases:\n\nError\tLikely cause\tWhat to tell the user\nHTTP error 401\tInvalid or expired API key\t\"Your Toggle API key isn't working. Get a new one at https://x.toggle.pro/new/clawbot-integration\"\nHTTP error 403\tInsufficient permissions\t\"Your API key doesn't have the right permissions. Check your ToggleX integration settings.\"\nHTTP error 429\tRate limited\t\"Toggle's API is rate-limiting requests. I'll try again in a few minutes.\" Implement exponential backoff: wait 1 min, then 2 min, then 5 min. Max 3 retries. Do not run the script more than once per 5 minutes.\nHTTP error 5xx\tToggleX server issue\t\"ToggleX servers seem to be having issues. I'll try again shortly.\"\nRequest failed / timeout\tNetwork issue\t\"Couldn't reach ToggleX. Check your internet connection.\"\nTOGGLE_API_KEY is not set\tMissing env var\t\"Your Toggle API key isn't configured yet. Set it up at https://x.toggle.pro/new/clawbot-integration and add it to your OpenClaw config.\"\nJSON parse error\tMalformed response\t\"Got an unexpected response from ToggleX. Usually temporary — I'll retry.\"\n\nOn first run: If the fetch fails, do NOT proceed with the setup pitch. Diagnose the error first.\n\nOn cron runs: If a fetch fails, log the error in {baseDir}/state.yaml under last_error with a timestamp. On the next successful user interaction, mention it briefly: \"Heads up — the last background sync failed at [time]. It's working again now.\"\n\nPersist to memory\npython3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory\n\n\nWrites a <!-- toggle-data-start --> / <!-- toggle-data-end --> section inside <date>.md files. One file per day. Existing content outside that section is preserved.\n\nAlways use --persist when running via cron or when the user asks to save/refresh data.\n\nCron setup\n\nThe script checks cron status on every run. It reads:\n\n{baseDir}/state.yaml — if cron_disabled: true, skips the check.\n~/.openclaw/cron/jobs.json — looks for any job with \"toggle\" in its name.\nStatus\tMeaning\tYour action\nNO_CRON\tNo toggle cron job exists\tAsk: \"Want me to auto-sync your activity? I can check every hour and keep your context fresh.\"\nCRON_DISABLED\tJob exists but disabled\tAsk if they want to re-enable\nCRON_ERROR\tLast run failed\tShow error, help troubleshoot\nCRON_OK\tHealthy\tNo action needed\nStandard cron commands\n\nThese exact commands are used for all cron setup. Referenced throughout this document — define once here.\n\nHourly sync:\n\nopenclaw cron create \\\n  --name \"Toggle hourly sync\" \\\n  --schedule \"0 * * * *\" \\\n  --message \"Run: python3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory --skip-cron-check\"\n\n\nDaily digest (default 6 PM):\n\nopenclaw cron create \\\n  --name \"Toggle daily digest\" \\\n  --schedule \"0 18 * * *\" \\\n  --message \"Fetch today's Toggle data and generate my end-of-day digest. Run: python3 {baseDir}/scripts/toggle.py --persist {baseDir}/../../memory --skip-cron-check\"\n\n\nAdjust the digest schedule if the user requests a different digest_time.\n\nIf user declines cron\n\nWrite to {baseDir}/state.yaml:\n\ncron_disabled: true\n\nState file\n\n{baseDir}/state.yaml stores preferences and tracking state. You can read and write it.\n\nUser preferences\nKey\tType\tDefault\tDescription\ncron_disabled\tbool\tfalse\tSkip cron status check\ndigest_enabled\tbool\ttrue\tWhether to generate end-of-day digests\ndigest_time\tstring\t\"18:00\"\tWhen to generate the daily digest (24h format)\nnudge_stale_hours\tint\t48\tHours of inactivity before nudging about a stale project\nfocus_alert_threshold\tint\t30\tproductivityScore below this triggers a context-switch alert\nfocus_alert_window_min\tint\t20\tMinutes of low-focus before alerting\npattern_detection_days\tint\t7\tDays of history to scan for repeated patterns\npattern_min_occurrences\tint\t3\tTimes a workflow must repeat before proposing automation\ntimezone\tstring\tnull\tUser's local timezone (e.g. \"Europe/Sofia\"). Ask once on first run if not set.\nprediction_enabled\tbool\ttrue\tWhether to proactively predict the user's next action\nprediction_min_days\tint\t5\tMinimum days of data before predictions activate\nprediction_confidence_min\tint\t3\tMinimum occurrences of a routine before predicting it\nTracking state (managed by you, the agent)\nKey\tType\tDescription\nlast_nudged\tmap\tProject names → ISO timestamps of last nudge. Don't re-nudge within 24h.\ndismissed_projects\tlist\tProject names the user explicitly dropped. Never nudge these again.\nlast_focus_alert\tstring\tISO timestamp of last context-switch alert. Back off 3h after alerting.\nfocus_alert_paused_until\tstring\tISO date. If set and today ≤ this date, skip focus alerts.\nproposed_patterns\tmap\tPattern description → ISO timestamp. Don't re-propose within 14 days.\nlast_error\tstring\tLast cron error message + timestamp. Clear after reporting to user.\nlast_prediction\tstring\tISO timestamp of last prediction offered. Back off 2h between predictions.\nprediction_dismissed_until\tstring\tISO date. If user declines predictions, pause until this date.\nprediction_hit_log\tlist\tLog of predictions made + whether the user followed them. Use to refine confidence.\nPROACTIVE BEHAVIORS\n\nThese are the core intelligence features. Do not wait for the user to ask. When data is available — through a cron run, a manual fetch, or persisted memory files — analyze it and act.\n\n1. Daily Digest\n\nTrigger: Cron job at the user's digest_time (default 6:00 PM), OR the first interaction after end of workday if no cron is set.\n\nWhat to do:\n\nFetch today's data with --persist and --skip-cron-check\nProduce a short default digest — 3 to 4 lines max:\nTotal work time + session count\nTop focus area (project with most time)\nBiggest open item (most-invested project that still has recent, unfinished activity)\nOne notable stat (focus score trend vs yesterday, longest session, or summary.totalContextSwitches)\n\nDefault format — keep it tight:\n\nYour day: 5.2h across 4 sessions. Deepest focus on auth migration (2.1h, 94 focus). Stripe webhooks still open — you were 80% through. Context switches down to 3 from 6 yesterday.\n\nIf the user asks for more detail, expand to: top 3 focus areas by time, all open items, full focus stats (average score, switch count, longest session), and a tomorrow suggestion.\n\nComparing to yesterday: If yesterday's data exists in {baseDir}/../../memory/, compare total time, focus score, and context-switch count. Note trends. Skip comparison if no prior data exists.\n\n2. Stale Project Nudges\n\nTrigger: Every time you fetch or read Toggle data, scan for stale projects.\n\nA project is stale when both are true:\n\nIt has more than 2 hours of total accumulated time across all days (a real project, not a one-off visit)\nIt has no activity in the last nudge_stale_hours (default: 48 hours)\n\nThat's it. Two criteria. Don't try to infer whether a project is \"completed\" — if it is, the user will dismiss the nudge and you'll record that.\n\nWhat to do:\n\nAfter any data fetch, compare current projects against persisted memory from previous days\nRead {baseDir}/../../memory/*.md files for the past 7 days\nSurface stale projects:\n\nYou haven't touched \"Landing Page Deploy\" in 3 days. Last session: 1.5h on responsive layout. Want me to pull up where you left off?\n\nRules:\n\nMaximum 2 stale nudges per interaction\nCheck last_nudged in state.yaml — skip if same project nudged within 24h\nCheck dismissed_projects — never nudge projects on this list\nIf the user says \"I dropped that\" / \"not working on it\" / \"done with that\", add to dismissed_projects\n3. Context-Switch Alerts\n\nTrigger: When analyzing current or recent data (last 2 hours), detect scattered behavior.\n\nAll three must be true:\n\n3+ different project.name values within a 30-minute window (use startTime to define the window)\nAverage productivityScore across those sessions is below focus_alert_threshold (default: 30)\nThis scattered pattern spans at least focus_alert_window_min minutes (default: 20)\n\nWhat to do:\n\nYou've switched between 5 different things in the last 25 minutes (focus score: 22). Want me to help you lock in on [project with most time today]?\n\nRules:\n\nCheck last_focus_alert — only alert once per 3-hour window\nCheck focus_alert_paused_until — if today ≤ that date, skip entirely\nIf user dismisses (\"I'm fine\" / \"intentionally browsing\"), set focus_alert_paused_until to tomorrow\nFrame as an offer, never a judgment\n4. Pattern Detection & Automation Proposals (Agentify)\n\nTrigger: When 7+ days of persisted data exist in {baseDir}/../../memory/. Run after each daily digest, or when the user asks about patterns or automations.\n\nHow to detect patterns:\n\nRead memory files for the past pattern_detection_days days (default: 7)\nFor each day, sort sessions by startTime to get the chronological sequence\nBuild sequences of (workflowType, project.name) tuples in time order\nIdentify subsequences that appear on pattern_min_occurrences+ different days (default: 3):\nSame projects visited in the same order (e.g. GitHub → Notion → Slack)\nSame workflowType at approximately the same time of day (±1 hour window on startTime)\n\nImportant: Do not assume the API returns entries in chronological order. Always sort by startTime before building sequences.\n\nWhat to propose:\n\nI noticed you check GitHub PR comments, then update Notion, then post in Slack — 4 times this week, ~12 min each. Want me to automate that pipeline?\n\nRules:\n\nCheck what other skills the user has installed. Only propose full automations if the required skills exist\nIf partial: \"I see you do X → Y → Z each morning. Can't automate all of it yet, but I can pre-fetch the data so it's ready.\"\nCheck proposed_patterns in state.yaml — don't re-propose the same pattern within 14 days\nIf approved, help create the appropriate cron job or workflow\n5. Instant Recall — \"What Was I Looking At?\"\n\nTrigger phrases:\n\n\"What was I working on [time period]?\"\n\"What was that thing I was reading on Tuesday?\"\n\"Where did I leave off on [project]?\"\n\"What was I looking at before the meeting?\"\n\"Pick up where I left off\"\n\nWhat to do:\n\nDetermine the date range from the user's question\nFetch data: python3 {baseDir}/scripts/toggle.py --from-date YYYY-MM-DD --to-date YYYY-MM-DD\nAlso check persisted memory: {baseDir}/../../memory/*.md\nUse startTime and endTime for precise timestamps in the answer\nUse workflowDescription for context about what they were doing, not just where\n\n\"Pick up where I left off\" (no other context): Find the most recent type: \"WORK\" session with the highest accumulated time. Describe exactly where they stopped — project, task, time, and description.\n\nTuesday afternoon (2:15–4:30 PM) you were deep in the Kalshi API docs — 1.5h across 3 sessions. Last session ended on the authentication endpoint. Focus: 87.\n\n6. Predictive Context — \"Your Agent Knows What's Next\"\n\nThis is the highest-value behavior. The agent doesn't just know what the user did — with enough history, it knows what they're about to do and can prepare for it.\n\nMinimum data required: prediction_min_days days of persisted memory (default: 5). Do NOT attempt predictions with less data — you'll guess wrong and lose trust. When insufficient data exists, silently skip. Never tell the user \"I don't have enough data to predict yet.\"\n\n6a. Routine Prediction — \"You usually do X right now\"\n\nTrigger: On every cron-triggered fetch, OR when the user starts a new interaction. Compare the current day of week + approximate time (±1 hour) against historical patterns.\n\nHow to build routines:\n\nRead {baseDir}/../../memory/*.md for the past prediction_min_days days\nFor each day, note what project.name and workflowType the user was engaged in at each hour block\nGroup by day of week + hour: e.g. \"Monday 9 AM → PR reviews (4 of last 5 Mondays)\"\nA routine is valid when the same activity appears at the same day+hour on prediction_confidence_min or more occasions (default: 3)\n\nWhat to do when a routine is detected for the current moment:\n\nIt's Tuesday 10 AM — you usually start with PR reviews around now. Want me to pull up open PRs?\n\nCritical rules:\n\nOnly predict if the user hasn't already started doing the thing. Check the most recent session in today's data — if they're already in PR reviews, saying \"you usually do PR reviews now\" is useless. Skip it.\nMaximum 1 routine prediction per 2-hour window. Check last_prediction in state.yaml.\nIf the user follows the prediction (their next session matches), log it as a hit in prediction_hit_log. If they ignore it, log as a miss. Over time, only surface predictions with a >60% hit rate.\nIf the user says \"stop predicting\" or dismisses predictions repeatedly (3 misses in a row), set prediction_dismissed_until to 7 days from now.\n6b. Session Endurance Prediction — \"You're about to hit your wall\"\n\nTrigger: When analyzing current data during a fetch, check if the user is in an active deep-work session.\n\nHow it works:\n\nFrom historical data, calculate the user's average deep-work session duration for the current project (or overall if not enough project-specific data)\nCheck the current active session's duration against that average\nWhen the current session reaches 90% of the average duration, offer a heads-up\n\nExample: If the user's average deep-work session on \"API Integration\" is 95 minutes and they're currently at 85 minutes:\n\nYou're 85 minutes into the API integration — around when you usually take a break. Want me to bookmark where you are so you can pick it up cleanly?\n\nRules:\n\nOnly trigger for sessions with productivityScore above 70 (actual deep work, not scattered browsing)\nOnly trigger once per session — don't nag at 90%, 95%, 100%\nIf the user keeps working past the prediction, that's fine. Don't mention it again. Log the actual duration to improve future estimates.\nNever frame it as \"you should stop.\" Frame it as \"here's a natural breakpoint if you want it.\"\n6c. Next-Task Prediction — \"You just finished X, you usually do Y next\"\n\nTrigger: When the most recent session just ended (the user went from active to inactive, or switched to a different project), check if there's a predictable next step.\n\nHow it works:\n\nFrom historical data, build transition sequences: when the user finishes project A, what do they do next?\nA transition is valid when the same A → B sequence appears on prediction_confidence_min or more occasions\nWhen the user finishes a session that matches the \"A\" side of a known transition, suggest \"B\"\n\nExample: The user just finished a 45-minute session reviewing PRs. Historical data shows that on 4 out of 5 occasions, they move to Notion for sprint notes afterward.\n\nYou just wrapped PR reviews. You usually hop into Notion for sprint notes after this — want me to open your current sprint page?\n\nRules:\n\nOnly predict transitions that are strong (appear on 60%+ of relevant occasions)\nPair with other skills when possible: if you predict they'll go to Notion and the Notion skill is installed, offer to do something useful (open the right page, pre-load context)\nIf the user does something different, log the miss. Transitions that drop below 60% hit rate get retired silently.\n6d. Pre-Meeting Briefing — \"You have context for what's coming\"\n\nTrigger: When calendar data is available (via another skill or the user's schedule), cross-reference upcoming events against Toggle work history.\n\nHow it works:\n\nIf a calendar skill is installed, check for meetings in the next 30 minutes\nSearch Toggle data for work sessions related to the meeting topic (match project.name or workflowDescription against the meeting title/attendees)\nIf relevant work is found, proactively brief the user\n\nExample: A calendar event \"Wallet App Sync\" is in 20 minutes. Toggle data shows 3 sessions this week on the wallet project: TON integration, FATF compliance research, and an auth bug fix.\n\nYou have \"Wallet App Sync\" in 20 minutes. This week you worked on: TON integration (2.1h), FATF compliance research (1.3h), and the auth bug fix (45 min). Want me to draft quick talking points?\n\nRules:\n\nOnly trigger if a calendar skill is available. Do not ask the user about their schedule — that defeats the purpose.\nOnly brief if there's actual Toggle data to cross-reference. An empty briefing (\"you have a meeting in 20 min\") adds no value.\nMaximum 1 briefing per meeting. Deliver it 15–30 minutes before, not 2 hours before.\nFIRST RUN BEHAVIOR\n\nWhen the skill is invoked for the first time (no {baseDir}/state.yaml exists):\n\nFetch today's data to confirm the API key works\nIf the fetch fails: Diagnose using the error handling table. Do NOT proceed to setup. Help fix the connection first.\nIf the fetch succeeds: Present a brief summary, then offer setup:\n\nYour Toggle data is flowing. I can do a lot with this:\n\nAuto-sync — Check your activity every hour so I always have context. Daily digest — Summary of your day at 6 PM, no prompt needed. Smart nudges — Flag projects you haven't touched in a while. Focus alerts — Heads up when you're context-switching too much. Pattern detection — After a week, I'll spot repeated workflows and suggest automations. Predictions — Once I learn your routines, I'll anticipate what you're about to do and have it ready.\n\nWant me to set up auto-sync and the daily digest?\n\nIf they agree, create both cron jobs (see \"Standard cron commands\" above) and write the initial state file with all preference defaults. Also ask: \"What timezone are you in?\" and store the answer in state.yaml under timezone. This ensures all times in digests and predictions are shown in local time.\n\nBEHAVIOR GUIDELINES\nBe proactive, not annoying. Surface insights when they matter. Don't repeat yourself.\nNever announce internal operations. Don't say \"I'm analyzing your Toggle data.\" Just present the result.\nUse the data to make every other skill smarter. If the user asks you to do something and you have Toggle context, use it. Don't silo it.\nPrivacy-first language in all user-facing output. Say \"your activity shows\" or \"based on your sessions.\" Never \"I watched you\" or \"I tracked you.\"\nShort by default. Digests and nudges should be concise. Expand only when the user asks."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/aleksandar-jive/toggle",
    "publisherUrl": "https://clawhub.ai/aleksandar-jive/toggle",
    "owner": "aleksandar-jive",
    "version": "1.0.6",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/toggle",
    "downloadUrl": "https://openagent3.xyz/downloads/toggle",
    "agentUrl": "https://openagent3.xyz/skills/toggle/agent",
    "manifestUrl": "https://openagent3.xyz/skills/toggle/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/toggle/agent.md"
  }
}