openclacky 1.5.19 → 1.5.21
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +95 -0
- data/README.md +19 -1
- data/README_CN.md +1 -1
- data/README_JA.md +1 -1
- data/lib/clacky/agent/chunk_index.rb +8 -1
- data/lib/clacky/agent/feedback.rb +30 -0
- data/lib/clacky/agent/history_navigation.rb +17 -3
- data/lib/clacky/agent/hook_manager.rb +6 -1
- data/lib/clacky/agent/llm_caller.rb +17 -3
- data/lib/clacky/agent/message_compressor_helper.rb +36 -2
- data/lib/clacky/agent/session_serializer.rb +45 -4
- data/lib/clacky/agent.rb +135 -55
- data/lib/clacky/agent_config.rb +82 -4
- data/lib/clacky/billing/platform_billing.rb +10 -5
- data/lib/clacky/brand_config.rb +1 -1
- data/lib/clacky/cli.rb +5 -4
- data/lib/clacky/client.rb +12 -5
- data/lib/clacky/deepseek_web_tools.rb +156 -0
- data/lib/clacky/default_extensions/ext-studio/api/handler.rb +8 -0
- data/lib/clacky/default_extensions/ext-studio/panels/studio/view.js +97 -20
- data/lib/clacky/default_extensions/time_machine/panels/time_machine/view.js +1 -0
- data/lib/clacky/default_skills/onboard/SKILL.md +1 -1
- data/lib/clacky/extension/loader.rb +5 -3
- data/lib/clacky/locales/en.rb +5 -5
- data/lib/clacky/locales/zh.rb +5 -5
- data/lib/clacky/message_format/anthropic.rb +20 -0
- data/lib/clacky/message_format/open_ai.rb +31 -14
- data/lib/clacky/message_history.rb +45 -4
- data/lib/clacky/platform_http_client.rb +6 -2
- data/lib/clacky/providers.rb +38 -138
- data/lib/clacky/search_config.rb +47 -13
- data/lib/clacky/server/browser_manager.rb +35 -5
- data/lib/clacky/server/channel/channel_manager.rb +6 -6
- data/lib/clacky/server/discover.rb +5 -4
- data/lib/clacky/server/http_server.rb +285 -53
- data/lib/clacky/server/model_prices.rb +10 -5
- data/lib/clacky/server/pid_files.rb +25 -0
- data/lib/clacky/server/server_master.rb +9 -3
- data/lib/clacky/server/session_registry.rb +37 -7
- data/lib/clacky/server/web_ui_controller.rb +72 -0
- data/lib/clacky/session_manager.rb +28 -6
- data/lib/clacky/skill.rb +1 -1
- data/lib/clacky/tools/ask_user.rb +4 -1
- data/lib/clacky/tools/base.rb +3 -2
- data/lib/clacky/tools/browser.rb +18 -2
- data/lib/clacky/tools/file_reader.rb +1 -1
- data/lib/clacky/tools/terminal/session_manager.rb +19 -1
- data/lib/clacky/tools/terminal.rb +65 -23
- data/lib/clacky/tools/trash_manager.rb +5 -3
- data/lib/clacky/tools/web_fetch.rb +81 -22
- data/lib/clacky/tools/web_search.rb +45 -4
- data/lib/clacky/ui2/ui_controller.rb +1 -1
- data/lib/clacky/ui_interface.rb +4 -3
- data/lib/clacky/utils/file_processor.rb +51 -0
- data/lib/clacky/utils/model_pricing.rb +242 -39
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +1158 -249
- data/lib/clacky/web/app.js +82 -13
- data/lib/clacky/web/components/chat-navigator.js +8 -1
- data/lib/clacky/web/components/code-editor.js +6 -2
- data/lib/clacky/web/components/mentions.js +2 -13
- data/lib/clacky/web/components/model-picker.js +92 -97
- data/lib/clacky/web/components/onboard.js +13 -10
- data/lib/clacky/web/components/sidebar.js +6 -2
- data/lib/clacky/web/features/archive/store.js +196 -0
- data/lib/clacky/web/features/archive/view.js +409 -0
- data/lib/clacky/web/features/backup/view.js +17 -7
- data/lib/clacky/web/features/billing/view.js +84 -10
- data/lib/clacky/web/features/channels/view.js +75 -29
- data/lib/clacky/web/features/new-session/store.js +3 -3
- data/lib/clacky/web/features/new-session/view.js +1 -0
- data/lib/clacky/web/features/trash/store.js +14 -11
- data/lib/clacky/web/features/trash/view.js +66 -13
- data/lib/clacky/web/features/workspace/view.js +421 -16
- data/lib/clacky/web/i18n.js +242 -70
- data/lib/clacky/web/index.html +270 -117
- data/lib/clacky/web/projects.js +56 -1
- data/lib/clacky/web/sessions.js +609 -267
- data/lib/clacky/web/settings.js +186 -32
- data/lib/clacky/web/ws-dispatcher.js +33 -21
- data/lib/clacky.rb +4 -2
- metadata +6 -1
data/lib/clacky/web/projects.js
CHANGED
|
@@ -157,6 +157,8 @@ const Projects = (() => {
|
|
|
157
157
|
Sessions.removeByProjectId(id);
|
|
158
158
|
Sessions.renderList();
|
|
159
159
|
renderSection();
|
|
160
|
+
Archive.refreshIfShown();
|
|
161
|
+
Trash.refreshIfShown();
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
/**
|
|
@@ -514,7 +516,8 @@ const Projects = (() => {
|
|
|
514
516
|
const iconPin = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="transform:rotate(45deg);display:block"><path d="M12 17v5"/><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"/></svg>`;
|
|
515
517
|
const iconEdit = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 1 1 3 3L7 19l-4 1 1-4z"/></svg>`;
|
|
516
518
|
const iconClearSessions = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m16 22-1-4"/><path d="M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1"/><path d="M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z"/><path d="m8 22 1-4"/></svg>`;
|
|
517
|
-
const iconTrash = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="
|
|
519
|
+
const iconTrash = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>`;
|
|
520
|
+
const iconArchive = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="5" rx="1"/><path d="M4 9v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9"/><line x1="10" y1="14" x2="14" y2="14"/></svg>`;
|
|
518
521
|
|
|
519
522
|
const addItem = (labelKey, defaultLabel, iconSvg, danger, onClick) => {
|
|
520
523
|
const item = document.createElement("button");
|
|
@@ -551,6 +554,14 @@ const Projects = (() => {
|
|
|
551
554
|
isPinned ? "Unpin" : "Pin to top", iconPin, false, pinToggle);
|
|
552
555
|
addItem("projects.menu.edit", "Edit Project", iconEdit, false, () => promptEdit(projectId));
|
|
553
556
|
addItem("projects.menu.deleteSessions", "Delete Sessions", iconClearSessions, false, () => promptDeleteSessions(projectId));
|
|
557
|
+
|
|
558
|
+
// The last group (archive + delete) mirrors the session menu: an explicit
|
|
559
|
+
// divider above Archive, then Archive right before Delete.
|
|
560
|
+
const divider = document.createElement("div");
|
|
561
|
+
divider.className = "project-actions-menu-divider";
|
|
562
|
+
menu.appendChild(divider);
|
|
563
|
+
|
|
564
|
+
addItem("projects.menu.archiveSessions", "Archive Sessions", iconArchive, false, () => promptArchiveSessions(projectId));
|
|
554
565
|
addItem("projects.menu.delete", "Delete", iconTrash, true, () => promptDelete(projectId));
|
|
555
566
|
|
|
556
567
|
// Position near anchor
|
|
@@ -1050,11 +1061,53 @@ const Projects = (() => {
|
|
|
1050
1061
|
Sessions.removeByProjectId(id);
|
|
1051
1062
|
Sessions.renderList();
|
|
1052
1063
|
renderSection();
|
|
1064
|
+
Archive.refreshIfShown();
|
|
1065
|
+
Trash.refreshIfShown();
|
|
1053
1066
|
} catch (err) {
|
|
1054
1067
|
console.error("[Projects] delete sessions error:", err);
|
|
1055
1068
|
}
|
|
1056
1069
|
}
|
|
1057
1070
|
|
|
1071
|
+
/**
|
|
1072
|
+
* Archive every session in a project. Unlike deleting, the chats stay
|
|
1073
|
+
* recoverable from the Archived sessions page.
|
|
1074
|
+
*/
|
|
1075
|
+
async function promptArchiveSessions(id) {
|
|
1076
|
+
const project = find(id);
|
|
1077
|
+
if (!project) return;
|
|
1078
|
+
|
|
1079
|
+
// Always ask first: the sidebar list may not hold every session of the
|
|
1080
|
+
// project (cron/ext sessions live in folded groups), so it can't be used
|
|
1081
|
+
// to decide whether there is anything worth confirming.
|
|
1082
|
+
const confirmed = await Modal.confirm(
|
|
1083
|
+
I18n.t("projects.archiveSessions.confirm", { name: project.name })
|
|
1084
|
+
);
|
|
1085
|
+
if (!confirmed) return;
|
|
1086
|
+
|
|
1087
|
+
const ids = Sessions.all.filter(s => s.project_id === id).map(s => s.id);
|
|
1088
|
+
try {
|
|
1089
|
+
const res = await fetch(`/api/projects/${id}/sessions/archive`, { method: "POST" });
|
|
1090
|
+
const data = await res.json();
|
|
1091
|
+
if (!res.ok) throw new Error(data.error || "Failed to archive sessions");
|
|
1092
|
+
|
|
1093
|
+
if (!data.archived) {
|
|
1094
|
+
Modal.toast(I18n.t("projects.archiveSessions.empty"), "info");
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
if (ids.includes(Sessions.activeId)) Router.navigate("welcome");
|
|
1099
|
+
ids.forEach(sessionId => Sessions.remove(sessionId));
|
|
1100
|
+
Sessions.renderList();
|
|
1101
|
+
renderSection();
|
|
1102
|
+
Archive.refreshIfShown();
|
|
1103
|
+
|
|
1104
|
+
Modal.toast(I18n.t("projects.archiveSessions.done", { count: data.archived }), "success");
|
|
1105
|
+
} catch (err) {
|
|
1106
|
+
console.error("[Projects] archive sessions error:", err);
|
|
1107
|
+
Modal.toast(I18n.t("projects.archiveSessions.fail", { msg: err.message }), "error");
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1058
1111
|
/** Confirm and delete a project. */
|
|
1059
1112
|
async function promptDelete(id) {
|
|
1060
1113
|
const project = find(id);
|
|
@@ -1132,6 +1185,8 @@ const Projects = (() => {
|
|
|
1132
1185
|
promptCreate,
|
|
1133
1186
|
promptEdit,
|
|
1134
1187
|
promptDelete,
|
|
1188
|
+
promptDeleteSessions,
|
|
1189
|
+
promptArchiveSessions,
|
|
1135
1190
|
renderSection,
|
|
1136
1191
|
expand,
|
|
1137
1192
|
getIconSvg: _getIconSvg,
|