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
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// ── NewSession · store — agent list + selection + advanced options ────────
|
|
2
|
+
//
|
|
3
|
+
// Owns the state for the "new session" landing page: the list of agents
|
|
4
|
+
// fetched from /api/agents, the current selection (persisted in localStorage),
|
|
5
|
+
// and the advanced-options form values (name / model / working dir / init).
|
|
6
|
+
// It never renders — NewSessionView owns the DOM.
|
|
7
|
+
//
|
|
8
|
+
// Also handles session creation: POST /api/sessions with the current selection
|
|
9
|
+
// and returns the created session summary. Sending the first message is the
|
|
10
|
+
// caller's job (via Sessions.setPendingMessage + Sessions.select).
|
|
11
|
+
//
|
|
12
|
+
// Depends on: Clacky.ext (for cross-module event emit).
|
|
13
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
const NewSessionStore = (() => {
|
|
16
|
+
const LS_AGENT_KEY = "openclacky.newSession.lastAgent";
|
|
17
|
+
|
|
18
|
+
const _state = {
|
|
19
|
+
agents: [],
|
|
20
|
+
selectedAgentId: null,
|
|
21
|
+
advanced: {
|
|
22
|
+
name: "",
|
|
23
|
+
modelId: "",
|
|
24
|
+
workingDir: "",
|
|
25
|
+
initProject: false,
|
|
26
|
+
},
|
|
27
|
+
advancedOpen: false,
|
|
28
|
+
creating: false,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const _listeners = {};
|
|
32
|
+
|
|
33
|
+
function _on(event, handler) {
|
|
34
|
+
(_listeners[event] ||= []).push(handler);
|
|
35
|
+
return () => {
|
|
36
|
+
const list = _listeners[event];
|
|
37
|
+
const i = list ? list.indexOf(handler) : -1;
|
|
38
|
+
if (i >= 0) list.splice(i, 1);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function _emit(event, payload) {
|
|
43
|
+
(_listeners[event] || []).forEach((h) => h(payload));
|
|
44
|
+
if (window.Clacky && Clacky.ext) Clacky.ext.emit(event, payload);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function loadAgents() {
|
|
48
|
+
try {
|
|
49
|
+
const res = await fetch("/api/agents");
|
|
50
|
+
if (!res.ok) return;
|
|
51
|
+
const data = await res.json();
|
|
52
|
+
_state.agents = (data && data.agents) || [];
|
|
53
|
+
|
|
54
|
+
// Restore last-used agent from localStorage; fall back to the first
|
|
55
|
+
// available one (typically "general").
|
|
56
|
+
const remembered = localStorage.getItem(LS_AGENT_KEY);
|
|
57
|
+
const found = _state.agents.find((a) => a.id === remembered);
|
|
58
|
+
_state.selectedAgentId = found
|
|
59
|
+
? found.id
|
|
60
|
+
: (_state.agents[0] && _state.agents[0].id) || "general";
|
|
61
|
+
|
|
62
|
+
_emit("newSession:agents-loaded", { agents: _state.agents });
|
|
63
|
+
_emit("newSession:selection-changed", { agentId: _state.selectedAgentId });
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error("Failed to load agents:", e);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function selectAgent(agentId) {
|
|
70
|
+
if (!agentId || agentId === _state.selectedAgentId) return;
|
|
71
|
+
const found = _state.agents.find((a) => a.id === agentId);
|
|
72
|
+
if (!found) return;
|
|
73
|
+
_state.selectedAgentId = agentId;
|
|
74
|
+
localStorage.setItem(LS_AGENT_KEY, agentId);
|
|
75
|
+
_emit("newSession:selection-changed", { agentId });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function currentAgent() {
|
|
79
|
+
return _state.agents.find((a) => a.id === _state.selectedAgentId) || null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function toggleAdvanced(open) {
|
|
83
|
+
_state.advancedOpen = open === undefined ? !_state.advancedOpen : !!open;
|
|
84
|
+
_emit("newSession:advanced-toggled", { open: _state.advancedOpen });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function updateAdvanced(patch) {
|
|
88
|
+
Object.assign(_state.advanced, patch);
|
|
89
|
+
_emit("newSession:advanced-changed", { advanced: _state.advanced });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function loadModels() {
|
|
93
|
+
try {
|
|
94
|
+
const res = await fetch("/api/config");
|
|
95
|
+
if (!res.ok) return [];
|
|
96
|
+
const data = await res.json();
|
|
97
|
+
return (data && data.models) || [];
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.error("Failed to load models:", e);
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function loadDefaultDirectory() {
|
|
105
|
+
try {
|
|
106
|
+
const res = await fetch("/api/dirs");
|
|
107
|
+
if (!res.ok) return "";
|
|
108
|
+
const data = await res.json();
|
|
109
|
+
const home = data && data.home;
|
|
110
|
+
if (!home) return "";
|
|
111
|
+
return home.replace(/\/+$/, "") + "/clacky_workspace";
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return "";
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function _autoName(existingSessions) {
|
|
118
|
+
const maxN = (existingSessions || []).reduce((max, s) => {
|
|
119
|
+
const m = s.name && s.name.match(/^Session (\d+)$/);
|
|
120
|
+
return m ? Math.max(max, parseInt(m[1], 10)) : max;
|
|
121
|
+
}, 0);
|
|
122
|
+
return "Session " + (maxN + 1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async function createSession({ existingSessions } = {}) {
|
|
126
|
+
if (_state.creating) return null;
|
|
127
|
+
_state.creating = true;
|
|
128
|
+
_emit("newSession:creating", { creating: true });
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
const agentId = _state.selectedAgentId || "general";
|
|
132
|
+
const adv = _state.advanced;
|
|
133
|
+
const name = adv.name.trim() || _autoName(existingSessions);
|
|
134
|
+
|
|
135
|
+
const payload = { name, agent_profile: agentId, source: "manual" };
|
|
136
|
+
if (adv.workingDir.trim()) payload.working_dir = adv.workingDir.trim();
|
|
137
|
+
if (adv.modelId) payload.model_id = adv.modelId;
|
|
138
|
+
|
|
139
|
+
const res = await fetch("/api/sessions", {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: { "Content-Type": "application/json" },
|
|
142
|
+
body: JSON.stringify(payload),
|
|
143
|
+
});
|
|
144
|
+
const data = await res.json();
|
|
145
|
+
|
|
146
|
+
if (!res.ok) {
|
|
147
|
+
const msg = data.error || "unknown error";
|
|
148
|
+
const friendly = res.status === 409
|
|
149
|
+
? I18n.t("sessions.dirNotEmpty")
|
|
150
|
+
: I18n.t("sessions.createError") + msg;
|
|
151
|
+
alert(friendly);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return data.session || null;
|
|
156
|
+
} catch (e) {
|
|
157
|
+
alert(I18n.t("sessions.createError") + e.message);
|
|
158
|
+
return null;
|
|
159
|
+
} finally {
|
|
160
|
+
_state.creating = false;
|
|
161
|
+
_emit("newSession:creating", { creating: false });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function reset() {
|
|
166
|
+
_state.advanced.name = "";
|
|
167
|
+
_state.advanced.initProject = false;
|
|
168
|
+
_emit("newSession:reset", {});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function fetchSkillsForAgent(agentId) {
|
|
172
|
+
try {
|
|
173
|
+
const res = await fetch(`/api/agents/${encodeURIComponent(agentId)}/skills`);
|
|
174
|
+
if (!res.ok) return [];
|
|
175
|
+
const data = await res.json();
|
|
176
|
+
return data.skills || [];
|
|
177
|
+
} catch (e) {
|
|
178
|
+
console.error("Failed to load skills:", e);
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
get state() { return _state; },
|
|
185
|
+
on: _on,
|
|
186
|
+
loadAgents,
|
|
187
|
+
selectAgent,
|
|
188
|
+
currentAgent,
|
|
189
|
+
toggleAdvanced,
|
|
190
|
+
updateAdvanced,
|
|
191
|
+
loadModels,
|
|
192
|
+
loadDefaultDirectory,
|
|
193
|
+
createSession,
|
|
194
|
+
fetchSkillsForAgent,
|
|
195
|
+
reset,
|
|
196
|
+
};
|
|
197
|
+
})();
|
|
198
|
+
|
|
199
|
+
window.NewSessionStore = NewSessionStore;
|