Claude-code-plugins hex-local-dev-loop
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/hex-pack/skills/hex-local-dev-loop" ~/.claude/skills/jeremylongshore-claude-code-plugins-hex-local-dev-loop && rm -rf "$T"
manifest:
plugins/saas-packs/hex-pack/skills/hex-local-dev-loop/SKILL.mdsource content
Hex Local Dev Loop
Overview
Set up a development workflow for Hex API orchestration with mocked API responses and testing.
Instructions
Step 1: Project Structure
hex-orchestrator/ ├── src/hex/ │ ├── client.ts # API client │ ├── orchestrator.ts # Pipeline runner │ └── types.ts # TypeScript interfaces ├── tests/ │ ├── fixtures/ # Mock API responses │ └── orchestrator.test.ts ├── .env.local └── package.json
Step 2: Typed Hex Client
// src/hex/client.ts export class HexClient { constructor(private token: string, private baseUrl = 'https://app.hex.tech/api/v1') {} async listProjects() { return this.get('/projects'); } async runProject(projectId: string, inputParams?: Record<string, any>) { return this.post(`/project/${projectId}/run`, { inputParams: inputParams || {}, updateCacheResult: true }); } async getRunStatus(projectId: string, runId: string) { return this.get(`/project/${projectId}/run/${runId}`); } async cancelRun(projectId: string, runId: string) { return this.delete(`/project/${projectId}/run/${runId}`); } private async get(path: string) { const res = await fetch(`${this.baseUrl}${path}`, { headers: { 'Authorization': `Bearer ${this.token}` } }); if (!res.ok) throw new Error(`Hex API ${res.status}`); return res.json(); } private async post(path: string, body: any) { const res = await fetch(`${this.baseUrl}${path}`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.token}`, 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); if (!res.ok) throw new Error(`Hex API ${res.status}`); return res.json(); } private async delete(path: string) { const res = await fetch(`${this.baseUrl}${path}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${this.token}` } }); return res.ok; } }
Step 3: Mocked Tests
import { describe, it, expect, vi } from 'vitest'; const mockFetch = vi.fn(); vi.stubGlobal('fetch', mockFetch); describe('HexClient', () => { it('should list projects', async () => { mockFetch.mockResolvedValueOnce({ ok: true, json: async () => [{ projectId: 'p1', name: 'Test' }] }); const client = new HexClient('test-token'); const projects = await client.listProjects(); expect(projects).toHaveLength(1); }); it('should trigger a run', async () => { mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({ runId: 'r1', projectId: 'p1' }) }); const client = new HexClient('test-token'); const run = await client.runProject('p1', { date: '2025-01-01' }); expect(run.runId).toBe('r1'); }); });
Resources
Next Steps
See
hex-sdk-patterns for production patterns.