.claude/skills/klytos-scheduled-actions/SKILL.md
Guide for scheduling background tasks, cron jobs, and recurring actions in Klytos CMS. Use when scheduling background tasks, creating cron jobs, running periodic cleanup, executing deferred actions, querying scheduled actions, setting up recurring tasks, handling action retries, managing the action scheduler, or working with ActionScheduler or CronManager.
npx skillsauth add joseconti/klytos klytos-scheduled-actionsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this reference when your plugin needs to run background tasks: daily cleanups, periodic API syncs, deferred processing, or any task that runs on a schedule.
Klytos has two systems:
klytos_schedule_single_action(int $timestamp, string $hook, array $args = [], string $group = ''): string
Returns the action ID.
// Run in 1 hour
$actionId = klytos_schedule_single_action(
time() + 3600,
'my_plugin.send_report',
['report_id' => 42],
'my-plugin'
);
// Handle the action when it fires
klytos_add_action('my_plugin.send_report', function (array $args): void {
$reportId = $args['report_id'];
// ... send the report
klytos_log('info', "Report {$reportId} sent");
});
klytos_schedule_recurring_action(int $timestamp, int $intervalSeconds, string $hook, array $args = [], string $group = ''): string
Minimum interval: 60 seconds.
// Run every hour starting now
$actionId = klytos_schedule_recurring_action(
time(),
3600, // Every hour
'my_plugin.sync_data',
[],
'my-plugin'
);
// Run daily (86400 seconds)
$actionId = klytos_schedule_recurring_action(
time(),
86400,
'my_plugin.daily_cleanup',
[],
'my-plugin'
);
// Cancel by ID
klytos_cancel_scheduled_action(string $actionId): bool
// Cancel ALL pending actions for a hook
klytos_unschedule_all_actions(string $hook, array $args = [], string $group = ''): int
// Cancel specific action
klytos_cancel_scheduled_action($actionId);
// Cancel all sync actions
$count = klytos_unschedule_all_actions('my_plugin.sync_data', [], 'my-plugin');
// Next run timestamp (or null)
klytos_next_scheduled_action(string $hook, array $args = [], string $group = ''): ?int
// Is action scheduled?
klytos_is_scheduled_action(string $hook, array $args = [], string $group = ''): bool
// Check before scheduling (avoid duplicates)
if (!klytos_is_scheduled_action('my_plugin.sync_data')) {
klytos_schedule_recurring_action(time(), 3600, 'my_plugin.sync_data', [], 'my-plugin');
}
// Get next run time
$next = klytos_next_scheduled_action('my_plugin.sync_data');
if ($next) {
echo "Next sync: " . date('Y-m-d H:i:s', $next);
}
[
'id' => string, // UUID
'hook' => string, // Hook name to fire
'args' => array, // Arguments for the hook
'group' => string, // Organization group
'status' => string, // 'pending', 'completed', 'failed', 'canceled'
'type' => string, // 'single' or 'recurring'
'interval' => ?int, // Seconds between runs (null for single)
'scheduled_at' => string, // ISO 8601 — when it should run
'started_at' => ?string, // When execution started
'completed_at' => ?string, // When execution finished
'attempts' => int, // Current attempt count
'max_attempts' => int, // Max retries (default: 3)
'last_error' => ?string, // Last error message
'created_at' => string, // ISO 8601
'updated_at' => string, // ISO 8601
]
cli.php scheduler:run every minuteFailed actions are retried up to max_attempts (default: 3) with exponential backoff.
{
"timestamp": 1711900800,
"hook": "my_plugin.send_report",
"args": {"report_id": 42},
"group": "my-plugin"
}
{
"timestamp": 1711900800,
"interval_seconds": 86400,
"hook": "my_plugin.daily_cleanup",
"args": {},
"group": "my-plugin"
}
{
"action_id": "abc123-def456"
}
{
"status": "pending",
"group": "my-plugin"
}
Returns scheduler health: queue size, last run, next run, failed count.
admin/scheduled-actions.phpFor simple recurring tasks. Runs on every admin page load.
klytos_add_filter('cron.tasks', function (array $tasks): array {
$tasks[] = [
'id' => 'my_plugin_daily_task',
'callback' => function (): void {
klytos_log('info', 'Running daily task');
// ... task logic
},
'interval' => 'daily',
];
return $tasks;
});
| Interval | Seconds | Description |
|---|---|---|
| 'hourly' | 3600 | Every hour |
| 'daily' | 86400 | Every 24 hours |
| 'weekly' | 604800 | Every 7 days |
| 'monthly' | 2592000 | Every 30 days |
| Task | Interval | Purpose |
|---|---|---|
| analytics_prune | daily | Prune analytics data older than 90 days |
| audit_log_prune | daily | Prune audit logs older than 90 days |
| rate_limit_cleanup | hourly | Clean expired rate limit entries |
| Scenario | System | Why | |---|---|---| | Run once in 1 hour | Action Scheduler | Single action with timestamp | | Run every day | Action Scheduler | Recurring with 86400 interval | | Retry on failure | Action Scheduler | Built-in retry logic | | Simple daily cleanup | CronManager | Simple, no retry needed | | Process queue of items | Action Scheduler | Each item can be its own action | | Deferred heavy processing | Action Scheduler | Runs via server cron, not on page load |
Recommendation: Use the Action Scheduler for new code. CronManager is maintained for backwards compatibility.
Always check before scheduling to avoid duplicate actions:
if (!klytos_is_scheduled_action('my_plugin.sync')) {
klytos_schedule_recurring_action(time(), 3600, 'my_plugin.sync');
}
Use groups to organize actions by plugin:
klytos_schedule_single_action(time() + 60, 'my_hook', [], 'my-plugin');
Clean up on deactivation:
// plugins/my-plugin/deactivate.php
klytos_unschedule_all_actions('my_plugin.sync', [], 'my-plugin');
klytos_unschedule_all_actions('my_plugin.cleanup', [], 'my-plugin');
Keep actions short — long-running actions may timeout. Break large tasks into smaller actions.
Log results for debugging:
klytos_add_action('my_plugin.sync', function (): void {
$start = microtime(true);
// ... work
$duration = round(microtime(true) - $start, 2);
klytos_log('info', "Sync completed in {$duration}s");
});
core/action-scheduler.phpcore/cron-manager.phpcore/helpers-global.php (lines 574-655)core/mcp/tools/scheduler-tools.phpadmin/scheduled-actions.phpdevelopment
Guide for working with dates, times, and timezones in Klytos CMS. Use when formatting dates, converting timezones, scheduling actions with timestamps, displaying local time, working with UTC storage, building timezone selectors, or using any klytos_date/klytos_gmdate/klytos_timezone functions.
tools
Guide for developing and extending the Klytos web terminal. Use when modifying terminal commands, adding terminal commands from plugins, fixing terminal bugs, extending the pseudo-terminal, working with TerminalExecutor class, registering custom permissions, adding custom category labels, or managing terminal UI and security.
development
--- name: klytos-site-builder description: Guide for building a complete website from scratch with Klytos CMS. Use when creating a new site, configuring a site after installation, setting up design/content/SEO/navigation, or when the user pastes the post-install prompt. Covers 9 phases: discovery, design reference, global config, theme, content structure, templates, content creation, additional features, and launch. --- # Klytos Site Builder ## Overview The Site Builder is a conversational AI
development
Use when creating or editing page content in Klytos CMS. Ensures every page has proper SEO structure, HTML semantics, meta tags, structured data, accessibility for maximum search engine visibility. Apply when writing page titles, descriptions, content, headings, images, internal links, JSON-LD schema, or following the SEO checklist before publishing pages.