Sublime Textを「精密な計測器」へ変貌させる:ActivityWatch連携によるエンジニアリング・メトリクスの極致
エンジニアの生産性は「時間の密度」と「コンテキストスイッチのコスト」に集約される。しかし、我々は往々にして「自分がどの設計思想に、どの程度のリソースを投下したか」を感覚だけで語ってしまう。これはエンジニアリングではない。
本稿では、Sublime Textの強力なPython APIを駆使し、オープンソースのトラッキングエンジン「ActivityWatch」と直結させることで、エディタ内での思考ログを定量的データへと変換するアーキテクチャを構築する。単なる時間計測ではない、あなたの開発ライフサイクルを科学する領域へ足を踏み入れよう。
—
1. アーキテクチャの設計思想:なぜ「直接連携」なのか
既存のプラグインやブラウザ拡張機能は、OSレベルのフォーカス追跡に頼るものが多い。しかし、これでは「どのファイルを開いているか」という粒度まで正確に追跡できない。
今回構築するのは、Sublime Textの `EventListener` をトリガーに、ActivityWatchのローカルAPI(REST API)へ直接JSONペイロードを投げるパイプラインだ。
- トリガー: `on_activated_async` / `on_modified_async` イベント(メインスレッドを阻害しない非同期処理)
- トランスポート: HTTP/1.1 POSTリクエスト
- データシンク: ActivityWatchの `aw-server`
これにより、OSの制約や他のアプリケーションのノイズを排除し、純粋な「コードエディタ上の思考時間」だけを抽出可能にする。
—
2. 実装:Sublime Textの深淵を叩くプラグイン設計
Sublime Textの `Packages/User/` 配下に `ActivityTracker.py` を作成する。このコードは、エディタのフォーカス変更を検知し、ActivityWatchへメタデータをプッシュする。
import sublime
import sublime_plugin
import urllib.request
import json
import time
ActivityWatchのデフォルトポートとエンドポイント
AW_URL = “http://localhost:5600/api/0/buckets/sublime-text-tracker/events”
class ActivityTracker(sublime_plugin.EventListener):
def on_activated_async(self, view):
# ファイルが変更された際、現在のパスとプロジェクト情報を抽出
filename = view.file_name()
if not filename:
return
# ActivityWatchが要求するデータ構造(バケットのスキーマに準拠)
payload = {
“timestamp”: time.strftime(“%Y-%m-%dT%H:%M:%SZ”, time.gmtime()),
“duration”: 0,
“data”: {
“file”: filename,
“project”: view.window().project_file_name() or “untracked”,
“syntax”: view.settings().get(“syntax”)
}
}
# 非同期で送信し、エディタのUIレスポンスを絶対に落とさない
self._push_to_aw(payload)
def _push_to_aw(self, data):
req = urllib.request.Request(AW_URL, data=json.dumps(data).encode(),
headers={‘Content-Type’: ‘application/json’})
try:
urllib.request.urlopen(req, timeout=1) # タイムアウトは極短に設定
except Exception:
pass # サーバーがオフラインでも開発フローを中断させない防衛的コード
—
3. DevOps的アプローチ:コンテナ環境との統合
Dockerベースの開発環境(Dev Containers)で作業する場合、ローカルのActivityWatchとコンテナ内のSublime Textをどう疎通させるか。ここが運用の肝だ。
ネットワークのトンネリング
コンテナ起動時に、ホスト側のActivityWatch APIポートを共有する。`docker-compose.yml` に以下の設定を追記する。
services:
dev-env:
# …
environment:
# コンテナ内からホストのポートへアクセスするためのゲートウェイ
- AW_API_URL=http://host.docker.internal:5600/api/0/
CI/CDパイプラインへの統合(メタデータの活用)
この計測データは、単なる個人記録に留まらない。CI/CDの実行時間と「コーディング時間」を突合させることで、「機能実装に費やした時間 vs テスト実行の待ち時間」という、DevOpsの最重要指標である「リードタイムの構成要素」を可視化できる。
ActivityWatchのCLI (`aw-cli`) を使い、リリース時にこのログを抽出するスクリプトをCIパイプラインに組み込む。
特定プロジェクトの今週の作業ログを抽出
aw-cli query ‘bucket = “sublime-text-tracker” | filter(project == “target-project”)’
—
4. パフォーマンス最適化と「アーキテクトの戒め」
Sublime Textの `EventListener` は強力だが、実装を誤ればエディタの挙動は一気に重くなる。
1. 非同期処理の徹底: 必ず `_async` 系メソッドを使用すること。同期的なAPIコールは、I/O待ちが発生した瞬間にエディタの入力ラグ(入力遅延)を引き起こす。これはエンジニアにとっての死を意味する。
2. バッファリング: 毎回HTTPリクエストを飛ばすのではなく、キューに溜めて数分おきにバッチ送信する実装へ改良することを推奨する。メモリフットプリントを最小限に抑えつつ、通信コストを劇的に下げることが可能だ。
3. フィルタリング: `node_modules` や `vendor` などのライブラリディレクトリを監視対象から外す条件分岐を入れること。これだけでデータ量は1/10になり、分析精度が10倍に向上する。
—
結びに:データで語るエンジニアへ
我々が書くコードは、単なる文字列ではない。それは意思決定の集合体だ。
ActivityWatchで可視化されたデータは、あなたがどのコードベースに、どの時間帯に、最も高い集中力を発揮しているかを教えてくれる。そのデータは、次なるリファクタリングの優先順位や、チームのボトルネックを特定するための最高級のインサイトとなるはずだ。
Sublime Textをただのテキスト編集ツールで終わらせるな。貴方の思考をデータという言語に翻訳する、高度な「インテリジェンス・インターフェース」へと昇華させるのだ。