@nicmeriano/spool-server 0.0.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/dist/bin.js +2184 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +426 -0
- package/dist/index.js +2195 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author - simple for MVP, extensible for future collaboration
|
|
3
|
+
*/
|
|
4
|
+
interface Author {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
avatar?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Attachment for comments (images only for MVP)
|
|
11
|
+
*/
|
|
12
|
+
interface Attachment {
|
|
13
|
+
id: string;
|
|
14
|
+
filename: string;
|
|
15
|
+
mimeType: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
|
|
16
|
+
/** Size in bytes */
|
|
17
|
+
size: number;
|
|
18
|
+
/** Base64 data URL */
|
|
19
|
+
dataUrl: string;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Comment within an annotation thread
|
|
24
|
+
*/
|
|
25
|
+
interface Comment {
|
|
26
|
+
id: string;
|
|
27
|
+
content: string;
|
|
28
|
+
author: Author;
|
|
29
|
+
createdAt: string;
|
|
30
|
+
/** Image attachments (optional) */
|
|
31
|
+
attachments?: Attachment[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Annotation status
|
|
35
|
+
* - open (blue bubble): Annotation created, Claude should address when submitted
|
|
36
|
+
* - in_progress (spinner): Claude is actively working on it
|
|
37
|
+
* - done (green bubble): Claude has implemented the change
|
|
38
|
+
*/
|
|
39
|
+
type AnnotationStatus = 'open' | 'in_progress' | 'done';
|
|
40
|
+
/**
|
|
41
|
+
* Element information captured during annotation
|
|
42
|
+
*/
|
|
43
|
+
interface ElementInfo {
|
|
44
|
+
/** CSS selector that uniquely identifies the element */
|
|
45
|
+
selector: string;
|
|
46
|
+
/** HTML tag name (e.g., "button", "div") */
|
|
47
|
+
tagName: string;
|
|
48
|
+
/** CSS class names */
|
|
49
|
+
className: string;
|
|
50
|
+
/** Element ID if present */
|
|
51
|
+
id?: string;
|
|
52
|
+
/** Text content (truncated) */
|
|
53
|
+
textContent?: string;
|
|
54
|
+
/** React component name if available */
|
|
55
|
+
componentName?: string;
|
|
56
|
+
/** Source file path of the React component */
|
|
57
|
+
componentFile?: string;
|
|
58
|
+
/** Line number in the source file */
|
|
59
|
+
lineNumber?: number;
|
|
60
|
+
/** React component props (if available) */
|
|
61
|
+
props?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Core annotation with thread support
|
|
65
|
+
*/
|
|
66
|
+
interface Annotation {
|
|
67
|
+
id: string;
|
|
68
|
+
/** Primary CSS selector to find element (for backward compatibility) */
|
|
69
|
+
selector: string;
|
|
70
|
+
/** Additional CSS selectors for multi-element annotations */
|
|
71
|
+
selectors?: string[];
|
|
72
|
+
/** Viewport-relative anchor point */
|
|
73
|
+
position: {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
};
|
|
77
|
+
/** 3-state workflow status */
|
|
78
|
+
status: AnnotationStatus;
|
|
79
|
+
createdAt: string;
|
|
80
|
+
createdBy: Author;
|
|
81
|
+
/** When Claude completed it */
|
|
82
|
+
doneAt?: string;
|
|
83
|
+
/** Claude marks this when done */
|
|
84
|
+
doneBy?: Author;
|
|
85
|
+
/** Git commit SHA for this annotation's changes (enables per-annotation revert) */
|
|
86
|
+
commitSha?: string;
|
|
87
|
+
/** Thread of comments */
|
|
88
|
+
comments: Comment[];
|
|
89
|
+
/** Primary element metadata (for backward compatibility) */
|
|
90
|
+
element: ElementInfo;
|
|
91
|
+
/** Additional element metadata for multi-element annotations */
|
|
92
|
+
elements?: ElementInfo[];
|
|
93
|
+
/** True for page-level comments (not tied to any element) */
|
|
94
|
+
isPageLevel?: boolean;
|
|
95
|
+
/** Exact click position for bubble placement (viewport + scroll offset) */
|
|
96
|
+
clickPosition?: {
|
|
97
|
+
x: number;
|
|
98
|
+
y: number;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Default author for Claude
|
|
103
|
+
*/
|
|
104
|
+
declare const CLAUDE_AUTHOR: Author;
|
|
105
|
+
declare const CLAUDE_MODEL = "claude-opus-4-5-20251101";
|
|
106
|
+
/**
|
|
107
|
+
* Pending change status
|
|
108
|
+
*/
|
|
109
|
+
type PendingChangeStatus = 'pending' | 'in_progress' | 'done' | 'error';
|
|
110
|
+
/**
|
|
111
|
+
* Base interface for all pending changes
|
|
112
|
+
*/
|
|
113
|
+
interface PendingChangeBase {
|
|
114
|
+
id: string;
|
|
115
|
+
selector: string;
|
|
116
|
+
element: ElementInfo;
|
|
117
|
+
status: PendingChangeStatus;
|
|
118
|
+
createdAt: string;
|
|
119
|
+
errorMessage?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Variant data
|
|
123
|
+
*/
|
|
124
|
+
interface Variant {
|
|
125
|
+
html: string;
|
|
126
|
+
metadata?: Record<string, unknown>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A pending variant change
|
|
130
|
+
*/
|
|
131
|
+
interface VariantChange extends PendingChangeBase {
|
|
132
|
+
type: 'variant';
|
|
133
|
+
prompt: string;
|
|
134
|
+
variants: Variant[];
|
|
135
|
+
selectedVariantIndex: number;
|
|
136
|
+
originalHtml: string;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* A pending style change
|
|
140
|
+
*/
|
|
141
|
+
interface StyleChange extends PendingChangeBase {
|
|
142
|
+
type: 'style';
|
|
143
|
+
styles: Record<string, string>;
|
|
144
|
+
originalStyles: Record<string, string>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* A pending note change
|
|
148
|
+
*/
|
|
149
|
+
interface NoteChange extends PendingChangeBase {
|
|
150
|
+
type: 'note';
|
|
151
|
+
content: string;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Union type for all pending changes
|
|
155
|
+
*/
|
|
156
|
+
type PendingChange = VariantChange | StyleChange | NoteChange;
|
|
157
|
+
/**
|
|
158
|
+
* Page-specific annotation data
|
|
159
|
+
*/
|
|
160
|
+
interface PageState {
|
|
161
|
+
url: string;
|
|
162
|
+
annotations: Annotation[];
|
|
163
|
+
pendingChanges?: PendingChange[];
|
|
164
|
+
lastModified: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Root state stored in .spool/state.json
|
|
168
|
+
*/
|
|
169
|
+
interface SpoolState {
|
|
170
|
+
appId: string;
|
|
171
|
+
status: 'idle' | 'generating';
|
|
172
|
+
currentTaskId: string | null;
|
|
173
|
+
pages: Record<string, PageState>;
|
|
174
|
+
/** Chat messages persisted across hot reloads */
|
|
175
|
+
chatMessages?: ChatMessageData[];
|
|
176
|
+
/** App URL reported by the Vite plugin (dynamic port resolution) */
|
|
177
|
+
appUrl?: string;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Task payload for addressing annotations
|
|
181
|
+
*/
|
|
182
|
+
interface TaskPayload {
|
|
183
|
+
action: 'address';
|
|
184
|
+
/** Optional: specific annotation IDs, or address all ready if omitted */
|
|
185
|
+
annotationIds?: string[];
|
|
186
|
+
/** Optional: additional user feedback/context */
|
|
187
|
+
feedback?: string;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Task result on completion
|
|
191
|
+
*/
|
|
192
|
+
interface TaskResult {
|
|
193
|
+
success: boolean;
|
|
194
|
+
annotationsAddressed: number;
|
|
195
|
+
message?: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Error details
|
|
199
|
+
*/
|
|
200
|
+
interface TaskError {
|
|
201
|
+
code: string;
|
|
202
|
+
message: string;
|
|
203
|
+
}
|
|
204
|
+
interface TaskSubmitMessage {
|
|
205
|
+
type: 'task:submit';
|
|
206
|
+
id: string;
|
|
207
|
+
payload: TaskPayload;
|
|
208
|
+
}
|
|
209
|
+
interface TaskCancelMessage {
|
|
210
|
+
type: 'task:cancel';
|
|
211
|
+
taskId: string;
|
|
212
|
+
}
|
|
213
|
+
interface AnnotationCreateMessage {
|
|
214
|
+
type: 'annotation:create';
|
|
215
|
+
url: string;
|
|
216
|
+
annotation: Annotation;
|
|
217
|
+
}
|
|
218
|
+
interface AnnotationUpdateMessage {
|
|
219
|
+
type: 'annotation:update';
|
|
220
|
+
id: string;
|
|
221
|
+
changes: Partial<Annotation>;
|
|
222
|
+
}
|
|
223
|
+
interface AnnotationDeleteMessage {
|
|
224
|
+
type: 'annotation:delete';
|
|
225
|
+
id: string;
|
|
226
|
+
}
|
|
227
|
+
interface AnnotationRevertMessage {
|
|
228
|
+
type: 'annotation:revert';
|
|
229
|
+
id: string;
|
|
230
|
+
}
|
|
231
|
+
interface ChangeAddMessage {
|
|
232
|
+
type: 'change:add';
|
|
233
|
+
url: string;
|
|
234
|
+
change: PendingChange;
|
|
235
|
+
}
|
|
236
|
+
interface ChangeRemoveMessage {
|
|
237
|
+
type: 'change:remove';
|
|
238
|
+
id: string;
|
|
239
|
+
}
|
|
240
|
+
interface ChangeApplyAllMessage {
|
|
241
|
+
type: 'change:apply_all';
|
|
242
|
+
url: string;
|
|
243
|
+
}
|
|
244
|
+
interface ChangeApplyMessage {
|
|
245
|
+
type: 'change:apply';
|
|
246
|
+
url: string;
|
|
247
|
+
changeId: string;
|
|
248
|
+
}
|
|
249
|
+
interface ChangeApplyDirectMessage {
|
|
250
|
+
type: 'change:apply_direct';
|
|
251
|
+
change: PendingChange;
|
|
252
|
+
}
|
|
253
|
+
interface VariantGenerateMessage {
|
|
254
|
+
type: 'variant:generate';
|
|
255
|
+
id: string;
|
|
256
|
+
payload: {
|
|
257
|
+
selector: string;
|
|
258
|
+
prompt: string;
|
|
259
|
+
elementHtml: string;
|
|
260
|
+
elementInfo: {
|
|
261
|
+
tagName: string;
|
|
262
|
+
componentName?: string;
|
|
263
|
+
componentFile?: string;
|
|
264
|
+
};
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Element reference included in a chat message
|
|
269
|
+
*/
|
|
270
|
+
interface ChatElementReference {
|
|
271
|
+
id: string;
|
|
272
|
+
selector: string;
|
|
273
|
+
element: ElementInfo;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Chat message data for server-side persistence
|
|
277
|
+
*/
|
|
278
|
+
interface ChatMessageData {
|
|
279
|
+
id: string;
|
|
280
|
+
role: 'user' | 'assistant';
|
|
281
|
+
content: string;
|
|
282
|
+
elementRefs?: ChatElementReference[];
|
|
283
|
+
timestamp: string;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* A message in the chat conversation
|
|
287
|
+
*/
|
|
288
|
+
interface ChatMessageData {
|
|
289
|
+
id: string;
|
|
290
|
+
role: 'user' | 'assistant';
|
|
291
|
+
content: string;
|
|
292
|
+
elementRefs?: ChatElementReference[];
|
|
293
|
+
timestamp: string;
|
|
294
|
+
}
|
|
295
|
+
interface ChatSendMessage {
|
|
296
|
+
type: 'chat:send';
|
|
297
|
+
id: string;
|
|
298
|
+
content: string;
|
|
299
|
+
elementRefs: ChatElementReference[];
|
|
300
|
+
history: ChatMessageData[];
|
|
301
|
+
}
|
|
302
|
+
interface ChatCancelMessage {
|
|
303
|
+
type: 'chat:cancel';
|
|
304
|
+
messageId: string;
|
|
305
|
+
}
|
|
306
|
+
interface ChatHistoryUpdateMessage {
|
|
307
|
+
type: 'chat:history:update';
|
|
308
|
+
messages: ChatMessageData[];
|
|
309
|
+
}
|
|
310
|
+
type ClientMessage = TaskSubmitMessage | TaskCancelMessage | AnnotationCreateMessage | AnnotationUpdateMessage | AnnotationDeleteMessage | AnnotationRevertMessage | ChangeAddMessage | ChangeRemoveMessage | ChangeApplyAllMessage | ChangeApplyMessage | ChangeApplyDirectMessage | VariantGenerateMessage | ChatSendMessage | ChatCancelMessage | ChatHistoryUpdateMessage;
|
|
311
|
+
interface TaskAckMessage {
|
|
312
|
+
type: 'task:ack';
|
|
313
|
+
taskId: string;
|
|
314
|
+
status: 'started';
|
|
315
|
+
}
|
|
316
|
+
interface StreamTextMessage {
|
|
317
|
+
type: 'stream:text';
|
|
318
|
+
taskId: string;
|
|
319
|
+
content: string;
|
|
320
|
+
isPartial: boolean;
|
|
321
|
+
}
|
|
322
|
+
interface StreamToolCallMessage {
|
|
323
|
+
type: 'stream:tool_call';
|
|
324
|
+
taskId: string;
|
|
325
|
+
toolName: string;
|
|
326
|
+
toolInput: Record<string, unknown>;
|
|
327
|
+
}
|
|
328
|
+
interface StateUpdateMessage {
|
|
329
|
+
type: 'state:update';
|
|
330
|
+
taskId: string | null;
|
|
331
|
+
state: SpoolState;
|
|
332
|
+
}
|
|
333
|
+
interface TaskCompleteMessage {
|
|
334
|
+
type: 'task:complete';
|
|
335
|
+
taskId: string;
|
|
336
|
+
result: TaskResult;
|
|
337
|
+
}
|
|
338
|
+
interface TaskErrorMessage {
|
|
339
|
+
type: 'task:error';
|
|
340
|
+
taskId: string;
|
|
341
|
+
error: TaskError;
|
|
342
|
+
}
|
|
343
|
+
interface RevertResultMessage {
|
|
344
|
+
type: 'revert:result';
|
|
345
|
+
annotationId: string;
|
|
346
|
+
success: boolean;
|
|
347
|
+
error?: string;
|
|
348
|
+
}
|
|
349
|
+
interface AppUrlMessage {
|
|
350
|
+
type: 'app:url';
|
|
351
|
+
url: string;
|
|
352
|
+
}
|
|
353
|
+
interface ApplyProgressMessage {
|
|
354
|
+
type: 'apply:progress';
|
|
355
|
+
changeId: string;
|
|
356
|
+
status: 'in_progress' | 'done' | 'error';
|
|
357
|
+
error?: string;
|
|
358
|
+
}
|
|
359
|
+
interface ApplyCompleteMessage {
|
|
360
|
+
type: 'apply:complete';
|
|
361
|
+
success: boolean;
|
|
362
|
+
message?: string;
|
|
363
|
+
}
|
|
364
|
+
interface VariantResultMessage {
|
|
365
|
+
type: 'variant:result';
|
|
366
|
+
requestId: string;
|
|
367
|
+
variants: Variant[];
|
|
368
|
+
error?: string;
|
|
369
|
+
}
|
|
370
|
+
interface ChatAckMessage {
|
|
371
|
+
type: 'chat:ack';
|
|
372
|
+
messageId: string;
|
|
373
|
+
}
|
|
374
|
+
interface ChatStreamMessage {
|
|
375
|
+
type: 'chat:stream';
|
|
376
|
+
messageId: string;
|
|
377
|
+
content: string;
|
|
378
|
+
isPartial: boolean;
|
|
379
|
+
}
|
|
380
|
+
interface ChatToolCallMessage {
|
|
381
|
+
type: 'chat:tool_call';
|
|
382
|
+
messageId: string;
|
|
383
|
+
toolName: string;
|
|
384
|
+
toolInput: Record<string, unknown>;
|
|
385
|
+
}
|
|
386
|
+
interface ChatCompleteMessage {
|
|
387
|
+
type: 'chat:complete';
|
|
388
|
+
messageId: string;
|
|
389
|
+
success: boolean;
|
|
390
|
+
error?: string;
|
|
391
|
+
}
|
|
392
|
+
type ServerMessage = TaskAckMessage | StreamTextMessage | StreamToolCallMessage | StateUpdateMessage | TaskCompleteMessage | TaskErrorMessage | RevertResultMessage | ApplyProgressMessage | ApplyCompleteMessage | VariantResultMessage | ChatAckMessage | ChatStreamMessage | ChatToolCallMessage | ChatCompleteMessage | AppUrlMessage;
|
|
393
|
+
/**
|
|
394
|
+
* Create an empty state structure
|
|
395
|
+
*/
|
|
396
|
+
declare function createEmptyState(appId: string): SpoolState;
|
|
397
|
+
/**
|
|
398
|
+
* Get all annotations from state, optionally filtered by status
|
|
399
|
+
*/
|
|
400
|
+
declare function getAnnotationsFromState(state: SpoolState, filter?: {
|
|
401
|
+
status?: AnnotationStatus;
|
|
402
|
+
}): Annotation[];
|
|
403
|
+
/**
|
|
404
|
+
* Find an annotation by ID in state
|
|
405
|
+
*/
|
|
406
|
+
declare function findAnnotationInState(state: SpoolState, annotationId: string): {
|
|
407
|
+
annotation: Annotation;
|
|
408
|
+
pageUrl: string;
|
|
409
|
+
} | null;
|
|
410
|
+
/**
|
|
411
|
+
* Update an annotation in state (returns new state, immutable)
|
|
412
|
+
*/
|
|
413
|
+
declare function updateAnnotationInState(state: SpoolState, annotationId: string, updates: Partial<Annotation>): SpoolState;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Options for starting the server
|
|
417
|
+
*/
|
|
418
|
+
interface ServerOptions {
|
|
419
|
+
/** Port to listen on (default: 3142) */
|
|
420
|
+
port?: number;
|
|
421
|
+
/** Working directory for state file and agent (default: process.cwd()) */
|
|
422
|
+
cwd?: string;
|
|
423
|
+
}
|
|
424
|
+
declare function startServer(options?: ServerOptions): Promise<void>;
|
|
425
|
+
|
|
426
|
+
export { type Annotation, type AnnotationCreateMessage, type AnnotationDeleteMessage, type AnnotationRevertMessage, type AnnotationStatus, type AnnotationUpdateMessage, type AppUrlMessage, type ApplyCompleteMessage, type ApplyProgressMessage, type Attachment, type Author, CLAUDE_AUTHOR, CLAUDE_MODEL, type ChangeAddMessage, type ChangeApplyAllMessage, type ChangeApplyDirectMessage, type ChangeApplyMessage, type ChangeRemoveMessage, type ChatAckMessage, type ChatCancelMessage, type ChatCompleteMessage, type ChatElementReference, type ChatHistoryUpdateMessage, type ChatMessageData, type ChatSendMessage, type ChatStreamMessage, type ChatToolCallMessage, type ClientMessage, type Comment, type ElementInfo, type NoteChange, type PageState, type PendingChange, type PendingChangeBase, type PendingChangeStatus, type RevertResultMessage, type ServerMessage, type ServerOptions, type SpoolState, type StateUpdateMessage, type StreamTextMessage, type StreamToolCallMessage, type StyleChange, type TaskAckMessage, type TaskCancelMessage, type TaskCompleteMessage, type TaskError, type TaskErrorMessage, type TaskPayload, type TaskResult, type TaskSubmitMessage, type Variant, type VariantChange, type VariantGenerateMessage, type VariantResultMessage, createEmptyState, findAnnotationInState, getAnnotationsFromState, startServer, updateAnnotationInState };
|