@artyfacts/claude 1.0.0

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.
@@ -0,0 +1,312 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ChildProcess } from 'child_process';
3
+
4
+ /**
5
+ * Artyfacts API Client (Simplified)
6
+ *
7
+ * Handles communication with the Artyfacts API for task management.
8
+ */
9
+ interface ArtyfactsConfig {
10
+ apiKey: string;
11
+ baseUrl?: string;
12
+ agentId?: string;
13
+ }
14
+ interface Task {
15
+ id: string;
16
+ sectionId: string;
17
+ heading: string;
18
+ content: string;
19
+ artifactId: string;
20
+ artifactTitle: string;
21
+ artifactUrl: string;
22
+ priority: 1 | 2 | 3;
23
+ dependsOn: string[];
24
+ createdAt: string;
25
+ }
26
+ interface ClaimResult {
27
+ success: boolean;
28
+ task: Task & {
29
+ claimedAt: string;
30
+ claimedBy: string;
31
+ };
32
+ }
33
+ interface CompleteResult {
34
+ success: boolean;
35
+ unblockedTasks: string[];
36
+ }
37
+ declare class ArtyfactsClient {
38
+ private config;
39
+ constructor(config: ArtyfactsConfig);
40
+ private fetch;
41
+ /**
42
+ * Get claimable tasks from the queue
43
+ */
44
+ getTaskQueue(options?: {
45
+ limit?: number;
46
+ }): Promise<Task[]>;
47
+ /**
48
+ * Claim a task
49
+ */
50
+ claimTask(taskId: string): Promise<ClaimResult>;
51
+ /**
52
+ * Complete a task
53
+ */
54
+ completeTask(taskId: string, options?: {
55
+ outputUrl?: string;
56
+ summary?: string;
57
+ }): Promise<CompleteResult>;
58
+ /**
59
+ * Report task as blocked
60
+ */
61
+ blockTask(taskId: string, reason: string): Promise<void>;
62
+ /**
63
+ * Get current user/org info
64
+ */
65
+ getMe(): Promise<{
66
+ id: string;
67
+ name: string;
68
+ orgId: string;
69
+ }>;
70
+ }
71
+
72
+ /**
73
+ * Claude Code Runner
74
+ *
75
+ * Spawns and manages Claude Code CLI processes for task execution.
76
+ */
77
+
78
+ interface ClaudeRunnerConfig {
79
+ /** Path to claude CLI (default: 'claude') */
80
+ claudePath?: string;
81
+ /** Model to use (default: 'sonnet') */
82
+ model?: string;
83
+ /** Working directory for Claude */
84
+ cwd?: string;
85
+ /** Timeout in ms (default: 5 minutes) */
86
+ timeoutMs?: number;
87
+ }
88
+ interface TaskResult {
89
+ success: boolean;
90
+ output: string;
91
+ error?: string;
92
+ exitCode: number | null;
93
+ durationMs: number;
94
+ }
95
+ interface RunningTask {
96
+ taskId: string;
97
+ process: ChildProcess;
98
+ startedAt: Date;
99
+ promise: Promise<TaskResult>;
100
+ }
101
+ declare class ClaudeRunner extends EventEmitter {
102
+ private config;
103
+ private runningTasks;
104
+ constructor(config?: ClaudeRunnerConfig);
105
+ /**
106
+ * Check if Claude Code is installed and authenticated
107
+ */
108
+ checkInstalled(): Promise<{
109
+ installed: boolean;
110
+ authenticated: boolean;
111
+ version?: string;
112
+ error?: string;
113
+ }>;
114
+ /**
115
+ * Run a task with Claude Code
116
+ */
117
+ runTask(taskId: string, prompt: string, options?: {
118
+ cwd?: string;
119
+ model?: string;
120
+ timeoutMs?: number;
121
+ }): Promise<TaskResult>;
122
+ /**
123
+ * Run a raw claude command
124
+ */
125
+ private runCommand;
126
+ /**
127
+ * Cancel a running task
128
+ */
129
+ cancelTask(taskId: string): boolean;
130
+ /**
131
+ * Get count of running tasks
132
+ */
133
+ getRunningCount(): number;
134
+ /**
135
+ * Cancel all running tasks
136
+ */
137
+ cancelAll(): void;
138
+ }
139
+
140
+ /**
141
+ * Claude Adapter
142
+ *
143
+ * Main orchestration class that:
144
+ * 1. Polls Artyfacts for claimable tasks
145
+ * 2. Spawns Claude Code to execute them
146
+ * 3. Reports results back to Artyfacts
147
+ */
148
+
149
+ interface AdapterConfig {
150
+ /** Artyfacts API key */
151
+ apiKey: string;
152
+ /** Artyfacts base URL */
153
+ baseUrl?: string;
154
+ /** Agent ID for attribution */
155
+ agentId?: string;
156
+ /** Poll interval in ms (default: 30s) */
157
+ pollIntervalMs?: number;
158
+ /** Max concurrent tasks (default: 1) */
159
+ maxConcurrent?: number;
160
+ /** Claude model to use (default: 'sonnet') */
161
+ model?: string;
162
+ /** Working directory for Claude */
163
+ cwd?: string;
164
+ }
165
+ interface AdapterEvents {
166
+ 'started': () => void;
167
+ 'stopped': () => void;
168
+ 'poll': (tasks: Task[]) => void;
169
+ 'task:claimed': (task: Task) => void;
170
+ 'task:running': (task: Task) => void;
171
+ 'task:completed': (task: Task, result: TaskResult) => void;
172
+ 'task:failed': (task: Task, error: string) => void;
173
+ 'error': (error: Error) => void;
174
+ }
175
+ declare class ClaudeAdapter extends EventEmitter {
176
+ private config;
177
+ private client;
178
+ private runner;
179
+ private running;
180
+ private pollTimer;
181
+ private activeTasks;
182
+ constructor(config: AdapterConfig);
183
+ /**
184
+ * Check if Claude Code is ready
185
+ */
186
+ checkReady(): Promise<{
187
+ ready: boolean;
188
+ error?: string;
189
+ }>;
190
+ /**
191
+ * Start the adapter
192
+ */
193
+ start(): Promise<void>;
194
+ /**
195
+ * Stop the adapter
196
+ */
197
+ stop(): Promise<void>;
198
+ /**
199
+ * Poll for and execute tasks
200
+ */
201
+ private poll;
202
+ /**
203
+ * Execute a single task
204
+ */
205
+ private executeTask;
206
+ /**
207
+ * Build a prompt for Claude from the task
208
+ */
209
+ private buildPrompt;
210
+ /**
211
+ * Extract a summary from Claude's output
212
+ */
213
+ private extractSummary;
214
+ /**
215
+ * Check if running
216
+ */
217
+ isRunning(): boolean;
218
+ /**
219
+ * Get stats
220
+ */
221
+ getStats(): {
222
+ running: boolean;
223
+ activeTasks: number;
224
+ maxConcurrent: number;
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Device Authorization Flow
230
+ *
231
+ * Handles browser-based authentication for the CLI.
232
+ * No API keys to copy — just run the CLI and click authorize.
233
+ */
234
+ interface DeviceCodeResponse {
235
+ deviceCode: string;
236
+ userCode: string;
237
+ verificationUri: string;
238
+ expiresIn: number;
239
+ interval: number;
240
+ }
241
+ interface TokenResponse {
242
+ accessToken: string;
243
+ refreshToken?: string;
244
+ expiresAt?: number;
245
+ user: {
246
+ id: string;
247
+ email: string;
248
+ name?: string;
249
+ orgId: string;
250
+ };
251
+ }
252
+ interface StoredCredentials {
253
+ accessToken: string;
254
+ refreshToken?: string;
255
+ expiresAt?: number;
256
+ user: {
257
+ id: string;
258
+ email: string;
259
+ name?: string;
260
+ orgId: string;
261
+ };
262
+ savedAt: string;
263
+ }
264
+ declare class DeviceAuth {
265
+ private baseUrl;
266
+ private credentialsPath;
267
+ constructor(options?: {
268
+ baseUrl?: string;
269
+ });
270
+ /**
271
+ * Check if we have stored credentials
272
+ */
273
+ hasCredentials(): boolean;
274
+ /**
275
+ * Get stored credentials
276
+ */
277
+ getCredentials(): StoredCredentials | null;
278
+ /**
279
+ * Get access token (for API calls)
280
+ */
281
+ getAccessToken(): string | null;
282
+ /**
283
+ * Clear stored credentials (logout)
284
+ */
285
+ logout(): void;
286
+ /**
287
+ * Start device authorization flow
288
+ */
289
+ startDeviceFlow(): Promise<DeviceCodeResponse>;
290
+ /**
291
+ * Poll for token after user authorizes
292
+ */
293
+ pollForToken(deviceCode: string, interval: number, expiresIn: number): Promise<TokenResponse>;
294
+ /**
295
+ * Save credentials to disk
296
+ */
297
+ saveCredentials(token: TokenResponse): void;
298
+ /**
299
+ * Open URL in browser
300
+ */
301
+ openBrowser(url: string): void;
302
+ /**
303
+ * Full login flow
304
+ */
305
+ login(options?: {
306
+ onDeviceCode?: (response: DeviceCodeResponse) => void;
307
+ onWaiting?: () => void;
308
+ }): Promise<TokenResponse>;
309
+ private sleep;
310
+ }
311
+
312
+ export { type AdapterConfig, type AdapterEvents, ArtyfactsClient, type ArtyfactsConfig, type ClaimResult, ClaudeAdapter, ClaudeRunner, type ClaudeRunnerConfig, type CompleteResult, DeviceAuth, type DeviceCodeResponse, type RunningTask, type StoredCredentials, type Task, type TaskResult, type TokenResponse };
@@ -0,0 +1,312 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ChildProcess } from 'child_process';
3
+
4
+ /**
5
+ * Artyfacts API Client (Simplified)
6
+ *
7
+ * Handles communication with the Artyfacts API for task management.
8
+ */
9
+ interface ArtyfactsConfig {
10
+ apiKey: string;
11
+ baseUrl?: string;
12
+ agentId?: string;
13
+ }
14
+ interface Task {
15
+ id: string;
16
+ sectionId: string;
17
+ heading: string;
18
+ content: string;
19
+ artifactId: string;
20
+ artifactTitle: string;
21
+ artifactUrl: string;
22
+ priority: 1 | 2 | 3;
23
+ dependsOn: string[];
24
+ createdAt: string;
25
+ }
26
+ interface ClaimResult {
27
+ success: boolean;
28
+ task: Task & {
29
+ claimedAt: string;
30
+ claimedBy: string;
31
+ };
32
+ }
33
+ interface CompleteResult {
34
+ success: boolean;
35
+ unblockedTasks: string[];
36
+ }
37
+ declare class ArtyfactsClient {
38
+ private config;
39
+ constructor(config: ArtyfactsConfig);
40
+ private fetch;
41
+ /**
42
+ * Get claimable tasks from the queue
43
+ */
44
+ getTaskQueue(options?: {
45
+ limit?: number;
46
+ }): Promise<Task[]>;
47
+ /**
48
+ * Claim a task
49
+ */
50
+ claimTask(taskId: string): Promise<ClaimResult>;
51
+ /**
52
+ * Complete a task
53
+ */
54
+ completeTask(taskId: string, options?: {
55
+ outputUrl?: string;
56
+ summary?: string;
57
+ }): Promise<CompleteResult>;
58
+ /**
59
+ * Report task as blocked
60
+ */
61
+ blockTask(taskId: string, reason: string): Promise<void>;
62
+ /**
63
+ * Get current user/org info
64
+ */
65
+ getMe(): Promise<{
66
+ id: string;
67
+ name: string;
68
+ orgId: string;
69
+ }>;
70
+ }
71
+
72
+ /**
73
+ * Claude Code Runner
74
+ *
75
+ * Spawns and manages Claude Code CLI processes for task execution.
76
+ */
77
+
78
+ interface ClaudeRunnerConfig {
79
+ /** Path to claude CLI (default: 'claude') */
80
+ claudePath?: string;
81
+ /** Model to use (default: 'sonnet') */
82
+ model?: string;
83
+ /** Working directory for Claude */
84
+ cwd?: string;
85
+ /** Timeout in ms (default: 5 minutes) */
86
+ timeoutMs?: number;
87
+ }
88
+ interface TaskResult {
89
+ success: boolean;
90
+ output: string;
91
+ error?: string;
92
+ exitCode: number | null;
93
+ durationMs: number;
94
+ }
95
+ interface RunningTask {
96
+ taskId: string;
97
+ process: ChildProcess;
98
+ startedAt: Date;
99
+ promise: Promise<TaskResult>;
100
+ }
101
+ declare class ClaudeRunner extends EventEmitter {
102
+ private config;
103
+ private runningTasks;
104
+ constructor(config?: ClaudeRunnerConfig);
105
+ /**
106
+ * Check if Claude Code is installed and authenticated
107
+ */
108
+ checkInstalled(): Promise<{
109
+ installed: boolean;
110
+ authenticated: boolean;
111
+ version?: string;
112
+ error?: string;
113
+ }>;
114
+ /**
115
+ * Run a task with Claude Code
116
+ */
117
+ runTask(taskId: string, prompt: string, options?: {
118
+ cwd?: string;
119
+ model?: string;
120
+ timeoutMs?: number;
121
+ }): Promise<TaskResult>;
122
+ /**
123
+ * Run a raw claude command
124
+ */
125
+ private runCommand;
126
+ /**
127
+ * Cancel a running task
128
+ */
129
+ cancelTask(taskId: string): boolean;
130
+ /**
131
+ * Get count of running tasks
132
+ */
133
+ getRunningCount(): number;
134
+ /**
135
+ * Cancel all running tasks
136
+ */
137
+ cancelAll(): void;
138
+ }
139
+
140
+ /**
141
+ * Claude Adapter
142
+ *
143
+ * Main orchestration class that:
144
+ * 1. Polls Artyfacts for claimable tasks
145
+ * 2. Spawns Claude Code to execute them
146
+ * 3. Reports results back to Artyfacts
147
+ */
148
+
149
+ interface AdapterConfig {
150
+ /** Artyfacts API key */
151
+ apiKey: string;
152
+ /** Artyfacts base URL */
153
+ baseUrl?: string;
154
+ /** Agent ID for attribution */
155
+ agentId?: string;
156
+ /** Poll interval in ms (default: 30s) */
157
+ pollIntervalMs?: number;
158
+ /** Max concurrent tasks (default: 1) */
159
+ maxConcurrent?: number;
160
+ /** Claude model to use (default: 'sonnet') */
161
+ model?: string;
162
+ /** Working directory for Claude */
163
+ cwd?: string;
164
+ }
165
+ interface AdapterEvents {
166
+ 'started': () => void;
167
+ 'stopped': () => void;
168
+ 'poll': (tasks: Task[]) => void;
169
+ 'task:claimed': (task: Task) => void;
170
+ 'task:running': (task: Task) => void;
171
+ 'task:completed': (task: Task, result: TaskResult) => void;
172
+ 'task:failed': (task: Task, error: string) => void;
173
+ 'error': (error: Error) => void;
174
+ }
175
+ declare class ClaudeAdapter extends EventEmitter {
176
+ private config;
177
+ private client;
178
+ private runner;
179
+ private running;
180
+ private pollTimer;
181
+ private activeTasks;
182
+ constructor(config: AdapterConfig);
183
+ /**
184
+ * Check if Claude Code is ready
185
+ */
186
+ checkReady(): Promise<{
187
+ ready: boolean;
188
+ error?: string;
189
+ }>;
190
+ /**
191
+ * Start the adapter
192
+ */
193
+ start(): Promise<void>;
194
+ /**
195
+ * Stop the adapter
196
+ */
197
+ stop(): Promise<void>;
198
+ /**
199
+ * Poll for and execute tasks
200
+ */
201
+ private poll;
202
+ /**
203
+ * Execute a single task
204
+ */
205
+ private executeTask;
206
+ /**
207
+ * Build a prompt for Claude from the task
208
+ */
209
+ private buildPrompt;
210
+ /**
211
+ * Extract a summary from Claude's output
212
+ */
213
+ private extractSummary;
214
+ /**
215
+ * Check if running
216
+ */
217
+ isRunning(): boolean;
218
+ /**
219
+ * Get stats
220
+ */
221
+ getStats(): {
222
+ running: boolean;
223
+ activeTasks: number;
224
+ maxConcurrent: number;
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Device Authorization Flow
230
+ *
231
+ * Handles browser-based authentication for the CLI.
232
+ * No API keys to copy — just run the CLI and click authorize.
233
+ */
234
+ interface DeviceCodeResponse {
235
+ deviceCode: string;
236
+ userCode: string;
237
+ verificationUri: string;
238
+ expiresIn: number;
239
+ interval: number;
240
+ }
241
+ interface TokenResponse {
242
+ accessToken: string;
243
+ refreshToken?: string;
244
+ expiresAt?: number;
245
+ user: {
246
+ id: string;
247
+ email: string;
248
+ name?: string;
249
+ orgId: string;
250
+ };
251
+ }
252
+ interface StoredCredentials {
253
+ accessToken: string;
254
+ refreshToken?: string;
255
+ expiresAt?: number;
256
+ user: {
257
+ id: string;
258
+ email: string;
259
+ name?: string;
260
+ orgId: string;
261
+ };
262
+ savedAt: string;
263
+ }
264
+ declare class DeviceAuth {
265
+ private baseUrl;
266
+ private credentialsPath;
267
+ constructor(options?: {
268
+ baseUrl?: string;
269
+ });
270
+ /**
271
+ * Check if we have stored credentials
272
+ */
273
+ hasCredentials(): boolean;
274
+ /**
275
+ * Get stored credentials
276
+ */
277
+ getCredentials(): StoredCredentials | null;
278
+ /**
279
+ * Get access token (for API calls)
280
+ */
281
+ getAccessToken(): string | null;
282
+ /**
283
+ * Clear stored credentials (logout)
284
+ */
285
+ logout(): void;
286
+ /**
287
+ * Start device authorization flow
288
+ */
289
+ startDeviceFlow(): Promise<DeviceCodeResponse>;
290
+ /**
291
+ * Poll for token after user authorizes
292
+ */
293
+ pollForToken(deviceCode: string, interval: number, expiresIn: number): Promise<TokenResponse>;
294
+ /**
295
+ * Save credentials to disk
296
+ */
297
+ saveCredentials(token: TokenResponse): void;
298
+ /**
299
+ * Open URL in browser
300
+ */
301
+ openBrowser(url: string): void;
302
+ /**
303
+ * Full login flow
304
+ */
305
+ login(options?: {
306
+ onDeviceCode?: (response: DeviceCodeResponse) => void;
307
+ onWaiting?: () => void;
308
+ }): Promise<TokenResponse>;
309
+ private sleep;
310
+ }
311
+
312
+ export { type AdapterConfig, type AdapterEvents, ArtyfactsClient, type ArtyfactsConfig, type ClaimResult, ClaudeAdapter, ClaudeRunner, type ClaudeRunnerConfig, type CompleteResult, DeviceAuth, type DeviceCodeResponse, type RunningTask, type StoredCredentials, type Task, type TaskResult, type TokenResponse };