Skip to content

Commit 532be7e

Browse files
authored
feat: add telemetry (agentscope-ai#2)
1 parent 86d6cf0 commit 532be7e

File tree

6 files changed

+405
-2
lines changed

6 files changed

+405
-2
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,25 @@ CoPaw represents both a **Co Personal Agent Workstation** and a "co-paw"—a par
466466
467467
---
468468
469+
## Telemetry
470+
471+
CoPaw collects **anonymous** usage data during `copaw init` to help us understand our user base and prioritize improvements. Data is sent **once per version** — when you upgrade CoPaw, telemetry is re-collected so we can track version adoption.
472+
473+
**What we collect:**
474+
475+
- CoPaw version (e.g., 0.0.7)
476+
- Install method (pip, Docker, or desktop app)
477+
- OS and version (e.g., macOS 14.0, Ubuntu 22.04)
478+
- Python version (e.g., 3.13)
479+
- CPU architecture (e.g., x86_64, arm64)
480+
- GPU availability (yes/no)
481+
482+
**What we do NOT collect:** No personal data, no files, no credentials, no IP addresses, no identifiable information.
483+
484+
When running `copaw init` interactively, you will be asked whether to opt in. If you choose `--defaults`, telemetry is accepted automatically. The prompt appears once per version and never affects CoPaw's functionality.
485+
486+
---
487+
469488
## License
470489
471490
CoPaw is released under the [Apache License 2.0](LICENSE).

README_ja.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,25 @@ CoPawは **Co Personal Agent Workstation**(共同パーソナルエージェ
465465
466466
---
467467
468+
## テレメトリ
469+
470+
CoPawは `copaw init` 実行時に**匿名**の利用データを収集し、ユーザー環境の把握と製品改善に役立てています。データは**バージョンごとに1回**送信されます — CoPawをアップグレードすると、バージョン分布を把握するために再収集されます。
471+
472+
**収集する情報:**
473+
474+
- CoPawバージョン(例: 0.0.7)
475+
- インストール方法(pip、Docker、またはデスクトップアプリ)
476+
- OSとバージョン(例: macOS 14.0、Ubuntu 22.04)
477+
- Pythonバージョン(例: 3.13)
478+
- CPUアーキテクチャ(例: x86_64、arm64)
479+
- GPUの利用可否(はい/いいえ)
480+
481+
**収集しないもの:** 個人データ、ファイル、認証情報、IPアドレス、個人を特定できる情報は一切収集しません。
482+
483+
`copaw init` を対話モードで実行すると、同意するかどうか尋ねられます。`--defaults` モードでは自動的に同意されます。プロンプトはバージョンごとに1回のみ表示され、CoPawの機能には影響しません。
484+
485+
---
486+
468487
## ライセンス
469488
470489
CoPawは[Apache License 2.0](LICENSE)の下でリリースされています。

README_zh.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,25 @@ CoPaw 既是「你的搭档小爪子」(co-paw),也寓意 **Co Personal Ag
471471
472472
---
473473
474+
## 遥测数据
475+
476+
CoPaw 在执行 `copaw init` 时会收集**匿名**使用数据,帮助我们了解用户环境并优化产品。数据**每个版本收集一次** — 当你升级 CoPaw 后,会重新收集以便我们了解版本分布。
477+
478+
**收集的信息:**
479+
480+
- CoPaw 版本(如 0.0.7)
481+
- 安装方式(pip、Docker 或桌面应用)
482+
- 操作系统及版本(如 macOS 14.0、Ubuntu 22.04)
483+
- Python 版本(如 3.13)
484+
- CPU 架构(如 x86_64、arm64)
485+
- GPU 是否可用(是/否)
486+
487+
**不收集:** 不涉及任何个人数据、文件、密钥、IP 地址或可识别信息。
488+
489+
交互式运行 `copaw init` 时,会询问你是否同意。使用 `--defaults` 模式则自动同意。提示每个版本仅出现一次,且不影响 CoPaw 的任何功能。
490+
491+
---
492+
474493
## 许可证
475494
476495
CoPaw 采用 [Apache License 2.0](LICENSE) 开源协议。

src/copaw/cli/clean_cmd.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import click
88

99
from ..constant import WORKING_DIR
10+
from ..utils.telemetry import TELEMETRY_MARKER_FILE
1011

1112

1213
def _iter_children(p: Path) -> list[Path]:
@@ -15,6 +16,7 @@ def _iter_children(p: Path) -> list[Path]:
1516
return sorted(list(p.iterdir()), key=lambda x: x.name)
1617

1718

19+
# pylint: disable=too-many-branches
1820
@click.command("clean")
1921
@click.option("--yes", is_flag=True, help="Do not prompt for confirmation")
2022
@click.option(
@@ -31,14 +33,25 @@ def clean_cmd(yes: bool, dry_run: bool) -> None:
3133
return
3234

3335
children = _iter_children(wd)
36+
# Filter out the telemetry marker file
37+
telemetry_marker = wd / TELEMETRY_MARKER_FILE
38+
children = [c for c in children if c != telemetry_marker]
39+
3440
if not children:
35-
click.echo(f"WORKING_DIR is already empty: {wd}")
41+
if telemetry_marker.exists():
42+
click.echo(
43+
"WORKING_DIR has no removable files",
44+
)
45+
else:
46+
click.echo(f"WORKING_DIR is already empty: {wd}")
3647
return
3748

3849
click.echo(f"WORKING_DIR: {wd}")
3950
click.echo("Will remove:")
4051
for c in children:
4152
click.echo(f" - {c}")
53+
if telemetry_marker.exists():
54+
click.echo(f"Will keep: {TELEMETRY_MARKER_FILE}")
4255

4356
if dry_run:
4457
click.echo("dry-run: nothing deleted.")

src/copaw/cli/init_cmd.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@
5353
Review your config and skills regularly; limit tool scope to what you need.
5454
"""
5555

56+
TELEMETRY_INFO = """
57+
Help improve CoPaw by sharing anonymous usage data!
58+
59+
We collect only:
60+
• CoPaw version (e.g., 0.0.7)
61+
• Install method (pip, Docker, or desktop app)
62+
• OS and version (e.g., macOS 14.0, Ubuntu 22.04)
63+
• Python version (e.g., 3.11)
64+
• CPU architecture (e.g., x86_64, arm64)
65+
• GPU availability (detected, not detailed specs)
66+
67+
No personal data collected! No files, no credentials, no identifiable information.
68+
This helps us understand CoPaw's usage environment and prioritize improvements.
69+
"""
70+
5671

5772
def _echo_security_warning_box() -> None:
5873
"""Print SECURITY_WARNING in a rich panel with blue border."""
@@ -66,6 +81,18 @@ def _echo_security_warning_box() -> None:
6681
)
6782

6883

84+
def _echo_telemetry_info_box() -> None:
85+
"""Print TELEMETRY_INFO in a rich panel with blue border."""
86+
console = Console()
87+
console.print(
88+
Panel(
89+
TELEMETRY_INFO.strip(),
90+
title="[bold]📊 Help improve CoPaw[/bold]",
91+
border_style="blue",
92+
),
93+
)
94+
95+
6996
DEFAULT_HEARTBEAT_MDS = {
7097
"zh": """# Heartbeat checklist
7198
- 扫描收件箱紧急邮件
@@ -107,7 +134,11 @@ def _echo_security_warning_box() -> None:
107134
help="Skip security confirmation (use with --defaults for scripts/Docker).",
108135
)
109136
# pylint: disable=too-many-branches,too-many-statements
110-
def init_cmd(force: bool, use_defaults: bool, accept_security: bool) -> None:
137+
def init_cmd(
138+
force: bool,
139+
use_defaults: bool,
140+
accept_security: bool,
141+
) -> None:
111142
"""Create working dir with config.json and HEARTBEAT.md (interactive)."""
112143
config_path = get_config_path()
113144
working_dir = config_path.parent
@@ -133,6 +164,26 @@ def init_cmd(force: bool, use_defaults: bool, accept_security: bool) -> None:
133164
raise click.Abort()
134165
working_dir.mkdir(parents=True, exist_ok=True)
135166

167+
# --- Telemetry collection (optional, anonymous) ---
168+
from ..utils.telemetry import (
169+
collect_and_upload_telemetry,
170+
has_telemetry_been_collected,
171+
mark_telemetry_collected,
172+
)
173+
174+
if not has_telemetry_been_collected(working_dir):
175+
if use_defaults:
176+
success = collect_and_upload_telemetry(working_dir)
177+
178+
else:
179+
_echo_telemetry_info_box()
180+
if prompt_confirm("Share usage data?", default=True):
181+
success = collect_and_upload_telemetry(working_dir)
182+
if success:
183+
click.echo("✓ Thank you!")
184+
else:
185+
mark_telemetry_collected(working_dir)
186+
136187
# --- config.json ---
137188
write_config = True
138189
if config_path.is_file() and not force and not use_defaults:

0 commit comments

Comments
 (0)