@tom2012/cc-web 2026.4.19-t → 2026.4.19-v

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 (68) hide show
  1. package/README.md +1 -1
  2. package/backend/dist/adapters/claude-adapter.d.ts.map +1 -1
  3. package/backend/dist/adapters/claude-adapter.js +155 -6
  4. package/backend/dist/adapters/claude-adapter.js.map +1 -1
  5. package/backend/dist/adapters/gemini-adapter.js +1 -1
  6. package/backend/dist/adapters/gemini-adapter.js.map +1 -1
  7. package/backend/dist/adapters/types.d.ts +3 -0
  8. package/backend/dist/adapters/types.d.ts.map +1 -1
  9. package/backend/dist/crypto-at-rest.d.ts +8 -0
  10. package/backend/dist/crypto-at-rest.d.ts.map +1 -0
  11. package/backend/dist/crypto-at-rest.js +96 -0
  12. package/backend/dist/crypto-at-rest.js.map +1 -0
  13. package/backend/dist/hub-auth.d.ts +12 -0
  14. package/backend/dist/hub-auth.d.ts.map +1 -0
  15. package/backend/dist/hub-auth.js +123 -0
  16. package/backend/dist/hub-auth.js.map +1 -0
  17. package/backend/dist/index.d.ts.map +1 -1
  18. package/backend/dist/index.js +2 -0
  19. package/backend/dist/index.js.map +1 -1
  20. package/backend/dist/memory-prompts.d.ts +30 -0
  21. package/backend/dist/memory-prompts.d.ts.map +1 -0
  22. package/backend/dist/memory-prompts.js +163 -0
  23. package/backend/dist/memory-prompts.js.map +1 -0
  24. package/backend/dist/routes/claude.d.ts.map +1 -1
  25. package/backend/dist/routes/claude.js +98 -0
  26. package/backend/dist/routes/claude.js.map +1 -1
  27. package/backend/dist/routes/memory-prompts.d.ts +3 -0
  28. package/backend/dist/routes/memory-prompts.d.ts.map +1 -0
  29. package/backend/dist/routes/memory-prompts.js +49 -0
  30. package/backend/dist/routes/memory-prompts.js.map +1 -0
  31. package/backend/dist/routes/skillhub.d.ts +27 -0
  32. package/backend/dist/routes/skillhub.d.ts.map +1 -1
  33. package/backend/dist/routes/skillhub.js +290 -151
  34. package/backend/dist/routes/skillhub.js.map +1 -1
  35. package/backend/dist/session-manager.d.ts +12 -0
  36. package/backend/dist/session-manager.d.ts.map +1 -1
  37. package/backend/dist/session-manager.js.map +1 -1
  38. package/backend/dist/sync-service.d.ts +9 -6
  39. package/backend/dist/sync-service.d.ts.map +1 -1
  40. package/backend/dist/sync-service.js +84 -14
  41. package/backend/dist/sync-service.js.map +1 -1
  42. package/backend/package-lock.json +26 -0
  43. package/backend/package.json +2 -0
  44. package/frontend/dist/assets/AssistantMessageContent-qmMdpSdp.js +13 -0
  45. package/frontend/dist/assets/{GraphPreview-CeI4sbtV.js → GraphPreview-Cj-m26nq.js} +1 -1
  46. package/frontend/dist/assets/MobilePage-Dt7mdX_t.js +14 -0
  47. package/frontend/dist/assets/{OfficePreview-Dgs4aiYi.js → OfficePreview-CQROE6jJ.js} +2 -2
  48. package/frontend/dist/assets/{ProjectPage-DPv57nD9.js → ProjectPage-B-7RSILW.js} +5 -5
  49. package/frontend/dist/assets/SettingsPage-DrnZKm6L.js +13 -0
  50. package/frontend/dist/assets/SkillHubPage-Cr3_-Iwx.js +13 -0
  51. package/frontend/dist/assets/{chevron-down-CyDTNuVw.js → chevron-down-Ck7IYzKo.js} +1 -1
  52. package/frontend/dist/assets/chevron-up-vfhplDGO.js +13 -0
  53. package/frontend/dist/assets/index-BIaRBMD3.js +75 -0
  54. package/frontend/dist/assets/{index-z4qRGojt.js → index-CPwWf4Su.js} +1 -1
  55. package/frontend/dist/assets/index-CYvos3U3.js +13 -0
  56. package/frontend/dist/assets/index-DCiTw3F5.css +1 -0
  57. package/frontend/dist/assets/{jszip.min-CPG_u-b-.js → jszip.min-OAmm8lsw.js} +1 -1
  58. package/frontend/dist/assets/{search-CZ83atP-.js → search-B2NI-Y0J.js} +1 -1
  59. package/frontend/dist/index.html +2 -2
  60. package/package.json +1 -1
  61. package/frontend/dist/assets/AssistantMessageContent-D1-3VpWE.js +0 -13
  62. package/frontend/dist/assets/MobilePage-BP7c3W3D.js +0 -14
  63. package/frontend/dist/assets/SettingsPage-CFSmKovg.js +0 -13
  64. package/frontend/dist/assets/SkillHubPage-4g29B-Hr.js +0 -13
  65. package/frontend/dist/assets/chevron-up-BURz786o.js +0 -7
  66. package/frontend/dist/assets/index-BFWZX3Hz.js +0 -75
  67. package/frontend/dist/assets/index-D0NB3R9q.css +0 -1
  68. package/frontend/dist/assets/index-Uy-V98k3.js +0 -13
@@ -34,34 +34,40 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const express_1 = require("express");
37
- const config_1 = require("../config");
38
- const uuid_1 = require("uuid");
39
37
  const https = __importStar(require("https"));
38
+ const yaml = __importStar(require("js-yaml"));
39
+ const hub_auth_1 = require("../hub-auth");
40
+ /**
41
+ * CCWeb Hub proxy.
42
+ *
43
+ * Serves a read-only view of `zbc0315/ccweb-hub`, which stores community-shared
44
+ * Quick Prompts (Shortcuts) and Agent Prompts as individual `.md` files in
45
+ * `quick-prompts/` and `agent-prompts/` directories. Each file has YAML
46
+ * frontmatter (`label`, `kind`, `author`, `tags`, `description`) and a body
47
+ * that is the prompt itself.
48
+ *
49
+ * Submission is handled client-side via a pre-filled GitHub Issue URL — there
50
+ * is no longer any write path through this server (avoids pitfalls #30: no
51
+ * token bundled in the npm package, ever).
52
+ *
53
+ * Plugin Hub (`/plugins` endpoint) still proxies `plugins.json` at repo root
54
+ * for the separate PluginDock install flow.
55
+ */
40
56
  const router = (0, express_1.Router)();
41
57
  const REPO_OWNER = 'zbc0315';
42
- const REPO_NAME = 'ccweb-skillhub';
58
+ const REPO_NAME = 'ccweb-hub';
43
59
  const RAW_BASE = `https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/main`;
44
60
  const API_BASE = `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}`;
45
- // ── GitHub token ─────────────────────────────────────────────────────────────
46
- // SkillHub write operations (submit issue, download-count bump) require a GitHub
47
- // PAT scoped to the SkillHub repo. The token MUST come from the CCWEB_GITHUB_TOKEN
48
- // environment variable — never bundled in the npm package, since any installed
49
- // user would be able to extract it from backend/dist and gain write access to
50
- // the SkillHub repo (which in turn would poison every ccweb client via
51
- // plugins.json / skills.json).
61
+ // ── HTTP ─────────────────────────────────────────────────────────────────────
52
62
  //
53
- // When the env var is absent, write endpoints fail fast with a clear message;
54
- // read-only endpoints (/skills, /plugins) continue to work unauthenticated.
55
- function getGithubToken() {
56
- const token = process.env.CCWEB_GITHUB_TOKEN;
57
- return token && token.trim() ? token.trim() : null;
58
- }
59
- let cachedSkills = null;
60
- let cacheTime = 0;
61
- const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
62
- function httpGet(url, maxRedirects = 5) {
63
+ // Two distinct helpers: `apiGet` talks to the GitHub v3 API (JSON, versioned
64
+ // Accept header); `rawGet` fetches raw file content with no content negotiation
65
+ // assumption. Previously a single helper sent the API Accept header for raw
66
+ // requests too — harmless today but would break if GitHub raw ever starts to
67
+ // respect the Accept header strictly.
68
+ function request(url, accept, maxRedirects = 5) {
63
69
  return new Promise((resolve, reject) => {
64
- https.get(url, { headers: { 'User-Agent': 'CCWeb' } }, (res) => {
70
+ https.get(url, { headers: { 'User-Agent': 'CCWeb', 'Accept': accept } }, (res) => {
65
71
  if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
66
72
  if (maxRedirects <= 0) {
67
73
  reject(new Error('Too many redirects'));
@@ -72,14 +78,14 @@ function httpGet(url, maxRedirects = 5) {
72
78
  reject(new Error('Redirect to non-HTTPS URL blocked'));
73
79
  return;
74
80
  }
75
- httpGet(loc, maxRedirects - 1).then(resolve, reject);
81
+ request(loc, accept, maxRedirects - 1).then(resolve, reject);
76
82
  return;
77
83
  }
78
84
  let data = '';
79
85
  res.on('data', (chunk) => { data += chunk; });
80
86
  res.on('end', () => {
81
87
  if (res.statusCode && res.statusCode >= 400) {
82
- reject(new Error(`HTTP ${res.statusCode}: ${data}`));
88
+ reject(new Error(`HTTP ${res.statusCode}: ${data.slice(0, 200)}`));
83
89
  }
84
90
  else {
85
91
  resolve(data);
@@ -89,22 +95,23 @@ function httpGet(url, maxRedirects = 5) {
89
95
  }).on('error', reject);
90
96
  });
91
97
  }
92
- function githubApi(method, endpoint, body) {
93
- const token = getGithubToken();
94
- if (!token) {
95
- return Promise.reject(new Error('SkillHub write operations require CCWEB_GITHUB_TOKEN env var'));
96
- }
97
- const url = new URL(`${API_BASE}${endpoint}`);
98
- const postData = body ? JSON.stringify(body) : '';
98
+ const apiGet = (url) => request(url, 'application/vnd.github.v3+json');
99
+ const rawGet = (url) => request(url, '*/*');
100
+ /** POST to GitHub API with an Authorization: Bearer token. Used for Issue
101
+ * creation under the caller's own PAT the token never lives on the
102
+ * server beyond the duration of this call's Bearer header. */
103
+ function apiPost(urlPath, token, body) {
104
+ const url = new URL(`${API_BASE}${urlPath}`);
105
+ const postData = JSON.stringify(body);
99
106
  return new Promise((resolve, reject) => {
100
107
  const req = https.request({
101
108
  hostname: url.hostname,
102
109
  path: url.pathname + url.search,
103
- method,
110
+ method: 'POST',
104
111
  headers: {
105
112
  'User-Agent': 'CCWeb',
106
- 'Authorization': `Bearer ${token}`,
107
113
  'Accept': 'application/vnd.github.v3+json',
114
+ 'Authorization': `Bearer ${token}`,
108
115
  'Content-Type': 'application/json',
109
116
  'Content-Length': Buffer.byteLength(postData),
110
117
  },
@@ -113,7 +120,7 @@ function githubApi(method, endpoint, body) {
113
120
  res.on('data', (chunk) => { data += chunk; });
114
121
  res.on('end', () => {
115
122
  if (res.statusCode && res.statusCode >= 400) {
116
- reject(new Error(`GitHub API ${res.statusCode}: ${data}`));
123
+ reject(new Error(`GitHub API ${res.statusCode}: ${data.slice(0, 300)}`));
117
124
  }
118
125
  else {
119
126
  resolve(data);
@@ -122,163 +129,295 @@ function githubApi(method, endpoint, body) {
122
129
  res.on('error', reject);
123
130
  });
124
131
  req.on('error', reject);
125
- if (postData)
126
- req.write(postData);
132
+ req.write(postData);
127
133
  req.end();
128
134
  });
129
135
  }
130
- async function fetchSkills(forceRefresh = false) {
131
- const now = Date.now();
132
- if (!forceRefresh && cachedSkills && (now - cacheTime) < CACHE_TTL) {
133
- return cachedSkills;
136
+ function parseMarkdown(raw) {
137
+ // Recognize `---\n<yaml>\n---\n<body>`; anything else → whole file is body.
138
+ const match = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/);
139
+ if (!match)
140
+ return { meta: {}, body: raw };
141
+ let meta = {};
142
+ try {
143
+ const loaded = yaml.load(match[1], { schema: yaml.FAILSAFE_SCHEMA });
144
+ if (loaded && typeof loaded === 'object')
145
+ meta = loaded;
146
+ }
147
+ catch {
148
+ // YAML malformed — treat as no frontmatter rather than crashing the hub
149
+ }
150
+ return { meta, body: match[2].trimStart() };
151
+ }
152
+ function coerceTags(raw) {
153
+ if (Array.isArray(raw)) {
154
+ const out = raw.filter((x) => typeof x === 'string');
155
+ return out.length ? out : undefined;
134
156
  }
157
+ if (typeof raw === 'string') {
158
+ // Single string → split on comma for forgiving input
159
+ const split = raw.split(',').map((s) => s.trim()).filter(Boolean);
160
+ return split.length ? split : undefined;
161
+ }
162
+ return undefined;
163
+ }
164
+ // ── Cache ────────────────────────────────────────────────────────────────────
165
+ let cachedItems = null;
166
+ let cacheTime = 0;
167
+ const CACHE_TTL = 5 * 60 * 1000;
168
+ async function listDir(dir) {
135
169
  try {
136
- const raw = await httpGet(`${RAW_BASE}/skills.json`);
137
- cachedSkills = JSON.parse(raw);
138
- cacheTime = now;
139
- return cachedSkills;
170
+ const raw = await apiGet(`${API_BASE}/contents/${dir}`);
171
+ const parsed = JSON.parse(raw);
172
+ return Array.isArray(parsed)
173
+ ? parsed.filter((f) => f && f.type === 'file' && f.name.endsWith('.md'))
174
+ : [];
140
175
  }
141
- catch (err) {
142
- // Return cached data if available, even if expired
143
- if (cachedSkills)
144
- return cachedSkills;
145
- throw err;
176
+ catch {
177
+ return []; // 404 = directory empty / absent not an error
146
178
  }
147
179
  }
180
+ async function fetchKind(kind) {
181
+ const dir = kind === 'quick-prompt' ? 'quick-prompts' : 'agent-prompts';
182
+ const files = await listDir(dir);
183
+ if (files.length === 0)
184
+ return [];
185
+ // Raw fetches are on raw.githubusercontent.com (not counted against the
186
+ // 60/hr GitHub API anon limit), so parallelizing is safe.
187
+ const results = await Promise.allSettled(files.map(async (file) => {
188
+ if (!file.download_url)
189
+ return null;
190
+ try {
191
+ const content = await rawGet(file.download_url);
192
+ const { meta, body } = parseMarkdown(content);
193
+ const basename = file.name.replace(/\.md$/, '');
194
+ const label = typeof meta.label === 'string' && meta.label ? meta.label : basename;
195
+ return {
196
+ id: `${kind}/${basename}`,
197
+ kind,
198
+ label,
199
+ body: body.trim(),
200
+ author: typeof meta.author === 'string' ? meta.author : undefined,
201
+ tags: coerceTags(meta.tags),
202
+ description: typeof meta.description === 'string' ? meta.description : undefined,
203
+ file: `${dir}/${file.name}`,
204
+ };
205
+ }
206
+ catch {
207
+ return null; // One bad file can't poison the whole kind
208
+ }
209
+ }));
210
+ return results
211
+ .map((r) => (r.status === 'fulfilled' ? r.value : null))
212
+ .filter((x) => x !== null);
213
+ }
214
+ async function fetchAllItems(forceRefresh = false) {
215
+ const now = Date.now();
216
+ if (!forceRefresh && cachedItems && (now - cacheTime) < CACHE_TTL) {
217
+ return cachedItems;
218
+ }
219
+ // Resolve each kind independently — a transient failure on one directory
220
+ // should not make the whole hub appear broken.
221
+ const [quickRes, agentRes] = await Promise.allSettled([
222
+ fetchKind('quick-prompt'),
223
+ fetchKind('agent-prompt'),
224
+ ]);
225
+ const quick = quickRes.status === 'fulfilled' ? quickRes.value : [];
226
+ const agent = agentRes.status === 'fulfilled' ? agentRes.value : [];
227
+ if (quickRes.status === 'rejected')
228
+ console.warn('[ccweb-hub] quick-prompts fetch failed:', quickRes.reason);
229
+ if (agentRes.status === 'rejected')
230
+ console.warn('[ccweb-hub] agent-prompts fetch failed:', agentRes.reason);
231
+ cachedItems = [...quick, ...agent];
232
+ cacheTime = now;
233
+ return cachedItems;
234
+ }
148
235
  // ── Routes ───────────────────────────────────────────────────────────────────
149
- // GET /skills fetch skill index
236
+ // GET /items unified list of Quick Prompts + Agent Prompts in ccweb-hub
237
+ router.get('/items', async (_req, res) => {
238
+ try {
239
+ const items = await fetchAllItems();
240
+ res.json(items);
241
+ }
242
+ catch (err) {
243
+ res.status(502).json({ error: 'Failed to fetch ccweb-hub', detail: err.message });
244
+ }
245
+ });
246
+ // GET /skills — legacy alias for pre-hub clients. Returns the Quick Prompts
247
+ // subset in the old SkillHubItem shape. `createdAt` is set to current ISO so
248
+ // clients that sort by date don't choke on empty strings.
150
249
  router.get('/skills', async (_req, res) => {
151
250
  try {
152
- const skills = await fetchSkills();
153
- res.json(skills);
251
+ const items = await fetchAllItems();
252
+ const iso = new Date().toISOString();
253
+ const legacy = items
254
+ .filter((i) => i.kind === 'quick-prompt')
255
+ .map((i) => ({
256
+ id: i.id,
257
+ label: i.label,
258
+ command: i.body,
259
+ description: i.description ?? '',
260
+ author: i.author ?? 'anonymous',
261
+ tags: i.tags ?? [],
262
+ downloads: 0,
263
+ createdAt: iso,
264
+ }));
265
+ res.json(legacy);
154
266
  }
155
267
  catch (err) {
156
- res.status(502).json({ error: 'Failed to fetch SkillHub index', detail: err.message });
268
+ res.status(502).json({ error: 'Failed to fetch ccweb-hub', detail: err.message });
269
+ }
270
+ });
271
+ // ── Hub auth (per-user GitHub PAT for one-click Issue submit) ──────────────
272
+ function requireUsername(req, res) {
273
+ const u = req.user?.username;
274
+ if (!u) {
275
+ res.status(401).json({ error: 'Unauthenticated' });
276
+ return null;
277
+ }
278
+ return u;
279
+ }
280
+ // GET /auth → { configured, needsReset }
281
+ router.get('/auth', (req, res) => {
282
+ const user = requireUsername(req, res);
283
+ if (!user)
284
+ return;
285
+ res.json((0, hub_auth_1.getHubTokenStatus)(user));
286
+ });
287
+ // PUT /auth body { token: string }
288
+ router.put('/auth', (req, res) => {
289
+ const user = requireUsername(req, res);
290
+ if (!user)
291
+ return;
292
+ const token = typeof req.body?.token === 'string'
293
+ ? req.body.token.trim()
294
+ : '';
295
+ if (!token) {
296
+ res.status(400).json({ error: 'token required' });
297
+ return;
157
298
  }
299
+ // Light sanity check — GitHub PATs start with ghp_ / github_pat_ etc. and
300
+ // are ≥40 chars. Don't block unusual forms outright; GitHub will reject.
301
+ // Printable ASCII only — GitHub PATs live in this range; rejecting
302
+ // zero-width spaces / BOM / other invisibles prevents the common
303
+ // copy-paste-from-formatted-source bug that would otherwise store a
304
+ // token GitHub will silently 401 on forever.
305
+ if (token.length < 20 || token.length > 200 || !/^[\x21-\x7E]+$/.test(token)) {
306
+ res.status(400).json({ error: 'token contains whitespace / non-printable characters, or has an unexpected length' });
307
+ return;
308
+ }
309
+ (0, hub_auth_1.setHubToken)(user, token);
310
+ res.json({ ok: true, ...(0, hub_auth_1.getHubTokenStatus)(user) });
311
+ });
312
+ // DELETE /auth → wipe stored token
313
+ router.delete('/auth', (req, res) => {
314
+ const user = requireUsername(req, res);
315
+ if (!user)
316
+ return;
317
+ (0, hub_auth_1.clearHubToken)(user);
318
+ res.json({ ok: true });
158
319
  });
159
- // POST /submit submit a skill via GitHub Issue
320
+ // POST /submit body { kind, label, body, description?, tags?, author? }
321
+ // Posts an Issue to zbc0315/ccweb-hub using the caller's stored PAT.
160
322
  router.post('/submit', async (req, res) => {
161
- const { label, command, description, author, tags, parentId } = req.body;
162
- if (!label || !command) {
163
- res.status(400).json({ error: 'label and command are required' });
323
+ const user = requireUsername(req, res);
324
+ if (!user)
325
+ return;
326
+ const token = (0, hub_auth_1.getHubToken)(user);
327
+ if (!token) {
328
+ res.status(412).json({ error: 'Hub token not configured — set one in Settings → CCWeb Hub' });
164
329
  return;
165
330
  }
166
- const skillData = {
167
- label,
168
- command,
169
- description: description || '',
170
- author: author || 'anonymous',
171
- tags: tags || [],
172
- createdAt: new Date().toISOString().slice(0, 10),
173
- };
174
- if (parentId)
175
- skillData.parentId = parentId;
176
- const issueBody = '```json\n' + JSON.stringify(skillData, null, 2) + '\n```';
177
- try {
178
- await githubApi('POST', '/issues', {
179
- title: `[Skill] ${label}`,
180
- body: issueBody,
181
- labels: ['new-skill'],
182
- });
183
- res.json({ success: true });
331
+ const b = (req.body ?? {});
332
+ if (b.kind !== 'quick-prompt' && b.kind !== 'agent-prompt') {
333
+ res.status(400).json({ error: 'kind must be "quick-prompt" or "agent-prompt"' });
334
+ return;
184
335
  }
185
- catch (err) {
186
- res.status(502).json({ error: 'Failed to submit to SkillHub', detail: err.message });
336
+ if (!b.label || typeof b.label !== 'string' || !b.body || typeof b.body !== 'string') {
337
+ res.status(400).json({ error: 'label and body are required strings' });
338
+ return;
187
339
  }
188
- });
189
- // POST /download/:id download skill as global shortcut
190
- router.post('/download/:id', async (req, res) => {
191
- const { id } = req.params;
192
- const username = req.user?.username;
340
+ // Newlines in GitHub Issue title get silently truncated; reject early so
341
+ // the submit flow doesn't produce a half-titled issue. Same-ish for the
342
+ // optional fields — keep them single-line, reasonable length.
343
+ if (/[\r\n]/.test(b.label) || b.label.length > 200) {
344
+ res.status(400).json({ error: 'label must be single-line and ≤ 200 chars' });
345
+ return;
346
+ }
347
+ if (typeof b.description === 'string' && (/[\r\n]/.test(b.description) || b.description.length > 300)) {
348
+ res.status(400).json({ error: 'description must be single-line and ≤ 300 chars' });
349
+ return;
350
+ }
351
+ if (typeof b.author === 'string' && (/[\r\n\s]/.test(b.author) || b.author.length > 64)) {
352
+ res.status(400).json({ error: 'author must be a single token (no whitespace), ≤ 64 chars' });
353
+ return;
354
+ }
355
+ const kindLabel = b.kind === 'quick-prompt' ? 'Quick Prompt' : 'Agent Prompt';
356
+ // Code-point-safe title slice to avoid splitting surrogate pairs
357
+ const titleRaw = `[${kindLabel}] ${b.label}`;
358
+ const title = Array.from(titleRaw).slice(0, 240).join('');
359
+ // Dynamic fence — user content containing backticks can't close the block
360
+ const backtickRuns = b.body.match(/`+/g) ?? [];
361
+ const maxRun = backtickRuns.reduce((m, r) => Math.max(m, r.length), 0);
362
+ const fence = '`'.repeat(Math.max(3, maxRun + 1));
363
+ const author = typeof b.author === 'string' && b.author.trim() ? b.author.trim() : 'anonymous';
364
+ const tagList = Array.isArray(b.tags)
365
+ ? b.tags.filter((t) => typeof t === 'string')
366
+ : [];
367
+ const bodyMd = `<!-- Submitted via ccweb. Review, then commit to ${b.kind}s/ as a .md file. -->\n\n` +
368
+ '```yaml\n' +
369
+ '---\n' +
370
+ `label: ${JSON.stringify(b.label)}\n` +
371
+ `kind: ${JSON.stringify(b.kind)}\n` +
372
+ `author: ${JSON.stringify(author)}\n` +
373
+ (tagList.length ? `tags: ${JSON.stringify(tagList)}\n` : '') +
374
+ (b.description && b.description.trim() ? `description: ${JSON.stringify(b.description.trim())}\n` : '') +
375
+ '---\n' +
376
+ '```\n\n' +
377
+ '## Body\n\n' +
378
+ `${fence}\n` +
379
+ b.body +
380
+ `\n${fence}\n`;
193
381
  try {
194
- const skills = await fetchSkills();
195
- const skill = skills.find((s) => s.id === id);
196
- if (!skill) {
197
- res.status(404).json({ error: 'Skill not found' });
198
- return;
199
- }
200
- // Resolve the full inheritance chain (parent first)
201
- const chain = [];
202
- const visited = new Set();
203
- let current = skill;
204
- while (current) {
205
- if (visited.has(current.id))
206
- break;
207
- visited.add(current.id);
208
- chain.unshift(current); // parent goes first
209
- current = current.parentId ? skills.find((s) => s.id === current.parentId) : undefined;
210
- }
211
- // Add all skills in the chain to global shortcuts, preserving parentId links
212
- const shortcuts = (0, config_1.getGlobalShortcuts)(username);
213
- // Map from SkillHub id → local shortcut id
214
- const idMap = new Map();
215
- for (const item of chain) {
216
- // Check if already exists
217
- const existing = shortcuts.find((s) => s.label === item.label && s.command === item.command);
218
- if (existing) {
219
- idMap.set(item.id, existing.id);
220
- }
221
- else {
222
- const localId = (0, uuid_1.v4)();
223
- const localParentId = item.parentId ? idMap.get(item.parentId) : undefined;
224
- const newItem = { id: localId, label: item.label, command: item.command };
225
- if (localParentId)
226
- newItem.parentId = localParentId;
227
- shortcuts.push(newItem);
228
- idMap.set(item.id, localId);
229
- }
230
- }
231
- (0, config_1.saveGlobalShortcuts)(shortcuts, username);
232
- const newShortcut = shortcuts.find((s) => s.id === idMap.get(skill.id));
233
- // Try to update download count in repo (best-effort, don't fail the request)
234
- try {
235
- // Get current skills.json content and sha
236
- const fileResp = await githubApi('GET', '/contents/skills.json');
237
- const fileData = JSON.parse(fileResp);
238
- const content = Buffer.from(fileData.content, 'base64').toString('utf-8');
239
- const repoSkills = JSON.parse(content);
240
- const target = repoSkills.find((s) => s.id === id);
241
- if (target) {
242
- target.downloads = (target.downloads || 0) + 1;
243
- const updated = Buffer.from(JSON.stringify(repoSkills, null, 2) + '\n').toString('base64');
244
- await githubApi('PUT', '/contents/skills.json', {
245
- message: `bump download count for ${id}`,
246
- content: updated,
247
- sha: fileData.sha,
248
- });
249
- // Update cache
250
- cachedSkills = repoSkills;
251
- cacheTime = Date.now();
252
- }
253
- }
254
- catch {
255
- // Silently ignore download count update failures
256
- }
257
- res.json(newShortcut);
382
+ const raw = await apiPost('/issues', token, {
383
+ title,
384
+ body: bodyMd,
385
+ labels: [b.kind],
386
+ });
387
+ const parsed = JSON.parse(raw);
388
+ res.json({ ok: true, issueNumber: parsed.number, issueUrl: parsed.html_url });
258
389
  }
259
390
  catch (err) {
260
- res.status(500).json({ error: 'Failed to download skill', detail: err.message });
391
+ const msg = err.message;
392
+ // Surface GitHub 401 / 403 distinctly so the UI can prompt for a fresh token
393
+ const is401 = /GitHub API 401/.test(msg);
394
+ const is403 = /GitHub API 403/.test(msg);
395
+ res.status(is401 || is403 ? 401 : 502).json({
396
+ error: is401
397
+ ? 'GitHub token invalid or expired — update in Settings'
398
+ : is403
399
+ ? 'GitHub rejected the request (token scope too narrow, or rate-limited)'
400
+ : `Failed to submit: ${msg}`,
401
+ });
261
402
  }
262
403
  });
263
- // ── Plugin Hub ──────────────────────────────────────────────────────────────
404
+ // ── Plugin Hub (unchanged — proxies plugins.json at hub repo root) ─────────
264
405
  let _pluginCache = null;
265
406
  let _pluginCacheTime = 0;
266
- const PLUGIN_CACHE_TTL = 5 * 60000; // 5 minutes
407
+ const PLUGIN_CACHE_TTL = 5 * 60000;
267
408
  router.get('/plugins', async (_req, res) => {
268
409
  const now = Date.now();
269
410
  if (_pluginCache && now - _pluginCacheTime < PLUGIN_CACHE_TTL) {
270
411
  return res.json(_pluginCache);
271
412
  }
272
413
  try {
273
- const url = `${RAW_BASE}/plugins.json`;
274
- const data = await httpGet(url);
414
+ const data = await rawGet(`${RAW_BASE}/plugins.json`);
275
415
  const plugins = JSON.parse(data);
276
416
  _pluginCache = Array.isArray(plugins) ? plugins : [];
277
417
  _pluginCacheTime = now;
278
418
  res.json(_pluginCache);
279
419
  }
280
420
  catch {
281
- // Return stale cache or empty
282
421
  res.json(_pluginCache ?? []);
283
422
  }
284
423
  });
@@ -1 +1 @@
1
- {"version":3,"file":"skillhub.js","sourceRoot":"","sources":["../../src/routes/skillhub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skillhub.js","sourceRoot":"","sources":["../../src/routes/skillhub.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,19 @@ import { EventEmitter } from 'events';
9
9
  import type { CliTool } from './types';
10
10
  export interface ChatBlockItem {
11
11
  type: 'text' | 'thinking' | 'tool_use' | 'tool_result';
12
+ /** Legacy string form; always populated for backwards compat. For tool_use
13
+ * it's still `name(args-truncated)`. Rich renderers should prefer `tool` /
14
+ * `input` / `output` below when present. */
12
15
  content: string;
16
+ /** tool_use: tool name (`Bash`, `Edit`, `TodoWrite`, …). */
17
+ tool?: string;
18
+ /** tool_use: structured input with deep string values capped at ~4KB to
19
+ * protect WS payload size. Object shape preserved so the frontend can
20
+ * render tool-specific UIs (TodoWrite checklist, Edit diff, etc.). */
21
+ input?: unknown;
22
+ /** tool_result: full-ish text (up to ~4KB) — `content` keeps the short
23
+ * legacy truncation for callers that serialize to markdown fences. */
24
+ output?: string;
13
25
  }
14
26
  export interface ChatBlock {
15
27
  /** Stable block id for dedup between WS replay and HTTP history. Derived
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB;;;2BAGuB;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAWD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,cAAM,cAAe,SAAQ,YAAY;IACvC,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,cAAc,CAAqC;;IAM3D,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI3D,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAQtD,0EAA0E;IAC1E,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI9C;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE;IA0B9C,uEAAuE;IACvE,OAAO,CAAC,cAAc;IA2BtB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,yBAAyB;IA6BjC,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI;IAK3E,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI;IAO7E;2EACuE;IACvE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,OAAkB,GAAG,IAAI;IAYtF,kFAAkF;IAClF,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9C,OAAO,CAAC,WAAW;IAKnB;;0DAEsD;IACtD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAU5D;;;gDAG4C;IAC5C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAiDpC,wFAAwF;IACxF,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM5C,+DAA+D;IAC/D,OAAO,CAAC,YAAY;IAepB,2GAA2G;IAC3G,OAAO,CAAC,oBAAoB;IAmC5B,gDAAgD;IAChD,OAAO,CAAC,oBAAoB;CAgD7B;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../src/session-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,CAAC;IACvD;;iDAE6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;2EAEuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;2EACuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB;;;2BAGuB;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAWD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAeD,cAAM,cAAe,SAAQ,YAAY;IACvC,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,cAAc,CAAqC;;IAM3D,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI3D,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAQtD,0EAA0E;IAC1E,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI9C;;;;;;;;;;;;;;OAcG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE;IA0B9C,uEAAuE;IACvE,OAAO,CAAC,cAAc;IA2BtB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,yBAAyB;IA6BjC,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI;IAK3E,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,GAAG,IAAI;IAO7E;2EACuE;IACvE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,OAAkB,GAAG,IAAI;IAYtF,kFAAkF;IAClF,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9C,OAAO,CAAC,WAAW;IAKnB;;0DAEsD;IACtD,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAU5D;;;gDAG4C;IAC5C,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAiDpC,wFAAwF;IACxF,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM5C,+DAA+D;IAC/D,OAAO,CAAC,YAAY;IAepB,2GAA2G;IAC3G,OAAO,CAAC,oBAAoB;IAmC5B,gDAAgD;IAChD,OAAO,CAAC,oBAAoB;CAgD7B;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}