Skip to content

fix: use symlinks for workspace script sync to fix data-path split#176

Merged
cft0808 merged 2 commits intocft0808:mainfrom
sliverp:fix/kanban-data-path-split
Mar 25, 2026
Merged

fix: use symlinks for workspace script sync to fix data-path split#176
cft0808 merged 2 commits intocft0808:mainfrom
sliverp:fix/kanban-data-path-split

Conversation

@sliverp
Copy link

@sliverp sliverp commented Mar 20, 2026

Problem

sync_scripts_to_workspaces() physically copies scripts from the project scripts/ directory into each agent workspace (~/.openclaw/workspace-xxx/scripts/). Several scripts — kanban_update.py, refresh_live_data.py, sync_officials_stats.py, sync_from_openclaw_runtime.py, etc. — derive the project root from __file__:

_BASE = pathlib.Path(__file__).resolve().parent.parent
TASKS_FILE = _BASE / 'data' / 'tasks_source.json'

When the script is a physical copy in a workspace directory, __file__ resolves to that workspace path. This causes TASKS_FILE (and similar constants) to point to a non-existent data/ directory under the workspace, while the Dashboard reads from the canonical project data/ directory — resulting in the kanban data-path split described in #56.

Fix

Replace dst_file.write_bytes(src_text) with os.symlink(src_file.resolve(), dst_file) so that each workspace script is a symlink pointing back to the project scripts/ directory. When Python resolves __file__ through the symlink, it reaches the original source path, and all Path(__file__).resolve().parent.parent computations correctly point to the project root.

Changes

  • scripts/sync_agent_config.py: Added _sync_script_symlink() helper; rewrote both sync loops (per-agent workspaces + legacy workspace-main) to use symlinks.

    • Idempotent: skips if symlink already points to the correct target
    • Cleans up stale physical copies and broken symlinks automatically
    • Added import os
  • tests/test_sync_symlinks.py (new): 10 tests covering:

    • Symlink creation, idempotency, replacement of physical copies, broken symlinks
    • Full sync_scripts_to_workspaces() integration: workspace dirs, legacy workspace-main, __init__.py skipping
    • The key test: verifying that __file__ resolution through the workspace symlink produces the correct project root

Test Results

tests/test_sync_symlinks.py  10 passed
tests/test_kanban.py          8 passed  (existing tests unaffected)

Closes #56

…ft0808#56)

sync_scripts_to_workspaces() previously used physical file copies.  Scripts
that derive project root from __file__ (e.g. kanban_update.py) therefore
resolved to the workspace directory when run as a copied file, causing
tasks_source.json writes to land in the wrong location while the Dashboard
reads from the canonical data/ directory.

Replace write_bytes() with os.symlink() so __file__ always resolves back to
the project scripts/ directory.  This ensures that all path-derived constants
(TASKS_FILE, DATA, etc.) point to the single canonical data/ folder regardless
of which agent workspace runs the script.

Added _sync_script_symlink() helper with:
- Idempotent re-runs (skip if link already correct)
- Automatic cleanup of stale physical copies and broken symlinks
- Full test suite (10 tests) covering creation, idempotency, replacement
  of physical copies, broken symlinks, __file__ resolution, etc.

Closes cft0808#56
Copy link
Owner

@cft0808 cft0808 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 用 symlink 替代物理复制解决 #56 数据路径分裂问题。__file__ 始终解析回项目 scripts/ 目录。幂等处理、旧副本/断链清理都考虑到了。10 个测试覆盖全面。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Agent 任务状态不实时显示:kanban_update.py 写入路径与 Dashboard 读取路径不一致导致数据分裂

2 participants