openclacky 1.3.6 → 1.3.8
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 +54 -0
- data/lib/clacky/agent/hook_manager.rb +10 -1
- data/lib/clacky/agent/system_prompt_builder.rb +1 -1
- data/lib/clacky/agent.rb +17 -3
- data/lib/clacky/agent_profile.rb +124 -53
- data/lib/clacky/billing/billing_store.rb +3 -2
- data/lib/clacky/brand_config.rb +309 -6
- data/lib/clacky/cli.rb +4 -57
- data/lib/clacky/default_extensions/coding/agents/coding/avatar.png +0 -0
- data/lib/clacky/default_extensions/coding/ext.yml +19 -0
- data/lib/clacky/default_extensions/ext-studio/agents/ext-developer/avatar.png +0 -0
- data/lib/clacky/default_extensions/ext-studio/agents/ext-developer/system_prompt.md +95 -0
- data/lib/clacky/default_extensions/ext-studio/api/handler.rb +254 -0
- data/lib/clacky/default_extensions/ext-studio/ext.yml +33 -0
- data/lib/clacky/default_extensions/ext-studio/panels/studio/view.js +1288 -0
- data/lib/clacky/default_extensions/ext-studio/skills/ext-debug/SKILL.md +71 -0
- data/lib/clacky/default_extensions/ext-studio/skills/ext-publish/SKILL.md +74 -0
- data/lib/clacky/default_extensions/ext-studio/skills/ext-scaffold/SKILL.md +65 -0
- data/lib/clacky/default_extensions/general/agents/general/avatar.png +0 -0
- data/lib/clacky/default_extensions/general/ext.yml +19 -0
- data/lib/clacky/default_extensions/git/ext.yml +12 -0
- data/lib/clacky/{default_agents/_panels/git/panel.js → default_extensions/git/panels/git/view.js} +4 -5
- data/lib/clacky/default_extensions/meeting/{handler.rb → api/handler.rb} +78 -26
- data/lib/clacky/default_extensions/meeting/ext.yml +15 -0
- data/lib/clacky/default_extensions/meeting/{meeting.js → panels/meeting/view.js} +266 -90
- data/lib/clacky/default_extensions/meeting/skills/meeting-summarizer/SKILL.md +2 -1
- data/lib/clacky/default_extensions/time_machine/ext.yml +12 -0
- data/lib/clacky/{default_agents/_panels/time_machine/panel.js → default_extensions/time_machine/panels/time_machine/view.js} +58 -47
- data/lib/clacky/default_skills/channel-manager/discord_setup.rb +1 -1
- data/lib/clacky/default_skills/extend-openclacky/SKILL.md +83 -18
- data/lib/clacky/{api_extension.rb → extension/api_extension.rb} +27 -11
- data/lib/clacky/extension/api_loader.rb +136 -0
- data/lib/clacky/extension/cli_commands.rb +226 -0
- data/lib/clacky/{server/api_extension_dispatcher.rb → extension/dispatcher.rb} +22 -9
- data/lib/clacky/extension/hook_loader.rb +77 -0
- data/lib/clacky/extension/loader.rb +489 -0
- data/lib/clacky/extension/packager.rb +226 -0
- data/lib/clacky/{patch_loader.rb → extension/patch_loader.rb} +45 -0
- data/lib/clacky/extension/scaffold/template_renderer.rb +64 -0
- data/lib/clacky/extension/scaffold/templates/full/README.md.erb +48 -0
- data/lib/clacky/extension/scaffold/templates/full/agents/designer.md +5 -0
- data/lib/clacky/extension/scaffold/templates/full/api/handler.rb.erb +16 -0
- data/lib/clacky/extension/scaffold/templates/full/channels/noop.rb.erb +40 -0
- data/lib/clacky/extension/scaffold/templates/full/ext.yml.erb +41 -0
- data/lib/clacky/extension/scaffold/templates/full/hooks/audit.rb +9 -0
- data/lib/clacky/extension/scaffold/templates/full/panels/dashboard/view.js.erb +194 -0
- data/lib/clacky/extension/scaffold/templates/full/patches/audit.rb +15 -0
- data/lib/clacky/extension/scaffold/templates/full/skills/__slug__-skill/SKILL.md.erb +8 -0
- data/lib/clacky/extension/scaffold/templates/hello/api/handler.rb.erb +9 -0
- data/lib/clacky/extension/scaffold/templates/hello/ext.yml.erb +12 -0
- data/lib/clacky/extension/scaffold/templates/hello/panels/hello/view.js.erb +31 -0
- data/lib/clacky/extension/scaffold.rb +55 -0
- data/lib/clacky/extension/verifier.rb +196 -0
- data/lib/clacky/identity.rb +70 -0
- data/lib/clacky/locales/en.rb +19 -1
- data/lib/clacky/locales/zh.rb +19 -1
- data/lib/clacky/platform_http_client.rb +18 -15
- data/lib/clacky/server/channel/extension_adapter_loader.rb +32 -0
- data/lib/clacky/server/channel.rb +6 -0
- data/lib/clacky/server/http_server.rb +439 -146
- data/lib/clacky/server/session_registry.rb +9 -2
- data/lib/clacky/shell_hook_loader.rb +266 -22
- data/lib/clacky/skill_loader.rb +28 -1
- data/lib/clacky/ui2/components/welcome_banner.rb +1 -1
- data/lib/clacky/ui2/ui_controller.rb +9 -6
- data/lib/clacky/utils/workspace_rules.rb +2 -2
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +1034 -675
- data/lib/clacky/web/app.js +63 -15
- data/lib/clacky/web/auth.js +2 -0
- data/lib/clacky/web/components/notify.js +2 -0
- data/lib/clacky/web/components/sidebar.js +1 -5
- data/lib/clacky/web/core/ext.js +432 -89
- data/lib/clacky/web/features/backup/store.js +1 -0
- data/lib/clacky/web/features/backup/view.js +0 -1
- data/lib/clacky/web/features/brand/view.js +13 -5
- data/lib/clacky/web/features/extensions/store.js +184 -0
- data/lib/clacky/web/features/extensions/view.js +390 -0
- data/lib/clacky/web/features/new-session/store.js +199 -0
- data/lib/clacky/web/features/new-session/view.js +619 -0
- data/lib/clacky/web/features/share/view.js +63 -14
- data/lib/clacky/web/features/skills/store.js +3 -1
- data/lib/clacky/web/features/skills/view.js +1 -1
- data/lib/clacky/web/features/tasks/view.js +12 -0
- data/lib/clacky/web/features/trash/store.js +24 -6
- data/lib/clacky/web/features/trash/view.js +48 -12
- data/lib/clacky/web/features/workspace/store.js +2 -0
- data/lib/clacky/web/features/workspace/view.js +0 -1
- data/lib/clacky/web/i18n.js +152 -106
- data/lib/clacky/web/index.html +172 -190
- data/lib/clacky/web/sessions.js +67 -272
- data/lib/clacky/web/settings.js +1 -1
- data/lib/clacky/web/skills.js +88 -48
- data/lib/clacky/web/theme.js +5 -0
- data/lib/clacky/web/ws-dispatcher.js +12 -2
- data/lib/clacky/web/ws.js +2 -0
- data/lib/clacky.rb +21 -10
- metadata +52 -21
- data/benchmark/runner.rb +0 -441
- data/lib/clacky/api_extension_loader.rb +0 -168
- data/lib/clacky/default_agents/SOUL.md +0 -3
- data/lib/clacky/default_agents/USER.md +0 -1
- data/lib/clacky/default_agents/coding/profile.yml +0 -5
- data/lib/clacky/default_agents/coding/webui/.gitkeep +0 -0
- data/lib/clacky/default_agents/general/profile.yml +0 -2
- data/lib/clacky/default_extensions/meeting/meta.yml +0 -3
- data/lib/clacky/web/features/creator/store.js +0 -81
- data/lib/clacky/web/features/creator/view.js +0 -380
- /data/lib/clacky/{default_agents → default_extensions/coding/agents}/coding/system_prompt.md +0 -0
- /data/lib/clacky/{default_agents → default_extensions/general/agents}/general/system_prompt.md +0 -0
- /data/lib/clacky/{default_agents/base_prompt.md → prompts/base.md} +0 -0
data/lib/clacky/web/skills.js
CHANGED
|
@@ -30,6 +30,25 @@ const SkillAC = (() => {
|
|
|
30
30
|
|
|
31
31
|
let _ime = null; // IME tracker for #user-input, set up in _initDOMBindings
|
|
32
32
|
|
|
33
|
+
// The active DOM/behavior config. Defaults to the chat composer; `attach()`
|
|
34
|
+
// can swap in a different set of element ids (e.g. the new-session page).
|
|
35
|
+
// `fetchSkills` returns the skill list; `onSend` fires on bare Enter.
|
|
36
|
+
const _chatCfg = {
|
|
37
|
+
input: "user-input",
|
|
38
|
+
dropdown: "skill-autocomplete",
|
|
39
|
+
list: "skill-autocomplete-list",
|
|
40
|
+
slashBtn: "btn-slash",
|
|
41
|
+
systemChk: "chk-ac-show-system-skills",
|
|
42
|
+
fetchSkills: null, // null → use session-scoped default fetch
|
|
43
|
+
onSend: () => Sessions.sendMessage(),
|
|
44
|
+
};
|
|
45
|
+
let _cfg = _chatCfg;
|
|
46
|
+
|
|
47
|
+
const _inputEl = () => $(_cfg.input);
|
|
48
|
+
const _dropdownEl = () => $(_cfg.dropdown);
|
|
49
|
+
const _listEl = () => $(_cfg.list);
|
|
50
|
+
const _slashBtnEl = () => $(_cfg.slashBtn);
|
|
51
|
+
|
|
33
52
|
/** Called whenever the active session changes — just store the id, no prefetch. */
|
|
34
53
|
function _loadForSession(sessionId) {
|
|
35
54
|
_currentSession = sessionId || null;
|
|
@@ -37,6 +56,14 @@ const SkillAC = (() => {
|
|
|
37
56
|
|
|
38
57
|
/** Fetch live skill list from server for the current session. */
|
|
39
58
|
async function _fetchSkills() {
|
|
59
|
+
if (_cfg.fetchSkills) {
|
|
60
|
+
try {
|
|
61
|
+
return (await _cfg.fetchSkills()) || [];
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.error("[SkillAC] custom fetchSkills failed", e);
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
40
67
|
if (!_currentSession) return [];
|
|
41
68
|
try {
|
|
42
69
|
const res = await fetch(`/api/sessions/${_currentSession}/skills`);
|
|
@@ -130,7 +157,7 @@ const SkillAC = (() => {
|
|
|
130
157
|
|
|
131
158
|
_items = scored.map(({ skill }) => skill);
|
|
132
159
|
|
|
133
|
-
const list =
|
|
160
|
+
const list = _listEl();
|
|
134
161
|
list.innerHTML = "";
|
|
135
162
|
|
|
136
163
|
if (_items.length === 0) {
|
|
@@ -139,7 +166,7 @@ const SkillAC = (() => {
|
|
|
139
166
|
emptyEl.className = "skill-ac-empty";
|
|
140
167
|
emptyEl.textContent = I18n.t("skills.ac.empty");
|
|
141
168
|
list.appendChild(emptyEl);
|
|
142
|
-
|
|
169
|
+
_dropdownEl().style.display = "";
|
|
143
170
|
_visible = true;
|
|
144
171
|
_createOverlay();
|
|
145
172
|
return;
|
|
@@ -222,17 +249,17 @@ const SkillAC = (() => {
|
|
|
222
249
|
list.appendChild(item);
|
|
223
250
|
});
|
|
224
251
|
|
|
225
|
-
|
|
252
|
+
_dropdownEl().style.display = "";
|
|
226
253
|
_visible = true;
|
|
227
254
|
_createOverlay();
|
|
228
255
|
}
|
|
229
256
|
|
|
230
257
|
function _hide() {
|
|
231
|
-
|
|
258
|
+
_dropdownEl().style.display = "none";
|
|
232
259
|
_visible = false;
|
|
233
260
|
_activeIndex = -1;
|
|
234
261
|
_items = [];
|
|
235
|
-
|
|
262
|
+
_slashBtnEl()?.classList.remove("active");
|
|
236
263
|
_removeOverlay();
|
|
237
264
|
}
|
|
238
265
|
|
|
@@ -260,7 +287,7 @@ const SkillAC = (() => {
|
|
|
260
287
|
function _select(idx) {
|
|
261
288
|
const skill = _items[idx];
|
|
262
289
|
if (!skill) return;
|
|
263
|
-
const input =
|
|
290
|
+
const input = _inputEl();
|
|
264
291
|
input.value = "/" + skill.name + " ";
|
|
265
292
|
input.style.height = "auto";
|
|
266
293
|
input.style.height = Math.min(input.scrollHeight, 200) + "px";
|
|
@@ -272,7 +299,7 @@ const SkillAC = (() => {
|
|
|
272
299
|
if (!_visible || _items.length === 0) return;
|
|
273
300
|
_activeIndex = (_activeIndex + delta + _items.length) % _items.length;
|
|
274
301
|
// Re-render to apply active class
|
|
275
|
-
const list =
|
|
302
|
+
const list = _listEl();
|
|
276
303
|
list.querySelectorAll(".skill-ac-item").forEach((el, i) => {
|
|
277
304
|
el.classList.toggle("active", i === _activeIndex);
|
|
278
305
|
if (i === _activeIndex) el.scrollIntoView({ block: "nearest" });
|
|
@@ -283,7 +310,7 @@ const SkillAC = (() => {
|
|
|
283
310
|
async function _openAll() {
|
|
284
311
|
_activeIndex = 0; // Default to first item
|
|
285
312
|
await _render("");
|
|
286
|
-
|
|
313
|
+
_inputEl().focus();
|
|
287
314
|
}
|
|
288
315
|
|
|
289
316
|
/** Toggle the dropdown (open if hidden, close if visible). */
|
|
@@ -297,16 +324,17 @@ const SkillAC = (() => {
|
|
|
297
324
|
|
|
298
325
|
// ── DOM bindings: composer keyboard/composition/input + slash button + ────
|
|
299
326
|
// ── skill-panel create/import buttons. Called once from init(). ──
|
|
300
|
-
function _initDOMBindings() {
|
|
327
|
+
function _initDOMBindings(cfg) {
|
|
301
328
|
// / button: set input to "/" and open skill autocomplete.
|
|
302
329
|
// mousedown + preventDefault prevents the textarea from losing focus
|
|
303
330
|
// (which would trigger the blur→hide timer and immediately close
|
|
304
331
|
// the dropdown we're about to open).
|
|
305
|
-
$(
|
|
306
|
-
e.preventDefault(); // keep focus on
|
|
332
|
+
$(cfg.slashBtn).addEventListener("mousedown", e => {
|
|
333
|
+
e.preventDefault(); // keep focus on the input
|
|
307
334
|
});
|
|
308
|
-
$(
|
|
309
|
-
|
|
335
|
+
$(cfg.slashBtn).addEventListener("click", () => {
|
|
336
|
+
_cfg = cfg;
|
|
337
|
+
const input = $(cfg.input);
|
|
310
338
|
if (input.value === "" || input.value === "/") {
|
|
311
339
|
input.value = "/";
|
|
312
340
|
input.style.height = "auto";
|
|
@@ -314,28 +342,31 @@ const SkillAC = (() => {
|
|
|
314
342
|
}
|
|
315
343
|
_toggle(); // Toggle dropdown instead of always opening
|
|
316
344
|
if (_visible) {
|
|
317
|
-
$(
|
|
345
|
+
$(cfg.slashBtn).classList.add("active");
|
|
318
346
|
}
|
|
319
347
|
input.focus();
|
|
320
348
|
});
|
|
321
349
|
|
|
322
350
|
// IME composition tracker: shared by main keydown + AC _handleKey.
|
|
323
|
-
|
|
351
|
+
const ime = IME.track($(cfg.input));
|
|
324
352
|
|
|
325
353
|
// Main composer keydown: SkillAC consumes nav keys first, then Enter → send.
|
|
326
|
-
$(
|
|
354
|
+
$(cfg.input).addEventListener("keydown", e => {
|
|
355
|
+
_cfg = cfg;
|
|
356
|
+
_ime = ime;
|
|
327
357
|
// Let skill autocomplete consume arrow/enter/escape first
|
|
328
358
|
if (_handleKey(e)) return;
|
|
329
359
|
|
|
330
|
-
if (e.key === "Enter" && !e.shiftKey && !
|
|
360
|
+
if (e.key === "Enter" && !e.shiftKey && !ime.isComposing(e)) {
|
|
331
361
|
e.preventDefault();
|
|
332
|
-
|
|
362
|
+
cfg.onSend();
|
|
333
363
|
}
|
|
334
364
|
});
|
|
335
365
|
|
|
336
366
|
// Composer input: auto-grow textarea, normalize full-width slash, drive AC.
|
|
337
|
-
$(
|
|
338
|
-
|
|
367
|
+
$(cfg.input).addEventListener("input", () => {
|
|
368
|
+
_cfg = cfg;
|
|
369
|
+
const el = $(cfg.input);
|
|
339
370
|
el.style.height = "auto";
|
|
340
371
|
el.style.height = Math.min(el.scrollHeight, 200) + "px";
|
|
341
372
|
|
|
@@ -350,11 +381,25 @@ const SkillAC = (() => {
|
|
|
350
381
|
_update(el.value);
|
|
351
382
|
});
|
|
352
383
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
384
|
+
const chk = $(cfg.systemChk);
|
|
385
|
+
if (chk) {
|
|
386
|
+
chk.checked = _showSystemSkills;
|
|
387
|
+
chk.addEventListener("change", async () => {
|
|
388
|
+
_cfg = cfg;
|
|
389
|
+
_showSystemSkills = chk.checked;
|
|
390
|
+
localStorage.setItem("skill-ac-show-system", _showSystemSkills ? "true" : "false");
|
|
391
|
+
if (_visible) {
|
|
392
|
+
const query = _getSlashQuery($(cfg.input).value);
|
|
393
|
+
if (query !== null) await _render(query);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Skills panel action buttons only exist in the chat composer.
|
|
399
|
+
if (cfg === _chatCfg) {
|
|
400
|
+
$("btn-create-skill").addEventListener("click", () => Skills.createInSession());
|
|
401
|
+
$("btn-import-skill").addEventListener("click", () => Skills.toggleImportBar());
|
|
402
|
+
}
|
|
358
403
|
}
|
|
359
404
|
|
|
360
405
|
// Update handler — driven from the input event above. Exposed on the
|
|
@@ -407,30 +452,23 @@ const SkillAC = (() => {
|
|
|
407
452
|
if (_initialized) return;
|
|
408
453
|
_initialized = true;
|
|
409
454
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
// Restore state from localStorage
|
|
414
|
-
chk.checked = _showSystemSkills;
|
|
415
|
-
|
|
416
|
-
chk.addEventListener("change", async () => {
|
|
417
|
-
_showSystemSkills = chk.checked;
|
|
418
|
-
// Persist to localStorage
|
|
419
|
-
localStorage.setItem("skill-ac-show-system", _showSystemSkills ? "true" : "false");
|
|
420
|
-
|
|
421
|
-
// If dropdown is visible, re-fetch and re-render
|
|
422
|
-
if (_visible) {
|
|
423
|
-
const input = $("user-input");
|
|
424
|
-
const query = _getSlashQuery(input.value);
|
|
425
|
-
if (query !== null) {
|
|
426
|
-
await _render(query);
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
});
|
|
430
|
-
}
|
|
455
|
+
// Wire up all composer/slash DOM bindings for the chat composer.
|
|
456
|
+
_initDOMBindings(_chatCfg);
|
|
457
|
+
},
|
|
431
458
|
|
|
432
|
-
|
|
433
|
-
|
|
459
|
+
/**
|
|
460
|
+
* Attach the autocomplete to a second composer (e.g. the new-session page).
|
|
461
|
+
* `config` overrides element ids and provides `fetchSkills` / `onSend`.
|
|
462
|
+
*/
|
|
463
|
+
attach(config) {
|
|
464
|
+
const cfg = Object.assign({}, _chatCfg, config);
|
|
465
|
+
_initDOMBindings(cfg);
|
|
466
|
+
return {
|
|
467
|
+
/** Programmatic input handler (call from the input event if needed). */
|
|
468
|
+
update: (value) => { _cfg = cfg; _update(value); },
|
|
469
|
+
hide: _hide,
|
|
470
|
+
get visible() { return _visible; },
|
|
471
|
+
};
|
|
434
472
|
},
|
|
435
473
|
|
|
436
474
|
/** Called on every `input` event — decide whether to show/hide/update. */
|
|
@@ -452,3 +490,5 @@ const SkillAC = (() => {
|
|
|
452
490
|
handleKey: _handleKey,
|
|
453
491
|
};
|
|
454
492
|
})();
|
|
493
|
+
|
|
494
|
+
Clacky.SkillAC = SkillAC;
|
data/lib/clacky/web/theme.js
CHANGED
|
@@ -30,11 +30,13 @@ const Theme = (() => {
|
|
|
30
30
|
// Icon shows what you'd switch TO, not what you are on.
|
|
31
31
|
if (theme === "light") {
|
|
32
32
|
// In light mode → show moon (click to go dark)
|
|
33
|
+
headerToggle.title = I18n.t("header.theme.toDark");
|
|
33
34
|
headerToggle.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-sm">
|
|
34
35
|
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>
|
|
35
36
|
</svg>`;
|
|
36
37
|
} else {
|
|
37
38
|
// In dark mode → show sun (click to go light)
|
|
39
|
+
headerToggle.title = I18n.t("header.theme.toLight");
|
|
38
40
|
headerToggle.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon-sm">
|
|
39
41
|
<circle cx="12" cy="12" r="4"/>
|
|
40
42
|
<path d="M12 2v2"/>
|
|
@@ -75,6 +77,9 @@ const Theme = (() => {
|
|
|
75
77
|
if (mq.addEventListener) mq.addEventListener("change", onChange);
|
|
76
78
|
else if (mq.addListener) mq.addListener(onChange); // Safari < 14
|
|
77
79
|
}
|
|
80
|
+
|
|
81
|
+
// Re-apply title text when language changes.
|
|
82
|
+
document.addEventListener("langchange", () => _updateToggleIcon(current()));
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
// Explicit apply (used by toggle). Persists the choice unless it equals
|
|
@@ -216,8 +216,17 @@ WS.onEvent(ev => {
|
|
|
216
216
|
// send it now — after restoreFromHash has settled — so appendMsg won't be wiped.
|
|
217
217
|
const pendingMsg = Sessions.takePendingMessage();
|
|
218
218
|
if (pendingMsg && pendingMsg.session_id === ev.session_id) {
|
|
219
|
-
|
|
220
|
-
|
|
219
|
+
const html = pendingMsg.files && pendingMsg.files.length
|
|
220
|
+
? (pendingMsg.display || escapeHtml(pendingMsg.content))
|
|
221
|
+
: escapeHtml(pendingMsg.display || pendingMsg.content);
|
|
222
|
+
Sessions.appendMsg("user", html, { time: new Date() });
|
|
223
|
+
WS.send({
|
|
224
|
+
type: "message",
|
|
225
|
+
session_id: pendingMsg.session_id,
|
|
226
|
+
content: pendingMsg.content,
|
|
227
|
+
files: pendingMsg.files || undefined,
|
|
228
|
+
lang: I18n.lang(),
|
|
229
|
+
});
|
|
221
230
|
}
|
|
222
231
|
break;
|
|
223
232
|
}
|
|
@@ -281,6 +290,7 @@ WS.onEvent(ev => {
|
|
|
281
290
|
}
|
|
282
291
|
|
|
283
292
|
case "session_deleted":
|
|
293
|
+
if (window.Clacky && Clacky.ext) Clacky.ext.notifySessionRemoved(ev.session_id);
|
|
284
294
|
Sessions.remove(ev.session_id);
|
|
285
295
|
if (ev.session_id === Sessions.activeId) Router.navigate("welcome");
|
|
286
296
|
Sessions.renderList();
|
data/lib/clacky/web/ws.js
CHANGED
data/lib/clacky.rb
CHANGED
|
@@ -95,6 +95,7 @@ require_relative "clacky/ui2/progress_indicator"
|
|
|
95
95
|
require_relative "clacky/utils/logger"
|
|
96
96
|
require_relative "clacky/proxy_config"
|
|
97
97
|
require_relative "clacky/platform_http_client"
|
|
98
|
+
require_relative "clacky/identity"
|
|
98
99
|
require_relative "clacky/utils/encoding"
|
|
99
100
|
require_relative "clacky/utils/environment_detector"
|
|
100
101
|
require_relative "clacky/utils/browser_detector"
|
|
@@ -140,18 +141,28 @@ require_relative "clacky/server/browser_manager"
|
|
|
140
141
|
require_relative "clacky/server/backup_manager"
|
|
141
142
|
require_relative "clacky/cli"
|
|
142
143
|
|
|
143
|
-
#
|
|
144
|
-
#
|
|
145
|
-
require_relative "clacky/
|
|
144
|
+
# Extension architecture: define the base class + container loader + scaffolding
|
|
145
|
+
# + dispatcher up front so the patch / hook loaders below can read its result.
|
|
146
|
+
require_relative "clacky/extension/api_extension"
|
|
147
|
+
require_relative "clacky/extension/api_loader"
|
|
148
|
+
require_relative "clacky/extension/loader"
|
|
149
|
+
require_relative "clacky/extension/scaffold/template_renderer"
|
|
150
|
+
require_relative "clacky/extension/scaffold"
|
|
151
|
+
require_relative "clacky/extension/packager"
|
|
152
|
+
require_relative "clacky/extension/dispatcher"
|
|
153
|
+
require_relative "clacky/extension/hook_loader"
|
|
154
|
+
require_relative "clacky/extension/verifier"
|
|
155
|
+
Clacky::ExtensionLoader.load_all
|
|
156
|
+
|
|
157
|
+
# Runtime patch layer: load user/AI patches from ~/.clacky/patches/ AND patches
|
|
158
|
+
# contributed by ext.yml containers (contributes.patches). Runs after all gem
|
|
159
|
+
# code is defined, so fingerprints reflect the actual installed source.
|
|
160
|
+
require_relative "clacky/extension/patch_loader"
|
|
146
161
|
Clacky::PatchLoader.load_all
|
|
147
162
|
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
# like session_manager or agent_config.
|
|
152
|
-
require_relative "clacky/api_extension"
|
|
153
|
-
require_relative "clacky/api_extension_loader"
|
|
154
|
-
require_relative "clacky/server/api_extension_dispatcher"
|
|
163
|
+
# Process-wide registry of hook callbacks contributed by ext.yml containers
|
|
164
|
+
# (contributes.hooks). Each agent copies them onto its own HookManager at init.
|
|
165
|
+
Clacky::ExtensionHookLoader.load_all
|
|
155
166
|
|
|
156
167
|
module Clacky
|
|
157
168
|
class AgentInterrupted < Exception; end # Inherit from Exception to bypass rescue StandardError
|
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.
|
|
4
|
+
version: 1.3.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- windy
|
|
@@ -315,7 +315,6 @@ files:
|
|
|
315
315
|
- benchmark/results/report_20260511_175256.json
|
|
316
316
|
- benchmark/results/report_20260511_175444.json
|
|
317
317
|
- benchmark/results/treatment_20260511_175103.json
|
|
318
|
-
- benchmark/runner.rb
|
|
319
318
|
- bin/clacky
|
|
320
319
|
- bin/clarky
|
|
321
320
|
- bin/openclacky
|
|
@@ -356,8 +355,6 @@ files:
|
|
|
356
355
|
- lib/clacky/agent_config.rb
|
|
357
356
|
- lib/clacky/agent_profile.rb
|
|
358
357
|
- lib/clacky/anthropic_stream_aggregator.rb
|
|
359
|
-
- lib/clacky/api_extension.rb
|
|
360
|
-
- lib/clacky/api_extension_loader.rb
|
|
361
358
|
- lib/clacky/banner.rb
|
|
362
359
|
- lib/clacky/bedrock_stream_aggregator.rb
|
|
363
360
|
- lib/clacky/billing/billing_record.rb
|
|
@@ -366,20 +363,28 @@ files:
|
|
|
366
363
|
- lib/clacky/brand_config.rb
|
|
367
364
|
- lib/clacky/cli.rb
|
|
368
365
|
- lib/clacky/client.rb
|
|
369
|
-
- lib/clacky/
|
|
370
|
-
- lib/clacky/
|
|
371
|
-
- lib/clacky/
|
|
372
|
-
- lib/clacky/
|
|
373
|
-
- lib/clacky/
|
|
374
|
-
- lib/clacky/
|
|
375
|
-
- lib/clacky/
|
|
376
|
-
- lib/clacky/
|
|
377
|
-
- lib/clacky/
|
|
378
|
-
- lib/clacky/
|
|
379
|
-
- lib/clacky/default_extensions/
|
|
380
|
-
- lib/clacky/default_extensions/
|
|
381
|
-
- lib/clacky/default_extensions/
|
|
366
|
+
- lib/clacky/default_extensions/coding/agents/coding/avatar.png
|
|
367
|
+
- lib/clacky/default_extensions/coding/agents/coding/system_prompt.md
|
|
368
|
+
- lib/clacky/default_extensions/coding/ext.yml
|
|
369
|
+
- lib/clacky/default_extensions/ext-studio/agents/ext-developer/avatar.png
|
|
370
|
+
- lib/clacky/default_extensions/ext-studio/agents/ext-developer/system_prompt.md
|
|
371
|
+
- lib/clacky/default_extensions/ext-studio/api/handler.rb
|
|
372
|
+
- lib/clacky/default_extensions/ext-studio/ext.yml
|
|
373
|
+
- lib/clacky/default_extensions/ext-studio/panels/studio/view.js
|
|
374
|
+
- lib/clacky/default_extensions/ext-studio/skills/ext-debug/SKILL.md
|
|
375
|
+
- lib/clacky/default_extensions/ext-studio/skills/ext-publish/SKILL.md
|
|
376
|
+
- lib/clacky/default_extensions/ext-studio/skills/ext-scaffold/SKILL.md
|
|
377
|
+
- lib/clacky/default_extensions/general/agents/general/avatar.png
|
|
378
|
+
- lib/clacky/default_extensions/general/agents/general/system_prompt.md
|
|
379
|
+
- lib/clacky/default_extensions/general/ext.yml
|
|
380
|
+
- lib/clacky/default_extensions/git/ext.yml
|
|
381
|
+
- lib/clacky/default_extensions/git/panels/git/view.js
|
|
382
|
+
- lib/clacky/default_extensions/meeting/api/handler.rb
|
|
383
|
+
- lib/clacky/default_extensions/meeting/ext.yml
|
|
384
|
+
- lib/clacky/default_extensions/meeting/panels/meeting/view.js
|
|
382
385
|
- lib/clacky/default_extensions/meeting/skills/meeting-summarizer/SKILL.md
|
|
386
|
+
- lib/clacky/default_extensions/time_machine/ext.yml
|
|
387
|
+
- lib/clacky/default_extensions/time_machine/panels/time_machine/view.js
|
|
383
388
|
- lib/clacky/default_parsers/doc_parser.rb
|
|
384
389
|
- lib/clacky/default_parsers/docx_parser.rb
|
|
385
390
|
- lib/clacky/default_parsers/pdf_parser.rb
|
|
@@ -434,6 +439,30 @@ files:
|
|
|
434
439
|
- lib/clacky/default_skills/skill-creator/scripts/run_loop.py
|
|
435
440
|
- lib/clacky/default_skills/skill-creator/scripts/utils.py
|
|
436
441
|
- lib/clacky/default_skills/skill-creator/scripts/validate_skill_frontmatter.rb
|
|
442
|
+
- lib/clacky/extension/api_extension.rb
|
|
443
|
+
- lib/clacky/extension/api_loader.rb
|
|
444
|
+
- lib/clacky/extension/cli_commands.rb
|
|
445
|
+
- lib/clacky/extension/dispatcher.rb
|
|
446
|
+
- lib/clacky/extension/hook_loader.rb
|
|
447
|
+
- lib/clacky/extension/loader.rb
|
|
448
|
+
- lib/clacky/extension/packager.rb
|
|
449
|
+
- lib/clacky/extension/patch_loader.rb
|
|
450
|
+
- lib/clacky/extension/scaffold.rb
|
|
451
|
+
- lib/clacky/extension/scaffold/template_renderer.rb
|
|
452
|
+
- lib/clacky/extension/scaffold/templates/full/README.md.erb
|
|
453
|
+
- lib/clacky/extension/scaffold/templates/full/agents/designer.md
|
|
454
|
+
- lib/clacky/extension/scaffold/templates/full/api/handler.rb.erb
|
|
455
|
+
- lib/clacky/extension/scaffold/templates/full/channels/noop.rb.erb
|
|
456
|
+
- lib/clacky/extension/scaffold/templates/full/ext.yml.erb
|
|
457
|
+
- lib/clacky/extension/scaffold/templates/full/hooks/audit.rb
|
|
458
|
+
- lib/clacky/extension/scaffold/templates/full/panels/dashboard/view.js.erb
|
|
459
|
+
- lib/clacky/extension/scaffold/templates/full/patches/audit.rb
|
|
460
|
+
- lib/clacky/extension/scaffold/templates/full/skills/__slug__-skill/SKILL.md.erb
|
|
461
|
+
- lib/clacky/extension/scaffold/templates/hello/api/handler.rb.erb
|
|
462
|
+
- lib/clacky/extension/scaffold/templates/hello/ext.yml.erb
|
|
463
|
+
- lib/clacky/extension/scaffold/templates/hello/panels/hello/view.js.erb
|
|
464
|
+
- lib/clacky/extension/verifier.rb
|
|
465
|
+
- lib/clacky/identity.rb
|
|
437
466
|
- lib/clacky/idle_compression_timer.rb
|
|
438
467
|
- lib/clacky/json_ui_controller.rb
|
|
439
468
|
- lib/clacky/locales/en.rb
|
|
@@ -457,9 +486,9 @@ files:
|
|
|
457
486
|
- lib/clacky/message_history.rb
|
|
458
487
|
- lib/clacky/null_ui_controller.rb
|
|
459
488
|
- lib/clacky/openai_stream_aggregator.rb
|
|
460
|
-
- lib/clacky/patch_loader.rb
|
|
461
489
|
- lib/clacky/plain_ui_controller.rb
|
|
462
490
|
- lib/clacky/platform_http_client.rb
|
|
491
|
+
- lib/clacky/prompts/base.md
|
|
463
492
|
- lib/clacky/providers.rb
|
|
464
493
|
- lib/clacky/proxy_config.rb
|
|
465
494
|
- lib/clacky/rich_ui.rb
|
|
@@ -478,7 +507,6 @@ files:
|
|
|
478
507
|
- lib/clacky/rich_ui/shell/rich_agent_shell.rb
|
|
479
508
|
- lib/clacky/rich_ui/view_renderer.rb
|
|
480
509
|
- lib/clacky/rich_ui_controller.rb
|
|
481
|
-
- lib/clacky/server/api_extension_dispatcher.rb
|
|
482
510
|
- lib/clacky/server/backup_manager.rb
|
|
483
511
|
- lib/clacky/server/browser_manager.rb
|
|
484
512
|
- lib/clacky/server/channel.rb
|
|
@@ -504,6 +532,7 @@ files:
|
|
|
504
532
|
- lib/clacky/server/channel/channel_config.rb
|
|
505
533
|
- lib/clacky/server/channel/channel_manager.rb
|
|
506
534
|
- lib/clacky/server/channel/channel_ui_controller.rb
|
|
535
|
+
- lib/clacky/server/channel/extension_adapter_loader.rb
|
|
507
536
|
- lib/clacky/server/channel/user_adapter_loader.rb
|
|
508
537
|
- lib/clacky/server/discover.rb
|
|
509
538
|
- lib/clacky/server/epipe_safe_io.rb
|
|
@@ -608,12 +637,14 @@ files:
|
|
|
608
637
|
- lib/clacky/web/features/brand/view.js
|
|
609
638
|
- lib/clacky/web/features/channels/store.js
|
|
610
639
|
- lib/clacky/web/features/channels/view.js
|
|
611
|
-
- lib/clacky/web/features/
|
|
612
|
-
- lib/clacky/web/features/
|
|
640
|
+
- lib/clacky/web/features/extensions/store.js
|
|
641
|
+
- lib/clacky/web/features/extensions/view.js
|
|
613
642
|
- lib/clacky/web/features/mcp/store.js
|
|
614
643
|
- lib/clacky/web/features/mcp/view.js
|
|
615
644
|
- lib/clacky/web/features/model-tester/store.js
|
|
616
645
|
- lib/clacky/web/features/model-tester/view.js
|
|
646
|
+
- lib/clacky/web/features/new-session/store.js
|
|
647
|
+
- lib/clacky/web/features/new-session/view.js
|
|
617
648
|
- lib/clacky/web/features/profile/store.js
|
|
618
649
|
- lib/clacky/web/features/profile/view.js
|
|
619
650
|
- lib/clacky/web/features/share/store.js
|