vibego 0.2.52__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of vibego might be problematic. Click here for more details.

scripts/stop_all.sh CHANGED
@@ -17,10 +17,10 @@ VERBOSE=0
17
17
 
18
18
  usage() {
19
19
  cat <<USAGE
20
- 用法:${0##*/} [--dry-run] [--verbose]
21
- --dry-run 仅打印将要执行的操作,不真正终止进程
22
- --verbose 输出更详细的诊断信息
23
- -h, --help 显示本帮助
20
+ usage:${0##*/} [--dry-run] [--verbose]
21
+ --dry-run Only prints what will be done, does not actually terminate the process
22
+ --verbose output more detailed diagnostic information
23
+ -h, --help Show this help
24
24
  USAGE
25
25
  }
26
26
 
@@ -53,7 +53,7 @@ parse_args() {
53
53
  -h|--help)
54
54
  usage; exit 0 ;;
55
55
  *)
56
- log_error "未知参数: $1"
56
+ log_error "unknown parameters: $1"
57
57
  usage
58
58
  exit 1 ;;
59
59
  esac
@@ -70,10 +70,10 @@ terminate_pattern() {
70
70
  local pids
71
71
  pids=$(list_pids "$pattern")
72
72
  if [[ -z "$pids" ]]; then
73
- (( VERBOSE )) && log_info "未发现 $desc 进程"
73
+ (( VERBOSE )) && log_info "not found $desc process"
74
74
  return 0
75
75
  fi
76
- log_info "停止 $desc: $pids"
76
+ log_info "stop $desc: $pids"
77
77
  if (( DRY_RUN )); then
78
78
  return 0
79
79
  fi
@@ -82,31 +82,31 @@ terminate_pattern() {
82
82
  local leftover
83
83
  leftover=$(list_pids "$pattern")
84
84
  if [[ -n "$leftover" ]]; then
85
- log_warn "$desc 未完全退出,执行 kill -9 $leftover"
85
+ log_warn "$desc Incomplete exit, execute kill -9 $leftover"
86
86
  kill -9 $leftover >/dev/null 2>&1 || true
87
87
  fi
88
88
  }
89
89
 
90
90
  stop_workers() {
91
91
  if [[ ! -x "$STOP_BOT_SCRIPT" ]]; then
92
- log_warn "未找到 stop_bot.sh,跳过 worker 清理"
92
+ log_warn "stop not found_bot.sh, Skip worker cleanup"
93
93
  return 0
94
94
  fi
95
95
  if (( DRY_RUN )); then
96
- log_info "[dry-run] 调用 stop_bot.sh 清理所有 worker"
96
+ log_info "[dry-run] call stop_bot.sh Clean all workers"
97
97
  return 0
98
98
  fi
99
99
  if "$STOP_BOT_SCRIPT" >/dev/null 2>&1; then
100
- log_info "worker 已停止"
100
+ log_info "worker alreadystop"
101
101
  else
102
- log_warn "stop_bot.sh 返回非零状态,请检查日志"
102
+ log_warn "stop_bot.sh Returns non-zero status, please check the logs"
103
103
  fi
104
104
  return 0
105
105
  }
106
106
 
107
107
  stop_tmux_sessions() {
108
108
  if ! command -v tmux >/dev/null 2>&1; then
109
- (( VERBOSE )) && log_info "未检测到 tmux,跳过会话清理"
109
+ (( VERBOSE )) && log_info "tmux not detected, session cleanup skipped"
110
110
  return 0
111
111
  fi
112
112
  local prefix="$DEFAULT_TMUX_PREFIX"
@@ -120,12 +120,12 @@ stop_tmux_sessions() {
120
120
  local tmux_output sessions
121
121
  tmux_output=$(tmux -u list-sessions 2>/dev/null || true)
122
122
  if [[ -z "$tmux_output" ]]; then
123
- (( VERBOSE )) && log_info "未发现匹配 tmux 会话"
123
+ (( VERBOSE )) && log_info "not foundmatch tmux session"
124
124
  return 0
125
125
  fi
126
126
  sessions=$(printf '%s\n' "$tmux_output" | awk -F: -v prefix="$full_prefix" '$1 ~ "^" prefix {print $1}')
127
127
  if [[ -z "$sessions" ]]; then
128
- (( VERBOSE )) && log_info "未发现匹配 tmux 会话"
128
+ (( VERBOSE )) && log_info "not foundmatch tmux session"
129
129
  return 0
130
130
  fi
131
131
  while IFS= read -r sess; do
@@ -134,7 +134,7 @@ stop_tmux_sessions() {
134
134
  log_info "[dry-run] tmux -u kill-session -t $sess"
135
135
  else
136
136
  tmux -u kill-session -t "$sess" >/dev/null 2>&1 || true
137
- log_info "已终止 tmux 会话: $sess"
137
+ log_info "tmux session terminated: $sess"
138
138
  fi
139
139
  done <<<"$sessions"
140
140
  return 0
@@ -150,26 +150,26 @@ cleanup_state_files() {
150
150
  rm -f "$file"
151
151
  fi
152
152
  removed=1
153
- log_info "已清理状态文件: $file"
153
+ log_info "Cleaned status file: $file"
154
154
  fi
155
155
  done
156
156
  if (( ! removed )) && (( VERBOSE )); then
157
- log_info "无状态文件需要清理"
157
+ log_info "Stateless files need to be cleaned"
158
158
  fi
159
159
  }
160
160
 
161
161
  main() {
162
162
  parse_args "$@"
163
- (( DRY_RUN )) && log_info "当前为 dry-run 模式,不会真正结束进程"
163
+ (( DRY_RUN )) && log_info "Dry-run mode: no processes will be terminated"
164
164
 
165
165
  stop_workers
166
166
  stop_tmux_sessions
167
167
  terminate_pattern "[Pp]ython.*master.py" "master"
168
168
  terminate_pattern "$ROOT_DIR/start.sh" "start.sh"
169
- terminate_pattern "$ROOT_DIR/bot.py" "残留 worker"
169
+ terminate_pattern "$ROOT_DIR/bot.py" "residual worker"
170
170
  cleanup_state_files
171
171
 
172
- log_info "所有相关进程与状态已处理完成"
172
+ log_info "All related processes and state cleaned up"
173
173
  }
174
174
 
175
175
  main "$@"
scripts/stop_bot.sh CHANGED
@@ -1,17 +1,38 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ # shellcheck disable=SC2155
4
5
  ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6
+
7
+ resolve_config_root() {
8
+ local raw=""
9
+ if [[ -n "${MASTER_CONFIG_ROOT:-}" ]]; then
10
+ raw="$MASTER_CONFIG_ROOT"
11
+ elif [[ -n "${VIBEGO_CONFIG_DIR:-}" ]]; then
12
+ raw="$VIBEGO_CONFIG_DIR"
13
+ elif [[ -n "${XDG_CONFIG_HOME:-}" ]]; then
14
+ raw="${XDG_CONFIG_HOME%/}/vibego"
15
+ else
16
+ raw="$HOME/.config/vibego"
17
+ fi
18
+ if [[ "$raw" == ~* ]]; then
19
+ printf '%s' "${raw/#\~/$HOME}"
20
+ else
21
+ printf '%s' "$raw"
22
+ fi
23
+ }
24
+
25
+ CONFIG_ROOT="$(resolve_config_root)"
26
+ LOG_ROOT="${LOG_ROOT:-$CONFIG_ROOT/logs}"
5
27
  MODELS_DIR="$ROOT_DIR/scripts/models"
6
- LOG_ROOT="${LOG_ROOT:-$ROOT_DIR/logs}"
7
28
  MODEL_DEFAULT="${MODEL_DEFAULT:-codex}"
8
29
  PROJECT_DEFAULT="${PROJECT_NAME:-}"
9
30
 
10
31
  usage() {
11
32
  cat <<USAGE
12
- 用法:${0##*/} [--model 名称] [--project 名称]
13
- --model 目标模型,默认 $MODEL_DEFAULT
14
- --project 项目别名;未指定时尝试使用当前目录配置
33
+ usage:${0##*/} [--model name] [--project name]
34
+ --model target model, default $MODEL_DEFAULT
35
+ --project Project alias; attempts to use the current directory configuration when not specified
15
36
  USAGE
16
37
  }
17
38
 
@@ -27,7 +48,7 @@ while [[ $# -gt 0 ]]; do
27
48
  -h|--help)
28
49
  usage; exit 0 ;;
29
50
  *)
30
- echo "未知参数: $1" >&2
51
+ echo "unknown parameters: $1" >&2
31
52
  usage
32
53
  exit 1 ;;
33
54
  esac
@@ -73,7 +94,7 @@ graceful_shutdown_claudecode() {
73
94
  done
74
95
  (( has_claude )) || return 0
75
96
 
76
- printf '[stop-bot] 检测到 ClaudeCode 会话,尝试发送 /exit (session=%s)\n' "$session"
97
+ printf '[stop-bot] ClaudeCode session detected, trying to send /exit (session=%s)\n' "$session"
77
98
  for pane in "${pane_ids[@]}"; do
78
99
  tmux -u send-keys -t "$pane" Escape
79
100
  tmux -u send-keys -t "$pane" C-u
@@ -91,11 +112,11 @@ graceful_shutdown_claudecode() {
91
112
  fi
92
113
  done
93
114
  if (( still_running == 0 )); then
94
- printf '[stop-bot] ClaudeCode 会话已响应 /exit (session=%s)\n' "$session"
115
+ printf '[stop-bot] ClaudeCode Session has responded /exit (session=%s)\n' "$session"
95
116
  break
96
117
  fi
97
118
  if (( $(date +%s) >= end_time )); then
98
- printf '[stop-bot] ClaudeCode /exit 超时,将继续执行强制关闭 (session=%s)\n' "$session" >&2
119
+ printf '[stop-bot] ClaudeCode /exit Timeout, forced shutdown will continue (session=%s)\n' "$session" >&2
99
120
  break
100
121
  fi
101
122
  sleep 0.5
@@ -194,11 +215,11 @@ if [[ -n "$PROJECT_OVERRIDE" ]]; then
194
215
  stop_single_worker "$PROJECT_NAME" "$MODEL"
195
216
  else
196
217
  if ! stop_all_workers; then
197
- # fallback:默认 project 名称
218
+ # fallback:default project name
198
219
  stop_single_worker "project" "$MODEL"
199
220
  fi
200
221
  fi
201
222
 
202
- # 已通过 pid 文件与 tmux 会话按项目停止进程,无需额外全局 pkill,避免误杀其它项目
223
+ # The process has been stopped by project through the pid file and tmux session. No additional global pkill is needed to avoid accidentally killing other projects.
203
224
 
204
225
  exit 0
@@ -1,66 +1,70 @@
1
1
  #!/usr/bin/env bash
2
- # 测试依赖检查函数的逻辑
2
+ # Test the logic of the dependency check function
3
3
  set -euo pipefail
4
4
 
5
5
  ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6
+ MASTER_CONFIG_ROOT="${MASTER_CONFIG_ROOT:-$HOME/.config/vibego}"
7
+ RUNTIME_DIR="${VIBEGO_RUNTIME_ROOT:-$MASTER_CONFIG_ROOT/runtime}"
8
+ VENV_DIR="$RUNTIME_DIR/.venv"
6
9
 
7
- echo "=== 测试依赖检查函数 ==="
10
+ echo "=== Test dependency check function ==="
8
11
  echo "ROOT_DIR: $ROOT_DIR"
12
+ echo "RUNTIME_DIR: $RUNTIME_DIR"
9
13
  echo ""
10
14
 
11
- # start.sh提取check_deps_installed函数进行测试
15
+ # from start.shExtract check_deps_installedfunction to test
12
16
  check_deps_installed() {
13
- if [[ ! -d "$ROOT_DIR/.venv" ]]; then
14
- echo " 虚拟环境不存在"
17
+ if [[ ! -d "$VENV_DIR" ]]; then
18
+ echo "ERROR: Virtual environment does not exist"
15
19
  return 1
16
20
  fi
17
21
 
18
- if [[ ! -x "$ROOT_DIR/.venv/bin/python" ]]; then
19
- echo " 虚拟环境Python解释器缺失"
22
+ if [[ ! -x "$VENV_DIR/bin/python" ]]; then
23
+ echo "ERROR: Python interpreter not found in virtual environment"
20
24
  return 1
21
25
  fi
22
26
 
23
- if ! "$ROOT_DIR/.venv/bin/python" -c "import aiogram, aiohttp, aiosqlite" 2>/dev/null; then
24
- echo " 关键依赖包缺失或损坏"
27
+ if ! "$VENV_DIR/bin/python" -c "import aiogram, aiohttp, aiosqlite" 2>/dev/null; then
28
+ echo "ERROR: Required dependencies are missing or broken"
25
29
  return 1
26
30
  fi
27
31
 
28
- echo " 依赖检查通过"
32
+ echo "OK: Dependency check passed"
29
33
  return 0
30
34
  }
31
35
 
32
- # 测试1:检查当前环境
33
- echo "【测试1】检查当前虚拟环境状态:"
36
+ # Test 1: Check the current environment
37
+ echo "[Test 1] Check the current virtual environment status:"
34
38
  if check_deps_installed; then
35
- echo "结果:依赖完整,重启时将跳过pip install"
39
+ echo "Result: dependencies are complete, pip install will be skipped when restarting"
36
40
  else
37
- echo "结果:依赖缺失,重启时将执行pip install"
41
+ echo "Result: Dependencies are missing, pip install will be executed when restarting"
38
42
  fi
39
43
  echo ""
40
44
 
41
- # 测试2:检查虚拟环境目录
42
- echo "【测试2】虚拟环境目录检查:"
43
- if [[ -d "$ROOT_DIR/.venv" ]]; then
44
- echo " .venv 目录存在"
45
- ls -lh "$ROOT_DIR/.venv/bin/python" 2>/dev/null || echo " Python解释器不存在"
45
+ # Test 2: Check the virtual environment directory
46
+ echo "[Test 2] Virtual environment directory check:"
47
+ if [[ -d "$VENV_DIR" ]]; then
48
+ echo "OK: Virtual environment directory exists: $VENV_DIR"
49
+ ls -lh "$VENV_DIR/bin/python" 2>/dev/null || echo "ERROR: Python interpreter does not exist"
46
50
  else
47
- echo " .venv 目录不存在"
51
+ echo "ERROR: Virtual environment directory does not exist: $VENV_DIR"
48
52
  fi
49
53
  echo ""
50
54
 
51
- # 测试3:检查关键依赖
52
- echo "【测试3】关键依赖包检查:"
53
- if [[ -x "$ROOT_DIR/.venv/bin/python" ]]; then
55
+ # Test 3: Check critical dependencies
56
+ echo "[Test 3] Key dependency package check:"
57
+ if [[ -x "$VENV_DIR/bin/python" ]]; then
54
58
  for pkg in aiogram aiohttp aiosqlite; do
55
- if "$ROOT_DIR/.venv/bin/python" -c "import $pkg" 2>/dev/null; then
56
- echo " $pkg 已安装"
59
+ if "$VENV_DIR/bin/python" -c "import $pkg" 2>/dev/null; then
60
+ echo "OK: $pkg installed"
57
61
  else
58
- echo " $pkg 未安装"
62
+ echo "ERROR: $pkg not installed"
59
63
  fi
60
64
  done
61
65
  else
62
- echo "⚠️ 无法检查(Python解释器不可用)"
66
+ echo "WARN: Unable to check (Python interpreter unavailable)"
63
67
  fi
64
68
  echo ""
65
69
 
66
- echo "=== 测试完成 ==="
70
+ echo "=== Test completed ==="
tasks/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- """任务管理模块,对外暴露核心服务接口。"""
1
+ """Task management module exposing the primary service interfaces."""
2
2
 
3
3
  from .service import TaskService
4
4
  from .models import TaskRecord, TaskNoteRecord, TaskHistoryRecord
tasks/commands.py CHANGED
@@ -1,4 +1,4 @@
1
- """命令行文本解析工具。"""
1
+ """Utilities for parsing command-style text payloads."""
2
2
  from __future__ import annotations
3
3
 
4
4
  import re
@@ -9,7 +9,7 @@ ESCAPED_PIPE_RE = re.compile(r"\\\|")
9
9
 
10
10
 
11
11
  def _split_segments(raw: str) -> list[str]:
12
- """按未转义的 `|` 分割字符串,并恢复转义管道。"""
12
+ """Split by unescaped ``|`` characters and restore escaped pipes."""
13
13
 
14
14
  if not raw:
15
15
  return []
@@ -35,7 +35,7 @@ def _split_segments(raw: str) -> list[str]:
35
35
 
36
36
 
37
37
  def parse_structured_text(raw: str) -> Tuple[str, Dict[str, str]]:
38
- """解析命令参数,返回主体文本与 key=value 字段。"""
38
+ """Parse command arguments and return the body together with key/value fields."""
39
39
 
40
40
  segments = _split_segments(raw)
41
41
  if not segments:
@@ -54,7 +54,7 @@ def parse_structured_text(raw: str) -> Tuple[str, Dict[str, str]]:
54
54
 
55
55
 
56
56
  def parse_simple_kv(raw: str) -> Dict[str, str]:
57
- """仅解析 key=value 片段,忽略主体文本。"""
57
+ """Parse only ``key=value`` segments and ignore the body text."""
58
58
 
59
59
  _, extra = parse_structured_text(raw)
60
60
  return extra
tasks/constants.py CHANGED
@@ -1,4 +1,4 @@
1
- """任务模块常量。"""
1
+ """Constants shared across the task module."""
2
2
 
3
3
  TASK_STATUSES = (
4
4
  "research",
tasks/fsm.py CHANGED
@@ -1,11 +1,11 @@
1
- """aiogram FSM 状态定义。"""
1
+ """aiogram FSM state definitions."""
2
2
  from __future__ import annotations
3
3
 
4
4
  from aiogram.fsm.state import State, StatesGroup
5
5
 
6
6
 
7
7
  class TaskCreateStates(StatesGroup):
8
- """任务创建引导流程的状态集。"""
8
+ """States for the guided task creation flow."""
9
9
 
10
10
  waiting_title = State()
11
11
  waiting_type = State()
@@ -14,7 +14,7 @@ class TaskCreateStates(StatesGroup):
14
14
 
15
15
 
16
16
  class TaskEditStates(StatesGroup):
17
- """任务编辑流程的状态集。"""
17
+ """States for editing existing tasks."""
18
18
 
19
19
  waiting_task_id = State()
20
20
  waiting_field_choice = State()
@@ -23,7 +23,7 @@ class TaskEditStates(StatesGroup):
23
23
 
24
24
 
25
25
  class TaskNoteStates(StatesGroup):
26
- """任务备注追加流程的状态集。"""
26
+ """States for appending notes to a task."""
27
27
 
28
28
  waiting_task_id = State()
29
29
  waiting_content = State()
@@ -31,7 +31,7 @@ class TaskNoteStates(StatesGroup):
31
31
 
32
32
 
33
33
  class TaskBugReportStates(StatesGroup):
34
- """缺陷报告流程状态。"""
34
+ """States for the defect reporting flow."""
35
35
 
36
36
  waiting_description = State()
37
37
  waiting_reproduction = State()
@@ -40,26 +40,26 @@ class TaskBugReportStates(StatesGroup):
40
40
 
41
41
 
42
42
  class TaskDescriptionStates(StatesGroup):
43
- """任务描述编辑流程状态。"""
43
+ """States for editing task descriptions."""
44
44
 
45
45
  waiting_content = State()
46
46
  waiting_confirm = State()
47
47
 
48
48
 
49
49
  class TaskPushStates(StatesGroup):
50
- """任务推送补充信息流程的状态集。"""
50
+ """States for sending supplemental task updates."""
51
51
 
52
52
  waiting_choice = State()
53
53
  waiting_supplement = State()
54
54
 
55
55
 
56
56
  class TaskListSearchStates(StatesGroup):
57
- """任务列表搜索流程的状态集。"""
57
+ """States for searching within the task list."""
58
58
 
59
59
  waiting_keyword = State()
60
60
 
61
61
 
62
62
  class ProjectDeleteStates(StatesGroup):
63
- """Master 项目删除确认流程的状态定义。"""
63
+ """States for confirming master project deletion."""
64
64
 
65
65
  confirming = State()
tasks/models.py CHANGED
@@ -1,4 +1,4 @@
1
- """任务相关的数据模型定义。"""
1
+ """Data models used by the task subsystem."""
2
2
  from __future__ import annotations
3
3
 
4
4
  from dataclasses import dataclass, field
@@ -14,7 +14,7 @@ except ZoneInfoNotFoundError:
14
14
 
15
15
 
16
16
  def _format_shanghai(dt: datetime) -> str:
17
- """格式化时间为上海时区 ISO8601 字符串(秒级,带偏移)。"""
17
+ """Format a datetime as an ISO8601 string in the Shanghai timezone."""
18
18
 
19
19
  if dt.tzinfo is None:
20
20
  dt = dt.replace(tzinfo=timezone.utc)
@@ -23,13 +23,13 @@ def _format_shanghai(dt: datetime) -> str:
23
23
 
24
24
 
25
25
  def shanghai_now_iso() -> str:
26
- """返回当前上海时区的 ISO8601 字符串。"""
26
+ """Return the current time in Shanghai as an ISO8601 string."""
27
27
 
28
28
  return _format_shanghai(datetime.now(SHANGHAI_TZ))
29
29
 
30
30
 
31
31
  def ensure_shanghai_iso(value: Optional[str]) -> Optional[str]:
32
- """将任意 ISO 字符串规范化为上海时区表示。"""
32
+ """Normalize an ISO string to the Shanghai timezone representation."""
33
33
 
34
34
  if value is None:
35
35
  return None
@@ -44,7 +44,7 @@ def ensure_shanghai_iso(value: Optional[str]) -> Optional[str]:
44
44
 
45
45
  @dataclass(slots=True)
46
46
  class TaskRecord:
47
- """表示单个任务的核心字段集合。"""
47
+ """Core fields that describe a single task."""
48
48
 
49
49
  id: str
50
50
  project_slug: str
@@ -66,7 +66,7 @@ class TaskRecord:
66
66
 
67
67
  @dataclass(slots=True)
68
68
  class TaskNoteRecord:
69
- """描述附加在任务上的备注信息。"""
69
+ """Note information attached to a task."""
70
70
 
71
71
  id: int
72
72
  task_id: str
@@ -77,7 +77,7 @@ class TaskNoteRecord:
77
77
 
78
78
  @dataclass(slots=True)
79
79
  class TaskHistoryRecord:
80
- """记录任务字段的历史变更信息。"""
80
+ """Historical trace of changes to task fields."""
81
81
 
82
82
  id: int
83
83
  task_id: str