Commit Graph

17 Commits

Author SHA1 Message Date
cft0808
5f4da4e184 Merge pull request #306 from luoyanglang/wolf/fix-official-skills-hub-404
fix(skills): remove broken default skills hub
2026-04-27 22:30:35 +08:00
luoyanglang
f21c0b293a fix(skills): remove broken default skills hub 2026-04-25 07:39:55 +00:00
voidborne-d
714f442e31 fix: eliminate TOCTOU race in task mutation paths
Background dispatch threads, the periodic scheduler scan, and HTTP
handlers all followed a load_tasks() → modify → save_tasks() pattern
without any mutual exclusion.  The atomic_json_write only protects the
write itself; it does NOT prevent a concurrent reader from loading a
stale snapshot and overwriting another thread's changes.

Scenario (before this fix):
  1. HTTP handler calls load_tasks() — gets snapshot A
  2. Dispatch thread calls load_tasks() — gets the same snapshot A
  3. HTTP handler modifies task X, calls save_tasks() — writes A'
  4. Dispatch thread modifies task Y, calls save_tasks() — writes A''
     (based on A, not A'), silently losing the HTTP handler's changes
     to task X

This is a classic TOCTOU (Time-of-Check-Time-of-Use) race.  The project
already has atomic_json_update() in file_lock.py that holds an exclusive
lock for the entire read-modify-write cycle, but none of the task
mutation paths used it.

Fix:
- Add modify_tasks(modifier) wrapper around atomic_json_update +
  refresh trigger
- Add modify_task(task_id, updater) convenience wrapper for single-task
  mutations
- Convert _update_task_scheduler (called from dispatch daemon threads)
  to use modify_task
- Convert handle_scheduler_scan (periodic background scanner) to use
  modify_tasks, with dispatch side-effects deferred until after the
  lock is released
- Convert handle_scheduler_retry and handle_scheduler_rollback to use
  modify_task

HTTP handler paths (handle_task_action, handle_review_action, etc.)
still use load_tasks/save_tasks for now — they run in the main thread
and are lower risk — but can be migrated incrementally.

Add 17 regression tests covering: atomic API correctness, scheduler
update persistence, scan stall detection, concurrent write survival
(the actual race), source-level audit of critical paths, and backward
compatibility of load_tasks/save_tasks.
2026-04-22 06:00:26 +00:00
狼哥
c958d06cb4 fix(flow): prevent premature task completion before review (#280)
cmd_done() 不再直接写 Done,改为校验 todos 完成度后路由到 Review;dashboard 准奏也增加 todo 完成度门控,防止子任务未完成就关闭任务
2026-04-20 00:17:01 +08:00
狼哥
78f54655cc fix(dashboard): handle missing OpenClaw CLI during dispatch (#290)
Windows 环境下 OpenClaw CLI 未在 PATH 时,subprocess 抛出 WinError 2。新增 shutil.which 解析和 OPENCLAW_BIN 环境变量支持,将原始错误转为可操作的 openclaw-missing 状态
2026-04-20 00:16:51 +08:00
Sebastion
c3c4e2a71f fix: CWE-22 path traversal in file:// URL handling (#258)
fix: apply allowed_roots check to file:// URLs in add_remote_skill (CWE-22)\n\nAdds .resolve() and allowed_roots validation to the file:// URL branch\nin add_remote_skill(), closing a path traversal vulnerability.\nIncludes 3 regression tests.
2026-04-05 21:48:44 +08:00
cft0808
74d8130391 feat: Week 0-4 optimizations - event bus, state machine, dispatch, outbox relay
- EventBus: Redis Streams pub/sub for decoupled service communication
- State machine: strict lifecycle transitions with audit logging
- Dispatch worker: parallel execution, retry with backoff, resource locking
- Orchestrator: DAG-based task decomposition and dependency resolution
- Outbox relay: transactional outbox pattern for reliable event delivery
- Auth: dashboard authentication module
- Agent groups: sansheng/liubu agent configuration
- CI/CD: Docker publish workflow, systemd service, start script
- Frontend: dashboard build assets
- Tests: state machine consistency tests
2026-04-04 12:16:32 +08:00
YueKang
260d5c9f9c test: add regression tests for self-referential symlink bug (#217)
Two new test cases in test_sync_symlinks.py:

1. TestSyncScriptSymlink.test_skips_self_referential_via_directory_symlink
   Unit test: verifies _sync_script_symlink() returns False and leaves
   the real source file intact when dst_file is accessed through a
   directory-level symlink that points back to the project scripts/ dir.

2. TestSyncScriptsToWorkspaces.test_no_self_referential_symlinks_when_workspace_scripts_is_dir_symlink
   Integration test: simulates the install.sh scenario where
   workspace-main/scripts -> project/scripts, then confirms that
   sync_scripts_to_workspaces() does not convert any real source file
   into a self-referential symlink."
2026-03-28 17:10:16 +08:00
Sliverp
c8d9b9d7c4 fix: use symlinks for workspace script sync to fix data-path split (#56) (#176)
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 #56

Co-authored-by: cft0808 <41196455+cft0808@users.noreply.github.com>
2026-03-25 22:20:21 +08:00
Ailuntz
99d672b065 fix(config): accept allowAgents in agent list (#108) 2026-03-25 00:23:21 +08:00
cft0808
6b3ab88128 refactor: 消除冗余I/O、去重复定义、补全测试覆盖
- kanban_update.py: 提取 _trigger_refresh(),消除 save(load()) 双重 I/O
  每次任务操作节省一次 fcntl 锁 + 读文件 + 写文件的冗余开销
- kanban_update.py + server.py: now_iso/read_json 统一从 utils 导入,
  删除本地重复实现,移除未使用的 datetime/atomic_json_write 导入
- server.py: 修复 yaml import 静默失败——分离 ImportError 与 YAML 语法错误,
  先做字符串结构校验(无需 PyYAML),再严格验证语法
- tests/test_kanban.py: 测试数从 3 增至 8,补全 cmd_flow/cmd_done/
  cmd_progress/cmd_todo/progress_log_capped 覆盖
- run_loop.sh: 补充第二参数(巡检间隔)文档注释
- install.sh: 删除 Python heredoc 中无效的 __file__ 判断死代码

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 22:18:11 +08:00
cft0808
f194c6b9e1 fix: 修复CI中test_kanban和test_server失败
- test_kanban: 标题'测试任务'(4字)被_MIN_TITLE_LEN=6拒绝,改为更长标题
- test_server: healthz在空数据下返回degraded是正常行为,放宽断言
2026-02-27 21:40:10 +08:00
cft0808
3505486e74 fix: 重构E2E测试为标准pytest格式 — 解决SystemExit崩溃
原测试在模块级别直接执行逻辑并sys.exit(),
pytest import时触发SystemExit导致INTERNALERROR。

重构:
- 每个测试场景独立为 test_* 函数(9个)
- 用 pytest fixture autouse 做 backup/restore
- 每个测试用独立ID避免互相依赖
- 保留 __main__ 入口支持直接运行
2026-02-27 21:37:40 +08:00
cft0808
a6fd9b9b95 fix: CI测试 FileExistsError — 移除git中的遗留data符号链接
根因:'data' 被git跟踪为符号链接(指向旧路径 /Users/bingsen/clawd/junjichu-v2/data),
CI clone后变成普通文件,mkdir报FileExistsError。

修复:
1. git rm --cached data,从版本控制移除
2. .gitignore 追加 data 条目
3. 测试代码:若 data 路径存在但不是目录,先 unlink 再 mkdir
2026-02-27 21:34:14 +08:00
cft0808
6bd643f3e8 fix: E2E测试兼容CI环境 — data目录不存在时自动创建空文件
CI环境没有 data/tasks_source.json(被gitignore),
模块加载时 read_text() 直接报 FileNotFoundError。
现在先 mkdir + 写入空 [] 再备份。
2026-02-27 21:30:54 +08:00
cft0808
a95eec05fe fix: remark也剥离下旨前缀 + 添加端到端测试(17/17) 2026-02-27 21:01:08 +08:00
cft0808
efd36ab729 feat: 添加 Copilot 模型配置 + 旨意看板归档功能
模型配置:
- 新增 Copilot 系列模型 (Claude Sonnet 4, Claude Opus 4.5, GPT-4o, Gemini 2.5 Pro, o3-mini)
- 新增 github-copilot/claude-opus-4.6 模型

旨意看板归档:
- 看板顶部新增筛选栏: 进行中 / 已归档 / 全部
- Done/Cancelled 状态自动归入归档视图
- 支持单条归档/取消归档操作
- 支持一键归档所有已完成任务
- 归档卡片虚线边框半透明展示
- Tab 徽章仅统计活跃旨意数

其他:
- agents SOUL.md 更新
- 脚本健壮性改进 (file_lock, refresh, sync)
2026-02-26 21:09:05 +08:00