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
data/lib/clacky.rb CHANGED
@@ -128,6 +128,7 @@ require_relative "clacky/mcp/registry"
128
128
  require_relative "clacky/mcp/skill_provider"
129
129
  require_relative "clacky/media/base"
130
130
  require_relative "clacky/media/openai_compat"
131
+ require_relative "clacky/media/output_dir"
131
132
  require_relative "clacky/media/generator"
132
133
  require_relative "clacky/vision/resolver"
133
134
  require_relative "clacky/telemetry"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openclacky
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - windy
@@ -288,6 +288,7 @@ files:
288
288
  - LICENSE.txt
289
289
  - README.md
290
290
  - README_CN.md
291
+ - README_JA.md
291
292
  - ROADMAP.md
292
293
  - Rakefile
293
294
  - benchmark/fixtures/sample_project/Gemfile
@@ -348,9 +349,12 @@ files:
348
349
  - lib/clacky/client.rb
349
350
  - lib/clacky/default_agents/SOUL.md
350
351
  - lib/clacky/default_agents/USER.md
352
+ - lib/clacky/default_agents/_panels/git/panel.js
353
+ - lib/clacky/default_agents/_panels/time_machine/panel.js
351
354
  - lib/clacky/default_agents/base_prompt.md
352
355
  - lib/clacky/default_agents/coding/profile.yml
353
356
  - lib/clacky/default_agents/coding/system_prompt.md
357
+ - lib/clacky/default_agents/coding/webui/.gitkeep
354
358
  - lib/clacky/default_agents/general/profile.yml
355
359
  - lib/clacky/default_agents/general/system_prompt.md
356
360
  - lib/clacky/default_parsers/doc_parser.rb
@@ -420,6 +424,7 @@ files:
420
424
  - lib/clacky/media/gemini.rb
421
425
  - lib/clacky/media/generator.rb
422
426
  - lib/clacky/media/openai_compat.rb
427
+ - lib/clacky/media/output_dir.rb
423
428
  - lib/clacky/message_format/anthropic.rb
424
429
  - lib/clacky/message_format/bedrock.rb
425
430
  - lib/clacky/message_format/open_ai.rb
@@ -459,6 +464,7 @@ files:
459
464
  - lib/clacky/server/channel/user_adapter_loader.rb
460
465
  - lib/clacky/server/discover.rb
461
466
  - lib/clacky/server/epipe_safe_io.rb
467
+ - lib/clacky/server/git_panel.rb
462
468
  - lib/clacky/server/http_server.rb
463
469
  - lib/clacky/server/scheduler.rb
464
470
  - lib/clacky/server/server_master.rb
@@ -538,38 +544,58 @@ files:
538
544
  - lib/clacky/web/app.css
539
545
  - lib/clacky/web/app.js
540
546
  - lib/clacky/web/apple-touch-icon-180.png
547
+ - lib/clacky/web/assets/notify.mp3
541
548
  - lib/clacky/web/auth.js
542
- - lib/clacky/web/backup.js
543
- - lib/clacky/web/billing.js
544
- - lib/clacky/web/brand.js
545
- - lib/clacky/web/channels.js
546
- - lib/clacky/web/creator.js
547
- - lib/clacky/web/datepicker.js
549
+ - lib/clacky/web/components/code-editor.js
550
+ - lib/clacky/web/components/datepicker.js
551
+ - lib/clacky/web/components/notify.js
552
+ - lib/clacky/web/components/onboard.js
553
+ - lib/clacky/web/components/sidebar.js
554
+ - lib/clacky/web/core/aside.js
555
+ - lib/clacky/web/core/ext.js
548
556
  - lib/clacky/web/design-sample.css
549
557
  - lib/clacky/web/design-sample.html
550
558
  - lib/clacky/web/favicon.ico
551
559
  - lib/clacky/web/favicon.svg
560
+ - lib/clacky/web/features/backup/store.js
561
+ - lib/clacky/web/features/backup/view.js
562
+ - lib/clacky/web/features/billing/store.js
563
+ - lib/clacky/web/features/billing/view.js
564
+ - lib/clacky/web/features/brand/store.js
565
+ - lib/clacky/web/features/brand/view.js
566
+ - lib/clacky/web/features/channels/store.js
567
+ - lib/clacky/web/features/channels/view.js
568
+ - lib/clacky/web/features/creator/store.js
569
+ - lib/clacky/web/features/creator/view.js
570
+ - lib/clacky/web/features/mcp/store.js
571
+ - lib/clacky/web/features/mcp/view.js
572
+ - lib/clacky/web/features/model-tester/store.js
573
+ - lib/clacky/web/features/model-tester/view.js
574
+ - lib/clacky/web/features/profile/store.js
575
+ - lib/clacky/web/features/profile/view.js
576
+ - lib/clacky/web/features/share/store.js
577
+ - lib/clacky/web/features/share/view.js
578
+ - lib/clacky/web/features/skills/store.js
579
+ - lib/clacky/web/features/skills/view.js
580
+ - lib/clacky/web/features/tasks/store.js
581
+ - lib/clacky/web/features/tasks/view.js
582
+ - lib/clacky/web/features/trash/store.js
583
+ - lib/clacky/web/features/trash/view.js
584
+ - lib/clacky/web/features/version/store.js
585
+ - lib/clacky/web/features/version/view.js
586
+ - lib/clacky/web/features/workspace/store.js
587
+ - lib/clacky/web/features/workspace/view.js
552
588
  - lib/clacky/web/i18n.js
553
589
  - lib/clacky/web/icon-dark.svg
554
590
  - lib/clacky/web/icon.svg
555
591
  - lib/clacky/web/index.html
556
592
  - lib/clacky/web/logo_nav_dark.png
557
- - lib/clacky/web/marked.min.js
558
- - lib/clacky/web/mcp.js
559
- - lib/clacky/web/model-tester.js
560
- - lib/clacky/web/notify.js
561
- - lib/clacky/web/notify.mp3
562
- - lib/clacky/web/onboard.js
563
- - lib/clacky/web/profile.js
564
593
  - lib/clacky/web/sessions.js
565
594
  - lib/clacky/web/settings.js
566
- - lib/clacky/web/share.js
567
- - lib/clacky/web/sidebar.js
568
595
  - lib/clacky/web/skills.js
569
- - lib/clacky/web/tasks.js
570
596
  - lib/clacky/web/theme.js
571
- - lib/clacky/web/trash.js
572
597
  - lib/clacky/web/utils.js
598
+ - lib/clacky/web/vendor/codemirror/codemirror.min.js
573
599
  - lib/clacky/web/vendor/hljs/highlight.min.js
574
600
  - lib/clacky/web/vendor/hljs/hljs-theme.css
575
601
  - lib/clacky/web/vendor/katex/auto-render.min.js
@@ -595,10 +621,9 @@ files:
595
621
  - lib/clacky/web/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2
596
622
  - lib/clacky/web/vendor/katex/katex.min.css
597
623
  - lib/clacky/web/vendor/katex/katex.min.js
624
+ - lib/clacky/web/vendor/marked/marked.min.js
598
625
  - lib/clacky/web/vendor/qrcode/qrcode.min.js
599
- - lib/clacky/web/version.js
600
626
  - lib/clacky/web/weixin-qr.html
601
- - lib/clacky/web/workspace.js
602
627
  - lib/clacky/web/ws-dispatcher.js
603
628
  - lib/clacky/web/ws.js
604
629
  - scripts/build/build.sh
@@ -1,119 +0,0 @@
1
- // backup.js — Backup settings panel (Settings → General → Backup).
2
- //
3
- // Talks to /api/backup/{status,config,download}. Lets the user toggle automatic
4
- // backups (handled by the server-side Scheduler — fixed daily at 03:00, keeps 7)
5
- // and download a one-off archive directly to the browser.
6
-
7
- const Backup = (() => {
8
-
9
- let _status = null;
10
- let _saving = false;
11
-
12
- async function load() {
13
- try {
14
- const res = await fetch("/api/backup/status");
15
- _status = await res.json();
16
- _render();
17
- } catch (e) {
18
- // Backup section is non-critical; fail quietly.
19
- }
20
- }
21
-
22
- function _render() {
23
- if (!_status) return;
24
- const cfg = _status.config || {};
25
-
26
- const incl = $("backup-include-sessions");
27
- if (incl) incl.checked = cfg.include_sessions !== false;
28
-
29
- const autoToggle = $("backup-auto-toggle");
30
- if (autoToggle) autoToggle.checked = !!cfg.enabled;
31
-
32
- _renderLastRun(cfg);
33
- }
34
-
35
- function _renderLastRun(cfg) {
36
- const el = $("backup-status");
37
- if (!el) return;
38
- if (!cfg.last_run_at) { el.textContent = ""; el.className = "model-test-result"; return; }
39
- if (cfg.last_status === "error") {
40
- el.textContent = I18n.t("settings.backup.lastError", { msg: cfg.last_error || "" });
41
- el.className = "model-test-result error";
42
- } else {
43
- el.textContent = I18n.t("settings.backup.lastOk", { time: _fmtDate(cfg.last_run_at) });
44
- el.className = "model-test-result success";
45
- }
46
- }
47
-
48
- async function _downloadNow() {
49
- const btn = $("btn-backup-now");
50
- const el = $("backup-status");
51
- if (btn) btn.disabled = true;
52
- if (el) { el.textContent = I18n.t("settings.backup.running"); el.className = "model-test-result"; }
53
- try {
54
- const res = await fetch("/api/backup/download");
55
- if (!res.ok) {
56
- let msg = "failed";
57
- try { msg = (await res.json()).error || msg; } catch (e) {}
58
- throw new Error(msg);
59
- }
60
- const blob = await res.blob();
61
- const cd = res.headers.get("Content-Disposition") || "";
62
- const m = cd.match(/filename="?([^"]+)"?/);
63
- const name = (m && m[1]) || "clacky-backup.tar.gz";
64
- const url = URL.createObjectURL(blob);
65
- const a = document.createElement("a");
66
- a.href = url;
67
- a.download = name;
68
- document.body.appendChild(a);
69
- a.click();
70
- a.remove();
71
- URL.revokeObjectURL(url);
72
- if (el) { el.textContent = I18n.t("settings.backup.downloaded"); el.className = "model-test-result success"; }
73
- } catch (e) {
74
- if (el) { el.textContent = I18n.t("settings.backup.lastError", { msg: e.message }); el.className = "model-test-result error"; }
75
- } finally {
76
- if (btn) btn.disabled = false;
77
- }
78
- }
79
-
80
- async function _saveConfig(patch) {
81
- if (_saving) return;
82
- _saving = true;
83
- try {
84
- const res = await fetch("/api/backup/config", {
85
- method: "PATCH",
86
- headers: { "Content-Type": "application/json" },
87
- body: JSON.stringify(patch)
88
- });
89
- const data = await res.json();
90
- if (data.ok) { _status = data.status; _render(); }
91
- } catch (e) {
92
- // ignore — next load will resync
93
- } finally {
94
- _saving = false;
95
- }
96
- }
97
-
98
- function _fmtDate(iso) {
99
- if (!iso) return "";
100
- try { return new Date(iso).toLocaleString(); } catch (e) { return iso; }
101
- }
102
-
103
- function _bind() {
104
- const btn = $("btn-backup-now");
105
- if (btn) btn.addEventListener("click", _downloadNow);
106
-
107
- const autoToggle = $("backup-auto-toggle");
108
- if (autoToggle) autoToggle.addEventListener("change", () => _saveConfig({ enabled: autoToggle.checked }));
109
-
110
- const incl = $("backup-include-sessions");
111
- if (incl) incl.addEventListener("change", () => _saveConfig({ include_sessions: incl.checked }));
112
- }
113
-
114
- document.addEventListener("DOMContentLoaded", _bind);
115
-
116
- return { load };
117
- })();
118
-
119
- window.Backup = Backup;
@@ -1,66 +0,0 @@
1
- // Shared helpers for the model config UI flows.
2
- // Used by both the onboarding wizard and the settings model modal.
3
- window.ModelTester = (function () {
4
- // Test a model connection.
5
- // Returns one of:
6
- // { ok: true, base_url, message } — connected, no rewrite
7
- // { ok: true, base_url, message, rewrote: true } — connected, base_url auto-corrected (/v1 appended)
8
- // { ok: false, message } — failed (server-reported or network)
9
- async function testConnection({ model, base_url, api_key, anthropic_format, index, id } = {}) {
10
- const body = { model, base_url, api_key };
11
- if (typeof id === "string" && id) body.id = id;
12
- if (typeof index === "number") body.index = index;
13
- if (anthropic_format) body.anthropic_format = true;
14
-
15
- let data;
16
- try {
17
- const res = await fetch("/api/config/test", {
18
- method: "POST",
19
- headers: { "Content-Type": "application/json" },
20
- body: JSON.stringify(body)
21
- });
22
- data = await res.json();
23
- } catch (e) {
24
- return { ok: false, message: e.message };
25
- }
26
-
27
- if (!data.ok) {
28
- const msg = data.message || "";
29
- const code = data.error_code || "";
30
- if (code === "insufficient_credit") {
31
- return { ok: false, message: I18n.t("error.insufficient_credit"), error_code: code };
32
- }
33
- return { ok: false, message: msg, error_code: code };
34
- }
35
-
36
- if (data.effective_base_url && data.effective_base_url !== base_url) {
37
- return { ok: true, base_url: data.effective_base_url, message: data.message || "", rewrote: true };
38
- }
39
- return { ok: true, base_url, message: data.message || "" };
40
- }
41
-
42
- // Persist a model config (create or update).
43
- // existingId === null/undefined → POST /api/config/models (create).
44
- // existingId === string → PATCH /api/config/models/:id (update).
45
- // Returns { ok: bool, error? }.
46
- async function saveModel(payload, { existingId } = {}) {
47
- const url = existingId
48
- ? `/api/config/models/${encodeURIComponent(existingId)}`
49
- : "/api/config/models";
50
- const method = existingId ? "PATCH" : "POST";
51
-
52
- try {
53
- const res = await fetch(url, {
54
- method,
55
- headers: { "Content-Type": "application/json" },
56
- body: JSON.stringify(payload)
57
- });
58
- const data = await res.json();
59
- return data.ok ? { ok: true } : { ok: false, error: data.error || "" };
60
- } catch (e) {
61
- return { ok: false, error: e.message };
62
- }
63
- }
64
-
65
- return { testConnection, saveModel };
66
- })();