Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
211 commits
Select commit Hold shift + click to select a range
5350e41
fix(log): restructure log directory retention
Jun 3, 2026
2282ec2
fix(log): address retention review feedback
Jun 4, 2026
602cc5a
Merge pull request #368 from AgentFlocks/fix/logging-retention-stability
xiami762 Jun 4, 2026
244d132
fix(updater): avoid Windows project install during dependency sync (#…
xiami762 Jun 4, 2026
025e4f3
fix(tdp): normalize base_url by stripping UI/API path suffixes (#376)
xiami762 Jun 5, 2026
decc503
feat(workspace): jsonl text preview and Files tab load stability (#367)
xiami762 Jun 5, 2026
53c7b2e
fix(session): recover orphaned running tools after server restart (#370)
xiami762 Jun 5, 2026
b09b9ea
feat(webui): improve workflow graph layout and editor edge UX (#379)
xiami762 Jun 5, 2026
f27ab70
Feat/workflow trigger integration (#375)
xiami762 Jun 5, 2026
8aaa1bf
feat(device): add multi-room support and i18n for device integration
duguwanglong Jun 5, 2026
281611f
Merge pull request #380 from AgentFlocks/feat/device-multi-room
xiami762 Jun 5, 2026
b29d961
feat(device): auto-inject device_id into tool test params
duguwanglong Jun 5, 2026
f5b1320
Merge pull request #382 from AgentFlocks/feat/device-tool-test-auto-d…
xiami762 Jun 5, 2026
bb0d8c3
fix(device): preserve device_id when applying a test fixture
duguwanglong Jun 5, 2026
767aa0b
fix(device): sync toolEnabled state into ToolDetailModal on open
duguwanglong Jun 5, 2026
e346088
feat(webui,device,web2cli): custom device access wizard and credentia…
xiami762 Jun 5, 2026
4d43671
fix(credential-context): resolve config override for versioned SERVIC…
duguwanglong Jun 5, 2026
57664c8
feat(session): add concise workflow tool output (#381)
xiami762 Jun 5, 2026
d40ca8d
fix: correct merge order and operator precedence from review
duguwanglong Jun 5, 2026
7c849b1
refactor(credential-context): address S2/S3/S4 from PR review
duguwanglong Jun 5, 2026
0f10cd0
test: fix ContextVar isolation and remove unused import
duguwanglong Jun 5, 2026
78ca7ed
Merge pull request #383 from AgentFlocks/fix/device-tool-test-fixture…
xiami762 Jun 5, 2026
4daef11
feat(channel): complete bidirectional file/image support for wecom, d…
xiami762 Jun 6, 2026
193fc55
docs(channel): add review guide for file/image attachment support
xiami762 Jun 6, 2026
cd6a3a8
docs(channel): remove standalone review guide (move content into PR d…
xiami762 Jun 6, 2026
2c1480c
docs(contributing): restructure PR description guidelines around chan…
xiami762 Jun 6, 2026
f0b57df
build(deps): bump starlette to >=1.0.1
xiami762 Jun 7, 2026
c3ac89d
fix(webui): remove global flex-col wrapper from standard pages (#384)
xiami762 Jun 8, 2026
47be58e
feat(user-defined-pages): add custom page runtime (#389)
Jieatgit Jun 8, 2026
e061ffa
Fix Telegram file roundtrip media upload
xiami762 Jun 8, 2026
e3cfcda
Fix channel media filename and caption handling
xiami762 Jun 8, 2026
de7b075
fix(provider): thinking params (#387)
xiami762 Jun 8, 2026
40c1c5f
feat(workflow): improve diagram usability
duguwanglong Jun 8, 2026
15e0dc0
chore(gitignore): ignore .codex/ directory
xiami762 Jun 8, 2026
a46c244
Merge pull request #393 from AgentFlocks/chore/ignore-codex
stephamie7 Jun 8, 2026
d107d0c
Fix fallback port conflict detection (#394)
xiami762 Jun 9, 2026
6839175
Improve chat model picker controls (#391)
xiami762 Jun 9, 2026
532bf38
Merge pull request #386 from AgentFlocks/feat/channel-file-roundtrip
xiami762 Jun 9, 2026
67b55cd
refactor: unify subagent delegation under delegate_task (#385)
xiami762 Jun 9, 2026
ea2b7d0
feat(workflow): support config-driven publish templates
duguwanglong Jun 9, 2026
54dfd66
feat(workflow): add editable workflow document flow
duguwanglong Jun 9, 2026
ddd44d6
Merge branch 'dev' of github.com:AgentFlocks/flocks into feat/workflo…
duguwanglong Jun 9, 2026
e00226a
feat(session): refine chat selector controls
duguwanglong Jun 9, 2026
cc7712f
Fix channel image preview rendering
xiami762 Jun 9, 2026
1f48e4b
Fix DingTalk inbound file detection
xiami762 Jun 9, 2026
24c5bb9
feat(session): refine agent and model selectors
duguwanglong Jun 9, 2026
e58e324
Merge pull request #397 from AgentFlocks/fix/channel-file-image-render
stephamie7 Jun 9, 2026
aed9d41
feat(session): add context usage indicator
duguwanglong Jun 9, 2026
4cb2601
fix(session): stabilize selector button widths
duguwanglong Jun 9, 2026
4638011
fix(session): localize selector control widths
duguwanglong Jun 9, 2026
bd34a35
fix(session): cap adaptive agent selector width
duguwanglong Jun 9, 2026
970c8d1
fix(session): stabilize streaming status (#396)
xiami762 Jun 9, 2026
60a9e94
Merge pull request #398 from AgentFlocks/input-selector-visual-tuning
xiami762 Jun 9, 2026
707c801
Reduce workflow default log noise (#399)
xiami762 Jun 9, 2026
4d798c2
fix: clarify browser doctor and session streaming status (#400)
xiami762 Jun 9, 2026
f0c4e07
feat(workflow): add publish config templates
duguwanglong Jun 9, 2026
d373579
revert(workflow): restore pre-pr398 workflow experience
duguwanglong Jun 9, 2026
f51a309
Merge pull request #401 from AgentFlocks/codex-revert-pr398-workflow
xiami762 Jun 9, 2026
3e419ac
feat(device): unify device plugin intake (#392)
xiami762 Jun 9, 2026
c4c4d0a
feat(workflows): improve workflow configuration UX
duguwanglong Jun 9, 2026
d31716c
fix(channel): preserve plugin instances across load_all (#402)
xiami762 Jun 10, 2026
cd47968
Fix session model persistence (#403)
xiami762 Jun 10, 2026
3a3a033
feat(device): Improve device integration auto-sync (#405)
xiami762 Jun 10, 2026
a4d7090
fix: default model reasoning to enabled (#406)
xiami762 Jun 10, 2026
247eadf
fix skill install from GitHub blob URLs (#407)
xiami762 Jun 10, 2026
4e7744b
chore/update-version-2026-6-10 (#408)
stephamie7 Jun 10, 2026
e889883
feat(workflows): improve workbench publishing guidance
duguwanglong Jun 10, 2026
a3e54e2
Fix device refresh sync flow (#410)
xiami762 Jun 10, 2026
a79b7e6
feat(workflow): refine builder workbench experience
duguwanglong Jun 10, 2026
5e81171
docs: reorganize web2cli reference guides (#411)
xiami762 Jun 10, 2026
18a911f
feat(tool): Add l IM send message tool (#404)
xiami762 Jun 11, 2026
796e01b
fix: bound SSH connection pool (#415)
xiami762 Jun 11, 2026
d1e5589
feat(device): add 360 FW v5.5 integration
magicmagicspider Jun 8, 2026
9bb498e
feat(session): refine todo tool rendering
duguwanglong Jun 11, 2026
fab2172
Fix updater cancellation and session statistics (#414)
xiami762 Jun 11, 2026
7d63769
Support structured ACP command arguments (#412)
JohnYin-hub Jun 11, 2026
88be504
Merge pull request #416 from AgentFlocks/feat/todo-write-flat-ui
xiami762 Jun 11, 2026
f8c1be4
fix(sip): preserve plugin result output
duguwanglong Jun 11, 2026
e2ec55e
Fix Windows updater venv rotation (#413)
xiami762 Jun 11, 2026
24166bd
Merge pull request #419 from AgentFlocks/fix/sip-toolresult-compat
xiami762 Jun 11, 2026
ee3f29b
Fix skill install timeouts and session streaming state (#418)
xiami762 Jun 11, 2026
d8c24cb
fix(updater): preserve restart after upgrade disconnect
Jun 11, 2026
6b040a4
Merge pull request #422 from AgentFlocks/fix-updater-restart-handover
stephamie7 Jun 11, 2026
0aeb7e8
fix: handle windows image paths and default workflow history
Jun 11, 2026
5baede8
Merge pull request #423 from AgentFlocks/fix-windows-image-rendering-…
stephamie7 Jun 11, 2026
1ffbed3
feat(workflow): improve workbench and publishing flows
duguwanglong Jun 11, 2026
cc5dd34
Merge branch 'dev' of github.com:AgentFlocks/flocks into feat/workflo…
duguwanglong Jun 11, 2026
791ea92
fix(workflow): show guide info tooltip above panels
duguwanglong Jun 11, 2026
8a5d47c
fix(updater): restore restart argv reconstruction
xiami762 Jun 11, 2026
8429de2
chore(updater): remove unused service restart argv helper
xiami762 Jun 11, 2026
d3e63b8
Add Windows updater restart handoff
xiami762 Jun 11, 2026
17b3693
fix(updater): tune restart handoff timeouts
xiami762 Jun 11, 2026
f25237f
Merge pull request #426 from AgentFlocks/fix/updater-restart-argv
stephamie7 Jun 12, 2026
a165330
fix(session): correct context usage after compaction
duguwanglong Jun 12, 2026
9033809
fix(session): handle multimodal image paths across platforms
Jun 12, 2026
6b5a138
fix(provider): enable vision for ThreatBook MiniMax M3
Jun 12, 2026
e0b18c9
fix(workflow): preserve cron schedules and refine guides
duguwanglong Jun 12, 2026
0a7e7cf
Merge pull request #427 from AgentFlocks/fix-multimodal-image-paths
stephamie7 Jun 12, 2026
77b0411
fix(updater): defer dependency sync to restart handoff
Jun 12, 2026
9114971
chore(skills): remove unused cybersecurity skills
Jun 12, 2026
c31fe0b
chore(skills): remove supply chain malware analysis skill
Jun 12, 2026
4d47fe8
feat(workflow): improve workflow authoring usability
duguwanglong Jun 12, 2026
98db373
fix(provider): support configured OpenAI-compatible extra_body (#424)
xiami762 Jun 12, 2026
a7248bb
Merge pull request #425 from AgentFlocks/feat/workflow-usability
xiami762 Jun 12, 2026
1300597
Resolve custom model limits automatically (#421)
xiami762 Jun 12, 2026
9a56308
Merge branch 'dev' of github.com:AgentFlocks/flocks into fix/context-…
duguwanglong Jun 12, 2026
06fba7c
fix(session): attribute context usage breakdown
duguwanglong Jun 12, 2026
9baaed1
fix(session): exclude delegated tools from usage calls
duguwanglong Jun 12, 2026
689f860
fix(session): include system prompt usage segment
duguwanglong Jun 12, 2026
850f000
fix(session): count tool schemas as definitions
duguwanglong Jun 12, 2026
51e95e6
fix(session): show zero agent delegation usage
duguwanglong Jun 12, 2026
7d055c7
fix(session): split reasoning from conversation usage
duguwanglong Jun 12, 2026
c2bef6d
fix(session): refine context usage and compaction divider
duguwanglong Jun 12, 2026
5e492a2
Merge pull request #428 from AgentFlocks/fix-updater-handoff-dependen…
stephamie7 Jun 12, 2026
f01aa01
fix(session): constrain compaction divider width
duguwanglong Jun 12, 2026
ae0bf8d
fix(session): show compacted history in timeline
duguwanglong Jun 12, 2026
acb4643
fix(session): reset context usage after compaction
duguwanglong Jun 12, 2026
57691d7
fix(session): stabilize context usage popover
duguwanglong Jun 12, 2026
7c11839
fix(session): compact only new turns after summary
duguwanglong Jun 12, 2026
30e7ec7
fix(session): refresh context usage on compaction failure
duguwanglong Jun 12, 2026
173f291
fix(session): keep context usage during compaction
duguwanglong Jun 12, 2026
7b6c556
fix(session): reduce context usage refresh overhead
duguwanglong Jun 12, 2026
14dc1f7
Merge pull request #429 from AgentFlocks/fix/context-usage-popover
xiami762 Jun 12, 2026
bed5ad0
Merge pull request #420 from magicmagicspider/feat/360-fw-device
xiami762 Jun 15, 2026
c995cca
Add WebUI dark mode support (#430)
xiami762 Jun 15, 2026
719b956
fix(workflow): collapse invisible chat process markers
duguwanglong Jun 15, 2026
a22b96c
fix(workflow): stabilize compact chat bubble width
duguwanglong Jun 15, 2026
586f6ec
Merge branch 'dev' of github.com:AgentFlocks/flocks into fix/workflow…
duguwanglong Jun 15, 2026
8ca6b87
fix(session): expand grouped process steps by default
duguwanglong Jun 15, 2026
b20b704
Merge pull request #432 from AgentFlocks/fix/workflow-process-collapse
xiami762 Jun 15, 2026
c95b990
fix(session): enforce disabled agent availability (#433)
xiami762 Jun 15, 2026
caf9239
feat(workflow): improve publish runtime configuration
duguwanglong Jun 15, 2026
ac82700
feat: add persistent goal mode (#431)
xiami762 Jun 15, 2026
4ab9d53
Merge pull request #434 from AgentFlocks/feat/workflow-publish-ui
xiami762 Jun 15, 2026
7062f1d
feat(webui): add guided Rex creation for capabilities
duguwanglong Jun 15, 2026
3fc1c90
feat(workflow): refine overview run experience
duguwanglong Jun 15, 2026
721add9
feat(webui): refine guided capability workbench
duguwanglong Jun 15, 2026
54724ef
fix(webui): handle guided workbench edge cases
duguwanglong Jun 15, 2026
1e55fb7
fix(webui): load user page bundles with credentials
duguwanglong Jun 15, 2026
3be2ec5
fix: enforce workflow API keys and restore agent tests
duguwanglong Jun 15, 2026
40b36fd
Merge pull request #436 from AgentFlocks/feat/guided-capability-creation
xiami762 Jun 15, 2026
0f80fd6
Reduce workflow progress storage contention (#435)
xiami762 Jun 15, 2026
883b3f1
fix(user-defined-pages): handle client disconnects in page api
duguwanglong Jun 16, 2026
834fc92
Merge pull request #438 from AgentFlocks/feat/workflow-run-followup
xiami762 Jun 16, 2026
04b6bb6
fix: preserve device draft config during tests (#437)
xiami762 Jun 16, 2026
a3b242e
fix(workflow): improve API service recovery
Jun 16, 2026
e4de7a4
fix(workflow): prevent workbench interaction timeouts
duguwanglong Jun 16, 2026
be7d651
Merge pull request #439 from AgentFlocks/fix-workflow-api-service-rec…
stephamie7 Jun 16, 2026
ffc7f3a
fix: improve device plugin loading and config defaults
Jun 17, 2026
09c4991
fix(webui): collapse entity workbench process details
duguwanglong Jun 17, 2026
8b5081b
fix: load package entry points for tool plugins
Jun 17, 2026
55771ac
fix: align device tool switch semantics
Jun 17, 2026
62f40e8
fix(webui): align entity Rex workbench with workflow
duguwanglong Jun 17, 2026
a234dd4
fix(webui): document workflow config API auth
duguwanglong Jun 17, 2026
3e5bd5d
Merge pull request #441 from AgentFlocks/fix-device-plugin-refresh
stephamie7 Jun 17, 2026
c9ca51d
fix(workflow): stabilize API service publishing
duguwanglong Jun 17, 2026
25ff7ed
Merge pull request #442 from AgentFlocks/fix/workbench-session-collapse
stephamie7 Jun 17, 2026
2161941
Merge pull request #440 from AgentFlocks/fix/workflow-workbench-timeouts
stephamie7 Jun 17, 2026
85a9439
fix(deps): upgrade litellm for CVE-2026-42271
duguwanglong Jun 17, 2026
7ff2d17
Merge pull request #443 from AgentFlocks/fix/litellm-cve-2026-42271
xiami762 Jun 17, 2026
ab457bd
fix(workflow): stabilize docker publish startup
Jun 17, 2026
e996d55
fix: prevent dingtalk stream from blocking event loop
Jun 17, 2026
bb70ce7
Merge pull request #444 from AgentFlocks/fix/docker-workflow-publish
stephamie7 Jun 17, 2026
e4e391a
Merge pull request #445 from AgentFlocks/fix/dingtalk-stream-event-lo…
stephamie7 Jun 17, 2026
737ba82
chore/update-version-2026-6-17 (#446)
stephamie7 Jun 17, 2026
e1b8ad8
Merge branch 'main' into fix/resolve-dev-main-conflicts
duguwanglong Jun 17, 2026
b8ab62a
Merge pull request #447 from AgentFlocks/fix/resolve-dev-main-conflicts
stephamie7 Jun 17, 2026
670261a
fix(cli): constrain typer below incompatible release
duguwanglong Jun 17, 2026
12238f6
Fix workflow integration tab JSX closure
Jun 17, 2026
d6b401f
Merge pull request #449 from AgentFlocks/fix/cli-and-ci-failures
xiami762 Jun 17, 2026
f8b811f
Remove duplicate WebUI declarations
Jun 17, 2026
9d9006b
Merge pull request #450 from AgentFlocks/fix/workflow-integration-tab…
stephamie7 Jun 17, 2026
0f77242
fix(ci): restore FlocksHub validation
duguwanglong Jun 17, 2026
960aac2
Merge pull request #452 from AgentFlocks/fix/flockshub-ci-validation
stephamie7 Jun 17, 2026
885f79c
perf: optimize session page loading (#453)
xiami762 Jun 18, 2026
2304d35
fix: allow nested delegation and clean Windows installs (#456)
xiami762 Jun 18, 2026
754d5bf
chore/update-version-2026-6-18 (#457)
stephamie7 Jun 18, 2026
2174abc
v2026.06.17 (#451) (#458)
stephamie7 Jun 18, 2026
c2c4abd
Merge main into dev and resolve conflicts
Jun 18, 2026
3212465
Merge pull request #460 from AgentFlocks/resolve-main-dev-conflicts
stephamie7 Jun 18, 2026
51150f5
fix: cap service log files before daemon startup
Jun 22, 2026
26cca0a
fix(task): tolerate legacy task text encoding
Jun 22, 2026
f32b86e
Merge pull request #462 from AgentFlocks/fix-service-log-size-cap
stephamie7 Jun 22, 2026
c9ed5a2
Merge pull request #463 from AgentFlocks/fix-task-legacy-text-decoding
stephamie7 Jun 22, 2026
3289dc6
Split storage into task and workflow databases
Jun 22, 2026
c462e08
Merge dev into split storage branch
Jun 22, 2026
32ac60f
Fix multi-db routing edge cases
Jun 22, 2026
ee2dd5e
Fix multi-db migration safety and routing
Jun 23, 2026
23e0820
chore: sync main into dev on main updates
stephamie7 Jun 23, 2026
9430d82
fix(webui): default to light theme (#468)
xiami762 Jun 23, 2026
7073c2d
Limit workflow execution history by index
Jun 23, 2026
05d0bc6
fix(session): refine process folding and tool rendering
duguwanglong Jun 23, 2026
6c9f6ad
Merge pull request #470 from AgentFlocks/fix/session-global-collapse
xiami762 Jun 23, 2026
4198db3
Merge pull request #465 from AgentFlocks/split-storage-multi-db
stephamie7 Jun 24, 2026
607bcdc
docs: refresh readme header badges
Jun 24, 2026
8bbfbe4
fix: tolerate windows start build runtime failures
Jun 24, 2026
74ea92d
docs: move README tagline under title
Jun 24, 2026
53f318a
docs: center README title and tagline
Jun 24, 2026
2b74a33
Merge pull request #472 from AgentFlocks/fix-windows-start-build-runtime
stephamie7 Jun 24, 2026
d2ce531
Merge pull request #469 from AgentFlocks/sync-main-into-dev-on-main-u…
xiami762 Jun 24, 2026
8580e85
fix(storage): keep source rows during multi-db migration
Jun 24, 2026
c2a64a1
Merge pull request #474 from AgentFlocks/fix-copy-only-db-migration
stephamie7 Jun 24, 2026
fd13e55
Merge pull request #473 from AgentFlocks/docs-readme-header-badges
stephamie7 Jun 24, 2026
2fed040
feat(device): add Rex-guided device onboarding (#471)
xiami762 Jun 24, 2026
37ef451
[codex] Port pro update bug fixes to dev (#475)
stephamie7 Jun 24, 2026
b395196
Revert "[codex] Port pro update bug fixes to dev (#475)" (#476)
stephamie7 Jun 24, 2026
e0a9097
chore/update-version-2026-6-24 (#477)
stephamie7 Jun 24, 2026
a824da2
v2026.06.18 (#461) (#478)
stephamie7 Jun 24, 2026
f1ab6b8
v2026.06.18 (#461) (#479)
stephamie7 Jun 24, 2026
837f6f7
chore: record main ancestry in dev
stephamie7 Jun 24, 2026
30e6135
Merge pull request #480 from AgentFlocks/chore/record-main-ancestor-2…
duguwanglong Jun 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions .github/workflows/sync-main-into-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: Sync main into dev

on:
push:
branches:
- main
workflow_dispatch:
inputs:
sync_label:
description: "Optional label to use in the sync branch and PR title"
required: false
type: string

permissions:
contents: write
pull-requests: write

concurrency:
group: sync-main-into-dev-${{ github.sha || github.run_id }}
cancel-in-progress: false

jobs:
sync-main-into-dev:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Configure git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Fetch branches
run: git fetch origin main dev

- name: Resolve sync label
id: sync
env:
INPUT_SYNC_LABEL: ${{ github.event.inputs.sync_label }}
run: |
set -euo pipefail

main_sha="$(git rev-parse --short=12 origin/main)"
sync_label="${INPUT_SYNC_LABEL:-main-${main_sha}}"
safe_label="$(printf '%s' "$sync_label" | tr -c 'A-Za-z0-9._-' '-' | sed -e 's/^-*//' -e 's/-*$//')"

if [ -z "$safe_label" ]; then
safe_label="main-${main_sha}"
fi

echo "label=$sync_label" >> "$GITHUB_OUTPUT"
echo "safe_label=$safe_label" >> "$GITHUB_OUTPUT"

- name: Check branch difference
id: diff
run: |
set -euo pipefail

counts="$(git rev-list --left-right --count origin/main...origin/dev)"
read -r main_only dev_only <<< "$counts"

echo "main_only=$main_only" >> "$GITHUB_OUTPUT"
echo "dev_only=$dev_only" >> "$GITHUB_OUTPUT"
echo "origin/main only: $main_only"
echo "origin/dev only: $dev_only"

- name: Skip when dev is not behind main
if: steps.diff.outputs.main_only == '0'
run: echo "dev is not behind main; nothing to sync."

- name: Merge main into generated sync branch
if: steps.diff.outputs.main_only != '0'
id: merge
env:
SAFE_SYNC_LABEL: ${{ steps.sync.outputs.safe_label }}
SYNC_LABEL: ${{ steps.sync.outputs.label }}
run: |
set -euo pipefail

branch="chore/sync-main-into-dev-${SAFE_SYNC_LABEL}"

git switch -C "$branch" origin/dev
git merge --no-ff origin/main -m "chore: sync main into dev after ${SYNC_LABEL}"
git push --force-with-lease -u origin "$branch"

echo "branch=$branch" >> "$GITHUB_OUTPUT"

- name: Create or reuse pull request
if: steps.diff.outputs.main_only != '0'
env:
GH_TOKEN: ${{ github.token }}
SYNC_BRANCH: ${{ steps.merge.outputs.branch }}
SYNC_LABEL: ${{ steps.sync.outputs.label }}
MAIN_ONLY: ${{ steps.diff.outputs.main_only }}
DEV_ONLY: ${{ steps.diff.outputs.dev_only }}
run: |
set -euo pipefail

existing_pr="$(gh pr list --base dev --head "$SYNC_BRANCH" --state open --json url --jq '.[0].url // ""')"
if [ -n "$existing_pr" ]; then
echo "Existing sync PR: $existing_pr"
exit 0
fi

body_file="$(mktemp)"
cat > "$body_file" <<EOF
This PR was created automatically after origin/main was updated.

It merges origin/main into origin/dev to clear dev's behind count while preserving dev-only commits.

Sync label: ${SYNC_LABEL}

Branch comparison before sync:
- origin/main only: ${MAIN_ONLY}
- origin/dev only: ${DEV_ONLY}
EOF

gh pr create \
--base dev \
--head "$SYNC_BRANCH" \
--title "chore: sync main into dev after ${SYNC_LABEL}" \
--body-file "$body_file"
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
# Flocks

**English** | [简体中文](README_zh.md)

AI-Native SecOps Platform
<h1 align="center">Flocks</h1>

<p align="center">
AI-Native SecOps Platform
</p>

<p align="center">
<a href="https://agentflocks.github.io/flocks-docs/"><img alt="Docs" src="https://img.shields.io/badge/docs-agentflocks.github.io-555555?style=for-the-badge"></a>
<a href="https://github.com/AgentFlocks/flocks/releases"><img alt="Release" src="https://img.shields.io/badge/release-v2026.6.18-f06f2f?style=for-the-badge"></a>
</p>

<p align="center">
<a href="LICENSE.txt"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-52b100?style=for-the-badge"></a>
<a href="README.md"><img alt="English" src="https://img.shields.io/badge/lang-English-e33f44?style=for-the-badge"></a>
<a href="README_zh.md"><img alt="Chinese" src="https://img.shields.io/badge/lang-%E4%B8%AD%E6%96%87-e33f44?style=for-the-badge"></a>
</p>

![Flocks WebUI](assets/flocks.webp)

Expand Down
21 changes: 16 additions & 5 deletions README_zh.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
# Flocks

[English](README.md) | **简体中文**

AI 原生 SecOps 平台
<h1 align="center">Flocks</h1>

<p align="center">
AI 原生 SecOps 平台
</p>

<p align="center">
<a href="https://agentflocks.github.io/flocks-docs/"><img alt="文档" src="https://img.shields.io/badge/docs-agentflocks.github.io-555555?style=for-the-badge"></a>
<a href="https://github.com/AgentFlocks/flocks/releases"><img alt="Release" src="https://img.shields.io/badge/release-v2026.6.18-f06f2f?style=for-the-badge"></a>
</p>

<p align="center">
<a href="LICENSE.txt"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-52b100?style=for-the-badge"></a>
<a href="README.md"><img alt="English" src="https://img.shields.io/badge/lang-English-e33f44?style=for-the-badge"></a>
<a href="README_zh.md"><img alt="中文" src="https://img.shields.io/badge/lang-%E4%B8%AD%E6%96%87-e33f44?style=for-the-badge"></a>
</p>

![Flocks Web](assets/flocks.webp)

Expand Down
75 changes: 67 additions & 8 deletions flocks/cli/service_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,20 @@

MIN_NODE_MAJOR = 22
FOLLOW_POLL_INTERVAL = 0.5
MAX_SERVICE_LOG_BYTES = 1024 * 1024 * 1024
LOG_TRIM_CHUNK_BYTES = 1024 * 1024
WEBUI_DIRECT_BACKEND_URLS_ENV = "FLOCKS_WEBUI_DIRECT_BACKEND_URLS"
DEFAULT_FLOCKS_CONSOLE_BASE_URL = "https://portalflocks.threatbook.cn"
DEFAULT_VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS = "portalflocks.threatbook.cn"
MISSING_PORT_OWNER_TOOLS_WARNING = (
"未检测到 lsof 或 fuser,无法解析端口占用 PID;将退回到 bind 检查。"
"可尝试安装:apt/yum install lsof -y"
)
WINDOWS_FRONTEND_BUILD_ASSERTION_MARKERS = (
"UV_HANDLE_CLOSING",
"src\\win\\async.c",
"src/win/async.c",
)


class ServiceError(RuntimeError):
Expand Down Expand Up @@ -557,10 +564,12 @@ def _windows_process_snapshot(pid: int) -> dict[str, str] | None:
check=False,
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
)
if completed.returncode == 0:
with contextlib.suppress(json.JSONDecodeError):
payload = json.loads(completed.stdout.strip() or "{}")
payload = json.loads((completed.stdout or "").strip() or "{}")
if isinstance(payload, dict):
return {
"name": str(payload.get("Name") or ""),
Expand Down Expand Up @@ -1036,14 +1045,20 @@ def start_frontend(config: ServiceConfig, console) -> None:
frontend_env = build_frontend_env(config)
if not config.skip_frontend_build:
console.print("[flocks] 构建 WebUI...")
completed = subprocess.run(
[npm, "run", "build"],
cwd=webui_dir,
check=False,
env=frontend_env,
)
run_kwargs: dict[str, object] = {"cwd": webui_dir, "check": False, "env": frontend_env}
if sys.platform == "win32":
run_kwargs.update({"capture_output": True, "text": True, "encoding": "utf-8", "errors": "replace"})
completed = subprocess.run([npm, "run", "build"], **run_kwargs)
if completed.returncode != 0:
raise ServiceError("WebUI 构建失败。")
output = "\n".join(
value for value in (getattr(completed, "stdout", None), getattr(completed, "stderr", None)) if value
)
if windows_frontend_build_assertion_is_recoverable(webui_dir, output):
console.print("[flocks] WebUI 构建产物已生成,忽略 Windows Node.js 退出断言。")
else:
if output:
console.print(output)
raise ServiceError("WebUI 构建失败。")

command = [
npm,
Expand Down Expand Up @@ -1612,6 +1627,15 @@ def websocket_access_base_url(config: ServiceConfig) -> str:
return _http_to_ws_url(backend_access_base_url(config))


def windows_frontend_build_assertion_is_recoverable(webui_dir: Path, output: str) -> bool:
"""Return True when Windows npm crashed after producing a usable build."""
if sys.platform != "win32":
return False
if not (webui_dir / "dist" / "index.html").exists():
return False
return any(marker in output for marker in WINDOWS_FRONTEND_BUILD_ASSERTION_MARKERS)


def build_frontend_env(config: ServiceConfig) -> dict[str, str]:
"""Build frontend proxy environment variables from backend service settings."""
env = os.environ.copy()
Expand Down Expand Up @@ -1680,6 +1704,7 @@ def _spawn_process(
kwargs["start_new_session"] = True

log_path.parent.mkdir(parents=True, exist_ok=True)
_cap_service_log_file(log_path, MAX_SERVICE_LOG_BYTES)
handle = log_path.open("a", encoding="utf-8")
try:
return subprocess.Popen(
Expand All @@ -1696,6 +1721,40 @@ def _spawn_process(
handle.close()


def _cap_service_log_file(log_path: Path, max_bytes: int = MAX_SERVICE_LOG_BYTES) -> bool:
"""Keep service logs under *max_bytes* without deleting or renaming them."""
if max_bytes <= 0:
return False
try:
size = log_path.stat().st_size
except FileNotFoundError:
return False
except OSError:
return False
if size <= max_bytes:
return False

read_offset = size - max_bytes
write_offset = 0
try:
with log_path.open("r+b") as handle:
while read_offset < size:
handle.seek(read_offset)
chunk = handle.read(min(LOG_TRIM_CHUNK_BYTES, size - read_offset))
if not chunk:
break
handle.seek(write_offset)
handle.write(chunk)
read_offset += len(chunk)
write_offset += len(chunk)
handle.truncate(write_offset)
return True
except OSError:
# Logging must not make daemon startup fail. If Windows still has a
# transient lock, leave the file untouched and continue with append.
return False


def _run_windows_netstat(port: int) -> str:
completed = subprocess.run(
["netstat", "-ano", "-p", "tcp"],
Expand Down
24 changes: 15 additions & 9 deletions flocks/server/routes/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,22 +448,28 @@ async def _cleanup_workflow_storage(workflow_id: str) -> None:
await _remove_storage_key_if_exists(f"{_WORKFLOW_CENTER_RUNTIME_PREFIX}{workflow_id}")
await _remove_storage_key_if_exists(f"{_WORKFLOW_CENTER_LOCAL_PID_PREFIX}{workflow_id}")
await _remove_storage_prefix(f"{_WORKFLOW_CENTER_RELEASE_PREFIX}{workflow_id}/")
await _remove_storage_prefix(f"workflow_execution_index/{workflow_id}/")

try:
exec_keys = await Storage.list("workflow_execution/")
exec_keys = await Storage.list_keys("workflow_execution/")
for key in exec_keys:
try:
exec_data = await Storage.read(key)
if isinstance(exec_data, dict) and exec_data.get("workflowId") == workflow_id:
await Storage.remove(key)
exec_id = key.rsplit("/", 1)[-1]
step_rows = await Storage.list_raw(_workflow_execution_step_prefix(exec_id))
for step_key, _value in step_rows:
await Storage.remove(step_key)
except Exception:
pass
except Exception:
pass
await Storage.clear(_workflow_execution_step_prefix(exec_id))
await Storage.remove(key)
except Exception as exc:
log.warning("workflow.delete.execution_cleanup_failed", {
"workflow_id": workflow_id,
"key": key,
"error": str(exc),
})
except Exception as exc:
log.warning("workflow.delete.execution_scan_failed", {
"workflow_id": workflow_id,
"error": str(exc),
})

service_dir = Config.get_data_path() / "workflow-services" / "workflows" / workflow_id
if service_dir.is_dir():
Expand Down
1 change: 1 addition & 0 deletions flocks/session/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,7 @@ async def _build_device_asset_hint(self) -> Optional[str]:
"## 安全设备使用\n\n"
f"{summary}\n\n"
"当用户要操作特定机房、设备或产品时,先调用 `device_context` 获取 `device_id` 等相关信息。"
"如果当前无已接入设备,请提示用户前往「设备接入」页面添加设备。"
"使用 `tool_search` 搜索工具名称查看用法;执行设备工具时必须传入目标 `device_id`。"
"如果同类设备有多个候选,不要猜测,先询问用户选择。"
)
Expand Down
Loading
Loading