mirror of
https://github.com/hanzoai/extension.git
synced 2026-10-31 21:57:06 +00:00
Bolt app bringing Hanzo AI into Slack, built on the shared foundation: @hanzo/ai (headless client), @hanzo/iam (identity), @hanzo/cards (UI). - /hanzo slash command → completion, replies with a @hanzo/cards panel - App Home assistant panel (model picker, quick actions, prompt, sign-in) via toSlackBlocks — no hand-written Block Kit - Interactivity for the stable card action ids (model select, quick actions, prompt submit, sign in) - 'Ask Hanzo' message shortcut + app_mention: pull thread/message context via conversations.replies/history, fence it into the prompt - OAuth install (/slack/install, /slack/oauth_redirect) with a per-workspace bot token + per-workspace Hanzo token, server-side only - Quick actions: Summarize, Draft reply, Explain, Action items - Endpoints via api.hanzo.ai /v1 only; secrets from env; /health + graceful shutdown for ingress/k8s - One path from Slack to the model (complete); pure modules unit-tested - README with Slack app manifest + registration steps Tests: 68 passing. tsc --noEmit clean. Build emits dist/.
47 lines
1.6 KiB
TypeScript
47 lines
1.6 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { ActionId } from '@hanzo/cards';
|
|
import { parseActionId, quickActionIdFrom, QUICK_ACTION_RE } from '../src/actions.js';
|
|
|
|
describe('parseActionId', () => {
|
|
it('classifies the four stable card action ids', () => {
|
|
expect(parseActionId(ActionId.ModelSelect)).toEqual({ kind: 'model_select' });
|
|
expect(parseActionId(ActionId.PromptSubmit)).toEqual({ kind: 'prompt_submit' });
|
|
expect(parseActionId(ActionId.SignIn)).toEqual({ kind: 'sign_in' });
|
|
});
|
|
|
|
it('classifies quick actions and pulls the id', () => {
|
|
expect(parseActionId('hanzo_quick_action:summarize')).toEqual({
|
|
kind: 'quick_action',
|
|
id: 'summarize',
|
|
});
|
|
expect(parseActionId('hanzo_quick_action:draft_reply')).toEqual({
|
|
kind: 'quick_action',
|
|
id: 'draft_reply',
|
|
});
|
|
});
|
|
|
|
it('reports unknown ids without throwing', () => {
|
|
expect(parseActionId('something_else')).toEqual({
|
|
kind: 'unknown',
|
|
actionId: 'something_else',
|
|
});
|
|
});
|
|
|
|
it('uses the card contract action id, not a hard-coded string', () => {
|
|
expect(ActionId.ModelSelect).toBe('hanzo_model_select');
|
|
expect(ActionId.QuickAction).toBe('hanzo_quick_action');
|
|
});
|
|
});
|
|
|
|
describe('quickActionIdFrom / QUICK_ACTION_RE', () => {
|
|
it('extracts the id or returns null', () => {
|
|
expect(quickActionIdFrom('hanzo_quick_action:explain')).toBe('explain');
|
|
expect(quickActionIdFrom('hanzo_model_select')).toBeNull();
|
|
});
|
|
|
|
it('regex matches only the quick-action namespace', () => {
|
|
expect(QUICK_ACTION_RE.test('hanzo_quick_action:x')).toBe(true);
|
|
expect(QUICK_ACTION_RE.test('hanzo_prompt_submit')).toBe(false);
|
|
});
|
|
});
|