add-cron
Skill50 starsChanged 21 days agoApache-2.0View on GitHub
Add a scheduled task (cron) to the project: a protected /api/cron route registered on the shared Hypervibe clock, a dedicated Cloudflare Worker, or a GitHub Action. Triggered by an event rather than a clock? /add-automation.
- Reads credentials
- Sends data out
- Commits and pushes
2 other projects use a version of this.
Adopted by
Most recently taken up by
- flavien-ia/hypervibe-craftword for word, first seen Oct 25, 2026
- buildpad-ai/skillstheir own version, first seen Oct 13, 2026
Other versions2 projects use a version of this.
Word for word · 1
- flavien-ia/hypervibe-craft★ 50100% same
Edited · 0
None found.
Wrote their own version · 1
- buildpad-ai/skills★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository89 other files it gives its agents.
- accessibilitySkill
- add-2faSkill
- add-agent-dashboardSkill
- add-aiSkill
- add-analyticsSkill
- add-authSkill
- add-automationSkill
- add-backup-dbSkill
- add-collabSkill
- add-dark-modeSkill
- add-dbSkill
- add-domainSkill
- add-emailSkill
- add-github-authSkill
- add-google-authSkill
- add-i18nSkill
- _add-keyringSkill
- add-mapSkill
- add-notification-centerSkill
- add-push-notificationSkill
- add-pwaSkill
- add-roleSkill
- add-routineSkill
- add-storageSkill
- add-stripeSkill
- add-testSkill
- bootstrapSkill
- _check-depsSkill
- cleanSkill
- _collect-secretSkill
- _convert-to-turborepoSkill
- _create-agentSkill
- _create-cloudflare-workerSkill
- _create-contact-pageSkill
- _create-render-workerSkill
- _create-routineSkill
- _create-workflowSkill
- delete-projectSkill
- _detect-project-rootSkill
- _dns-brevoSkill
- _dns-cloudflareSkill
- _dns-gandiSkill
- _dns-godaddy-manualSkill
- _dns-hostingerSkill
- _dns-infomaniak-manualSkill
- _dns-ionos-manualSkill
- _dns-lwsSkill
- _dns-namecheapSkill
- _dns-ovhSkill
- _dns-porkbunSkill
- _dns-resendSkill
- _dns-squarespace-manualSkill
- eco-auditSkill
- _ensure-aiSkill
- _ensure-vaultSkill
- _generate-secretSkill
- geoSkill
- _get-secretSkill
- gscSkill
- _hash-passwordSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. About 0 are common, 8 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
Use plain, non-technical business language.
- Distinctive: line 23
When generating user-facing content for the scaffolded project (UI labels, emails, copy), write it in the user's language too.
- Distinctive: line 68
Make sure the unified shared worker is provisioned (idempotent, fast when already there):
- Distinctive: line 92
No need for persistent in-memory state between runs
- Distinctive: line 99
If no red flag, continue silently.
- Very specific: line 105
If the user passed a description as an argument ($ARGUMENTS not empty), use it directly.
- Very specific: line 142
Avoid night ticks when the task only matters during the day: prefer 0 6-22 * * * over 0 * * * * when it fits.
- Distinctive: line 143
Never schedule below every 15 min without the user explicitly acknowledging the compute cost.
- Very specific: line 174
If CHOICE=gh AND the task smells timing-critical (frequency > 1x/hour, "exactly at midnight", "reset", user-visible consequence when late), …
- Very specific: line 180
Check whether CRON_SECRET already exists in .env:
- Very specific: line 236
Add --web-dir apps/web if monorepo.
- Very specific: line 251
Create <WEB_DIR>/src/app/api/cron/<TASK_NAME>/route.ts (route protected by CRON_SECRET):
- Distinctive: line 277
If absent → abort, ask the user to push the project to GitHub first.
- Distinctive: line 373
Add as the section intro (created only once):
- Very specific: line 444
If after the final summary the user says *"no, GitHub instead"* / *"give it a dedicated clock"*, restart from Step 6 with the forced CHOICE.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
⚠️ Before any call to wrangler (do this BEFORE any other wrangler command in this skill)
eval "$(node "${CLAUDE_SKILL_DIR}/../../scripts/wrangler-env-init.mjs")"This line loads CLOUDFLARE_API_TOKEN from User scope (Windows registry / shell rc on Mac/Linux) if it is not already in process.env, and adds the pnpm bin to PATH (for bash sessions where pnpm setup has not yet propagated). Without it, wrangler fails with "command not found" on Mac (Spotlight), or may use a different Cloudflare account than the one the user expects.
Add Cron - Scheduled tasks (auto-routing between 3 clocks)
Communication
- Detect the user's language from the conversation (the user's own messages, anywhere in the session - not just this invocation: a bare slash command like
/bootstrapcarries no language signal by itself). If nothing in the conversation gives a signal, fall back to the OS locale (node -e "console.log(Intl.DateTimeFormat().resolvedOptions().locale)") before defaulting to English. ALWAYS reply in that language for every user-facing message: questions, progress, confirmations, summaries, errors - including any example text quoted in this skill, which is illustrative and must be translated, never sent verbatim. - Use plain, non-technical business language. Never expose internal script names (*.mjs) or jargon; describe actions in human terms.
- When generating user-facing content for the scaffolded project (UI labels, emails, copy), write it in the user's language too.
- Show progress as a short natural-language checklist (in-progress and done states).
You add a scheduled task to the current Next.js project. You decide yourself which clock is best, based on the nature of the task. You ask the user NOTHING about this choice - you act, then you explain in 1 sentence what you did in the final summary.
Non-tech audience: language rules
The users of this plugin may be non-technical. In EVERYTHING you show to the user:
- Zero gratuitous jargon. No "Worker", "Action", "workflow", "endpoint", "slot", "trigger", "cron expression", "bearer token", "repo", "yaml" without explanation. When a technical term is unavoidable, put it in parentheses or explain it in a short clause.
- Speak in business terms, not infrastructure. Say "a scheduled task" rather than "a cron", "your shared clock" / "a dedicated clock" / "the GitHub clock" rather than "the hypervibe-jobs worker" / "CF Worker" / "GitHub Action", "your site" rather than "your Next.js endpoint", "your keys" rather than "your env vars".
- NEVER suggest commands to type. The user does not open a terminal. When an action is possible (delete, test, view the logs, change the schedule), offer it in natural language - "tell me 'delete task X' and I'll take care of it", "do you want me to run it right now to test it?". Claude executes, the user does not type.
- Avoid tech anglicisms ("skipped", "overkill", "fallback", "deploy") in user-facing blocks. Internal use only.
Architecture (identical for all 3 clocks)
Clock → fetch() → Vercel /api/cron/<task-name> (protected by CRON_SECRET)The business logic always lives in Next.js (/api/cron/<task-name>/route.ts), protected by a CRON_SECRET bearer. The clock only pings the endpoint at the desired time. What changes between the options is solely who presses the button.
The 3 options
1. Unified shared worker - the DEFAULT (precise, zero extra slot)
The account-wide hypervibe-jobs worker, shared across ALL the user's projects and roles (scheduled pings, database backups, quota watch). Lives in a git-versioned local repo (~/.hypervibe-jobs/), ticks every minute, and consumes ONE Cloudflare cron slot in total no matter how many tasks and projects use it. Precision: to the minute. This is where virtually every scheduled task belongs.
2. Dedicated Cloudflare Worker (only for isolated resources)
A Cloudflare Worker created specifically for this task. Only justified when the task itself needs an isolated Cloudflare binding (its own R2 / KV / D1 / Durable Object) or a secret that must NOT coexist with other projects' secrets. Consumes 1 of the 5 free cron slots on the account.
3. GitHub Action (fallback without Cloudflare)
A YAML workflow in the project's GitHub repo. Used ONLY when Cloudflare is not configured on the machine and the user does not want to configure it. Free on a public repository; on a private one, each run counts at least one minute against the account's Actions minutes (2,000 a month on GitHub's free plan, shared by all its private repositories): an hourly task uses about 720, a task every 15 minutes 2,880. Delays of 30-60 min are possible during peak load.
Preflight - vault unlocked
This skill reads the Cloudflare token from the vault → first, make sure it is unlocked (follow _ensure-vault): node "${CLAUDE_SKILL_DIR}/../../scripts/vault/vault.mjs" status → if locked/expired, run launch.mjs unlock; if the vault does not exist, delegate to _add-keyring. (Not needed if you already know Cloudflare is unavailable and the cron will go to a GitHub Action.)
Step 0 - Preflight: the shared worker
Make sure the unified shared worker is provisioned (idempotent, fast when already there):
eval "$(node "${CLAUDE_SKILL_DIR}/../../scripts/wrangler-env-init.mjs")"
dry=$(node "${CLAUDE_SKILL_DIR}/../../scripts/shared-worker/ensure.mjs" --dry-run)The dry run changes nothing and says whether the real run would deploy: status: "not-scaffolded" (first setup, the clock would be created and deployed), "would-deploy" (the clock is behind or missing on the account; reasons says why), or "in-step" (nothing would change). In step: do not run the real command, treat the dry run's JSON as the provisioning result (it carries dir, workerName, workerUrl, jobs; read its status as already_present). Otherwise, say in one sentence what is about to happen on the user's Cloudflare account, then run the real command below; the guardrail asks for confirmation at that moment, and that question is the user's yes (outside review, 3.1.6):
result=$(node "${CLAUDE_SKILL_DIR}/../../scripts/shared-worker/ensure.mjs")Parse the JSON:
ok=true→ storeCF_OK=true, plusWORKER_DIR,WORKER_URL, and the currentjobscount.statusiscreated(first time - one sentence to the user: "I set up your shared clock, a single mechanism that will serve all your projects") oralready_present(silent).ok=false→ Cloudflare is not usable on this machine (wrangler missing, token missing/locked). StoreCF_OK=false. Do NOT abort: the GitHub clock can still take the task (Step 4 will force it). Mention/startas the way to enable Cloudflare later.
Step 0.b - Sanity check (is the need really a cron?)
Briefly verify that the user's need is really a cron:
Good candidate:
- Periodic tasks that run inside a Vercel function (max 60s, stateless)
- Daily, hourly, or every-N-minutes schedules
- No need for persistent in-memory state between runs
Bad candidate (→ suggest /add-automation instead):
- Long-running process (> 60s)
- Continuous listeners (WebSocket, queue consumers)
- Need for persistent in-memory state
If no red flag, continue silently.
Step 1 - Get the cron description
If the user passed a description as an argument ($ARGUMENTS not empty), use it directly. Do not ask.
Otherwise, ask:
What will this scheduled task be used for?
Describe in one sentence what it should do, e.g.:
- "send a weekly SEO report by email"
- "reset user quotas at midnight"
- "sync Brevo contacts every hour"
- "clean up temporary files every night"
Capture the answer in TASK_DESCRIPTION.
Step 2 - Project prerequisites
Invoke _detect-project-root to retrieve PROJECT_NAME, WEB_DIR, IS_NEXTJS, IS_MONOREPO. Abort if IS_NEXTJS=no.
Step 3 - Ask for the schedule
When do you want this task to run?
Say it in your own words, for example: "every day at 9am", "every Monday morning", "every hour", "on the 1st of the month at midnight".
Convert it into a 5-field UTC cron expression (the user thinks in local time, it is up to you to convert). Store it in CRON_EXPR and keep the human-readable version in CRON_HUMAN.
Bash: date -u +%H
# If you need to convert a local time to UTCCadence guard (Neon wake cost, apply BEFORE accepting the schedule). If the cron route touches the database, every tick wakes the Neon compute for at least 5 minutes (its autosuspend window). The math adds up fast on the Free plan's 100 compute-hours per project per month: every 15 min ≈ 60 CU-h/month, every 20 min ≈ 34, hourly ≈ 15. So:
- If the user asks for a sub-hourly cadence, check whether the actual send/processing windows tolerate hourly (a catch-up window in the handler almost always makes hourly enough , an idempotent handler with a 90-min window is always covered by an hourly tick). If so, propose hourly and explain the quota cost in one sentence.
- Avoid night ticks when the task only matters during the day: prefer
0 6-22 * * *over0 * * * *when it fits. - Never schedule below every 15 min without the user explicitly acknowledging the compute cost.
Also ask:
Give a short name for this task, so we can recognize it easily later. For example:
rapport-hebdo,sync-clients,nettoyage.
Store it in TASK_NAME (kebab-case ASCII).
Step 4 - Infer the clock (silently)
You ask the user nothing. The logic is now simple:
4.a - Detect "isolated resources"
If the description explicitly mentions a need for an isolated Cloudflare R2 / KV / D1 / Durable Object, or a secret that must NOT be shared with other projects on the same account, store NEEDS_DEDICATED_CF=true. Otherwise false. (This is rare: a plain "ping my site on a schedule" task NEVER needs this.)
4.b - Decision
| Case | CF_OK | NEEDS_DEDICATED_CF | → CHOICE |
| 1 | true | false | shared (the default for virtually everything) |
| 2 | true | true | cf-dedicated - but first check a free slot exists: run node "${CLAUDE_SKILL_DIR}/../../scripts/count-cf-cron-slots.mjs"; if cfFree = 0, fall back to shared and note in the summary that the isolated spot was not possible |
| 3 | false | * | gh (no Cloudflare on this machine) |
Also build REASON (1 non-tech sentence) for the final summary:
shared: "I put it on your shared clock: precise to the minute, it serves all your projects at zero extra cost"cf-dedicated: "I gave it its own dedicated clock because this task needs its own isolated storage"gh: "Cloudflare is not set up on this machine, so I used the GitHub clock - free, though on a private repository each run uses at least one of GitHub's 2,000 free minutes a month, and it can run 30-60 minutes late. If that ever matters, run /start to enable Cloudflare and tell me to move the task."
If CHOICE=gh AND the task smells timing-critical (frequency > 1x/hour, "exactly at midnight", "reset", user-visible consequence when late), be honest in the final summary about the concrete impact of a possible delay.
Step 5 - Generate CRON_SECRET (if absent)
Check whether CRON_SECRET already exists in .env:
grep -q "^CRON_SECRET=" .env 2>/dev/null && echo "exists" || echo "missing"If missing
Generate it and send it to the project in one command: the value goes from the generator into .env and Vercel, never into the conversation nor into a process argument (printf is a shell builtin):
NEW_VALUE=$(node "${CLAUDE_SKILL_DIR}/../../scripts/generate-secret.mjs" --format hex --length 32) && [ -n "$NEW_VALUE" ] \
|| { echo "The generator failed: nothing was written."; exit 1; }
printf 'CRON_SECRET=%s\n' "$NEW_VALUE" | node "${CLAUDE_SKILL_DIR}/../../scripts/push-env-vars.mjs" --stdinIf present
Nothing to do here. The commands below read it from .env themselves (env-value.mjs), into a shell variable: the value never appears in the conversation.
Step 6 - Implement according to CHOICE
If CHOICE=shared → unified shared worker (one command does everything)
WEB_DIR_FLAG=""
[ "$IS_MONOREPO" = "yes" ] && WEB_DIR_FLAG="--web-dir apps/web"
[ "$IS_MONOREPO" = "no" ] && WEB_DIR_FLAG="--web-dir ."
CRON_SECRET_VALUE=$(node "${CLAUDE_SKILL_DIR}/../../scripts/env-value.mjs" --project-dir "<WEB_DIR>" CRON_SECRET) \
|| { echo "CRON_SECRET is not in the project's .env: see Step 5."; exit 1; }
result=$(CRON_SECRET_VALUE="$CRON_SECRET_VALUE" node "${CLAUDE_SKILL_DIR}/../../scripts/shared-worker/register.mjs" \
--kind ping \
--task-name "<TASK_NAME>" \
--cron "<CRON_EXPR>" \
--app-url "<NEXT_PUBLIC_APP_URL>" \
--project-name "<PROJECT_NAME>" \
$WEB_DIR_FLAG \
--put-secrets)This single call: creates the protected Next.js route (if absent), registers the task in the versioned registry, commits the change, uploads the project's secret to the shared worker (first time only), and redeploys. Parse the JSON: ok, action (added/replaced), job (the name of the entry in the shared registry, normally <PROJECT_NAME>-<TASK_NAME> - store it as JOB_NAME, the management commands below use it), routeCreated, missingSecrets (should be empty; if not, follow its nextSteps).
If the task ever answers in error (expired secret, renamed route, application crash), the shared worker emails the address already configured for the account's backup/quota alerts, at most once every 6 hours per task. Worth telling the user in plain words: a scheduled task that fails does not retry on its own, so the mail is what tells them the work did not happen. If no job in the registry carries an alert address yet, the failure is only written to the worker logs, which nobody reads - in that case suggest running /add-backup-db or /quotas, which set that address.
If CHOICE=cf-dedicated → dedicated Cloudflare Worker
Invoke _setup-wrangler. Then:
node "${CLAUDE_SKILL_DIR}/../../scripts/setup-cron-worker.mjs" \
--task-name "<TASK_NAME>" \
--cron-expr "<CRON_EXPR>" \
--app-url "<NEXT_PUBLIC_APP_URL>" \
--project-name "<PROJECT_NAME>"Add --web-dir apps/web if monorepo.
Upload the secret + deploy:
V=$(node "${CLAUDE_SKILL_DIR}/../../scripts/env-value.mjs" --project-dir "<WEB_DIR>" CRON_SECRET) \
|| { echo "CRON_SECRET is not in the project's .env: see Step 5."; exit 1; }
cd cron-workers/<TASK_NAME>
printf '%s' "$V" | wrangler secret put CRON_SECRET
wrangler deploy
cd ../..If CHOICE=gh → GitHub Action
6a. Create the Next.js route
Create <WEB_DIR>/src/app/api/cron/<TASK_NAME>/route.ts (route protected by CRON_SECRET):
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
// Closed while CRON_SECRET is missing: the comparison would otherwise accept "Bearer undefined".
const secret = process.env.CRON_SECRET;
if (!secret || req.headers.get("authorization") !== `Bearer ${secret}`) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// YOUR CRON LOGIC HERE - described as: <TASK_DESCRIPTION>
return NextResponse.json({ success: true, timestamp: new Date().toISOString() });
}
export async function GET(req: NextRequest) {
return POST(req);
}6b. Check the GitHub repo
gh repo view --json nameWithOwner -q .nameWithOwnerIf absent → abort, ask the user to push the project to GitHub first.
6c. Push the GitHub secrets
# The secret goes to gh on its standard input (no --body): never in the conversation, never as an argument.
V=$(node "${CLAUDE_SKILL_DIR}/../../scripts/env-value.mjs" --project-dir "<WEB_DIR>" CRON_SECRET) \
|| { echo "CRON_SECRET is not in the project's .env: see Step 5."; exit 1; }
printf '%s' "$V" | gh secret set CRON_SECRET
# The address is public: an argument is fine.
gh secret set CRON_APP_URL --body "<NEXT_PUBLIC_APP_URL>"6d. Create the cron workflow
Write .github/workflows/cron-<TASK_NAME>.yml:
name: Cron - <TASK_NAME>
on:
schedule:
- cron: "<CRON_EXPR>"
workflow_dispatch:
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Ping /api/cron/<TASK_NAME>
env:
CRON_SECRET: ${{ secrets.CRON_SECRET }}
CRON_APP_URL: ${{ secrets.CRON_APP_URL }}
run: |
printf 'header = "Authorization: Bearer %s"\n' "$CRON_SECRET" | curl -fsSL --config - -X POST \
"$CRON_APP_URL/api/cron/<TASK_NAME>"6e. Keepalive workflow: on a public repository only
GitHub only puts the scheduled tasks of public repositories to sleep, after 60 days without activity. On a private repository this workflow would only spend minutes and push an empty commit every month, which triggers a deploy. Read the repository's visibility:
gh repo view --json visibility -q .visibilityPRIVATEorINTERNAL: no keepalive, go on to 6f.PUBLIC: if.github/workflows/keepalive.ymldoes not exist, create it:
name: Keepalive
on:
schedule:
- cron: "0 8 1 * *"
workflow_dispatch:
jobs:
keepalive:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v5
- run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git commit --allow-empty -m "chore: keepalive"
git push6f. Commit + push
git add .github/workflows/ <WEB_DIR>/src/app/api/cron/<TASK_NAME>/
git commit -m "feat: add scheduled task <TASK_NAME> via GitHub Action"
git pushStep 7 - Update CLAUDE.md
Invoke _update-claude-md with:
customheading:## Cron- Body (adapt to the type):
For a shared worker cron:
- **<TASK_NAME>** (shared hypervibe-jobs worker) - `<CRON_EXPR>` (<CRON_HUMAN>) → registered as `<JOB_NAME>` in `~/.hypervibe-jobs/jobs.js` (git-versioned) → calls `/api/cron/<TASK_NAME>`For a dedicated CF Worker cron:
- **<TASK_NAME>** (dedicated Cloudflare Worker) - `<CRON_EXPR>` (<CRON_HUMAN>) → `cron-workers/<TASK_NAME>/` → calls `/api/cron/<TASK_NAME>`For a GitHub Action cron:
- **<TASK_NAME>** (GitHub Action) - `<CRON_EXPR>` (<CRON_HUMAN>) → `.github/workflows/cron-<TASK_NAME>.yml` → calls `/api/cron/<TASK_NAME>`Add as the section intro (created only once):
Scheduled tasks. A clock pings the `/api/cron/<name>` endpoint on the Next.js side, protected by `CRON_SECRET`. The business logic lives in Next.js. 3 possible clocks:
- **Shared hypervibe-jobs worker** (default): one account-wide Cloudflare worker for all projects (pings, backups, quota watch), registry git-versioned in `~/.hypervibe-jobs/`, timing to the minute, 1 CF slot total
- **Dedicated Cloudflare Worker**: only when the task needs isolated resources (own R2/KV/D1), 1 CF slot per task
- **GitHub Action**: fallback without Cloudflare, best-effort (±30-60 min), each run counts at least one Actions minute on a private repository, monthly keepalive on a public one onlyAnd env-vars:
- \CRON_SECRET` - Bearer token used to authenticate cron clock against `/api/cron/<name>``
Step 8 - Final summary
Choose the right block according to CHOICE, incorporating REASON in non-tech language.
If shared
✅ Your task <TASK_NAME> is in place
It will trigger <CRON_HUMAN>.
<REASON><If the shared clock was created on this occasion: "I set up your shared clock for the first time: a single mechanism, versioned and kept safe on your computer, that will serve all your current and future projects at no extra cost.">
For now it does nothing concrete - I prepared the file where you will write what it should do (<TASK_DESCRIPTION>). Tell me what it should run and I'll code the logic for you.
You can also ask me at any time:
- "run the task right now to test it"
- "show me the latest triggers"
- "change the schedule to X"
- "delete this task"
If cf-dedicated
✅ Your task <TASK_NAME> is in place
It will trigger <CRON_HUMAN>.
<REASON>For now it does nothing concrete - I prepared the file where you will write what it should do (<TASK_DESCRIPTION>). Tell me what it should run and I'll code the logic for you.
You can also ask me at any time: "run the task right now to test it", "show me the latest triggers", "change the schedule to X", "delete this task".
If gh
✅ Your task <TASK_NAME> is in place
It will trigger <CRON_HUMAN>.
<REASON>A small reminder: GitHub can be 30 to 60 min late<, concrete consequence for this task if relevant>.<On a private repository: Each trigger counts at least one minute of the computing time GitHub offers you each month (2,000 minutes on its free plan)<, about N minutes a month for this task, if it runs more than hourly>.><If a keepalive was created (public repository): I also added a tiny invisible task that runs once a month to prevent GitHub from disabling the clock if you don't touch the project for 60 days.>
If the delay ever becomes a problem, run
/startto enable Cloudflare on this machine, then tell me "move this task to my shared clock" and I'll migrate it.For now it does nothing concrete - I prepared the file where you will write what it should do (<TASK_DESCRIPTION>). Tell me what it should run and I'll code the logic for you.
Natural-language management (after setup)
On the shared clock, the registry job name is JOB_NAME = <PROJECT_NAME>-<TASK_NAME> (tasks registered by older plugin versions may be listed under <TASK_NAME> alone - when in doubt, --list shows the exact names).
- "run the task right now" (shared clock): trigger it manually through the worker's control endpoint (if
workerUrlisnull(controlPlane: "off": the account has no workers.dev address, so the clock has no manual trigger), skip this call and say when the job runs on its own instead):
(The header reaches curl on its standard input,ADMIN=$(node "${CLAUDE_SKILL_DIR}/../../scripts/_read-user-env.mjs" HYPERVIBE_JOBS_ADMIN_TOKEN) \ && printf 'Authorization: Bearer %s\n' "$ADMIN" | curl -s -X POST -H @- "<WORKER_URL>/trigger?name=<JOB_NAME>"-H @-: the token is never an argument.) For a GitHub clock:gh workflow run cron-<TASK_NAME>.yml. For a dedicated clock, call the route with the project'sCRON_SECRET, read from.envthe same way:V=$(node "${CLAUDE_SKILL_DIR}/../../scripts/env-value.mjs" --project-dir "<WEB_DIR>" CRON_SECRET) \ && printf 'Authorization: Bearer %s\n' "$V" | curl -s -X POST -H @- "<NEXT_PUBLIC_APP_URL>/api/cron/<TASK_NAME>" - "show me my scheduled tasks":
node "${CLAUDE_SKILL_DIR}/../../scripts/shared-worker/register.mjs" --list(+.github/workflows/cron-*.yml+cron-workers/*/for the other clocks). Present them in plain language. - "change the schedule" (shared): re-run the register command from Step 6 with the new
--cron(same project + same task name = update in place). - "delete this task" (shared):
node "${CLAUDE_SKILL_DIR}/../../scripts/shared-worker/register.mjs" --remove --name <JOB_NAME>. Also offer to delete the now-unused/api/cron/<TASK_NAME>route. - If after the final summary the user says "no, GitHub instead" / "give it a dedicated clock", restart from Step 6 with the forced
CHOICE. Not before - the automatic decision is the default.
Resource manifest (always)
Every cloud resource this skill creates or adopts is recorded in the project resource manifest (.hypervibe/resources.json, versioned with the code) - it is what /save-project and /delete-project read first, instead of guessing resources by name. Run the recording right after the resource exists; it is idempotent, silent on success, and stores identifiers only (never secrets). Full reference: the _track-resource skill.
Record the scheduled task, naming the clock that carries it:
node "${CLAUDE_SKILL_DIR}/../../scripts/manifest/manifest.mjs" add --project-dir "<project-root>" \
--kind cron-job --name "<task-name>" --field worker=hypervibe-jobs --field "schedule=<cron-expr>" --added-by add-cronA dedicated worker created for the task is recorded separately by _create-cloudflare-worker. The shared hypervibe-jobs worker, if this is the project's first job on it, gets one informative entry:
node "${CLAUDE_SKILL_DIR}/../../scripts/manifest/manifest.mjs" add --project-dir "<project-root>" \
--kind cf-worker --name hypervibe-jobs --shared --note "shared Hypervibe clock - never deleted with this project" --added-by add-cronDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

