openclacky 1.3.2 → 1.3.3

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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -0
  3. data/Dockerfile +3 -0
  4. data/README.md +1 -1
  5. data/README_JA.md +237 -0
  6. data/lib/clacky/agent/session_serializer.rb +49 -5
  7. data/lib/clacky/agent/time_machine.rb +247 -26
  8. data/lib/clacky/agent.rb +12 -1
  9. data/lib/clacky/agent_config.rb +14 -2
  10. data/lib/clacky/default_agents/_panels/git/panel.js +201 -0
  11. data/lib/clacky/default_agents/_panels/time_machine/panel.js +640 -0
  12. data/lib/clacky/default_agents/coding/profile.yml +3 -0
  13. data/lib/clacky/default_agents/coding/webui/.gitkeep +0 -0
  14. data/lib/clacky/default_skills/cron-task-creator/SKILL.md +1 -1
  15. data/lib/clacky/default_skills/extend-openclacky/SKILL.md +6 -4
  16. data/lib/clacky/default_skills/media-gen/SKILL.md +30 -6
  17. data/lib/clacky/media/openai_compat.rb +64 -1
  18. data/lib/clacky/media/output_dir.rb +43 -0
  19. data/lib/clacky/message_history.rb +9 -0
  20. data/lib/clacky/server/channel/channel_manager.rb +26 -0
  21. data/lib/clacky/server/git_panel.rb +115 -0
  22. data/lib/clacky/server/http_server.rb +497 -12
  23. data/lib/clacky/server/server_master.rb +6 -4
  24. data/lib/clacky/version.rb +1 -1
  25. data/lib/clacky/web/app.css +473 -60
  26. data/lib/clacky/web/app.js +30 -7
  27. data/lib/clacky/web/components/code-editor.js +197 -0
  28. data/lib/clacky/web/{notify.js → components/notify.js} +1 -1
  29. data/lib/clacky/web/core/aside.js +112 -0
  30. data/lib/clacky/web/core/ext.js +387 -0
  31. data/lib/clacky/web/features/backup/store.js +92 -0
  32. data/lib/clacky/web/features/backup/view.js +94 -0
  33. data/lib/clacky/web/features/billing/store.js +163 -0
  34. data/lib/clacky/web/{billing.js → features/billing/view.js} +132 -240
  35. data/lib/clacky/web/features/brand/store.js +110 -0
  36. data/lib/clacky/web/{brand.js → features/brand/view.js} +49 -199
  37. data/lib/clacky/web/features/channels/store.js +103 -0
  38. data/lib/clacky/web/{channels.js → features/channels/view.js} +50 -127
  39. data/lib/clacky/web/features/creator/store.js +81 -0
  40. data/lib/clacky/web/{creator.js → features/creator/view.js} +53 -102
  41. data/lib/clacky/web/features/mcp/store.js +158 -0
  42. data/lib/clacky/web/{mcp.js → features/mcp/view.js} +57 -134
  43. data/lib/clacky/web/features/model-tester/store.js +77 -0
  44. data/lib/clacky/web/features/model-tester/view.js +7 -0
  45. data/lib/clacky/web/features/profile/store.js +170 -0
  46. data/lib/clacky/web/{profile.js → features/profile/view.js} +94 -144
  47. data/lib/clacky/web/features/share/store.js +145 -0
  48. data/lib/clacky/web/{share.js → features/share/view.js} +66 -202
  49. data/lib/clacky/web/features/skills/store.js +303 -0
  50. data/lib/clacky/web/features/skills/view.js +550 -0
  51. data/lib/clacky/web/features/tasks/store.js +135 -0
  52. data/lib/clacky/web/features/tasks/view.js +241 -0
  53. data/lib/clacky/web/features/trash/store.js +242 -0
  54. data/lib/clacky/web/{trash.js → features/trash/view.js} +102 -293
  55. data/lib/clacky/web/features/version/store.js +165 -0
  56. data/lib/clacky/web/features/version/view.js +323 -0
  57. data/lib/clacky/web/features/workspace/store.js +99 -0
  58. data/lib/clacky/web/features/workspace/view.js +305 -0
  59. data/lib/clacky/web/i18n.js +56 -6
  60. data/lib/clacky/web/index.html +117 -58
  61. data/lib/clacky/web/sessions.js +221 -25
  62. data/lib/clacky/web/settings.js +118 -22
  63. data/lib/clacky/web/skills.js +3 -863
  64. data/lib/clacky/web/vendor/codemirror/codemirror.min.js +29 -0
  65. data/lib/clacky.rb +1 -0
  66. metadata +45 -20
  67. data/lib/clacky/web/backup.js +0 -119
  68. data/lib/clacky/web/model-tester.js +0 -66
  69. data/lib/clacky/web/tasks.js +0 -373
  70. data/lib/clacky/web/version.js +0 -449
  71. data/lib/clacky/web/workspace.js +0 -316
  72. /data/lib/clacky/web/{notify.mp3 → assets/notify.mp3} +0 -0
  73. /data/lib/clacky/web/{datepicker.js → components/datepicker.js} +0 -0
  74. /data/lib/clacky/web/{onboard.js → components/onboard.js} +0 -0
  75. /data/lib/clacky/web/{sidebar.js → components/sidebar.js} +0 -0
  76. /data/lib/clacky/web/{marked.min.js → vendor/marked/marked.min.js} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed703cddac3ffa9887b5c500c5dfbe57c895eb5aab0e9dc3338592c9317555ec
4
- data.tar.gz: 67d21c3c857e72bb729cfcecbdb3749eaaac1c76b21e1d0600081d1e4d79e880
3
+ metadata.gz: 6b9b4de98a5b98c110e4ee71bc8039c1b6445fda13f4479c42d466d80bb307bd
4
+ data.tar.gz: b47e189d857b86955eb95253e0b873d1cad16f9dfcb5040e29e638134151b9a8
5
5
  SHA512:
6
- metadata.gz: 4fe46c92c67e5937bf24e325be47046a9ebf555afb722aaaaf108a17b2c13403c7e42c08d4b1a7abafad5c5ffb5d79d2749264c051572d157d0094dcb067ac78
7
- data.tar.gz: 5fa8e909159560aa13944c0435716e7a98265504c6f61e8cfc298bc09553aa218ac404423d4e9b45f5a8d17563f0ae8a7a50547460fb497e06a98bc46b55aa53
6
+ metadata.gz: 1ab60195873b54c48d72a4d6ebe5f79c9e5daeaa826f867c50cb79e5f6d367dd809b53ebe50aecd42af397cdd03962c0f0a5517ac2e94112b7399778d52c22ec
7
+ data.tar.gz: c11638e5355fde8fc2ade76d7868f8b68f47722dada241abafd34adf5a61fc88d5b734292ded5cb97cbdb4bc6360c9fd7b84a77ebd9fe95ec156a8eb02828556
data/CHANGELOG.md CHANGED
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.3.3] - 2026-06-23
9
+
10
+ ### Added
11
+ - Profile editor with CodeMirror for editing agent SOUL/USER files
12
+ - Inline editing for memory cards
13
+ - Workspace file preview, plus "copy path" in the context menu and a close button in the code editor
14
+ - Time Machine: browse and restore previous workspace states via git
15
+ - Image editing support in media generation
16
+ - Copy and edit actions on user/assistant message bubbles
17
+ - Media output directory configuration in settings
18
+ - Web UI extension support
19
+ - Health check endpoint and signal logging
20
+
21
+ ### Improved
22
+ - Differentiated icons and reordered buttons in the context menu and memory card
23
+ - Removed the standalone preview panel for a cleaner workspace layout
24
+ - Throttle duplicate inbound channel messages
25
+ - Session bar labels no longer wrap
26
+ - Added Japanese README (README_JA.md)
27
+
28
+ ### Fixed
29
+ - Lock the default-model checkbox when only one model exists (C-5677)
30
+ - Jump to a session that is not yet loaded in the sidebar (C-5679)
31
+ - Workspace panel now uses overlay mode on mobile
32
+ - Clarified that `include_sessions` applies to auto-backup only (UI)
33
+ - Removed extra padding from model cards in the grid
34
+ - Moved profile fetch into the store and fixed the architecture spec
35
+
8
36
  ## [1.3.2] - 2026-06-18
9
37
 
10
38
  ### Added
data/Dockerfile CHANGED
@@ -24,5 +24,8 @@ VOLUME ["/root/.clacky"]
24
24
 
25
25
  EXPOSE 7070
26
26
 
27
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
28
+ CMD curl -f http://localhost:7070/health || exit 1
29
+
27
30
  ENTRYPOINT ["openclacky"]
28
31
  CMD ["server", "--host", "0.0.0.0"]
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![License](https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square)](LICENSE.txt)
8
8
 
9
9
  <p align="center">
10
- <a href="README.md">English</a> · <a href="README_CN.md">简体中文</a>
10
+ <a href="README.md">English</a> · <a href="README_CN.md">简体中文</a> · <a href="README_JA.md">日本語</a>
11
11
  </p>
12
12
 
13
13
  > Contributing? Read **[CONTRIBUTING.md](./CONTRIBUTING.md)** before opening a PR.
data/README_JA.md ADDED
@@ -0,0 +1,237 @@
1
+ # OpenClacky
2
+
3
+ [![Build](https://img.shields.io/github/actions/workflow/status/clacky-ai/openclacky/main.yml?label=build&style=flat-square)](https://github.com/clacky-ai/openclacky/actions)
4
+ [![Release](https://img.shields.io/gem/v/openclacky?label=release&style=flat-square&color=blue)](https://rubygems.org/gems/openclacky)
5
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.1.0-red?style=flat-square)](https://www.ruby-lang.org)
6
+ [![Downloads](https://img.shields.io/gem/dt/openclacky?label=downloads&style=flat-square&color=brightgreen)](https://rubygems.org/gems/openclacky)
7
+ [![License](https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square)](LICENSE.txt)
8
+
9
+ <p align="center">
10
+ <a href="README.md">English</a> · <a href="README_CN.md">简体中文</a> · <a href="README_JA.md">日本語</a>
11
+ </p>
12
+
13
+ > コントリビュートする場合は、PR を作成する前に **[CONTRIBUTING.md](./CONTRIBUTING.md)** をお読みください。
14
+
15
+ **最もトークン効率の高いオープンソース AI エージェント。**
16
+
17
+ OpenClacky は Claude Code と同等の性能を同等のコストで実現しつつ、他のオープンソースエージェントと比べて大幅にコストを削減します(OpenClaw 比で約 50%、Hermes 比で約 3 倍安価)。100% オープンソース(MIT)、任意の OpenAI 互換モデルで BYOK が可能で、2 年にわたるエージェント開発(Agentic R&D)とハーネスエンジニアリングの上に構築されています。
18
+
19
+ > Web サイト: https://www.openclacky.com/ · 出資元 **MiraclePlus · ZhenFund · Sequoia China · Hillhouse Capital**
20
+
21
+ ## なぜ OpenClacky なのか?
22
+
23
+ 同じタスクで、どれだけ支払いますか? 同等のエージェントワークロードにおいて、OpenClacky は主流の代替手段と比べて大量のトークン消費を節約します。
24
+
25
+ | エージェント | 相対コスト | 備考 |
26
+ |---|---|---|
27
+ | **OpenClacky** | **約 0.8** | 16 ツール · キャッシュヒット率約 100% · サブエージェントルーティング |
28
+ | Claude Code | 1.0×(基準) | 世界クラスのハーネス、クローズドソースのサブスクリプション |
29
+ | OpenClaw | 約 1.5× | 同等のハーネスエージェント |
30
+ | Hermes | 約 3× | 52 個の組み込みツール — スキーマの肥大化が約 3〜4 倍 |
31
+
32
+ *数値は社内の一般的なエージェントタスクで計測した平均値であり、Claude Code を基準としています。詳細なベンチマークレポートは GitHub で公開予定です。*
33
+
34
+ ## 機能比較
35
+
36
+ エージェントのコア性能はこの分野でおおむね横並びであり、本当の差別化要因は **コスト、オープン性、Skill の進化、そして統合機能** です。
37
+
38
+ | 機能 | Claude Code | OpenClaw | Hermes | **OpenClacky** |
39
+ |---|:---:|:---:|:---:|:---:|
40
+ | トークンコスト | 1.0× | 約 1.5× | 約 3× | **約 0.8** |
41
+ | オープンソース | ❌ クローズド | ✅ オープン | ✅ オープン | ✅ MIT |
42
+ | BYOK / モデルの自由度 | ❌ Anthropic のみ | ✅ | ✅ | ✅ |
43
+ | Skill の自己進化 | ❌ | ❌ | ✅ | ✅ |
44
+ | IM 統合(Feishu/WeCom/WeChat/Discord/Telegram) | ❌ | ✅ | ✅ | ✅ |
45
+
46
+ ## どうやってコストを下げているのか
47
+
48
+ 機能を削るのではなく、すべてのレイヤーで正しい選択を積み重ねることで実現しています。
49
+
50
+ ### 1. 超高水準のキャッシュヒット率
51
+ セッションを再起動しない、ダブルキャッシュマーカー、**Insert-then-Compress(挿入してから圧縮)** — システムプロンプトは決して書き換えられないため、圧縮後もキャッシュを再利用できます。**計測されたキャッシュヒット率: ほぼ 100%。**
52
+
53
+ ### 2. 最小限のツールセット
54
+ **コアツールはわずか 16 個** です。機能は単一の `invoke_skill` メタツールを介して Skill エコシステムにオフロードされます。指標はツールの数ではなく、タスクの完了率です。
55
+
56
+ | OpenClacky | Claude Code | OpenClaw | Hermes |
57
+ |:--:|:--:|:--:|:--:|
58
+ | **16** | 40+ | 23 | 52 |
59
+
60
+ ### 3. アイドル時の自動圧縮
61
+ 会議に行く、コーヒーを淹れる — その間にエージェントは長いコンテキストをバックグラウンドで圧縮し、キャッシュを事前にウォームアップします。戻ってきて最初に送るメッセージは直接キャッシュにヒットします。**コールドスタート時の初回トークンコストを 50% 以上削減。**
62
+
63
+ ### 4. BYOK — モデルを自分で選び、コストを自分で決める
64
+ 任意の OpenAI 互換 API をプラグアンドプレイで利用できます。公式の直接接続、集約ルーティング、互換リレー — 選択は 100% あなた次第です。コードには Claude を使い、サブタスクは自動的に DeepSeek にルーティングして、さらにトークンを節約しましょう。
65
+
66
+ **2 年 · 3 世代のエージェントアーキテクチャ · 6 つのコアハーネスエンジニアリングの意思決定** の上に構築されています。
67
+
68
+ ## Skill — エージェントの魂
69
+
70
+ - **`/` で呼び出す** — 瞬時の閲覧、あいまい検索、ダイレクトコール。何百もの Skill を指先で操作できます。
71
+ - **自然言語で Skill を作成** — やりたいことを説明するだけで、エージェントが `SKILL.md` を起草し、手順を分解し、検証を実行します。コードは不要です。
72
+ - **自己進化** — 各実行のあと、エージェントは実行コンテキストと結果に基づいて Skill を更新します。次回の呼び出しはより安定し、より正確になります。
73
+ - **オープンで互換性が高い** — Claude Skills / Markdown Pack / カスタム形式をサポートします。
74
+ - **収益化が可能** — 洗練された Skill はパッケージ化して販売でき、暗号化配布、License 管理、作者が設定する価格設定に対応します。
75
+
76
+ ## インストール
77
+
78
+ ### デスクトップインストーラー(推奨)
79
+
80
+ ダブルクリックでインストール — 環境、依存関係、Skill のすべてが自動的にセットアップされます。
81
+
82
+ - **macOS** — [`.dmg` をダウンロード](https://oss.1024code.com/openclacky-installer/official/openclacky-installer.dmg)(Apple Silicon / Intel)
83
+ - **Windows** — [`.exe` をダウンロード](https://oss.1024code.com/openclacky-installer/official/openclacky-installer.exe)(Windows 10 2004+ / Windows 11)
84
+
85
+ その他のオプション: https://www.openclacky.com/
86
+
87
+ ### コマンドライン
88
+
89
+ ワンラインインストール(Mac/Ubuntu):
90
+
91
+ ```bash
92
+ /bin/bash -c "$(curl -sSL https://raw.githubusercontent.com/clacky-ai/openclacky/main/scripts/install.sh)"
93
+ ```
94
+
95
+ Windows:
96
+
97
+ ```bash
98
+ powershell -c "& ([scriptblock]::Create((irm 'https://raw.githubusercontent.com/clacky-ai/openclacky/main/scripts/install.ps1')))"
99
+ ```
100
+
101
+ または Ruby(3.x/4.x)を使う場合:
102
+
103
+ **要件:** Ruby >= 3.1.0
104
+
105
+ ```bash
106
+ gem install openclacky
107
+ ```
108
+
109
+ 詳細はこちら: https://www.openclacky.com/docs/installation
110
+
111
+ ### Docker
112
+
113
+ ビルド:
114
+
115
+ ```bash
116
+ git clone https://github.com/clacky-ai/openclacky.git
117
+ cd openclacky
118
+ docker build -t openclacky .
119
+ ```
120
+
121
+ **Linux:**
122
+
123
+ ```bash
124
+ docker run -d --network=host -e CLACKY_ACCESS_KEY="" openclacky
125
+ ```
126
+
127
+ `--network=host` は、コンテナ内のエージェントがホスト上で動作する Chrome のリモートデバッグポートに到達するために必要です。
128
+
129
+ **macOS / Windows:**
130
+
131
+ ```bash
132
+ docker run -d -p 7070:7070 -e CLACKY_ACCESS_KEY="" openclacky
133
+ ```
134
+
135
+ > **注意:** macOS/Windows では `--network=host` がサポートされていないため、ブラウザの自動化が制限される場合があります。
136
+
137
+ 起動後、**http://localhost:7070** を開いてください。
138
+
139
+ 環境変数:
140
+
141
+ | 変数 | 説明 |
142
+ |---|---|
143
+ | `CLACKY_ACCESS_KEY` | アクセスキーで Web UI を保護します(空の場合はパブリックモード) |
144
+
145
+
146
+ ## クイックスタート
147
+
148
+ ### ターミナル(CLI)
149
+
150
+ ```bash
151
+ openclacky # カレントディレクトリで対話型エージェントを起動
152
+ ```
153
+
154
+ ### Web UI
155
+
156
+ ```bash
157
+ openclacky server # デフォルト: http://localhost:7070
158
+ ```
159
+
160
+ **http://localhost:7070** を開くと、マルチセッション対応の本格的なチャットインターフェースが利用できます — コーディング、コピーライティング、リサーチのセッションを並行して実行できます。
161
+
162
+ オプション:
163
+
164
+ ```bash
165
+ openclacky server --port 8080 # カスタムポート
166
+ openclacky server --host 0.0.0.0 # すべてのインターフェースでリッスン(リモートアクセス)
167
+ ```
168
+
169
+ ## 設定
170
+
171
+ ```bash
172
+ $ openclacky
173
+ > /config
174
+ ```
175
+
176
+ **API Key**、**Model**、**Base URL**(任意の OpenAI 互換プロバイダー)を設定します。
177
+
178
+ 標準でサポート: **Claude (Anthropic) · GPT (OpenAI) · DeepSeek · Kimi (Moonshot) · MiniMax · OpenRouter** — または任意のカスタムエンドポイント。
179
+
180
+ ## コーディングのユースケース
181
+
182
+ OpenClacky は汎用 AI コーディングアシスタントとして機能します — フルスタックアプリの雛形作成、機能追加、あるいは未知のコードベースの探索が可能です:
183
+
184
+ ```bash
185
+ $ openclacky
186
+ > /new my-app # 新しいプロジェクトの雛形を作成
187
+ > メールとパスワードによるユーザー認証を追加して
188
+ > 決済モジュールはどのように動作しますか?
189
+ ```
190
+
191
+ ## Star History
192
+
193
+ <a href="https://www.star-history.com/?repos=clacky-ai%2Fopenclacky&type=date&legend=top-left">
194
+ <picture>
195
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=clacky-ai/openclacky&type=date&theme=dark&legend=top-left" />
196
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=clacky-ai/openclacky&type=date&legend=top-left" />
197
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=clacky-ai/openclacky&type=date&legend=top-left" />
198
+ </picture>
199
+ </a>
200
+
201
+ ## 上級者向け — クリエイタープログラム
202
+
203
+ すでにパワーユーザーたちは、自身のワークフローを OpenClacky 上の垂直特化型 AI エキスパートへと変えています — 暗号化配布、License 管理、自分で設定する価格。法務、医療、ファイナンシャルプランニングなど、さまざまな分野で展開されています。
204
+
205
+ 詳細はこちら: https://www.openclacky.com/ → Creators
206
+
207
+ ## ソースからのインストール
208
+
209
+ ```bash
210
+ git clone https://github.com/clacky-ai/openclacky.git
211
+ cd openclacky
212
+ bundle install
213
+ bin/clacky
214
+ ```
215
+
216
+ ## 信頼性と信用
217
+
218
+ - **100% オープンソース** — MIT ライセンス、すべてのコードが公開され、すべての意思決定が追跡可能
219
+ - **2 年にわたるエージェント開発(Agentic R&D)** — 3 世代のアーキテクチャ
220
+ - **16 個のコアツール** — 設計思想としての最小主義
221
+ - **出資元** MiraclePlus · ZhenFund · Sequoia China · Hillhouse Capital
222
+
223
+ ## コントリビューター
224
+
225
+ すべてのコード、バグ報告、そして丁寧なレビューが大切です。OpenClacky をより良くしてくださり、ありがとうございます。
226
+
227
+ <a href="https://github.com/clacky-ai/openclacky/graphs/contributors">
228
+ <img src="https://contrib.rocks/image?repo=clacky-ai/openclacky" />
229
+ </a>
230
+
231
+ ## コントリビュート
232
+
233
+ バグ報告とプルリクエストは GitHub( https://github.com/clacky-ai/openclacky )で歓迎しています。コントリビューターは[行動規範](https://github.com/clacky-ai/openclacky/blob/main/CODE_OF_CONDUCT.md)を遵守することが求められます。
234
+
235
+ ## ライセンス
236
+
237
+ [MIT ライセンス](https://opensource.org/licenses/MIT)のもとでオープンソースとして利用可能です。
@@ -48,10 +48,25 @@ module Clacky
48
48
  end
49
49
  @latest_latency = last_assistant_with_latency&.dig(:latency)
50
50
 
51
- # Restore Time Machine state
52
- @task_parents = session_data.dig(:time_machine, :task_parents) || {}
53
- @current_task_id = session_data.dig(:time_machine, :current_task_id) || 0
54
- @active_task_id = session_data.dig(:time_machine, :active_task_id) || 0
51
+ # Restore Time Machine state. JSON.parse(symbolize_names:) turns the
52
+ # task_parents hash keys into symbols like :"1"; the runtime expects
53
+ # Integer keys/values, so coerce both ends back here.
54
+ raw_parents = session_data.dig(:time_machine, :task_parents) || {}
55
+ @task_parents = raw_parents.each_with_object({}) { |(k, v), h| h[k.to_s.to_i] = v.to_i }
56
+ @current_task_id = (session_data.dig(:time_machine, :current_task_id) || 0).to_i
57
+ @active_task_id = (session_data.dig(:time_machine, :active_task_id) || 0).to_i
58
+
59
+ raw_meta = session_data.dig(:time_machine, :task_meta) || {}
60
+ @task_meta = raw_meta.each_with_object({}) do |(k, v), h|
61
+ tid = k.to_s.to_i
62
+ attrs = v.is_a?(Hash) ? v : {}
63
+ h[tid] = {
64
+ title: attrs[:title] || attrs["title"],
65
+ started_at: (attrs[:started_at] || attrs["started_at"])&.to_f,
66
+ ended_at: (attrs[:ended_at] || attrs["ended_at"])&.to_f,
67
+ }
68
+ end
69
+ backfill_task_meta_from_history!
55
70
 
56
71
  # Check if the session ended with an error.
57
72
  # We record the rollback intent here but do NOT truncate history immediately —
@@ -99,6 +114,34 @@ module Clacky
99
114
  refresh_system_prompt
100
115
  end
101
116
 
117
+ # Fill missing entries in @task_meta from @history (for sessions saved
118
+ # before task_meta existed, or for tasks whose meta was lost). The first
119
+ # real user message of each task supplies the title; created_at becomes
120
+ # started_at; the latest message in the task supplies ended_at. Tasks
121
+ # whose user turn has already been archived stay without a title and
122
+ # the UI falls back to "Task N".
123
+ private def backfill_task_meta_from_history!
124
+ @task_meta ||= {}
125
+ return if @current_task_id.to_i <= 0
126
+
127
+ @history.to_a.each do |m|
128
+ tid = m[:task_id]
129
+ next unless tid.is_a?(Integer) && tid > 0
130
+ next if m[:system_injected]
131
+
132
+ entry = (@task_meta[tid] ||= {})
133
+ if m[:role].to_s == "user" && (entry[:title].nil? || entry[:title].to_s.empty?)
134
+ text = extract_text_from_content(m[:content]).to_s.gsub(/\s+/, " ").strip
135
+ entry[:title] = text.length > 60 ? "#{text[0...57]}..." : text unless text.empty?
136
+ end
137
+ ts = m[:created_at]
138
+ next unless ts
139
+ entry[:started_at] ||= ts.to_f
140
+ cur_end = entry[:ended_at]
141
+ entry[:ended_at] = ts.to_f if cur_end.nil? || ts.to_f > cur_end
142
+ end
143
+ end
144
+
102
145
  private def persisted_card_field(key)
103
146
  card_id = @config.current_model_id
104
147
  return nil unless card_id
@@ -138,7 +181,8 @@ module Clacky
138
181
  time_machine: { # Include Time Machine state
139
182
  task_parents: @task_parents || {},
140
183
  current_task_id: @current_task_id || 0,
141
- active_task_id: @active_task_id || 0
184
+ active_task_id: @active_task_id || 0,
185
+ task_meta: @task_meta || {}
142
186
  },
143
187
  config: {
144
188
  # NOTE: api_key and other sensitive credentials are intentionally excluded