task Plugin
Task definitions, task actions, and cron-trigger runtime owned by one plugin instance
task Plugin
task is the task runtime plugin.
It owns:
- task-facing actions
- task system text
- one cron trigger engine per plugin instance
Main shape
lifecycleactionssystem
What it is for
Use task when you need:
- task definitions and mutations
- cron-triggered task execution
- scheduler reload after task changes
How users use it
Task does not declare Config. It remains visible in the Plugins Catalog for its documentation and also contributes a top-level navigation entry. Its Sidebar uses a Task → runs tree: clicking a Task opens its definition, while expanding it loads runs. The Mainview can create, edit, enable, pause, run, and delete Tasks and display run details. Tasks are not grouped by Agent or Workspace. Task definitions and Runs share TaskPlugin's City lifecycle storage; agent_id and workspace_id are rebindable execution targets rather than storage partitions. A Task remains visible, editable, and removable when either target disappears; deletion is rejected while it is running.
A successful or failed Task Run publishes an unread notification after its artifacts are persisted; skipped runs do not notify. Notifications aggregate to the latest unread Run for the same Task. Desktop reflects that state on the Task icon, Task item, matching Run, and system app badge, and marks it read when the Run is opened.
When a definition commits but incremental scheduler synchronization fails, the host action returns the synchronization failure and Desktop reports that the Task was saved but scheduler synchronization failed. A missing or unparseable canonical task.md is exposed as an error item and is not scheduled. It does not appear absent or prevent other Tasks from recovering, and Desktop can delete it.
The CLI invokes task through the shared Plugin Action command:
city plugin action task list <agent_id> --input '{}' --token <token>
city plugin action task run <agent_id> --input '{"title":"daily-summary","reason":"manual check"}' --token <token>Use the task Plugin when automation should remain named, editable, and manually runnable, instead of adding another top-level CLI special case.
SDK Assembly
Every Task binds one execution Workspace. When create is called from an Agent Session, the runtime automatically captures the current Agent, Workspace, session_id, and origin.type as the fixed delivery target; the model neither needs nor is allowed to provide Session routing in the action payload. Rebinding an Agent or Workspace changes only the execution target, while City continues to deliver results to the original Session. An Agent Task inherits the delivery Session model only when execution and delivery still use the same Agent and Workspace; otherwise it uses the execution Agent model. An SDK registers the built-in Task module with City and binds an Agent:
const registrations = create_builtin_plugin_registrations();
const city = new City({ plugins: registrations, workspaces: [workspace] });
city.agents.add(agent);Cron uses the current machine timezone by default. To customize it, provide
new TaskPlugin({ timezone }) directly to City. One-shot time:<ISO8601-with-timezone> tasks use the
offset embedded in the ISO string itself.
SDK action use
await city.plugins.scope({ agent_id: agent.id, workspace_id: workspace.id }).run_action({
plugin: "task",
action: "run",
payload: {
title: "daily-summary",
reason: "manual check",
},
});The action names are list, history, run_detail, create, run, delete, update, status, enable, and disable. history returns one Task's execution summaries in reverse chronological order; run_detail uses a timestamp returned by history to read final output, errors, and the remaining details.
Important semantics
- the cron scheduler restores the unified Store during TaskPlugin initialize and is released by TaskPlugin's City lifecycle
- cron timezone comes from constructor
timezone, defaulting to the local machine timezone - agent tasks read the effective runtime model from the Session port in PluginContext
- each run creates an independent task Session while reusing the host Agent's complete Plugin capabilities
agent_idandworkspace_idare Task execution settings; the matching execution context is entered only when a trigger fires- Session-scoped
createautomatically stores the current(agent_id, workspace_id, origin.type, session_id)and appends completed results to that Session - Tasks created from CLI, HTTP, or host management surfaces without a Session context have no delivery target, so results remain in run history
- create, update, delete, and status commits reconcile the scheduler incrementally by
task_id - all definition mutations commit serially per TaskPlugin instance; one-shot completion conditionally updates the latest definition
- the running-task lock belongs to the plugin instance, so reloads still keep each task serial
- a running Task cannot be deleted
- scheduler or timer disposal failures do not skip settlement of other runs and lifecycle resources; final failures are aggregated
Public status
TaskPlugin is exported from @downcity/plugins. SDK code provides the instance to City; the CLI
invokes it through the shared city plugin action command.