@agenticmail/enterprise 0.5.41 → 0.5.43

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.
@@ -211,6 +211,18 @@ export function SkillsPage() {
211
211
  setConfigSaving(false);
212
212
  };
213
213
 
214
+ // Install a builtin skill
215
+ var installBuiltinSkill = async function(skillId) {
216
+ try {
217
+ await engineCall('/community/skills/' + skillId + '/install', {
218
+ method: 'POST',
219
+ body: JSON.stringify({ orgId: getOrgId() })
220
+ });
221
+ toast('Skill installed', 'success');
222
+ loadInstalled();
223
+ } catch (e) { toast(e.message || 'Install failed', 'error'); }
224
+ };
225
+
214
226
  // Computed
215
227
  var allSkills = Object.entries(skills).flatMap(function(entry) {
216
228
  return entry[1].map(function(s) { return Object.assign({}, s, { category: entry[0] }); });
@@ -246,11 +258,26 @@ export function SkillsPage() {
246
258
  return h('div', { key: cat, style: { marginBottom: 24 } },
247
259
  h('h3', { style: { fontSize: 13, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em', color: 'var(--text-muted)', marginBottom: 10 } }, cat.replace(/-/g, ' ')),
248
260
  h('div', { className: 'skill-grid' }, list.map(function(s) {
261
+ var isInstalled = installed.some(function(i) { return i.skillId === s.id; });
249
262
  return h('div', { key: s.id, className: 'skill-card' },
250
263
  h('div', { className: 'skill-cat' }, s.category || cat),
251
264
  h('div', { className: 'skill-name' }, s.name),
252
265
  h('div', { className: 'skill-desc' }, s.description),
253
- s.tools && h('div', { style: { marginTop: 6, fontSize: 11, color: 'var(--text-muted)' } }, s.tools.length + ' tools')
266
+ s.tools && h('div', { style: { marginTop: 6, fontSize: 11, color: 'var(--text-muted)' } }, s.tools.length + ' tools'),
267
+ h('div', { style: { marginTop: 8, display: 'flex', gap: 6 } },
268
+ isInstalled
269
+ ? h('span', { style: { fontSize: 11, color: 'var(--success)', fontWeight: 600 } }, '\u2713 Installed')
270
+ : h('button', {
271
+ className: 'btn btn-primary btn-sm',
272
+ style: { fontSize: 11, padding: '3px 10px' },
273
+ onClick: function() { installBuiltinSkill(s.id); }
274
+ }, 'Install'),
275
+ !isInstalled && h('button', {
276
+ className: 'btn btn-secondary btn-sm',
277
+ style: { fontSize: 11, padding: '3px 10px' },
278
+ onClick: function() { setTokenModal({ skillId: s.id, skillName: s.name }); }
279
+ }, 'Add Token')
280
+ )
254
281
  );
255
282
  }))
256
283
  );
@@ -388,7 +388,7 @@ export class PostgresAdapter extends DatabaseAdapter {
388
388
  async validateApiKey(plaintext: string): Promise<ApiKey | null> {
389
389
  const keyHash = createHash('sha256').update(plaintext).digest('hex');
390
390
  const { rows } = await this.pool.query(
391
- 'SELECT * FROM api_keys WHERE key_hash = $1 AND revoked = 0',
391
+ 'SELECT * FROM api_keys WHERE key_hash = $1 AND (revoked IS NULL OR revoked = FALSE)',
392
392
  [keyHash]
393
393
  );
394
394
  if (!rows[0]) return null;
@@ -400,16 +400,16 @@ export class PostgresAdapter extends DatabaseAdapter {
400
400
  }
401
401
 
402
402
  async listApiKeys(opts?: { createdBy?: string }): Promise<ApiKey[]> {
403
- let q = 'SELECT * FROM api_keys';
403
+ let q = 'SELECT * FROM api_keys WHERE (revoked IS NULL OR revoked = FALSE)';
404
404
  const params: any[] = [];
405
- if (opts?.createdBy) { q += ' WHERE created_by = $1'; params.push(opts.createdBy); }
405
+ if (opts?.createdBy) { q += ' AND created_by = $' + (params.length + 1); params.push(opts.createdBy); }
406
406
  q += ' ORDER BY created_at DESC';
407
407
  const { rows } = await this.pool.query(q, params);
408
408
  return rows.map((r: any) => this.mapApiKey(r));
409
409
  }
410
410
 
411
411
  async revokeApiKey(id: string): Promise<void> {
412
- await this.pool.query('UPDATE api_keys SET revoked = 1 WHERE id = $1', [id]);
412
+ await this.pool.query('UPDATE api_keys SET revoked = TRUE WHERE id = $1', [id]);
413
413
  }
414
414
 
415
415
  // ─── Rules ───────────────────────────────────────────────