Skip to content

Rewrite Settings → Workflows as a flowchart page - #1374

Merged
Birfy merged 1 commit into
mainfrom
workflow-settings-ui-1364
Oct 27, 2026
Merged

Birfy merged 1 commit into
mainfrom
workflow-settings-ui-1364

Conversation

@Birfy

@Birfy Birfy commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Written-by: Dev
Owner: Dev
Reviewer: Reviewer

Fixes #1364

What changed

Settings → Workflows lists the factory pipelines and the workflows saved on this machine, and opens the drag-drop flowchart. A read that fails or never returns shows an error with Retry. An empty store says there are no workflows. The page no longer leads with workflows/<id>.json.

Factory rows are drawable before they are copied. Use this copies a template. A saved workflow can be dragged: move a node, draw an edge, drop a local Bot, or remove a node. Copy is Chinese and English through the settings dictionary. The task board stays. This branch is workflow-settings-ui-1364, rebased onto current main (ed89efc).

Verification at the tip

Tip SHA: cfdad06

Ran:

  • node scripts/ds-bot-patches.mjs check (patches apply, core equals ds-bot + patches)
  • node core/scripts/build-client.mjs --check
  • node --test core/test/workflows-page.test.js plugins/workflow/test/assign.test.js (16 pass)
  • node core/scripts/check-arch-docs.mjs (OK, 18 files)
  • Before the rebase, on the same source change: npm --prefix core test (1892 pass), core lint, plugin lint, changelog check, mojibake check

Not run (and why): a second full npm run verify after the rebase onto ed89efc. The rebase conflict was in generated client.js, the patches, and one docs paragraph; sources were rebuilt and the workflow tests above were re-run on that tree. Smoke bench and a live Desktop session were not run.

Checkpoint

{
  "pr": 1374,
  "claim": "Dev",
  "issue": 1364,
  "summary": "Settings → Workflows lists factory pipelines and saved graphs and opens a drag-drop flowchart. A read that fails or never returns shows an error with Retry. The page no longer leads with workflows/<id>.json. Factory templates are drawable before they are copied. The branch is rebased onto current main.",
  "files": ["core/src/client/workflows.js", "core/src/client/styles.js", "core/src/client/i18n.js", "core/src/client/settings.js", "core/test/workflows-page.test.js", "plugins/workflow/src/template.js", "changelog.d/1364-workflow-settings.fixed.md"],
  "checks": { "ran": "node scripts/ds-bot-patches.mjs check", "result": "green", "at": "cfdad069f2faac1098ecad5bbbbdbcf1d62320c0" },
  "next": "none — ready for review"
}
Open in Web Open in Cursor 

The settings page led with workflows/<id>.json and could stay on
"Reading workflows…" when the host never answered. It now lists the
factory pipelines and the graphs saved on this machine, opens the
drag-drop flowchart, and settles a hung or failed read as an error
with Retry.

Fixes #1364

Co-authored-by: Danyang Chen <birfychen@gmail.com>
@Birfy Birfy added the agent-pr Pull request opened by an agent label Oct 27, 2026

Birfy commented Oct 27, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at cfdad06
Written-by: Reviewer
Attestation: cfdad06 role=Reviewer

Ran:

  • npm --prefix plugins/workflow test — 19 pass, 0 fail

Settings → Workflows lists factory + own workflows and opens the drag-drop flowchart; failed reads show Retry. Branch workflow-settings-ui-1364 is not under frozen cursor/. Fixes #1364. Ready for merge queue.

@Birfy
Birfy enabled auto-merge October 27, 2026 07:28
@github-actions github-actions Bot added the pass label Oct 27, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 9c8e51b Oct 27, 2026
13 of 15 checks passed
@Birfy
Birfy deleted the workflow-settings-ui-1364 branch October 27, 2026 07:32
cursor Bot pushed a commit that referenced this pull request Oct 27, 2026
createPortal was called with no container, so opening a row, New, or
Hand-a-task threw. The sidebar slot boundary then drew nothing until
reload. Portal onto document.body, and keep the node in the section
when that container is missing.

The settings list from #1374 stays. That page does not replace the
sidebar stage.

Fixes #1375
HugoXK pushed a commit to HugoXK/FlyBot that referenced this pull request Oct 27, 2026
…FlowLab#1371) (ThinkFlowLab#1372)

Owner: Dev
Reviewer: Reviewer
Fixes ThinkFlowLab#1371
Tip SHA: 5da667e

**`ThinkFlowLab#1352` removed the frozen-branch seal and left its data file in the
tree; this deletes that file and nothing else.**

## Reproduce

`ThinkFlowLab#1352` merged at `07:12:44Z`, removing `FROZEN_PATH`, `frozenList()`,
`frozenRefusal()` and every call site from
`.github/scripts/enqueue-guard.mjs`. The document those functions read —
`.github/agent/frozen-branches.json` — is still there, byte-identical to
what the seal shipped (blob `12c3f3fe`):

```json
{
  "branches": ["cursor/"],
  "markers": ["CURSOR_AGENT_PR_BODY"]
}
```

**Nothing on `main` reads it.** On a tree extracted from `main`
`9c8e51bf`: `grep -rIn frozen .github/` → the only hit is
`check-dsh-task-shape.mjs:70` talking about a frozen *task record*, not
this file. `grep -rn
'frozen-branches\|frozenList\|frozenRefusal\|external agent branch'`
over `*.mjs`, `*.md`, `*.json`, `*.yml`, `*.yaml` → **no hit** before or
after this deletion: `ThinkFlowLab#1352` removed every reference in the same merge.
The file is dead config.

**It could not be deleted in `ThinkFlowLab#1352`.** `enqueue-guard.yml` is
`pull_request_target` with `ref: main` and never runs pull request code,
so a diff is judged by main's copy of the guard. When `ThinkFlowLab#1352` first
pushed the deletion (`8f97e4f5`, main still carrying the seal), the
check answered:

```
do not enqueue ThinkFlowLab#1352: frozen: .github/agent/frozen-branches.json is not editable by a pull request
```

With the seal on `main` there is no such rule and no reader, so the
deletion is an ordinary change now. **What kind of change it is, is not
mine to pick:** `.github/**` sits at the top of
`.github/agent/risk-rules.json`, so this one-file deletion computes
**T3** and needs a Reviewer PASS at this tip — the tier is not something
a pull request argues its way out of, and `exemptFromPass` is `false`
for it. That ordering — reader first, document second, in two pull
requests — is the mechanical constraint `ThinkFlowLab#1352` recorded in its own Risk
section, not a choice made again here.

## What changed

1. **`.github/agent/frozen-branches.json` deleted** — 69 bytes, 4 lines:
`branches: ["cursor/"]` and `markers: ["CURSOR_AGENT_PR_BODY"]`.
2. **Nothing else.** The diff is `1 file, +0 / −4`; the commit's parent
is the current `main` `9c8e51bf` and no other path differs from it.
3. **The branch was rebuilt as `main` moved** (`2346077a` → `ed89efc4` →
`9c8e51bf`), because a base that lags `main` would mean the checks ran
on a tree missing whatever merged in between. The content of the change
never changed: one deletion.

## What I ran

On `/data/w1372`, a tree extracted from the repository's own tarball of
`main` `9c8e51bf`:

- **Control, the unmodified tree with the file still present:** `node
--test ".github/scripts/*.test.mjs"` → **538 tests, 536 pass, 0 fail, 2
skipped**.
- **With the deletion:** the same command → **538 tests, 536 pass, 0
fail, 2 skipped** — identical line for line. Nothing in the suite reads
the file, which is the point of the change. The two skips are
environmental (`…# SKIP git and bash are needed to run the fetch step`;
this shell has no `git` on `PATH`).
- `node --test .github/scripts/enqueue-guard.test.mjs` → **88 / 88
pass**.
- `node .github/scripts/check-mojibake.mjs` → `ok — 0 occurrences of
U+FFFD in 1163 text file(s)`.
- `node .github/scripts/testing-layers.mjs --check` → `439 test file(s)
in 16 workflow(s)`, every file and every workflow classified.
- `grep` for the seal's four names, deletion in place → 0 lines (exit
1).
- GitHub's own read of this pull request: `1 file, +0 / −4`, base
`9c8e51bf`.

## Red without the source change

**A deletion has no source to revert, so nothing can be made to go red;
claiming one would be a fabrication.** The mechanical substitutes, each
run:

1. **The same diff, two copies of the guard.** At `8f97e4f5` the
identical deletion was refused by main's seal — the sentence quoted
under Reproduce. On this tip the same deletion is judged by the ordinary
rules only. That before/after pair is the real evidence that the
mechanical blocker is gone, and it is why `ThinkFlowLab#1352` had to leave the file
behind.
2. **Suite identity.** 538 / 536 / 2 skipped with the file and without
it — no test reads, imports or resolves it, so its removal changes no
behaviour a test can see.
3. **The grep.** 0 hits for `frozen-branches`, `frozenList`,
`frozenRefusal`, `external agent branch` — there is no second reader to
break.
4. **This pull request's own check run** on `5da667ed`: `enqueue-guard`
must answer with the ordinary rules (`no Verifier report names the tip
…` until a PASS lands) and must **not** print `frozen:` — the seal's
sentence no longer exists on main.

## Not run

- `npm run verify`, `node scripts/ds-bot-patches.mjs check`, `generate`:
nothing under `core/`, `plugins/`, `patches/` or `apps/` is touched.
- `check-arch-docs`: its rule reads `core/` changes; there are none.
- A live queue entry: a pull request cannot stage one without merging;
the guard reads at the queue entry.

## Risk

- **The last trace of the seal goes away with it.** That is the intent:
`ThinkFlowLab#1352` left the document in the tree and wrote that anyone reading the
tree in that window should read it as a stale config, not a live rule.
Deleting it removes the chance of that misreading; no rule changes here,
because no rule has read it since `ThinkFlowLab#1352`.
- **A revert of `ThinkFlowLab#1352` would need this file restored too.** It can be
restored from that commit's tree; this pull request is a later commit on
`main` and does not stand in the way.
- **Nothing outside this repository is known to read the path.** The
only reader in the tree was `enqueue-guard.mjs` and its reference is
gone; a workflow or script that referenced the path would have shown in
the grep above.
- **It needs a PASS, not a tier argument.** `.github/**` is the top rule
in `risk-rules.json`; the computed tier is T3 and `exemptFromPass` is
false. The verdict has to name `5da667ed`.
- **`ThinkFlowLab#1328`, `ThinkFlowLab#1346` and the `cursor/` branches stay as they are.** This
is cleanup of dead data, not a re-litigation of the seal's decision.

## Scope

- `.github/agent/frozen-branches.json` — deleted.

Not touched: `.github/scripts/**` (no code change; `ThinkFlowLab#1352` already
removed the reader), `AGENTS.md`, `docs/`, `core/`, `patches/`,
`.github/workflows/**`, tier calculation, and every tip belonging to
`ThinkFlowLab#1328`, `ThinkFlowLab#1346`, `ThinkFlowLab#1350`, `ThinkFlowLab#1354`, `ThinkFlowLab#1367`, `ThinkFlowLab#1370`, `ThinkFlowLab#1374`.

## Checkpoint

<!-- flybot:checkpoint -->
```json
{
  "pr": 1372,
  "claim": "Dev",
  "issue": 1371,
  "summary": "ThinkFlowLab#1352 removed the frozen-branch seal but left its data file in the tree, because main's copy of the guard refused any pull request that edited or deleted it. This deletes .github/agent/frozen-branches.json and nothing else: one file, +0/-4, rebuilt on the current main. A grep for the seal's four names returns nothing, and the .github/scripts suite gives identical numbers with and without the file (538 tests, 536 pass, 0 fail, 2 environmental skips). Nothing reads the file now, so the only effect is that a stale config can no longer be mistaken for a live rule.",

  "files": [".github/agent/frozen-branches.json"],
  "checks": { "ran": "node --test \".github/scripts/*.test.mjs\" (538/536 pass, 2 environmental skips, identical with and without the file); enqueue-guard 88/88; check-mojibake; testing-layers --check; grep for the seal names", "result": "green", "at": "5da667ed95c5ba47a4db2e83088613494ec42cf3" },
  "next": "Reviewer PASS naming this tip (tier T3: .github/** is the highest rule in risk-rules.json), then the queue"
}
```
<!-- /flybot:checkpoint -->
HugoXK pushed a commit to HugoXK/FlyBot that referenced this pull request Oct 27, 2026
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
Written-by: Dev
Owner: Dev
Reviewer: Reviewer

Fixes ThinkFlowLab#1375

## What changed

Clicking a Workflow row, New, or Hand a task in the sidebar opens that
chat or dialog. The Workflows section stays. Before this, `createPortal`
was called with no container, the call threw, and the sidebar slot
boundary drew nothing until reload.

The stage and the dialogs portal onto `document.body`. When that
container is missing they stay in the section tree. Settings → Workflows
from ThinkFlowLab#1374 is unchanged.

## Red without the change

`node --test plugins/workflow/test/client.test.js` on the unbroken
client, with a `createPortal` that throws the shell's "Target container
is not a DOM element.": the new test failed (`doesNotThrow` on the row
click). The other two tests in that file passed. After the fix the same
file is 3 pass, and the workflow suite is 20 pass, 0 fail.

## Verification at the tip

Tip SHA: 802502d

Ran:
- `TZ=UTC npm run verify` — exit 0. Core lint and `arch-docs: OK (4
changed file(s))`. Plugin lint (workflow reported no warnings).
`build-client --check`. `ds-bot-patches check` (`core/ equals ds-bot/ +
patches/ds-bot/`). Core tests 1795 pass. Social 525, tree 125, timeline
125, workflow 20, all 0 fail. `.github/scripts` 543 pass. Interop 37
pass. Live-e2e 24 pass.
- `git diff origin/main...HEAD --stat` — four files, base `9c8e51bf`
(ThinkFlowLab#1374).

Not run (and why):
- Smoke bench (`dev/bench.sh`): no `../deepseek-harness` checkout.
`core/index.js` and `core/src/host/` are unchanged.
- A live Desktop click-through.
- CI `package` extras (typecheck, actionlint, pack). `verify` is the
local stand-in for `tests-ok` minus that job.

## Checkpoint
<!-- flybot:checkpoint -->
```json
{
  "pr": 1377,
  "claim": "Dev",
  "issue": 1375,
  "summary": "Clicking a Workflow, New, or Hand a task in the sidebar opens the chat or dialog. The Workflows section stays. The stage is portaled onto document.body, and a missing container stays in the section instead of throwing. The Settings → Workflows page from ThinkFlowLab#1374 is unchanged.",
  "files": ["plugins/workflow/client.js", "plugins/workflow/test/client.test.js", "docs/subsystems/workflow.md", "changelog.d/1375-workflow-sidebar.fixed.md"],
  "checks": { "ran": "TZ=UTC npm run verify", "result": "green", "at": "802502d34ec56882d6358acfbc6468f9654319ba" },
  "next": "none — ready for review"
}
```
<!-- /flybot:checkpoint -->

<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-6762f774-969d-5782-a33f-7635b78296b4?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-6762f774-969d-5782-a33f-7635b78296b4&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
HugoXK pushed a commit to HugoXK/FlyBot that referenced this pull request Oct 27, 2026
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
Written-by: Dev

Owner: Dev
Reviewer: Reviewer

Fixes ThinkFlowLab#1373

## What changed
Starting a workflow creates one temporary Bot per node from that node's
prompt, role, model and tools. Those Bots do the step and are removed
when the run finishes, fails for good, or is cancelled. They stay out of
the sidebar. The prompt and the graph are edited in Settings → Workflow
graphs, on the flowchart, or with `define_workflow`.

Rebased onto current `main`
(`c2a7b9ce8ed57764876afb08cb132a0cf95bcedc`). The sidebar portal from
ThinkFlowLab#1377 and the Settings → Workflows page from ThinkFlowLab#1374 stay. A sidebar click
still opens the stage and leaves the Workflows section in place.

## Verification at the tip
Tip SHA: 1bb1aab
The local commit is `8c45bad11740cf45e6d0249c2579f483607d5c26`. Both
have tree `6db2784b6aadf7f36dbe5c16e21342a4a8b31434` and parent
`c2a7b9ce8ed57764876afb08cb132a0cf95bcedc`. GitHub re-encoded the
signature header; GitHub reports that signature verified.
Ran:
- On the rebased tree: `node --test plugins/workflow/test/*.test.js` —
27 pass, including the sidebar click that keeps the section and the
settings/flowchart prompt save.
- On the rebased tree: `node --import ./test/harness-resolve.mjs --test
test/flybot.test.js` in `core/` — 45 pass.
- `node scripts/ds-bot-patches.mjs check` — ok. `git merge-tree
--write-tree HEAD origin/main` — clean, same tree.
- `TZ=UTC npm run verify` reached the core suite (lint, plugin lint,
client check, patch check green). One core cleanup hook failed with
`ENOTEMPTY` on a Feishu temp dir (`core/test/feishu.test.js`); that file
reran alone and passed 9/9. It is not part of this diff.
Not run: bench smoke (`core/dev/bench.sh`). No `../deepseek-harness`
checkout.

## Checkpoint
<!-- flybot:checkpoint -->
```json
{
  "pr": 1380,
  "claim": "Dev",
  "issue": 1373,
  "summary": "Starting a workflow creates one temporary Bot for each node from that node's prompt, role, model and tools. Those Bots carry out the step and are removed when the run finishes, fails for good, or is cancelled, and they stay out of the sidebar. The same prompt and graph can be edited in Settings, on the flowchart, or with define_workflow. A fail-once retry keeps the run Bots until the run actually ends. The sidebar portal and Settings → Workflows page from main stay.",
  "files": ["plugins/workflow/src/ephemeral.js", "plugins/workflow/src/service.js", "plugins/workflow/index.js", "plugins/workflow/client.js", "core/src/host/hooks.js", "core/src/host/roster.js", "core/src/host/channel.js", "core/src/host/tools.js", "docs/subsystems/workflow.md", "changelog.d/1373.added.md"],
  "checks": { "ran": "node --test plugins/workflow/test/*.test.js", "result": "green", "at": "8c45bad11740cf45e6d0249c2579f483607d5c26" },
  "next": "none — ready for review"
}
```
<!-- /flybot:checkpoint -->

<!-- CURSOR_AGENT_PR_BODY_END -->

<div><a
href="https://cursor.com/agents/bc-ca8a6996-0dd3-585c-a8ef-8cbb3f638075?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a
href="https://cursor.com/background-agent?bcId=bc-ca8a6996-0dd3-585c-a8ef-8cbb3f638075&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div>

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rewrite Workflow settings UI to match the group+flowchart demo

2 participants