@artyfacts/claude 1.0.0 → 1.1.1
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.
- package/README.md +159 -78
- package/bin/artyfacts-claude.js +38 -0
- package/dist/chunk-365PEWTO.mjs +567 -0
- package/dist/chunk-4RRGLYN6.mjs +567 -0
- package/dist/chunk-QKDOZSBI.mjs +571 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +791 -0
- package/dist/cli.mjs +189 -726
- package/dist/index.d.mts +178 -249
- package/dist/index.d.ts +178 -249
- package/dist/index.js +472 -486
- package/dist/index.mjs +22 -584
- package/package.json +27 -16
- package/src/auth.ts +350 -0
- package/src/cli.ts +344 -0
- package/src/executor.ts +293 -0
- package/src/index.ts +86 -0
- package/src/listener.ts +313 -0
- package/tsconfig.json +20 -0
- package/bin/cli.js +0 -2
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,312 +1,241 @@
|
|
|
1
|
-
import { EventEmitter } from 'events';
|
|
2
|
-
import { ChildProcess } from 'child_process';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
|
-
* Artyfacts
|
|
2
|
+
* Device authentication flow for Artyfacts Claude adapter
|
|
6
3
|
*
|
|
7
|
-
*
|
|
4
|
+
* Implements device auth flow:
|
|
5
|
+
* 1. Request device code from Artyfacts
|
|
6
|
+
* 2. Display code for user to enter on website
|
|
7
|
+
* 3. Poll for completion
|
|
8
|
+
* 4. Store credentials locally
|
|
8
9
|
*/
|
|
9
|
-
interface
|
|
10
|
+
interface Credentials {
|
|
10
11
|
apiKey: string;
|
|
11
|
-
|
|
12
|
-
|
|
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;
|
|
12
|
+
agentId: string;
|
|
13
|
+
agentName?: string;
|
|
14
|
+
expiresAt?: string;
|
|
25
15
|
}
|
|
26
|
-
interface
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
interface CompleteResult {
|
|
34
|
-
success: boolean;
|
|
35
|
-
unblockedTasks: string[];
|
|
16
|
+
interface DeviceAuthResponse {
|
|
17
|
+
deviceCode: string;
|
|
18
|
+
userCode: string;
|
|
19
|
+
verificationUri: string;
|
|
20
|
+
expiresIn: number;
|
|
21
|
+
interval: number;
|
|
36
22
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
}>;
|
|
23
|
+
interface TokenResponse {
|
|
24
|
+
apiKey: string;
|
|
25
|
+
agentId: string;
|
|
26
|
+
agentName?: string;
|
|
27
|
+
expiresAt?: string;
|
|
70
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Load stored credentials from disk
|
|
31
|
+
*/
|
|
32
|
+
declare function loadCredentials(): Credentials | null;
|
|
33
|
+
/**
|
|
34
|
+
* Save credentials to disk
|
|
35
|
+
*/
|
|
36
|
+
declare function saveCredentials(credentials: Credentials): void;
|
|
37
|
+
/**
|
|
38
|
+
* Clear stored credentials
|
|
39
|
+
*/
|
|
40
|
+
declare function clearCredentials(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Run the device authentication flow
|
|
43
|
+
*/
|
|
44
|
+
declare function runDeviceAuth(baseUrl?: string): Promise<Credentials>;
|
|
45
|
+
/**
|
|
46
|
+
* Prompt user for manual API key entry
|
|
47
|
+
*/
|
|
48
|
+
declare function promptForApiKey(): Promise<Credentials>;
|
|
49
|
+
/**
|
|
50
|
+
* Get credentials, running auth flow if needed
|
|
51
|
+
*/
|
|
52
|
+
declare function getCredentials(options?: {
|
|
53
|
+
baseUrl?: string;
|
|
54
|
+
forceAuth?: boolean;
|
|
55
|
+
}): Promise<Credentials>;
|
|
71
56
|
|
|
72
57
|
/**
|
|
73
|
-
* Claude Code
|
|
58
|
+
* Claude Code executor for Artyfacts tasks
|
|
74
59
|
*
|
|
75
|
-
*
|
|
60
|
+
* Executes tasks by shelling out to the Claude Code CLI (claude).
|
|
61
|
+
* This uses the user's existing Claude Code authentication - no separate API key needed.
|
|
76
62
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
63
|
+
interface TaskContext {
|
|
64
|
+
/** Task ID (section ID) */
|
|
65
|
+
taskId: string;
|
|
66
|
+
/** Task heading/title */
|
|
67
|
+
heading: string;
|
|
68
|
+
/** Task content/description */
|
|
69
|
+
content: string;
|
|
70
|
+
/** Parent artifact ID */
|
|
71
|
+
artifactId: string;
|
|
72
|
+
/** Parent artifact title */
|
|
73
|
+
artifactTitle?: string;
|
|
74
|
+
/** Task priority (1=high, 2=medium, 3=low) */
|
|
75
|
+
priority?: number;
|
|
76
|
+
/** Additional context */
|
|
77
|
+
context?: Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
interface ExecutionResult {
|
|
80
|
+
/** Whether execution was successful */
|
|
89
81
|
success: boolean;
|
|
82
|
+
/** The generated output */
|
|
90
83
|
output: string;
|
|
84
|
+
/** Summary of what was accomplished */
|
|
85
|
+
summary: string;
|
|
86
|
+
/** Any error message if failed */
|
|
91
87
|
error?: string;
|
|
92
|
-
exitCode: number | null;
|
|
93
|
-
durationMs: number;
|
|
94
88
|
}
|
|
95
|
-
interface
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
interface ExecutorConfig {
|
|
90
|
+
/** Path to claude CLI (default: 'claude') */
|
|
91
|
+
claudePath?: string;
|
|
92
|
+
/** Timeout in milliseconds (default: 5 minutes) */
|
|
93
|
+
timeout?: number;
|
|
94
|
+
/** System prompt prefix */
|
|
95
|
+
systemPromptPrefix?: string;
|
|
100
96
|
}
|
|
101
|
-
declare class
|
|
97
|
+
declare class ClaudeExecutor {
|
|
102
98
|
private config;
|
|
103
|
-
|
|
104
|
-
constructor(config?: ClaudeRunnerConfig);
|
|
99
|
+
constructor(config?: ExecutorConfig);
|
|
105
100
|
/**
|
|
106
|
-
*
|
|
101
|
+
* Execute a task using Claude Code CLI
|
|
107
102
|
*/
|
|
108
|
-
|
|
109
|
-
installed: boolean;
|
|
110
|
-
authenticated: boolean;
|
|
111
|
-
version?: string;
|
|
112
|
-
error?: string;
|
|
113
|
-
}>;
|
|
103
|
+
execute(task: TaskContext): Promise<ExecutionResult>;
|
|
114
104
|
/**
|
|
115
|
-
* Run
|
|
105
|
+
* Run Claude Code CLI with the given prompt
|
|
116
106
|
*/
|
|
117
|
-
|
|
118
|
-
cwd?: string;
|
|
119
|
-
model?: string;
|
|
120
|
-
timeoutMs?: number;
|
|
121
|
-
}): Promise<TaskResult>;
|
|
107
|
+
private runClaude;
|
|
122
108
|
/**
|
|
123
|
-
*
|
|
109
|
+
* Build the task prompt
|
|
124
110
|
*/
|
|
125
|
-
private
|
|
111
|
+
private buildTaskPrompt;
|
|
126
112
|
/**
|
|
127
|
-
*
|
|
113
|
+
* Parse the response to extract output and summary
|
|
128
114
|
*/
|
|
129
|
-
|
|
115
|
+
private parseResponse;
|
|
130
116
|
/**
|
|
131
|
-
*
|
|
117
|
+
* Test that Claude Code CLI is available and working
|
|
132
118
|
*/
|
|
133
|
-
|
|
119
|
+
testConnection(): Promise<boolean>;
|
|
134
120
|
/**
|
|
135
|
-
*
|
|
121
|
+
* Check if Claude Code CLI is installed
|
|
136
122
|
*/
|
|
137
|
-
|
|
123
|
+
isInstalled(): Promise<boolean>;
|
|
138
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Create a Claude executor
|
|
127
|
+
*/
|
|
128
|
+
declare function createExecutor(config?: ExecutorConfig): ClaudeExecutor;
|
|
139
129
|
|
|
140
130
|
/**
|
|
141
|
-
*
|
|
131
|
+
* SSE Event Listener for Artyfacts task assignments
|
|
142
132
|
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* 2. Spawns Claude Code to execute them
|
|
146
|
-
* 3. Reports results back to Artyfacts
|
|
133
|
+
* Connects to the Artyfacts SSE stream and listens for task_assigned events.
|
|
134
|
+
* Uses EventSource for automatic reconnection handling.
|
|
147
135
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
136
|
+
interface TaskAssignedEvent {
|
|
137
|
+
type: 'task_assigned';
|
|
138
|
+
timestamp: string;
|
|
139
|
+
data: {
|
|
140
|
+
taskId: string;
|
|
141
|
+
sectionId: string;
|
|
142
|
+
heading: string;
|
|
143
|
+
content: string;
|
|
144
|
+
artifactId: string;
|
|
145
|
+
artifactTitle?: string;
|
|
146
|
+
priority?: number;
|
|
147
|
+
assignedTo: string;
|
|
148
|
+
assignedAt: string;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
interface HeartbeatEvent {
|
|
152
|
+
type: 'heartbeat';
|
|
153
|
+
timestamp: string;
|
|
154
|
+
}
|
|
155
|
+
interface ConnectedEvent {
|
|
156
|
+
type: 'connected';
|
|
157
|
+
timestamp: string;
|
|
158
|
+
data: {
|
|
159
|
+
agentId: string;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
type ArtyfactsEvent = TaskAssignedEvent | HeartbeatEvent | ConnectedEvent | {
|
|
163
|
+
type: string;
|
|
164
|
+
timestamp: string;
|
|
165
|
+
data?: Record<string, unknown>;
|
|
166
|
+
};
|
|
167
|
+
type EventCallback<T extends ArtyfactsEvent = ArtyfactsEvent> = (event: T) => void | Promise<void>;
|
|
168
|
+
interface ListenerConfig {
|
|
150
169
|
/** Artyfacts API key */
|
|
151
170
|
apiKey: string;
|
|
152
|
-
/**
|
|
171
|
+
/** Agent ID to listen for */
|
|
172
|
+
agentId: string;
|
|
173
|
+
/** Base URL for Artyfacts API */
|
|
153
174
|
baseUrl?: string;
|
|
154
|
-
/**
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
|
|
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;
|
|
175
|
+
/** Callback for state changes */
|
|
176
|
+
onStateChange?: (state: ConnectionState) => void;
|
|
177
|
+
/** Callback for errors */
|
|
178
|
+
onError?: (error: Error) => void;
|
|
174
179
|
}
|
|
175
|
-
|
|
180
|
+
type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
|
|
181
|
+
declare class ArtyfactsListener {
|
|
176
182
|
private config;
|
|
177
|
-
private
|
|
178
|
-
private
|
|
179
|
-
private
|
|
180
|
-
private
|
|
181
|
-
private
|
|
182
|
-
|
|
183
|
+
private eventSource;
|
|
184
|
+
private callbacks;
|
|
185
|
+
private allCallbacks;
|
|
186
|
+
private state;
|
|
187
|
+
private reconnectAttempts;
|
|
188
|
+
private maxReconnectAttempts;
|
|
189
|
+
private reconnectDelay;
|
|
190
|
+
constructor(config: ListenerConfig);
|
|
183
191
|
/**
|
|
184
|
-
*
|
|
192
|
+
* Get current connection state
|
|
185
193
|
*/
|
|
186
|
-
|
|
187
|
-
ready: boolean;
|
|
188
|
-
error?: string;
|
|
189
|
-
}>;
|
|
194
|
+
get connectionState(): ConnectionState;
|
|
190
195
|
/**
|
|
191
|
-
*
|
|
196
|
+
* Check if connected
|
|
192
197
|
*/
|
|
193
|
-
|
|
198
|
+
get isConnected(): boolean;
|
|
194
199
|
/**
|
|
195
|
-
*
|
|
200
|
+
* Subscribe to all events
|
|
196
201
|
*/
|
|
197
|
-
|
|
202
|
+
subscribe(callback: EventCallback): () => void;
|
|
198
203
|
/**
|
|
199
|
-
*
|
|
204
|
+
* Subscribe to a specific event type
|
|
200
205
|
*/
|
|
201
|
-
|
|
206
|
+
on<T extends ArtyfactsEvent>(type: string, callback: EventCallback<T>): () => void;
|
|
202
207
|
/**
|
|
203
|
-
*
|
|
208
|
+
* Connect to the SSE stream
|
|
204
209
|
*/
|
|
205
|
-
|
|
210
|
+
connect(): void;
|
|
206
211
|
/**
|
|
207
|
-
*
|
|
212
|
+
* Disconnect from the SSE stream
|
|
208
213
|
*/
|
|
209
|
-
|
|
214
|
+
disconnect(): void;
|
|
210
215
|
/**
|
|
211
|
-
*
|
|
216
|
+
* Reconnect to the SSE stream
|
|
212
217
|
*/
|
|
213
|
-
|
|
218
|
+
reconnect(): void;
|
|
214
219
|
/**
|
|
215
|
-
*
|
|
220
|
+
* Handle incoming SSE message
|
|
216
221
|
*/
|
|
217
|
-
|
|
222
|
+
private handleMessage;
|
|
218
223
|
/**
|
|
219
|
-
*
|
|
224
|
+
* Safely call a callback, handling async and errors
|
|
220
225
|
*/
|
|
221
|
-
|
|
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;
|
|
226
|
+
private safeCallCallback;
|
|
274
227
|
/**
|
|
275
|
-
*
|
|
228
|
+
* Handle SSE error
|
|
276
229
|
*/
|
|
277
|
-
|
|
230
|
+
private handleError;
|
|
278
231
|
/**
|
|
279
|
-
*
|
|
232
|
+
* Update connection state
|
|
280
233
|
*/
|
|
281
|
-
|
|
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;
|
|
234
|
+
private setState;
|
|
310
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Create an Artyfacts event listener
|
|
238
|
+
*/
|
|
239
|
+
declare function createListener(config: ListenerConfig): ArtyfactsListener;
|
|
311
240
|
|
|
312
|
-
export { type
|
|
241
|
+
export { type ArtyfactsEvent, ArtyfactsListener, ClaudeExecutor, type ConnectedEvent, type ConnectionState, type Credentials, type DeviceAuthResponse, type EventCallback, type ExecutionResult, type ExecutorConfig, type HeartbeatEvent, type ListenerConfig, type TaskAssignedEvent, type TaskContext, type TokenResponse, clearCredentials, createExecutor, createListener, getCredentials, loadCredentials, promptForApiKey, runDeviceAuth, saveCredentials };
|