Classic Workflow logo

Classic Workflow

Organization
serac-labs
classic-workflow

Read and change the classic Workflow engine (wf_workflow, wf_workflow_version, wf_activity, wf_transition, wf_context) — the checked-out-version model, running contexts, and when the right answer is to leave the workflow alone and build the new thing in Flow Designer.

Overview

Publisherserac-labs
Repositoryserac
Skill nameclassic-workflow
Stars
78
Forks
26
Bundled files
Instructions only
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by serac-labs on GitHub. Read the source before you install it.

Installation

Install the Classic Workflow AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/serac-labs/serac.git /tmp/serac
mkdir -p .claude/skills
cp -r /tmp/serac/packages/skills/classic-workflow .claude/skills/classic-workflow
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Classic Workflow in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Classic Workflow on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Classic Workflow is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

The Classic Workflow Engine

Flow Designer is what ServiceNow recommends and flow-designer is the skill for it. This is the other engine — the one that still fulfils catalog items on most instances that have been live more than a few years. blast-radius says outright that legacy workflows are not scanned, so an agent that cannot read one is blind to a large part of what a record actually does.

Every tool here carries a ⚠️ LEGACY marker in its description. That is guidance about what to build, not permission to ignore what exists.

The version model — read this before changing anything

This is the part that catches people out, and the tools do not hide it from you:

wf_workflow            the workflow's identity. Name, table, description. Almost no content.
   └── wf_workflow_version   THE ACTUAL WORKFLOW. One per checkout. Has `published`.
        ├── wf_activity      steps — belong to a VERSION, not to the workflow
        └── wf_transition    edges between activities — also per version
wf_context             one running instance of a published version against one record

A workflow is not edited in place. Checking it out creates a new wf_workflow_version with published = false; you edit that; publishing flips it to published = true and retires the previous one. Records already running keep executing the version they started on — which is why a fix does not apply to work in flight, and why wf_context rows can point at versions nobody can find in the UI.

So the first question about any classic workflow is which version:

javascript
await snow_query_table({
  table: "wf_workflow_version",
  query: "workflow.name=Standard Change Approval^published=true",
  fields: "sys_id,name,published,sys_updated_on",
})

The trap in the write tools

snow_create_workflow_activity and snow_start_workflow both set the workflow_version field, and both resolve a name by looking it up in wf_workflow — which returns a workflow sys_id, not a version sys_id. wf_activity.workflow_version and wf_context.workflow_version reference wf_workflow_version. Passing a name therefore points the new row at a version that does not exist.

Both parameters skip the lookup when you give them a 32-character hex sys_id, and that is the way to use them: resolve the version yourself and pass its sys_id.

javascript
const versions = await snow_query_table({ table: "wf_workflow_version",
                                          query: "workflow=" + workflowSysId + "^published=true",
                                          fields: "sys_id" })
const versionSysId = versions.records[0].sys_id

await snow_create_workflow_activity({ name: "Manager approval", workflowName: versionSysId,
                                      activityType: "approval", order: 100 })

Even done correctly, adding an activity to a published version edits a live workflow underneath running contexts. The safe sequence is checkout → edit the unpublished version → publish, and checkout is a UI operation. If you cannot check out, do not write.

Reading one

snow_workflow_manage is the tool for everything except creation:

javascript
await snow_workflow_manage({ action: "list", table: "sc_req_item" })     // what runs on this table
await snow_workflow_manage({ action: "get", workflow_id: "Standard Change Approval" })
await snow_workflow_manage({ action: "get_history", context_id: ctxSysId })

get returns the workflow with its activities and transitions — enough to describe the graph without opening the UI. list filtered by table is the fastest answer to "what else fires on this record", and the one blast-radius cannot give you.

Running contexts

wf_context is one execution. It is where "the request is stuck" lives.

javascript
// everything currently executing for a workflow
await snow_query_table({ table: "wf_context",
                         query: "workflow_version.workflow.name=Standard Change Approval^state=executing",
                         fields: "id,state,started,workflow_version" })

await snow_workflow_manage({ action: "stop", context_id: ctx })   // cancels the execution
await snow_workflow_manage({ action: "retry", context_id: ctx })  // re-runs the failed activity

stop cancels the run and leaves the record where it is — approvals already generated are not withdrawn and the record's state is not rolled back. Cancelling a context is not undoing a workflow; there is no such operation. Clean up whatever the workflow created separately.

snow_workflow_analyze({ workflow_name, time_range_hours }) aggregates contexts over a window for error and duration patterns. Use it before concluding a workflow is broken — "it never completes" is usually one activity waiting on an approval nobody sees.

Starting one

javascript
await snow_start_workflow({ workflow_sys_id: versionSysId, table: "sc_req_item", record_sys_id: ritm })

It inserts a wf_context and returns. Workflows are asynchronous: a success here means the context was created, not that anything ran. Poll wf_context.state rather than assuming.

Note the same version trap: pass a wf_workflow_version sys_id. If the call succeeds and nothing ever runs, an unresolvable workflow_version is the first thing to check.

When to leave it alone

Classic workflows are a poor place to add behaviour and a fine place to read it. Prefer the honest answer when it applies:

  • The change is new behaviour. Build it in Flow Designer, triggered on the same table, and leave the workflow untouched. Two engines on one record is normal on real instances.
  • The workflow is not the actual problem. A catalog item that stalls is more often a missing approver or an inactive group than the graph.
  • You cannot check out. Editing a published version under running contexts is not a change you can reason about.

The one case for editing it in place: the workflow is wrong and it must keep running for records that are mid-flight. Then it is checkout → edit the version → publish, and every context started before the publish keeps the old behaviour by design.

Related

  • flow-designersys_hub_*, the engine to build new automation in.
  • blast-radius — does not scan classic workflows. snow_workflow_manage({ action: "list", table }) is the manual step that fills that gap.
  • update-set-workflow — a published workflow version is captured; a running context is not.

Frequently asked questions

What does the Classic Workflow AI skill do?

Read and change the classic Workflow engine (wf_workflow, wf_workflow_version, wf_activity, wf_transition, wf_context) — the checked-out-version model, running contexts, and when the right answer is to leave the workflow alone and build the new thing in Flow Designer.

Why use Classic Workflow on TypingMind?

Because you install it once and use it with any model. Classic Workflow is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Classic Workflow in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/serac-labs/serac/tree/main/packages/skills/classic-workflow. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Classic Workflow?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Classic Workflow?

As many as you like. As long as a model supports skills, you can use Classic Workflow with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Classic Workflow AI skill free?

Yes. It is published on GitHub by serac-labs under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇