Skip to content

Applies to Cowork 0.1.45 · For everyone who uses Cowork

Background Tasks ​

Not yet released

A background task is a function that keeps running while the Extension is on, such as a sync every 15 minutes. It needs service in dozin.capabilities. Register it with api.registerService(definition).

ServiceDefinition ​

FieldTypeRequiredDescription
idstringNoDefaults to the package name. Lowercase letters, digits and hyphens. At most 8 per Extension
namestringNoShown in Settings › Extensions, 1–80 characters; defaults to id
start'auto' | 'manual'NoDefault manual. auto starts with the Extension once its secrets are filled in. The person's choice wins
restart{ policy?, maxRetries?, backoffSeconds? }Nopolicy: never, on-failure (default) or always; maxRetries 0–100 (default 5); backoffSeconds 1–10 waits of 1–3600 seconds each (default 5, 30, 120)
stopTimeoutSecondsnumberNo1–30, default 10: how long Stop waits for run to return
run(ctx)functionYesSee below

An invalid field refuses the whole task (registerService throws TypeError); nothing is corrected for you.

run(ctx) Not yet released ​

The task itself. Run until ctx.signal fires.

NameTypeDescription
ctxServiceContextThe fields and functions below

Returns Promise<void>. Returning ends the run. Throwing counts as a failure and is retried by restart. When Stop is pressed and run has not returned within stopTimeoutSeconds, the Extension's process is restarted.

ServiceContext fields ​

FieldTypeDescription
serviceIdstringThe task's key: the package name, or <package>.<id>
runIdstringThis run
signalAbortSignalFires on Stop, Restart, switching the Extension off, uninstalling and quitting Cowork. Check it before each request
envReadonly<Record<string, string>>The values of dozin.secrets. A task with a missing value does not start and shows "Missing configuration"
dataDirstringThe Extension's own data folder, also its working folder

ctx.status(text, level?, progress?) Not yet released ​

Sets the line shown under the task in Settings › Extensions.

NameTypeRequiredDescription
textstringYesThe line; at most 300 characters are kept
level'info' | 'warn' | 'error'NoDefault info
progress{ done: number, total: number }NoShown as progress

Returns nothing. Values of dozin.secrets are replaced with ***. Keep personal data out of it: the line is visible to anyone at the computer.

js
ctx.status('Synced 52 patients', 'info', { done: 52, total: 52 });

ctx.log(text) Not yet released ​

Writes one line to the Extension's log. Values of dozin.secrets are replaced with ***. Returns nothing.

js
ctx.log('round started');

ctx.readJson(rel) Not yet released ​

Reads a JSON file inside dataDir.

NameTypeRequiredDescription
relstringYesPath relative to dataDir

Returns Promise<unknown>: the parsed value, or undefined when the file does not exist. Rejects with PATH_OUTSIDE_DATA for an empty path or a path outside dataDir, and with the parse error when the file is not valid JSON.

ctx.writeJson(rel, value) Not yet released ​

Writes a JSON file inside dataDir, replacing it in one step, so a crash never leaves half a file.

NameTypeRequiredDescription
relstringYesPath relative to dataDir
valueunknownYesAnything JSON.stringify accepts

Returns Promise<void>. Rejects with PATH_OUTSIDE_DATA for an empty path or a path outside dataDir.

After a run has ended, ctx.site and ctx.agent calls from it reject with RUN_ENDED.

Example ​

js
export function activate(api) {
  api.registerService({
    id: 'sync', name: 'Sync', start: 'auto',
    async run(ctx) {
      while (!ctx.signal.aborted) {
        const state = (await ctx.readJson('state.json')) ?? { runs: 0 };
        state.runs += 1;
        await ctx.writeJson('state.json', state);
        ctx.status(`Run ${state.runs} done`);
        await new Promise((resolve) => setTimeout(resolve, 15 * 60 * 1000));
      }
    }
  });
}

For Micromeet Cowork 0.1.41 · build 261111110020