artifact-cafe 0.0.14 → 0.0.15
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/index.js +713 -594
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -83,6 +83,19 @@ var artifactListResponseSchema = z.object({
|
|
|
83
83
|
artifacts: z.array(artifactListItemSchema)
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
+
// ../shared/src/agent-tokens.ts
|
|
87
|
+
import { z as z2 } from "zod";
|
|
88
|
+
var createAgentTokenSchema = z2.object({
|
|
89
|
+
externalId: z2.string().min(1).max(1024),
|
|
90
|
+
name: z2.string().trim().min(1).max(100).optional(),
|
|
91
|
+
ttlSeconds: z2.number().int().positive().max(3600)
|
|
92
|
+
});
|
|
93
|
+
var agentTokenResponseSchema = z2.object({
|
|
94
|
+
expiresAt: z2.string().datetime(),
|
|
95
|
+
token: z2.string(),
|
|
96
|
+
workspaceId: z2.string()
|
|
97
|
+
});
|
|
98
|
+
|
|
86
99
|
// ../shared/src/agents.ts
|
|
87
100
|
var AGENT_BRANDS = [
|
|
88
101
|
{
|
|
@@ -152,43 +165,43 @@ function detectAgentFromEnv(env) {
|
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
// ../shared/src/avatars.ts
|
|
155
|
-
import { z as
|
|
168
|
+
import { z as z3 } from "zod";
|
|
156
169
|
var AVATAR_CONTENT_TYPES = [
|
|
157
170
|
"image/png",
|
|
158
171
|
"image/jpeg",
|
|
159
172
|
"image/webp"
|
|
160
173
|
];
|
|
161
174
|
var AVATAR_MAX_BYTES = 2 * 1024 * 1024;
|
|
162
|
-
var avatarContentTypeSchema =
|
|
163
|
-
var userAvatarResponseSchema =
|
|
164
|
-
image:
|
|
175
|
+
var avatarContentTypeSchema = z3.enum(AVATAR_CONTENT_TYPES);
|
|
176
|
+
var userAvatarResponseSchema = z3.object({
|
|
177
|
+
image: z3.string().nullable()
|
|
165
178
|
});
|
|
166
|
-
var workspaceAvatarResponseSchema =
|
|
167
|
-
logo:
|
|
179
|
+
var workspaceAvatarResponseSchema = z3.object({
|
|
180
|
+
logo: z3.string().nullable()
|
|
168
181
|
});
|
|
169
182
|
|
|
170
183
|
// ../shared/src/comments.ts
|
|
171
|
-
import { z as
|
|
184
|
+
import { z as z7 } from "zod";
|
|
172
185
|
|
|
173
186
|
// ../shared/src/emoji.ts
|
|
174
|
-
import { z as
|
|
187
|
+
import { z as z4 } from "zod";
|
|
175
188
|
var SINGLE_EMOJI = new RegExp("^\\p{RGI_Emoji}$", "v");
|
|
176
189
|
var REDUNDANT_VS16 = new RegExp("(\\p{Emoji_Presentation})\\uFE0F", "gu");
|
|
177
190
|
function canonicalizeEmoji(s) {
|
|
178
191
|
return s.replace(REDUNDANT_VS16, "$1");
|
|
179
192
|
}
|
|
180
|
-
var iconEmojiSchema =
|
|
193
|
+
var iconEmojiSchema = z4.string().max(64).transform(canonicalizeEmoji).refine((s) => SINGLE_EMOJI.test(s), { message: "Must be a single emoji." }).nullable().describe("A single emoji shown as the icon, or null for the default.");
|
|
181
194
|
|
|
182
195
|
// ../shared/src/publish.ts
|
|
183
|
-
import { z as
|
|
196
|
+
import { z as z6 } from "zod";
|
|
184
197
|
|
|
185
198
|
// ../shared/src/review-mode.ts
|
|
186
|
-
import { z as
|
|
187
|
-
var reviewModeSchema =
|
|
188
|
-
var setReviewModeSchema =
|
|
199
|
+
import { z as z5 } from "zod";
|
|
200
|
+
var reviewModeSchema = z5.enum(["open", "readonly", "off"]);
|
|
201
|
+
var setReviewModeSchema = z5.object({
|
|
189
202
|
mode: reviewModeSchema
|
|
190
203
|
});
|
|
191
|
-
var reviewModeResponseSchema =
|
|
204
|
+
var reviewModeResponseSchema = z5.object({
|
|
192
205
|
mode: reviewModeSchema
|
|
193
206
|
});
|
|
194
207
|
|
|
@@ -207,273 +220,274 @@ function isSafeArtifactPath(p) {
|
|
|
207
220
|
}
|
|
208
221
|
var CARD_DESCRIPTION_MAX = 300;
|
|
209
222
|
var CARD_IMAGE_MAX_BYTES = 5 * 1024 * 1024;
|
|
210
|
-
var manifestFileSchema =
|
|
211
|
-
hash:
|
|
212
|
-
mimeType:
|
|
213
|
-
path:
|
|
223
|
+
var manifestFileSchema = z6.object({
|
|
224
|
+
hash: z6.string().regex(/^sha256_[a-f0-9]{64}$/),
|
|
225
|
+
mimeType: z6.string().regex(/^[-\w.+]+\/[-\w.+]+$/, { message: "invalid MIME type" }),
|
|
226
|
+
path: z6.string().min(1).max(1024).refine(isSafeArtifactPath, {
|
|
214
227
|
message: "path must be a safe relative path"
|
|
215
228
|
}),
|
|
216
|
-
size:
|
|
229
|
+
size: z6.number().int().positive()
|
|
217
230
|
});
|
|
218
|
-
var publishSourceSchema =
|
|
219
|
-
agent:
|
|
220
|
-
runId:
|
|
221
|
-
type:
|
|
231
|
+
var publishSourceSchema = z6.object({
|
|
232
|
+
agent: z6.string().optional(),
|
|
233
|
+
runId: z6.string().optional(),
|
|
234
|
+
type: z6.literal("cli")
|
|
222
235
|
});
|
|
223
|
-
var createPublishSessionSchema =
|
|
224
|
-
artifactId:
|
|
236
|
+
var createPublishSessionSchema = z6.object({
|
|
237
|
+
artifactId: z6.string().nullable(),
|
|
225
238
|
// One-line share-card summary (`--description`). Overrides whatever the
|
|
226
239
|
// entry HTML declares; leave it off and the API reads the document's own
|
|
227
240
|
// `og:description`/`description` at finalize.
|
|
228
|
-
description:
|
|
229
|
-
entryPath:
|
|
230
|
-
files:
|
|
241
|
+
description: z6.string().max(CARD_DESCRIPTION_MAX).optional(),
|
|
242
|
+
entryPath: z6.string().optional(),
|
|
243
|
+
files: z6.array(manifestFileSchema).min(1).max(1e3),
|
|
231
244
|
// SPEC-2 §6.4 — workspace placement is available only to authenticated
|
|
232
245
|
// members; the API enforces membership and folder ownership. folderId
|
|
233
246
|
// without workspaceId resolves against the account's personal workspace.
|
|
234
|
-
folderId:
|
|
247
|
+
folderId: z6.string().min(1).optional(),
|
|
235
248
|
// Bullet-point changelog for this version, authored by the publisher.
|
|
236
249
|
// Optional on every publish (incl. v1); stored immutably on the version.
|
|
237
|
-
notes:
|
|
250
|
+
notes: z6.string().max(4e3).optional(),
|
|
238
251
|
source: publishSourceSchema,
|
|
239
|
-
title:
|
|
240
|
-
workspaceId:
|
|
241
|
-
});
|
|
242
|
-
var publishSessionResponseSchema =
|
|
243
|
-
artifactId:
|
|
244
|
-
expiresAt:
|
|
245
|
-
filesToUpload:
|
|
246
|
-
|
|
247
|
-
method:
|
|
248
|
-
path:
|
|
249
|
-
uploadUrl:
|
|
252
|
+
title: z6.string().max(200).optional(),
|
|
253
|
+
workspaceId: z6.string().min(1).optional()
|
|
254
|
+
});
|
|
255
|
+
var publishSessionResponseSchema = z6.object({
|
|
256
|
+
artifactId: z6.string(),
|
|
257
|
+
expiresAt: z6.string(),
|
|
258
|
+
filesToUpload: z6.array(
|
|
259
|
+
z6.object({
|
|
260
|
+
method: z6.literal("PUT"),
|
|
261
|
+
path: z6.string(),
|
|
262
|
+
uploadUrl: z6.string().url()
|
|
250
263
|
})
|
|
251
264
|
),
|
|
252
|
-
publishSessionId:
|
|
253
|
-
skippedFiles:
|
|
254
|
-
versionId:
|
|
265
|
+
publishSessionId: z6.string(),
|
|
266
|
+
skippedFiles: z6.array(z6.string()),
|
|
267
|
+
versionId: z6.string()
|
|
255
268
|
});
|
|
256
|
-
var finalizeResponseSchema =
|
|
257
|
-
artifactId:
|
|
269
|
+
var finalizeResponseSchema = z6.object({
|
|
270
|
+
artifactId: z6.string(),
|
|
258
271
|
// API-key publishes create the artifact already claimed (SPEC §5.4) —
|
|
259
272
|
// the CLI uses this to tell "claim URL pending" from "already yours".
|
|
260
|
-
claimed:
|
|
273
|
+
claimed: z6.boolean(),
|
|
261
274
|
// Returned only on first publish of a new artifact (one-time).
|
|
262
|
-
claimUrl:
|
|
263
|
-
publishToken:
|
|
264
|
-
url:
|
|
265
|
-
versionId:
|
|
266
|
-
versionNumber:
|
|
275
|
+
claimUrl: z6.string().url().optional(),
|
|
276
|
+
publishToken: z6.string().optional(),
|
|
277
|
+
url: z6.string().url(),
|
|
278
|
+
versionId: z6.string(),
|
|
279
|
+
versionNumber: z6.number().int().positive(),
|
|
267
280
|
// SPEC-2 §5.2 — who can open the review URL. A publish into a folder
|
|
268
281
|
// inherits that folder's visibility, so this is the only place the CLI
|
|
269
282
|
// learns that a link it just printed is members-only. Optional so a new
|
|
270
283
|
// CLI against an older API degrades to "unknown" instead of failing the
|
|
271
284
|
// publish over a field that only shapes the closing message.
|
|
272
|
-
visibility:
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
285
|
+
visibility: z6.enum(["public", "unlisted", "workspace", "private"]).optional(),
|
|
286
|
+
workspaceId: z6.string().nullable().optional()
|
|
287
|
+
});
|
|
288
|
+
var artifactResponseSchema = z6.object({
|
|
289
|
+
claimed: z6.boolean(),
|
|
290
|
+
currentVersion: z6.object({
|
|
291
|
+
entryUrl: z6.string().url(),
|
|
292
|
+
id: z6.string(),
|
|
293
|
+
versionNumber: z6.number().int().positive()
|
|
280
294
|
}).nullable(),
|
|
281
295
|
// Custom icon, or null to render the default document glyph.
|
|
282
|
-
emoji:
|
|
296
|
+
emoji: z6.string().nullable(),
|
|
283
297
|
// SPEC-2 §6.4 — placement + visibility surface on the artifact.
|
|
284
|
-
folderId:
|
|
285
|
-
id:
|
|
298
|
+
folderId: z6.string().nullable(),
|
|
299
|
+
id: z6.string(),
|
|
286
300
|
// SPEC-2 §5.8 — what a viewer may do once in (open / readonly / off).
|
|
287
301
|
reviewMode: reviewModeSchema,
|
|
288
|
-
slug:
|
|
289
|
-
title:
|
|
290
|
-
visibility:
|
|
291
|
-
workspaceId:
|
|
302
|
+
slug: z6.string(),
|
|
303
|
+
title: z6.string(),
|
|
304
|
+
visibility: z6.enum(["public", "unlisted", "workspace", "private"]),
|
|
305
|
+
workspaceId: z6.string().nullable()
|
|
292
306
|
});
|
|
293
307
|
|
|
294
308
|
// ../shared/src/comments.ts
|
|
295
|
-
var anchorPageSchema =
|
|
309
|
+
var anchorPageSchema = z7.string().max(1024).refine(isSafeArtifactPath, {
|
|
296
310
|
message: "page must be a safe relative path"
|
|
297
311
|
}).optional();
|
|
298
|
-
var elementSnapshotSchema =
|
|
299
|
-
classes:
|
|
300
|
-
id:
|
|
301
|
-
tag:
|
|
302
|
-
text:
|
|
312
|
+
var elementSnapshotSchema = z7.object({
|
|
313
|
+
classes: z7.string().max(256).optional(),
|
|
314
|
+
id: z7.string().max(256).optional(),
|
|
315
|
+
tag: z7.string().min(1).max(128),
|
|
316
|
+
text: z7.string().max(200).optional()
|
|
303
317
|
});
|
|
304
|
-
var pointAnchorSchema =
|
|
318
|
+
var pointAnchorSchema = z7.object({
|
|
305
319
|
element: elementSnapshotSchema.optional(),
|
|
306
320
|
// elementPath is the primary anchor; x/y are offsets within the
|
|
307
321
|
// element's box, normalized 0..1 (SPEC.md §8.1).
|
|
308
|
-
elementPath:
|
|
322
|
+
elementPath: z7.string().max(2048),
|
|
309
323
|
page: anchorPageSchema,
|
|
310
|
-
type:
|
|
311
|
-
viewportHeight:
|
|
312
|
-
viewportWidth:
|
|
313
|
-
x:
|
|
314
|
-
y:
|
|
315
|
-
});
|
|
316
|
-
var textAnchorSchema =
|
|
317
|
-
elementPath:
|
|
318
|
-
endOffset:
|
|
324
|
+
type: z7.literal("point"),
|
|
325
|
+
viewportHeight: z7.number().int().positive().max(1e5),
|
|
326
|
+
viewportWidth: z7.number().int().positive().max(1e5),
|
|
327
|
+
x: z7.number().min(0).max(1),
|
|
328
|
+
y: z7.number().min(0).max(1)
|
|
329
|
+
});
|
|
330
|
+
var textAnchorSchema = z7.object({
|
|
331
|
+
elementPath: z7.string().max(2048),
|
|
332
|
+
endOffset: z7.number().int().nonnegative().max(1e8),
|
|
319
333
|
page: anchorPageSchema,
|
|
320
|
-
prefix:
|
|
321
|
-
quote:
|
|
322
|
-
startOffset:
|
|
323
|
-
suffix:
|
|
324
|
-
type:
|
|
334
|
+
prefix: z7.string().max(200).optional(),
|
|
335
|
+
quote: z7.string().min(1).max(1e3),
|
|
336
|
+
startOffset: z7.number().int().nonnegative().max(1e8),
|
|
337
|
+
suffix: z7.string().max(200).optional(),
|
|
338
|
+
type: z7.literal("text")
|
|
325
339
|
});
|
|
326
|
-
var pageAnchorSchema =
|
|
340
|
+
var pageAnchorSchema = z7.object({
|
|
327
341
|
page: anchorPageSchema,
|
|
328
|
-
type:
|
|
342
|
+
type: z7.literal("page")
|
|
329
343
|
});
|
|
330
|
-
var anchorSchema =
|
|
344
|
+
var anchorSchema = z7.discriminatedUnion("type", [
|
|
331
345
|
pointAnchorSchema,
|
|
332
346
|
textAnchorSchema,
|
|
333
347
|
pageAnchorSchema
|
|
334
348
|
]);
|
|
335
|
-
var displayNameSchema =
|
|
336
|
-
var guestSchema =
|
|
349
|
+
var displayNameSchema = z7.string().trim().min(1).max(64);
|
|
350
|
+
var guestSchema = z7.object({
|
|
337
351
|
displayName: displayNameSchema,
|
|
338
|
-
guestId:
|
|
352
|
+
guestId: z7.string().min(16)
|
|
339
353
|
});
|
|
340
|
-
var viaLabelSchema =
|
|
341
|
-
var createCommentThreadSchema =
|
|
354
|
+
var viaLabelSchema = z7.string().trim().min(1).max(64);
|
|
355
|
+
var createCommentThreadSchema = z7.object({
|
|
342
356
|
anchor: anchorSchema,
|
|
343
|
-
body:
|
|
357
|
+
body: z7.string().min(1).max(1e4),
|
|
344
358
|
guest: guestSchema.optional(),
|
|
345
|
-
versionId:
|
|
359
|
+
versionId: z7.string(),
|
|
346
360
|
via: viaLabelSchema.optional()
|
|
347
361
|
});
|
|
348
|
-
var createCommentMessageSchema =
|
|
349
|
-
body:
|
|
362
|
+
var createCommentMessageSchema = z7.object({
|
|
363
|
+
body: z7.string().min(1).max(1e4),
|
|
350
364
|
guest: guestSchema.optional(),
|
|
351
365
|
via: viaLabelSchema.optional()
|
|
352
366
|
});
|
|
353
|
-
var editCommentMessageSchema =
|
|
354
|
-
body:
|
|
367
|
+
var editCommentMessageSchema = z7.object({
|
|
368
|
+
body: z7.string().min(1).max(1e4),
|
|
355
369
|
guest: guestSchema.optional()
|
|
356
370
|
});
|
|
357
|
-
var threadActionSchema =
|
|
371
|
+
var threadActionSchema = z7.object({
|
|
358
372
|
guest: guestSchema.optional()
|
|
359
373
|
});
|
|
360
|
-
var reactionEmojiSchema =
|
|
361
|
-
var toggleReactionSchema =
|
|
374
|
+
var reactionEmojiSchema = z7.string().max(64).transform(canonicalizeEmoji).refine((s) => SINGLE_EMOJI.test(s), { message: "Must be a single emoji." }).describe("A single emoji, e.g. \u{1F44D}");
|
|
375
|
+
var toggleReactionSchema = z7.object({
|
|
362
376
|
emoji: reactionEmojiSchema,
|
|
363
377
|
guest: guestSchema.optional()
|
|
364
378
|
});
|
|
365
|
-
var commentAgentSchema =
|
|
366
|
-
id:
|
|
367
|
-
label:
|
|
379
|
+
var commentAgentSchema = z7.object({
|
|
380
|
+
id: z7.string().nullable(),
|
|
381
|
+
label: z7.string()
|
|
368
382
|
});
|
|
369
|
-
var commentAuthorSchema =
|
|
383
|
+
var commentAuthorSchema = z7.object({
|
|
370
384
|
agent: commentAgentSchema.nullable().default(null),
|
|
371
|
-
avatarUrl:
|
|
372
|
-
displayName:
|
|
373
|
-
guestId:
|
|
374
|
-
isViewer:
|
|
375
|
-
kind:
|
|
385
|
+
avatarUrl: z7.string().nullable(),
|
|
386
|
+
displayName: z7.string(),
|
|
387
|
+
guestId: z7.string().nullable(),
|
|
388
|
+
isViewer: z7.boolean(),
|
|
389
|
+
kind: z7.enum(["member", "guest"]),
|
|
376
390
|
// Optional "via" attribution (§6.4). Null for plain comments; a bounded
|
|
377
391
|
// label the shell appends after the display name. Defaulted for the same
|
|
378
392
|
// reason as `agent`: a server predating §6.4 omits the key entirely.
|
|
379
|
-
via:
|
|
393
|
+
via: z7.string().nullable().default(null)
|
|
380
394
|
});
|
|
381
|
-
var messageReactionSchema =
|
|
382
|
-
emoji:
|
|
383
|
-
reactors:
|
|
395
|
+
var messageReactionSchema = z7.object({
|
|
396
|
+
emoji: z7.string(),
|
|
397
|
+
reactors: z7.array(commentAuthorSchema)
|
|
384
398
|
});
|
|
385
|
-
var commentMessageSchema =
|
|
399
|
+
var commentMessageSchema = z7.object({
|
|
386
400
|
author: commentAuthorSchema,
|
|
387
401
|
// Empty string for a deleted message — the body is stripped server-side
|
|
388
402
|
// (§6.7.1 tombstone), never sent to the client and hidden there.
|
|
389
|
-
body:
|
|
390
|
-
createdAt:
|
|
403
|
+
body: z7.string(),
|
|
404
|
+
createdAt: z7.string(),
|
|
391
405
|
// Soft-deleted (§6.7.1). A tombstone keeps thread structure and replies;
|
|
392
406
|
// the shell renders "Comment deleted" instead of the (absent) body.
|
|
393
|
-
deleted:
|
|
407
|
+
deleted: z7.boolean(),
|
|
394
408
|
// Last edit time (§6.7.1), or null if never edited — drives the "edited"
|
|
395
409
|
// badge. No edit history is kept.
|
|
396
|
-
editedAt:
|
|
397
|
-
id:
|
|
410
|
+
editedAt: z7.string().nullable(),
|
|
411
|
+
id: z7.string(),
|
|
398
412
|
// Defaulted, not required: a new CLI parsing an older server's
|
|
399
413
|
// response must not fail on the missing key.
|
|
400
|
-
reactions:
|
|
414
|
+
reactions: z7.array(messageReactionSchema).default([])
|
|
401
415
|
});
|
|
402
|
-
var threadActorSchema =
|
|
403
|
-
displayName:
|
|
404
|
-
kind:
|
|
416
|
+
var threadActorSchema = z7.object({
|
|
417
|
+
displayName: z7.string(),
|
|
418
|
+
kind: z7.enum(["member", "guest", "agent"])
|
|
405
419
|
});
|
|
406
|
-
var commentThreadSchema =
|
|
420
|
+
var commentThreadSchema = z7.object({
|
|
407
421
|
// §6.6.1 — set while open to signal "seen, working on it"; cleared on
|
|
408
422
|
// reopen, kept (but superseded in display) once resolved. Defaulted so
|
|
409
423
|
// clients parsing an older server's response don't fail.
|
|
410
|
-
acknowledgedAt:
|
|
424
|
+
acknowledgedAt: z7.string().nullable().default(null),
|
|
411
425
|
acknowledgedBy: threadActorSchema.nullable().default(null),
|
|
412
426
|
anchor: anchorSchema,
|
|
413
|
-
artifactId:
|
|
414
|
-
createdAt:
|
|
427
|
+
artifactId: z7.string(),
|
|
428
|
+
createdAt: z7.string(),
|
|
415
429
|
createdBy: commentAuthorSchema,
|
|
416
|
-
id:
|
|
417
|
-
messages:
|
|
430
|
+
id: z7.string(),
|
|
431
|
+
messages: z7.array(commentMessageSchema),
|
|
418
432
|
// Null on threads resolved before actor recording existed, and always
|
|
419
433
|
// null while open.
|
|
420
434
|
resolvedBy: threadActorSchema.nullable().default(null),
|
|
421
|
-
status:
|
|
422
|
-
versionId:
|
|
435
|
+
status: z7.enum(["open", "resolved"]),
|
|
436
|
+
versionId: z7.string()
|
|
423
437
|
});
|
|
424
|
-
var commentThreadListSchema =
|
|
425
|
-
threads:
|
|
438
|
+
var commentThreadListSchema = z7.object({
|
|
439
|
+
threads: z7.array(commentThreadSchema)
|
|
426
440
|
});
|
|
427
|
-
var commentExportQuerySchema =
|
|
428
|
-
status:
|
|
429
|
-
version:
|
|
441
|
+
var commentExportQuerySchema = z7.object({
|
|
442
|
+
status: z7.enum(["open", "resolved", "all"]).default("open"),
|
|
443
|
+
version: z7.enum(["current", "all"]).default("current")
|
|
430
444
|
});
|
|
431
|
-
var exportReactionSchema =
|
|
432
|
-
count:
|
|
433
|
-
emoji:
|
|
445
|
+
var exportReactionSchema = z7.object({
|
|
446
|
+
count: z7.number().int().positive(),
|
|
447
|
+
emoji: z7.string()
|
|
434
448
|
});
|
|
435
|
-
var commentExportReplySchema =
|
|
436
|
-
author:
|
|
437
|
-
authorKind:
|
|
438
|
-
body:
|
|
439
|
-
createdAt:
|
|
449
|
+
var commentExportReplySchema = z7.object({
|
|
450
|
+
author: z7.string(),
|
|
451
|
+
authorKind: z7.enum(["member", "guest"]),
|
|
452
|
+
body: z7.string(),
|
|
453
|
+
createdAt: z7.string(),
|
|
440
454
|
// Soft-delete tombstone (§6.7.1): body is "" when true.
|
|
441
|
-
deleted:
|
|
442
|
-
editedAt:
|
|
455
|
+
deleted: z7.boolean(),
|
|
456
|
+
editedAt: z7.string().nullable(),
|
|
443
457
|
// The message id — what `edit`/`delete` target (§5.1).
|
|
444
|
-
id:
|
|
445
|
-
reactions:
|
|
458
|
+
id: z7.string(),
|
|
459
|
+
reactions: z7.array(exportReactionSchema).optional()
|
|
446
460
|
});
|
|
447
|
-
var commentExportThreadSchema =
|
|
461
|
+
var commentExportThreadSchema = z7.object({
|
|
448
462
|
// §6.6.1 — lets a polling agent skip threads it already acknowledged
|
|
449
463
|
// (acknowledged threads stay in status=open exports on purpose).
|
|
450
|
-
acknowledgedAt:
|
|
464
|
+
acknowledgedAt: z7.string().nullable().default(null),
|
|
451
465
|
anchor: anchorSchema,
|
|
452
|
-
author:
|
|
453
|
-
authorKind:
|
|
454
|
-
body:
|
|
455
|
-
createdAt:
|
|
456
|
-
deleted:
|
|
457
|
-
editedAt:
|
|
458
|
-
id:
|
|
466
|
+
author: z7.string(),
|
|
467
|
+
authorKind: z7.enum(["member", "guest"]),
|
|
468
|
+
body: z7.string(),
|
|
469
|
+
createdAt: z7.string(),
|
|
470
|
+
deleted: z7.boolean(),
|
|
471
|
+
editedAt: z7.string().nullable(),
|
|
472
|
+
id: z7.string(),
|
|
459
473
|
// The opening message's id (distinct from the thread `id`) — `edit`/
|
|
460
474
|
// `delete` operate on messages, so the CLI needs it to target the first
|
|
461
475
|
// comment, not just the replies.
|
|
462
|
-
messageId:
|
|
463
|
-
reactions:
|
|
464
|
-
replies:
|
|
476
|
+
messageId: z7.string(),
|
|
477
|
+
reactions: z7.array(exportReactionSchema).optional(),
|
|
478
|
+
replies: z7.array(commentExportReplySchema),
|
|
465
479
|
resolvedBy: threadActorSchema.nullable().default(null),
|
|
466
|
-
status:
|
|
467
|
-
versionNumber:
|
|
480
|
+
status: z7.enum(["open", "resolved"]),
|
|
481
|
+
versionNumber: z7.number().int().positive()
|
|
468
482
|
});
|
|
469
|
-
var commentExportSchema =
|
|
470
|
-
artifactId:
|
|
471
|
-
comments:
|
|
483
|
+
var commentExportSchema = z7.object({
|
|
484
|
+
artifactId: z7.string(),
|
|
485
|
+
comments: z7.array(commentExportThreadSchema),
|
|
472
486
|
// The artifact's current version (null before the first finalize).
|
|
473
|
-
versionNumber:
|
|
487
|
+
versionNumber: z7.number().int().positive().nullable()
|
|
474
488
|
});
|
|
475
|
-
var commentReadResponseSchema =
|
|
476
|
-
lastSeenAt:
|
|
489
|
+
var commentReadResponseSchema = z7.object({
|
|
490
|
+
lastSeenAt: z7.string()
|
|
477
491
|
});
|
|
478
492
|
function elementLabel(el) {
|
|
479
493
|
if (el.id) {
|
|
@@ -484,244 +498,244 @@ function elementLabel(el) {
|
|
|
484
498
|
}
|
|
485
499
|
|
|
486
500
|
// ../shared/src/errors.ts
|
|
487
|
-
import { z as
|
|
488
|
-
var apiErrorSchema =
|
|
489
|
-
code:
|
|
490
|
-
docsUrl:
|
|
491
|
-
message:
|
|
492
|
-
retryAfter:
|
|
501
|
+
import { z as z8 } from "zod";
|
|
502
|
+
var apiErrorSchema = z8.object({
|
|
503
|
+
code: z8.string(),
|
|
504
|
+
docsUrl: z8.string().url(),
|
|
505
|
+
message: z8.string(),
|
|
506
|
+
retryAfter: z8.number().int().positive().optional()
|
|
493
507
|
});
|
|
494
508
|
|
|
495
509
|
// ../shared/src/feedback.ts
|
|
496
|
-
import { z as
|
|
497
|
-
var feedbackRequestSchema =
|
|
498
|
-
email:
|
|
499
|
-
message:
|
|
510
|
+
import { z as z9 } from "zod";
|
|
511
|
+
var feedbackRequestSchema = z9.object({
|
|
512
|
+
email: z9.string().trim().toLowerCase().email().optional().or(z9.literal("")),
|
|
513
|
+
message: z9.string().trim().min(1).max(4e3)
|
|
500
514
|
});
|
|
501
|
-
var feedbackResponseSchema =
|
|
502
|
-
sent:
|
|
515
|
+
var feedbackResponseSchema = z9.object({
|
|
516
|
+
sent: z9.literal(true)
|
|
503
517
|
});
|
|
504
518
|
|
|
505
519
|
// ../shared/src/grants.ts
|
|
506
|
-
import { z as
|
|
507
|
-
var grantRoleSchema =
|
|
508
|
-
var createGrantSchema =
|
|
509
|
-
email:
|
|
520
|
+
import { z as z10 } from "zod";
|
|
521
|
+
var grantRoleSchema = z10.enum(["viewer"]);
|
|
522
|
+
var createGrantSchema = z10.object({
|
|
523
|
+
email: z10.string().trim().toLowerCase().email().optional(),
|
|
510
524
|
role: grantRoleSchema.default("viewer"),
|
|
511
|
-
userId:
|
|
525
|
+
userId: z10.string().min(1).optional()
|
|
512
526
|
}).refine((body) => Boolean(body.email) !== Boolean(body.userId), {
|
|
513
527
|
message: "provide exactly one of email or userId"
|
|
514
528
|
});
|
|
515
|
-
var grantSchema =
|
|
516
|
-
createdAt:
|
|
517
|
-
email:
|
|
518
|
-
expiresAt:
|
|
519
|
-
id:
|
|
529
|
+
var grantSchema = z10.object({
|
|
530
|
+
createdAt: z10.string(),
|
|
531
|
+
email: z10.string().email().nullable(),
|
|
532
|
+
expiresAt: z10.string().nullable(),
|
|
533
|
+
id: z10.string(),
|
|
520
534
|
// The subject's avatar once they have an account; null otherwise.
|
|
521
|
-
image:
|
|
535
|
+
image: z10.string().nullable(),
|
|
522
536
|
// Present on the invited account after redemption / when granting an
|
|
523
537
|
// existing user; null for a still-pending email invite.
|
|
524
|
-
name:
|
|
525
|
-
redeemedAt:
|
|
538
|
+
name: z10.string().nullable(),
|
|
539
|
+
redeemedAt: z10.string().nullable(),
|
|
526
540
|
role: grantRoleSchema,
|
|
527
541
|
// Shown as "· pending" beside the role until the link is redeemed.
|
|
528
|
-
status:
|
|
542
|
+
status: z10.enum(["pending", "active"]),
|
|
529
543
|
// Display fragment of the live invitation token, or null once redeemed.
|
|
530
|
-
tokenPrefix:
|
|
531
|
-
userId:
|
|
544
|
+
tokenPrefix: z10.string().nullable(),
|
|
545
|
+
userId: z10.string().nullable()
|
|
532
546
|
});
|
|
533
547
|
var createdGrantSchema = grantSchema.extend({
|
|
534
|
-
url:
|
|
548
|
+
url: z10.string().url()
|
|
535
549
|
});
|
|
536
|
-
var grantListResponseSchema =
|
|
537
|
-
grants:
|
|
550
|
+
var grantListResponseSchema = z10.object({
|
|
551
|
+
grants: z10.array(grantSchema),
|
|
538
552
|
// The artifact's current general-access value, so the share surface can
|
|
539
553
|
// render the "General access" line without a second read.
|
|
540
|
-
visibility:
|
|
554
|
+
visibility: z10.enum(["public", "unlisted", "workspace", "private"]),
|
|
541
555
|
// The owning workspace's logo, so the share modal can draw the workspace
|
|
542
556
|
// itself rather than a generic glyph. Null when none was uploaded.
|
|
543
|
-
workspaceLogo:
|
|
557
|
+
workspaceLogo: z10.string().nullable().optional(),
|
|
544
558
|
// The owning workspace's display name, so "People with access" can name the
|
|
545
559
|
// audience `workspace` visibility actually admits ("All Acme members") rather
|
|
546
560
|
// than leaving an empty list to imply nobody. Null for a workspace-less
|
|
547
561
|
// artifact; optional so an older server still parses.
|
|
548
|
-
workspaceName:
|
|
562
|
+
workspaceName: z10.string().nullable().optional()
|
|
549
563
|
});
|
|
550
|
-
var revokeGrantResponseSchema =
|
|
551
|
-
revoked:
|
|
564
|
+
var revokeGrantResponseSchema = z10.object({
|
|
565
|
+
revoked: z10.literal(true)
|
|
552
566
|
});
|
|
553
|
-
var acceptGrantSchema =
|
|
554
|
-
token:
|
|
567
|
+
var acceptGrantSchema = z10.object({
|
|
568
|
+
token: z10.string().min(1)
|
|
555
569
|
});
|
|
556
|
-
var acceptGrantResponseSchema =
|
|
557
|
-
artifactId:
|
|
570
|
+
var acceptGrantResponseSchema = z10.object({
|
|
571
|
+
artifactId: z10.string(),
|
|
558
572
|
// The review shell URL to land on, carrying ?invited=1 for the banner.
|
|
559
|
-
artifactUrl:
|
|
560
|
-
slug:
|
|
561
|
-
title:
|
|
562
|
-
});
|
|
563
|
-
var workspaceGuestSchema =
|
|
564
|
-
artifacts:
|
|
565
|
-
|
|
566
|
-
artifactId:
|
|
567
|
-
grantId:
|
|
568
|
-
slug:
|
|
569
|
-
status:
|
|
570
|
-
title:
|
|
573
|
+
artifactUrl: z10.string().url(),
|
|
574
|
+
slug: z10.string(),
|
|
575
|
+
title: z10.string()
|
|
576
|
+
});
|
|
577
|
+
var workspaceGuestSchema = z10.object({
|
|
578
|
+
artifacts: z10.array(
|
|
579
|
+
z10.object({
|
|
580
|
+
artifactId: z10.string(),
|
|
581
|
+
grantId: z10.string(),
|
|
582
|
+
slug: z10.string(),
|
|
583
|
+
status: z10.enum(["pending", "active"]),
|
|
584
|
+
title: z10.string()
|
|
571
585
|
})
|
|
572
586
|
),
|
|
573
|
-
email:
|
|
574
|
-
image:
|
|
575
|
-
name:
|
|
576
|
-
userId:
|
|
577
|
-
});
|
|
578
|
-
var workspaceGuestListResponseSchema =
|
|
579
|
-
guests:
|
|
580
|
-
});
|
|
581
|
-
var sharedWithMeArtifactSchema =
|
|
582
|
-
artifactId:
|
|
583
|
-
slug:
|
|
584
|
-
title:
|
|
585
|
-
url:
|
|
587
|
+
email: z10.string().nullable(),
|
|
588
|
+
image: z10.string().nullable(),
|
|
589
|
+
name: z10.string().nullable(),
|
|
590
|
+
userId: z10.string().nullable()
|
|
591
|
+
});
|
|
592
|
+
var workspaceGuestListResponseSchema = z10.object({
|
|
593
|
+
guests: z10.array(workspaceGuestSchema)
|
|
594
|
+
});
|
|
595
|
+
var sharedWithMeArtifactSchema = z10.object({
|
|
596
|
+
artifactId: z10.string(),
|
|
597
|
+
slug: z10.string(),
|
|
598
|
+
title: z10.string(),
|
|
599
|
+
url: z10.string().url(),
|
|
586
600
|
// Who shared it, for the "Shared with me" list.
|
|
587
|
-
workspaceName:
|
|
601
|
+
workspaceName: z10.string()
|
|
588
602
|
});
|
|
589
|
-
var sharedWithMeListResponseSchema =
|
|
590
|
-
artifacts:
|
|
603
|
+
var sharedWithMeListResponseSchema = z10.object({
|
|
604
|
+
artifacts: z10.array(sharedWithMeArtifactSchema)
|
|
591
605
|
});
|
|
592
606
|
|
|
593
607
|
// ../shared/src/html-meta.ts
|
|
594
608
|
var HEAD_SCAN_CHARS = 64 * 1024;
|
|
595
609
|
|
|
596
610
|
// ../shared/src/me.ts
|
|
597
|
-
import { z as
|
|
611
|
+
import { z as z12 } from "zod";
|
|
598
612
|
|
|
599
613
|
// ../shared/src/workspaces.ts
|
|
600
|
-
import { z as
|
|
614
|
+
import { z as z11 } from "zod";
|
|
601
615
|
var WORKSPACE_HANDLE_PATTERN = /^[a-z0-9](?:[a-z0-9-]{1,30}[a-z0-9])$/;
|
|
602
|
-
var workspaceHandleUnavailableReasonSchema =
|
|
616
|
+
var workspaceHandleUnavailableReasonSchema = z11.enum([
|
|
603
617
|
"held",
|
|
604
618
|
"invalid",
|
|
605
619
|
"reserved",
|
|
606
620
|
"taken"
|
|
607
621
|
]);
|
|
608
|
-
var workspaceHandleAvailabilitySchema =
|
|
609
|
-
available:
|
|
610
|
-
handle:
|
|
622
|
+
var workspaceHandleAvailabilitySchema = z11.object({
|
|
623
|
+
available: z11.boolean(),
|
|
624
|
+
handle: z11.string(),
|
|
611
625
|
// Human-readable sentence for the field hint; null when available.
|
|
612
|
-
message:
|
|
626
|
+
message: z11.string().nullable(),
|
|
613
627
|
reason: workspaceHandleUnavailableReasonSchema.nullable()
|
|
614
628
|
});
|
|
615
|
-
var workspaceRoleSchema =
|
|
616
|
-
var workspaceInviteRoleSchema =
|
|
617
|
-
var workspaceHandleSchema =
|
|
629
|
+
var workspaceRoleSchema = z11.enum(["owner", "admin", "member"]);
|
|
630
|
+
var workspaceInviteRoleSchema = z11.enum(["admin", "member"]);
|
|
631
|
+
var workspaceHandleSchema = z11.string().min(3).max(32).regex(WORKSPACE_HANDLE_PATTERN, {
|
|
618
632
|
message: "handle must be lowercase letters, digits, and hyphens, with no leading/trailing hyphen"
|
|
619
633
|
});
|
|
620
|
-
var createWorkspaceSchema =
|
|
634
|
+
var createWorkspaceSchema = z11.object({
|
|
621
635
|
handle: workspaceHandleSchema.optional(),
|
|
622
|
-
name:
|
|
636
|
+
name: z11.string().trim().min(1).max(100)
|
|
623
637
|
});
|
|
624
|
-
var updateWorkspaceSchema =
|
|
638
|
+
var updateWorkspaceSchema = z11.object({
|
|
625
639
|
handle: workspaceHandleSchema.optional(),
|
|
626
|
-
name:
|
|
640
|
+
name: z11.string().trim().min(1).max(100).optional()
|
|
627
641
|
}).refine((body) => body.handle !== void 0 || body.name !== void 0, {
|
|
628
642
|
message: "provide at least one of name or handle"
|
|
629
643
|
});
|
|
630
|
-
var workspaceSchema =
|
|
631
|
-
createdAt:
|
|
632
|
-
handle:
|
|
644
|
+
var workspaceSchema = z11.object({
|
|
645
|
+
createdAt: z11.string(),
|
|
646
|
+
handle: z11.string(),
|
|
633
647
|
// ISO timestamp when `{handle}.artifact.cafe` was provisioned, or null.
|
|
634
648
|
// Set by the one-time, self-serve enable flow (§4.4); never auto at
|
|
635
649
|
// create, and always null for personal workspaces.
|
|
636
|
-
hostnameProvisionedAt:
|
|
637
|
-
id:
|
|
650
|
+
hostnameProvisionedAt: z11.string().nullable(),
|
|
651
|
+
id: z11.string(),
|
|
638
652
|
// Auto-provisioned solo workspace, one per user: non-deletable, takes
|
|
639
653
|
// no members, renameable like any workspace.
|
|
640
|
-
isPersonal:
|
|
654
|
+
isPersonal: z11.boolean(),
|
|
641
655
|
// Uploaded logo URL, or null for the initials fallback. Set through the
|
|
642
656
|
// dedicated /workspaces/:id/avatar route, never the generic update.
|
|
643
|
-
logo:
|
|
644
|
-
name:
|
|
657
|
+
logo: z11.string().nullable(),
|
|
658
|
+
name: z11.string(),
|
|
645
659
|
role: workspaceRoleSchema.nullable(),
|
|
646
|
-
updatedAt:
|
|
660
|
+
updatedAt: z11.string()
|
|
647
661
|
});
|
|
648
|
-
var workspaceListResponseSchema =
|
|
649
|
-
workspaces:
|
|
662
|
+
var workspaceListResponseSchema = z11.object({
|
|
663
|
+
workspaces: z11.array(workspaceSchema)
|
|
650
664
|
});
|
|
651
|
-
var deleteWorkspaceResponseSchema =
|
|
652
|
-
deleted:
|
|
665
|
+
var deleteWorkspaceResponseSchema = z11.object({
|
|
666
|
+
deleted: z11.literal(true)
|
|
653
667
|
});
|
|
654
|
-
var workspaceMemberSchema =
|
|
655
|
-
createdAt:
|
|
656
|
-
email:
|
|
657
|
-
image:
|
|
658
|
-
name:
|
|
668
|
+
var workspaceMemberSchema = z11.object({
|
|
669
|
+
createdAt: z11.string(),
|
|
670
|
+
email: z11.string().email(),
|
|
671
|
+
image: z11.string().nullable(),
|
|
672
|
+
name: z11.string(),
|
|
659
673
|
role: workspaceRoleSchema,
|
|
660
|
-
userId:
|
|
674
|
+
userId: z11.string()
|
|
661
675
|
});
|
|
662
|
-
var workspaceMemberListResponseSchema =
|
|
663
|
-
members:
|
|
676
|
+
var workspaceMemberListResponseSchema = z11.object({
|
|
677
|
+
members: z11.array(workspaceMemberSchema)
|
|
664
678
|
});
|
|
665
|
-
var updateWorkspaceMemberSchema =
|
|
679
|
+
var updateWorkspaceMemberSchema = z11.object({
|
|
666
680
|
role: workspaceRoleSchema
|
|
667
681
|
});
|
|
668
|
-
var removeWorkspaceMemberResponseSchema =
|
|
669
|
-
removed:
|
|
682
|
+
var removeWorkspaceMemberResponseSchema = z11.object({
|
|
683
|
+
removed: z11.literal(true)
|
|
670
684
|
});
|
|
671
|
-
var createWorkspaceInviteSchema =
|
|
672
|
-
email:
|
|
673
|
-
expiresAt:
|
|
674
|
-
maxUses:
|
|
685
|
+
var createWorkspaceInviteSchema = z11.object({
|
|
686
|
+
email: z11.string().trim().toLowerCase().email().optional(),
|
|
687
|
+
expiresAt: z11.string().datetime(),
|
|
688
|
+
maxUses: z11.number().int().positive().optional(),
|
|
675
689
|
role: workspaceInviteRoleSchema
|
|
676
690
|
});
|
|
677
|
-
var workspaceInviteSchema =
|
|
678
|
-
createdAt:
|
|
679
|
-
email:
|
|
680
|
-
expiresAt:
|
|
681
|
-
id:
|
|
682
|
-
maxUses:
|
|
691
|
+
var workspaceInviteSchema = z11.object({
|
|
692
|
+
createdAt: z11.string(),
|
|
693
|
+
email: z11.string().email().nullable(),
|
|
694
|
+
expiresAt: z11.string(),
|
|
695
|
+
id: z11.string(),
|
|
696
|
+
maxUses: z11.number().int().positive().nullable(),
|
|
683
697
|
role: workspaceInviteRoleSchema,
|
|
684
|
-
tokenPrefix:
|
|
685
|
-
useCount:
|
|
698
|
+
tokenPrefix: z11.string(),
|
|
699
|
+
useCount: z11.number().int().nonnegative()
|
|
686
700
|
});
|
|
687
701
|
var createdWorkspaceInviteSchema = workspaceInviteSchema.extend({
|
|
688
|
-
url:
|
|
702
|
+
url: z11.string().url()
|
|
689
703
|
});
|
|
690
|
-
var workspaceInviteListResponseSchema =
|
|
691
|
-
invites:
|
|
704
|
+
var workspaceInviteListResponseSchema = z11.object({
|
|
705
|
+
invites: z11.array(workspaceInviteSchema)
|
|
692
706
|
});
|
|
693
|
-
var revokeWorkspaceInviteResponseSchema =
|
|
694
|
-
revoked:
|
|
707
|
+
var revokeWorkspaceInviteResponseSchema = z11.object({
|
|
708
|
+
revoked: z11.literal(true)
|
|
695
709
|
});
|
|
696
|
-
var acceptWorkspaceInviteSchema =
|
|
697
|
-
token:
|
|
710
|
+
var acceptWorkspaceInviteSchema = z11.object({
|
|
711
|
+
token: z11.string().min(1)
|
|
698
712
|
});
|
|
699
|
-
var acceptWorkspaceInviteResponseSchema =
|
|
713
|
+
var acceptWorkspaceInviteResponseSchema = z11.object({
|
|
700
714
|
role: workspaceRoleSchema,
|
|
701
715
|
workspace: workspaceSchema
|
|
702
716
|
});
|
|
703
|
-
var folderVisibilitySchema =
|
|
704
|
-
var artifactVisibilitySchema =
|
|
717
|
+
var folderVisibilitySchema = z11.enum(["public", "workspace"]);
|
|
718
|
+
var artifactVisibilitySchema = z11.enum([
|
|
705
719
|
"public",
|
|
706
720
|
"unlisted",
|
|
707
721
|
"workspace",
|
|
708
722
|
"private"
|
|
709
723
|
]);
|
|
710
|
-
var createFolderSchema =
|
|
724
|
+
var createFolderSchema = z11.object({
|
|
711
725
|
// Optional custom icon; omitted (or null) leaves the default glyph.
|
|
712
726
|
emoji: iconEmojiSchema.optional(),
|
|
713
|
-
name:
|
|
727
|
+
name: z11.string().trim().min(1).max(100),
|
|
714
728
|
visibility: folderVisibilitySchema
|
|
715
729
|
});
|
|
716
|
-
var updateFolderSchema =
|
|
730
|
+
var updateFolderSchema = z11.object({
|
|
717
731
|
// With `visibility`: bulk-update the folder's artifacts to match
|
|
718
732
|
// (SPEC-2 §3.4 "Changing a folder's visibility offers a bulk update").
|
|
719
|
-
cascade:
|
|
733
|
+
cascade: z11.boolean().optional(),
|
|
720
734
|
// Explicit null clears the icon back to the default glyph, so this is
|
|
721
735
|
// a field where "sent as null" and "omitted" mean different things.
|
|
722
736
|
emoji: iconEmojiSchema.optional(),
|
|
723
|
-
name:
|
|
724
|
-
sortOrder:
|
|
737
|
+
name: z11.string().trim().min(1).max(100).optional(),
|
|
738
|
+
sortOrder: z11.number().int().min(0).optional(),
|
|
725
739
|
visibility: folderVisibilitySchema.optional()
|
|
726
740
|
}).refine(
|
|
727
741
|
(body) => body.name !== void 0 || body.visibility !== void 0 || body.sortOrder !== void 0 || body.emoji !== void 0,
|
|
@@ -729,122 +743,139 @@ var updateFolderSchema = z10.object({
|
|
|
729
743
|
).refine((body) => !body.cascade || body.visibility !== void 0, {
|
|
730
744
|
message: "cascade requires visibility"
|
|
731
745
|
});
|
|
732
|
-
var folderSchema =
|
|
733
|
-
createdAt:
|
|
746
|
+
var folderSchema = z11.object({
|
|
747
|
+
createdAt: z11.string(),
|
|
734
748
|
// Custom icon, or null to render the default folder glyph.
|
|
735
|
-
emoji:
|
|
736
|
-
id:
|
|
737
|
-
name:
|
|
749
|
+
emoji: z11.string().nullable(),
|
|
750
|
+
id: z11.string(),
|
|
751
|
+
name: z11.string(),
|
|
738
752
|
// Permalink segment for the public folder page (/w/{handle}/f/{slug}).
|
|
739
753
|
// Server-derived from the name; renames regenerate it.
|
|
740
|
-
slug:
|
|
741
|
-
sortOrder:
|
|
742
|
-
updatedAt:
|
|
754
|
+
slug: z11.string(),
|
|
755
|
+
sortOrder: z11.number().int(),
|
|
756
|
+
updatedAt: z11.string(),
|
|
743
757
|
visibility: folderVisibilitySchema,
|
|
744
|
-
workspaceId:
|
|
758
|
+
workspaceId: z11.string()
|
|
745
759
|
});
|
|
746
|
-
var folderListResponseSchema =
|
|
747
|
-
folders:
|
|
760
|
+
var folderListResponseSchema = z11.object({
|
|
761
|
+
folders: z11.array(folderSchema)
|
|
748
762
|
});
|
|
749
|
-
var deleteFolderResponseSchema =
|
|
750
|
-
deleted:
|
|
763
|
+
var deleteFolderResponseSchema = z11.object({
|
|
764
|
+
deleted: z11.literal(true)
|
|
751
765
|
});
|
|
752
|
-
var workspaceArtifactSchema =
|
|
753
|
-
createdAt:
|
|
754
|
-
currentVersionNumber:
|
|
766
|
+
var workspaceArtifactSchema = z11.object({
|
|
767
|
+
createdAt: z11.string(),
|
|
768
|
+
currentVersionNumber: z11.number().int().nullable(),
|
|
755
769
|
// Custom icon, or null to render the default document glyph.
|
|
756
|
-
emoji:
|
|
757
|
-
folderId:
|
|
758
|
-
id:
|
|
759
|
-
openCommentCount:
|
|
770
|
+
emoji: z11.string().nullable(),
|
|
771
|
+
folderId: z11.string().nullable(),
|
|
772
|
+
id: z11.string(),
|
|
773
|
+
openCommentCount: z11.number().int().nonnegative(),
|
|
760
774
|
reviewMode: reviewModeSchema,
|
|
761
|
-
slug:
|
|
762
|
-
title:
|
|
763
|
-
updatedAt:
|
|
764
|
-
url:
|
|
765
|
-
versionCount:
|
|
775
|
+
slug: z11.string(),
|
|
776
|
+
title: z11.string(),
|
|
777
|
+
updatedAt: z11.string(),
|
|
778
|
+
url: z11.string().url(),
|
|
779
|
+
versionCount: z11.number().int().nonnegative(),
|
|
766
780
|
visibility: artifactVisibilitySchema
|
|
767
781
|
});
|
|
768
|
-
var workspaceArtifactListResponseSchema =
|
|
769
|
-
artifacts:
|
|
782
|
+
var workspaceArtifactListResponseSchema = z11.object({
|
|
783
|
+
artifacts: z11.array(workspaceArtifactSchema)
|
|
770
784
|
});
|
|
771
|
-
var workspaceArtifactSearchResultSchema =
|
|
772
|
-
id:
|
|
773
|
-
slug:
|
|
774
|
-
title:
|
|
785
|
+
var workspaceArtifactSearchResultSchema = z11.object({
|
|
786
|
+
id: z11.string(),
|
|
787
|
+
slug: z11.string(),
|
|
788
|
+
title: z11.string()
|
|
775
789
|
});
|
|
776
|
-
var workspaceArtifactSearchResponseSchema =
|
|
777
|
-
results:
|
|
790
|
+
var workspaceArtifactSearchResponseSchema = z11.object({
|
|
791
|
+
results: z11.array(workspaceArtifactSearchResultSchema)
|
|
778
792
|
});
|
|
779
793
|
|
|
780
794
|
// ../shared/src/me.ts
|
|
781
|
-
var
|
|
782
|
-
|
|
783
|
-
|
|
795
|
+
var personSchema = z12.object({
|
|
796
|
+
image: z12.string().nullable(),
|
|
797
|
+
name: z12.string()
|
|
798
|
+
});
|
|
799
|
+
var ownArtifactSchema = z12.object({
|
|
800
|
+
// Everyone else who has published a version, oldest first. Any member may
|
|
801
|
+
// publish a new one (SPEC-2 §5.1), so an artifact's byline is often more
|
|
802
|
+
// than one person and the card stacks their faces rather than crediting
|
|
803
|
+
// whoever shipped last. Excludes `publishedBy`; empty on a solo artifact.
|
|
804
|
+
coPublishers: z12.array(personSchema),
|
|
805
|
+
createdAt: z12.string(),
|
|
806
|
+
// SPEC-2 §5.1 — who *made* the artifact: the author of its first
|
|
807
|
+
// finalized version, the same row `viewerCanManage` is decided on. Not
|
|
808
|
+
// the same person as `publishedBy` once an agent ships v2, which is why
|
|
809
|
+
// the dashboard filters on both. Null for a token-only publish.
|
|
810
|
+
createdBy: z12.object({ image: z12.string().nullable(), name: z12.string() }).nullable(),
|
|
811
|
+
currentVersionNumber: z12.number().nullable(),
|
|
784
812
|
// Custom icon, or null to render the default document glyph.
|
|
785
|
-
emoji:
|
|
813
|
+
emoji: z12.string().nullable(),
|
|
786
814
|
// Owned artifacts normally never expire; non-null only while an
|
|
787
815
|
// expiry is still set (e.g. an unclaimed publish surfaced here later).
|
|
788
|
-
expiresAt:
|
|
816
|
+
expiresAt: z12.string().nullable(),
|
|
789
817
|
// SPEC-2 §8.4 — the containing folder for workspace-owned artifacts;
|
|
790
818
|
// both null for personal artifacts. `folderId` drives the dashboard's
|
|
791
819
|
// move control and folder filter; `folderName` is the display label,
|
|
792
820
|
// `folderEmoji` its icon (null = the default folder glyph).
|
|
793
|
-
folderEmoji:
|
|
794
|
-
folderId:
|
|
795
|
-
folderName:
|
|
821
|
+
folderEmoji: z12.string().nullable(),
|
|
822
|
+
folderId: z12.string().nullable(),
|
|
823
|
+
folderName: z12.string().nullable(),
|
|
796
824
|
// Whether a publish token is still active — revocable from the
|
|
797
825
|
// dashboard (§6.18); the token itself is never returned.
|
|
798
|
-
hasPublishToken:
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
826
|
+
hasPublishToken: z12.boolean(),
|
|
827
|
+
// Owner preference: hide the version list from reviewers in the review
|
|
828
|
+
// shell. Managers still see it.
|
|
829
|
+
hideVersions: z12.boolean(),
|
|
830
|
+
id: z12.string(),
|
|
831
|
+
openThreads: z12.number(),
|
|
832
|
+
protected: z12.boolean(),
|
|
802
833
|
// Who published the current version (falling back to the claiming
|
|
803
834
|
// owner) — the dashboard shows a name and avatar per artifact so a
|
|
804
835
|
// shared workspace reads as people's work, not anonymous rows. Null
|
|
805
836
|
// when the publish was token-only and the artifact is unclaimed.
|
|
806
|
-
publishedBy:
|
|
837
|
+
publishedBy: personSchema.nullable(),
|
|
807
838
|
// SPEC-2 §5.8 — the review dial, so the dashboard's settings dialog can
|
|
808
839
|
// render current state without a second fetch.
|
|
809
840
|
reviewMode: reviewModeSchema,
|
|
810
|
-
slug:
|
|
811
|
-
title:
|
|
812
|
-
totalViews:
|
|
841
|
+
slug: z12.string(),
|
|
842
|
+
title: z12.string(),
|
|
843
|
+
totalViews: z12.number(),
|
|
813
844
|
// SPEC §6.20 — messages by others newer than the viewer's last-seen
|
|
814
845
|
// watermark. 0 for signed-out/API-key-less contexts.
|
|
815
|
-
unreadComments:
|
|
816
|
-
updatedAt:
|
|
817
|
-
url:
|
|
818
|
-
versionCount:
|
|
846
|
+
unreadComments: z12.number(),
|
|
847
|
+
updatedAt: z12.string(),
|
|
848
|
+
url: z12.string(),
|
|
849
|
+
versionCount: z12.number(),
|
|
819
850
|
// SPEC-2 §5.1 — whether the caller clears the manage bar for this
|
|
820
851
|
// artifact (workspace admin, or the person who first published it).
|
|
821
852
|
// Only a manager's folder move inherits the folder's visibility, so the
|
|
822
853
|
// dashboard warns exactly the people the change can actually affect, and
|
|
823
854
|
// only a manager is offered the Share entry (§5.7).
|
|
824
|
-
viewerCanManage:
|
|
855
|
+
viewerCanManage: z12.boolean(),
|
|
825
856
|
// SPEC-2 §5.2 — the artifact's own visibility, the single enforcement
|
|
826
857
|
// source. The dashboard needs it to tell whether a folder move would
|
|
827
858
|
// widen exposure before it sends the PATCH (§3.4), and to render the
|
|
828
859
|
// audience glyph — one per level — on rows and cards (§5.7).
|
|
829
860
|
visibility: artifactVisibilitySchema
|
|
830
861
|
});
|
|
831
|
-
var ownArtifactsResponseSchema =
|
|
832
|
-
artifacts:
|
|
862
|
+
var ownArtifactsResponseSchema = z12.object({
|
|
863
|
+
artifacts: z12.array(ownArtifactSchema)
|
|
833
864
|
});
|
|
834
|
-
var revokePublishTokenResponseSchema =
|
|
835
|
-
revoked:
|
|
865
|
+
var revokePublishTokenResponseSchema = z12.object({
|
|
866
|
+
revoked: z12.boolean()
|
|
836
867
|
});
|
|
837
868
|
|
|
838
869
|
// ../shared/src/owner.ts
|
|
839
|
-
import { z as
|
|
870
|
+
import { z as z13 } from "zod";
|
|
840
871
|
var SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])$/;
|
|
841
|
-
var claimResponseSchema =
|
|
842
|
-
artifactId:
|
|
843
|
-
slug:
|
|
844
|
-
title:
|
|
845
|
-
url:
|
|
872
|
+
var claimResponseSchema = z13.object({
|
|
873
|
+
artifactId: z13.string(),
|
|
874
|
+
slug: z13.string(),
|
|
875
|
+
title: z13.string(),
|
|
876
|
+
url: z13.string().url()
|
|
846
877
|
});
|
|
847
|
-
var updateArtifactSchema =
|
|
878
|
+
var updateArtifactSchema = z13.object({
|
|
848
879
|
// Custom icon; explicit null clears it back to the default glyph.
|
|
849
880
|
// Part of what the artifact *is* (like the title), so it takes the
|
|
850
881
|
// same manage rights as title/slug — not the member-level folder move.
|
|
@@ -852,150 +883,159 @@ var updateArtifactSchema = z12.object({
|
|
|
852
883
|
// SPEC-2 §6.4 — placement + visibility. `folderId: null` clears the
|
|
853
884
|
// folder; `workspaceId: null` moves the artifact out of its workspace
|
|
854
885
|
// (§5.5 ownership transfer).
|
|
855
|
-
folderId:
|
|
856
|
-
|
|
886
|
+
folderId: z13.string().min(1).nullable().optional(),
|
|
887
|
+
// Keep the version list out of the review shell. Presentation only:
|
|
888
|
+
// versions stay immutable, and a `/vN/` URL still resolves.
|
|
889
|
+
hideVersions: z13.boolean().optional(),
|
|
890
|
+
slug: z13.string().min(3).max(63).regex(SLUG_PATTERN, {
|
|
857
891
|
message: "slug must be lowercase letters, digits, and hyphens, with no leading/trailing hyphen"
|
|
858
892
|
}).optional(),
|
|
859
|
-
title:
|
|
893
|
+
title: z13.string().min(1).max(200).optional(),
|
|
860
894
|
visibility: artifactVisibilitySchema.optional(),
|
|
861
|
-
workspaceId:
|
|
895
|
+
workspaceId: z13.string().min(1).nullable().optional()
|
|
862
896
|
}).refine(
|
|
863
|
-
(body) => body.title !== void 0 || body.slug !== void 0 || body.visibility !== void 0 || body.folderId !== void 0 || body.workspaceId !== void 0 || body.emoji !== void 0,
|
|
897
|
+
(body) => body.title !== void 0 || body.slug !== void 0 || body.visibility !== void 0 || body.folderId !== void 0 || body.workspaceId !== void 0 || body.emoji !== void 0 || body.hideVersions !== void 0,
|
|
864
898
|
{
|
|
865
|
-
message: "provide at least one of title, slug, visibility, folderId, workspaceId, emoji"
|
|
899
|
+
message: "provide at least one of title, slug, visibility, folderId, workspaceId, emoji, hideVersions"
|
|
866
900
|
}
|
|
867
901
|
);
|
|
868
|
-
var deleteArtifactResponseSchema =
|
|
869
|
-
deleted:
|
|
902
|
+
var deleteArtifactResponseSchema = z13.object({
|
|
903
|
+
deleted: z13.literal(true)
|
|
870
904
|
});
|
|
871
905
|
|
|
872
906
|
// ../shared/src/presence.ts
|
|
873
|
-
import { z as
|
|
907
|
+
import { z as z14 } from "zod";
|
|
874
908
|
var AGENT_STATES = ["listening", "editing", "publishing"];
|
|
875
|
-
var agentStateSchema =
|
|
909
|
+
var agentStateSchema = z14.enum(AGENT_STATES);
|
|
876
910
|
var AGENT_PRESENCE = {
|
|
877
911
|
editingTtlSeconds: 300,
|
|
878
912
|
heartbeatSeconds: 15,
|
|
879
913
|
shellPollSeconds: 15,
|
|
880
914
|
ttlSeconds: 45
|
|
881
915
|
};
|
|
882
|
-
var agentHeartbeatBodySchema =
|
|
916
|
+
var agentHeartbeatBodySchema = z14.object({
|
|
883
917
|
state: agentStateSchema.optional()
|
|
884
918
|
});
|
|
885
|
-
var agentHeartbeatResponseSchema =
|
|
886
|
-
listening:
|
|
919
|
+
var agentHeartbeatResponseSchema = z14.object({
|
|
920
|
+
listening: z14.literal(true),
|
|
887
921
|
state: agentStateSchema.optional(),
|
|
888
|
-
ttlSeconds:
|
|
922
|
+
ttlSeconds: z14.number().int().positive()
|
|
889
923
|
});
|
|
890
|
-
var agentPresenceSchema =
|
|
891
|
-
agent:
|
|
892
|
-
listening:
|
|
924
|
+
var agentPresenceSchema = z14.object({
|
|
925
|
+
agent: z14.object({ id: z14.string().nullable(), label: z14.string() }).nullable().default(null),
|
|
926
|
+
listening: z14.boolean(),
|
|
893
927
|
state: agentStateSchema.nullable().optional(),
|
|
894
|
-
versionNumber:
|
|
928
|
+
versionNumber: z14.number().int().positive().nullable()
|
|
895
929
|
});
|
|
896
930
|
|
|
897
931
|
// ../shared/src/protection.ts
|
|
898
|
-
import { z as
|
|
932
|
+
import { z as z15 } from "zod";
|
|
899
933
|
var PASSWORD_MIN = 6;
|
|
900
934
|
var PASSWORD_MAX = 128;
|
|
901
|
-
var gatePasswordSchema =
|
|
902
|
-
var setProtectionSchema =
|
|
935
|
+
var gatePasswordSchema = z15.string().min(PASSWORD_MIN, `Password must be at least ${PASSWORD_MIN} characters.`).max(PASSWORD_MAX, `Password must be at most ${PASSWORD_MAX} characters.`);
|
|
936
|
+
var setProtectionSchema = z15.object({
|
|
903
937
|
password: gatePasswordSchema.nullable()
|
|
904
938
|
});
|
|
905
|
-
var protectionResponseSchema =
|
|
906
|
-
protected:
|
|
939
|
+
var protectionResponseSchema = z15.object({
|
|
940
|
+
protected: z15.boolean()
|
|
907
941
|
});
|
|
908
|
-
var unlockSchema =
|
|
909
|
-
password:
|
|
942
|
+
var unlockSchema = z15.object({
|
|
943
|
+
password: z15.string().min(1).max(1024)
|
|
910
944
|
});
|
|
911
|
-
var unlockResponseSchema =
|
|
912
|
-
unlocked:
|
|
945
|
+
var unlockResponseSchema = z15.object({
|
|
946
|
+
unlocked: z15.literal(true)
|
|
913
947
|
});
|
|
914
948
|
|
|
915
949
|
// ../shared/src/report.ts
|
|
916
|
-
import { z as
|
|
917
|
-
var reportRequestSchema =
|
|
918
|
-
reason:
|
|
950
|
+
import { z as z16 } from "zod";
|
|
951
|
+
var reportRequestSchema = z16.object({
|
|
952
|
+
reason: z16.string().max(1e3).optional()
|
|
919
953
|
});
|
|
920
|
-
var reportResponseSchema =
|
|
921
|
-
reported:
|
|
954
|
+
var reportResponseSchema = z16.object({
|
|
955
|
+
reported: z16.literal(true)
|
|
922
956
|
});
|
|
923
957
|
|
|
924
958
|
// ../shared/src/reviewers.ts
|
|
925
|
-
import { z as
|
|
926
|
-
var artifactReviewerSchema =
|
|
927
|
-
avatarUrl:
|
|
928
|
-
displayName:
|
|
959
|
+
import { z as z17 } from "zod";
|
|
960
|
+
var artifactReviewerSchema = z17.object({
|
|
961
|
+
avatarUrl: z17.string().nullable(),
|
|
962
|
+
displayName: z17.string(),
|
|
929
963
|
// Exactly one of userId/guestId is set, per `kind`.
|
|
930
|
-
guestId:
|
|
964
|
+
guestId: z17.string().nullable(),
|
|
931
965
|
// "account", not commentAuthorSchema's "member" — the whole point here is
|
|
932
966
|
// that these people need not be workspace members. A guest can be named in
|
|
933
967
|
// a comment but never notified: guest_identities carries a display name and
|
|
934
968
|
// no email, so there is nowhere to send anything.
|
|
935
|
-
kind:
|
|
936
|
-
userId:
|
|
969
|
+
kind: z17.enum(["account", "guest"]),
|
|
970
|
+
userId: z17.string().nullable()
|
|
937
971
|
});
|
|
938
|
-
var artifactReviewerListResponseSchema =
|
|
939
|
-
reviewers:
|
|
972
|
+
var artifactReviewerListResponseSchema = z17.object({
|
|
973
|
+
reviewers: z17.array(artifactReviewerSchema)
|
|
940
974
|
});
|
|
941
975
|
|
|
942
976
|
// ../shared/src/stats.ts
|
|
943
|
-
import { z as
|
|
944
|
-
var avgViewSecondsSchema =
|
|
945
|
-
var versionViewStatsSchema =
|
|
977
|
+
import { z as z18 } from "zod";
|
|
978
|
+
var avgViewSecondsSchema = z18.number().int().nonnegative().nullable();
|
|
979
|
+
var versionViewStatsSchema = z18.object({
|
|
946
980
|
avgViewSeconds: avgViewSecondsSchema,
|
|
947
981
|
// Views from inside the review shell's iframe vs. direct visits to
|
|
948
982
|
// the render URL. views = embeddedViews + directViews.
|
|
949
|
-
directViews:
|
|
950
|
-
embeddedViews:
|
|
983
|
+
directViews: z18.number().int().nonnegative(),
|
|
984
|
+
embeddedViews: z18.number().int().nonnegative(),
|
|
951
985
|
// Distinct hashed viewer IPs across the version's lifetime.
|
|
952
|
-
uniqueViewers:
|
|
953
|
-
versionNumber:
|
|
954
|
-
views:
|
|
986
|
+
uniqueViewers: z18.number().int().nonnegative(),
|
|
987
|
+
versionNumber: z18.number().int().positive(),
|
|
988
|
+
views: z18.number().int().nonnegative()
|
|
955
989
|
});
|
|
956
|
-
var dailyViewsSchema =
|
|
990
|
+
var dailyViewsSchema = z18.object({
|
|
957
991
|
avgViewSeconds: avgViewSecondsSchema,
|
|
958
992
|
// UTC day, YYYY-MM-DD.
|
|
959
|
-
day:
|
|
960
|
-
uniqueViewers:
|
|
961
|
-
views:
|
|
993
|
+
day: z18.string(),
|
|
994
|
+
uniqueViewers: z18.number().int().nonnegative(),
|
|
995
|
+
views: z18.number().int().nonnegative()
|
|
962
996
|
});
|
|
963
|
-
var artifactStatsResponseSchema =
|
|
997
|
+
var artifactStatsResponseSchema = z18.object({
|
|
964
998
|
avgViewSeconds: avgViewSecondsSchema,
|
|
965
|
-
daily:
|
|
999
|
+
daily: z18.array(dailyViewsSchema),
|
|
966
1000
|
// Distinct hashed viewer IPs across all versions and days.
|
|
967
|
-
totalUniqueViewers:
|
|
968
|
-
totalViews:
|
|
969
|
-
versions:
|
|
1001
|
+
totalUniqueViewers: z18.number().int().nonnegative(),
|
|
1002
|
+
totalViews: z18.number().int().nonnegative(),
|
|
1003
|
+
versions: z18.array(versionViewStatsSchema)
|
|
970
1004
|
});
|
|
971
1005
|
|
|
972
1006
|
// ../shared/src/versions.ts
|
|
973
|
-
import { z as
|
|
974
|
-
var versionSourceSchema =
|
|
975
|
-
agentName:
|
|
976
|
-
type:
|
|
1007
|
+
import { z as z19 } from "zod";
|
|
1008
|
+
var versionSourceSchema = z19.object({
|
|
1009
|
+
agentName: z19.string().nullable(),
|
|
1010
|
+
type: z19.string()
|
|
977
1011
|
});
|
|
978
|
-
var versionChangesSchema =
|
|
979
|
-
added:
|
|
980
|
-
changed:
|
|
981
|
-
removed:
|
|
1012
|
+
var versionChangesSchema = z19.object({
|
|
1013
|
+
added: z19.array(z19.string()),
|
|
1014
|
+
changed: z19.array(z19.string()),
|
|
1015
|
+
removed: z19.array(z19.string())
|
|
982
1016
|
});
|
|
983
|
-
var versionSummarySchema =
|
|
1017
|
+
var versionSummarySchema = z19.object({
|
|
984
1018
|
// Absent for the first version — there is no previous version to diff against.
|
|
985
1019
|
changes: versionChangesSchema.nullable(),
|
|
986
|
-
createdAt:
|
|
987
|
-
entryUrl:
|
|
988
|
-
fileCount:
|
|
989
|
-
id:
|
|
990
|
-
isCurrent:
|
|
1020
|
+
createdAt: z19.string(),
|
|
1021
|
+
entryUrl: z19.string().url(),
|
|
1022
|
+
fileCount: z19.number().int().nonnegative(),
|
|
1023
|
+
id: z19.string(),
|
|
1024
|
+
isCurrent: z19.boolean(),
|
|
991
1025
|
// Author-supplied bullet-point changelog; null when the publish omitted it.
|
|
992
|
-
notes:
|
|
1026
|
+
notes: z19.string().nullable(),
|
|
1027
|
+
// The account that published this version, with their own avatar where
|
|
1028
|
+
// they've set one. Any workspace member can publish a new version
|
|
1029
|
+
// (SPEC-2 §5.1), so "which teammate" outranks "which agent" — the agent
|
|
1030
|
+
// is the tool, this is the person. Null for token-only publishes, which
|
|
1031
|
+
// carry no account.
|
|
1032
|
+
publishedBy: z19.object({ image: z19.string().nullable(), name: z19.string() }).nullable(),
|
|
993
1033
|
source: versionSourceSchema,
|
|
994
|
-
totalSizeBytes:
|
|
995
|
-
versionNumber:
|
|
1034
|
+
totalSizeBytes: z19.number().int().nonnegative(),
|
|
1035
|
+
versionNumber: z19.number().int().positive()
|
|
996
1036
|
});
|
|
997
|
-
var versionListResponseSchema =
|
|
998
|
-
versions:
|
|
1037
|
+
var versionListResponseSchema = z19.object({
|
|
1038
|
+
versions: z19.array(versionSummarySchema)
|
|
999
1039
|
});
|
|
1000
1040
|
|
|
1001
1041
|
// src/agent-identity.ts
|
|
@@ -1306,17 +1346,17 @@ import {
|
|
|
1306
1346
|
writeFileSync as writeFileSync2
|
|
1307
1347
|
} from "fs";
|
|
1308
1348
|
import path2 from "path";
|
|
1309
|
-
import { z as
|
|
1349
|
+
import { z as z21 } from "zod";
|
|
1310
1350
|
|
|
1311
1351
|
// src/credentials.ts
|
|
1312
1352
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
1313
1353
|
import { homedir } from "os";
|
|
1314
1354
|
import path from "path";
|
|
1315
|
-
import { z as
|
|
1355
|
+
import { z as z20 } from "zod";
|
|
1316
1356
|
var DEFAULT_API_URL = "https://artifact.cafe";
|
|
1317
|
-
var credentialsSchema =
|
|
1318
|
-
keys:
|
|
1319
|
-
version:
|
|
1357
|
+
var credentialsSchema = z20.object({
|
|
1358
|
+
keys: z20.record(z20.string(), z20.string()),
|
|
1359
|
+
version: z20.literal(1)
|
|
1320
1360
|
});
|
|
1321
1361
|
function credentialsPath() {
|
|
1322
1362
|
return path.join(homedir(), ".artifactcafe", "credentials");
|
|
@@ -1366,24 +1406,24 @@ function resolveApiKey(apiUrl2, flag) {
|
|
|
1366
1406
|
}
|
|
1367
1407
|
|
|
1368
1408
|
// src/config.ts
|
|
1369
|
-
var configSchema =
|
|
1370
|
-
apiUrl:
|
|
1371
|
-
artifactId:
|
|
1372
|
-
folder:
|
|
1373
|
-
folderId:
|
|
1409
|
+
var configSchema = z21.object({
|
|
1410
|
+
apiUrl: z21.string(),
|
|
1411
|
+
artifactId: z21.string(),
|
|
1412
|
+
folder: z21.string().optional(),
|
|
1413
|
+
folderId: z21.string().optional(),
|
|
1374
1414
|
// Optional: a folder linked by `link` to an artifact you own carries no
|
|
1375
1415
|
// token — owner actions authorize via your stored login instead. A first
|
|
1376
1416
|
// publish still writes the anonymous-mode token here.
|
|
1377
|
-
publishToken:
|
|
1378
|
-
slug:
|
|
1379
|
-
url:
|
|
1380
|
-
workspace:
|
|
1381
|
-
workspaceId:
|
|
1382
|
-
workspaceKind:
|
|
1383
|
-
});
|
|
1384
|
-
var projectConfigSchema =
|
|
1385
|
-
folder:
|
|
1386
|
-
workspace:
|
|
1417
|
+
publishToken: z21.string().optional(),
|
|
1418
|
+
slug: z21.string(),
|
|
1419
|
+
url: z21.string(),
|
|
1420
|
+
workspace: z21.string().optional(),
|
|
1421
|
+
workspaceId: z21.string().optional(),
|
|
1422
|
+
workspaceKind: z21.enum(["personal", "workspace"]).optional()
|
|
1423
|
+
});
|
|
1424
|
+
var projectConfigSchema = z21.object({
|
|
1425
|
+
folder: z21.string().trim().min(1).optional(),
|
|
1426
|
+
workspace: z21.string().trim().min(1)
|
|
1387
1427
|
}).strict();
|
|
1388
1428
|
var CONFIG_DIR = ".artifactcafe";
|
|
1389
1429
|
var CONFIG_FILE = "config.json";
|
|
@@ -1419,7 +1459,7 @@ function readProjectConfig(dir) {
|
|
|
1419
1459
|
JSON.parse(readFileSync2(file, "utf8"))
|
|
1420
1460
|
);
|
|
1421
1461
|
} catch (error) {
|
|
1422
|
-
const message = error instanceof
|
|
1462
|
+
const message = error instanceof z21.ZodError ? error.issues[0]?.message ?? "invalid project target" : "invalid JSON";
|
|
1423
1463
|
throw new Error(`Invalid ${file}: ${message}.`);
|
|
1424
1464
|
}
|
|
1425
1465
|
}
|
|
@@ -1484,7 +1524,8 @@ function resolveArtifactTarget(dir, opts = {}) {
|
|
|
1484
1524
|
);
|
|
1485
1525
|
}
|
|
1486
1526
|
const folderToken = artifactId === config?.artifactId ? config.publishToken : void 0;
|
|
1487
|
-
const
|
|
1527
|
+
const apiKey = resolveApiKey(apiUrl2, opts.apiKey);
|
|
1528
|
+
const credential = (apiKey?.startsWith("aat_") ? apiKey : void 0) ?? folderToken ?? process.env.ARTIFACT_CAFE_TOKEN ?? apiKey;
|
|
1488
1529
|
const url = artifactId === config?.artifactId ? config.url : void 0;
|
|
1489
1530
|
return { apiUrl: apiUrl2, artifactId, credential, url };
|
|
1490
1531
|
}
|
|
@@ -1971,6 +2012,7 @@ async function publish(opts) {
|
|
|
1971
2012
|
const token = (artifactId !== null && artifactId === config?.artifactId ? config.publishToken : void 0) ?? process.env.ARTIFACT_CAFE_TOKEN;
|
|
1972
2013
|
const apiUrl2 = process.env.ARTIFACT_CAFE_URL ?? config?.apiUrl ?? DEFAULT_API_URL;
|
|
1973
2014
|
const apiKey = resolveApiKey(apiUrl2, opts.apiKey);
|
|
2015
|
+
const usingAgentToken = apiKey?.startsWith("aat_") === true;
|
|
1974
2016
|
const placement = await resolvePlacement({
|
|
1975
2017
|
apiKey,
|
|
1976
2018
|
apiUrl: apiUrl2,
|
|
@@ -2019,7 +2061,7 @@ async function publish(opts) {
|
|
|
2019
2061
|
try {
|
|
2020
2062
|
session = await client.createSession(sessionBody);
|
|
2021
2063
|
} catch (err) {
|
|
2022
|
-
const keyRefused = apiKey !== void 0 && token !== void 0 && apiKey !== token && artifactId !== null && err instanceof ApiRequestError && (err.status === 401 || err.status === 403);
|
|
2064
|
+
const keyRefused = apiKey !== void 0 && !usingAgentToken && token !== void 0 && apiKey !== token && artifactId !== null && err instanceof ApiRequestError && (err.status === 401 || err.status === 403);
|
|
2023
2065
|
if (!keyRefused) {
|
|
2024
2066
|
throw err;
|
|
2025
2067
|
}
|
|
@@ -2052,16 +2094,19 @@ async function publish(opts) {
|
|
|
2052
2094
|
presence.stop();
|
|
2053
2095
|
}
|
|
2054
2096
|
const result = await client.finalize(session.publishSessionId);
|
|
2097
|
+
if (usingAgentToken && result.workspaceId) {
|
|
2098
|
+
placement.workspaceId = result.workspaceId;
|
|
2099
|
+
}
|
|
2055
2100
|
const rememberedProjectFile = placement.rememberProjectDefault ? writeProjectConfig(dir, placement.rememberProjectDefault) : null;
|
|
2056
|
-
const existingToken = config?.artifactId === result.artifactId ? config.publishToken : void 0;
|
|
2057
|
-
const shouldWriteConfig = result.publishToken !== void 0 || config?.artifactId === result.artifactId || opts.workspace !== void 0 || opts.folder !== void 0 || placement.workspaceId !== void 0;
|
|
2101
|
+
const existingToken = !usingAgentToken && config?.artifactId === result.artifactId ? config.publishToken : void 0;
|
|
2102
|
+
const shouldWriteConfig = usingAgentToken || result.publishToken !== void 0 || config?.artifactId === result.artifactId || opts.workspace !== void 0 || opts.folder !== void 0 || placement.workspaceId !== void 0;
|
|
2058
2103
|
if (shouldWriteConfig) {
|
|
2059
2104
|
writeConfig(dir, {
|
|
2060
2105
|
apiUrl: apiUrl2,
|
|
2061
2106
|
artifactId: result.artifactId,
|
|
2062
2107
|
...placement.folder ? { folder: placement.folder } : {},
|
|
2063
2108
|
...placement.folderId ? { folderId: placement.folderId } : {},
|
|
2064
|
-
|
|
2109
|
+
...!usingAgentToken && (result.publishToken ?? existingToken) ? { publishToken: result.publishToken ?? existingToken } : {},
|
|
2065
2110
|
slug: slugFromUrl(result.url),
|
|
2066
2111
|
url: result.url,
|
|
2067
2112
|
...placement.workspace ? { workspace: placement.workspace } : {},
|
|
@@ -2181,6 +2226,18 @@ function accessNote(visibility) {
|
|
|
2181
2226
|
}
|
|
2182
2227
|
async function resolvePlacement(params) {
|
|
2183
2228
|
const { apiKey, apiUrl: apiUrl2, config, isNewArtifact, opts } = params;
|
|
2229
|
+
if (apiKey?.startsWith("aat_")) {
|
|
2230
|
+
if (opts.workspace !== void 0 || opts.folder !== void 0) {
|
|
2231
|
+
throw new Error(
|
|
2232
|
+
"An agent token selects its own workspace; omit --workspace and --folder."
|
|
2233
|
+
);
|
|
2234
|
+
}
|
|
2235
|
+
return {
|
|
2236
|
+
destination: "workspace",
|
|
2237
|
+
destinationLabel: "Agent token's workspace",
|
|
2238
|
+
destinationSource: "agent-token"
|
|
2239
|
+
};
|
|
2240
|
+
}
|
|
2184
2241
|
const hasPlacementFlag = opts.workspace !== void 0 || opts.folder !== void 0;
|
|
2185
2242
|
if (!hasPlacementFlag && config?.workspaceId) {
|
|
2186
2243
|
const isPersonal = config.workspaceKind === "personal";
|
|
@@ -2541,100 +2598,45 @@ function printFolder(folder) {
|
|
|
2541
2598
|
// src/link.ts
|
|
2542
2599
|
import path8 from "path";
|
|
2543
2600
|
import { createInterface as createInterface2 } from "readline";
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
const { artifacts } = await createApiClient(apiUrl2, key).listArtifacts();
|
|
2556
|
-
if (artifacts.length === 0) {
|
|
2557
|
-
throw new Error(
|
|
2558
|
-
"No artifacts in your account yet \u2014 publish one first, or claim one via its claim link."
|
|
2559
|
-
);
|
|
2560
|
-
}
|
|
2561
|
-
const selector = opts.artifact ?? opts.slug;
|
|
2562
|
-
let chosen;
|
|
2563
|
-
if (opts.artifact) {
|
|
2564
|
-
chosen = artifacts.find((a) => a.id === opts.artifact);
|
|
2565
|
-
} else if (opts.slug) {
|
|
2566
|
-
chosen = artifacts.find((a) => a.slug === opts.slug);
|
|
2567
|
-
}
|
|
2568
|
-
if (selector && !chosen) {
|
|
2569
|
-
throw new Error(
|
|
2570
|
-
`No artifact "${selector}" in your account \u2014 run \`artifact-cafe list\` to see them.`
|
|
2571
|
-
);
|
|
2572
|
-
}
|
|
2573
|
-
if (opts.json && !chosen) {
|
|
2574
|
-
console.log(JSON.stringify({ artifacts }, null, 2));
|
|
2575
|
-
return;
|
|
2576
|
-
}
|
|
2577
|
-
if (!chosen) {
|
|
2578
|
-
if (!process.stdin.isTTY) {
|
|
2579
|
-
throw new Error(
|
|
2580
|
-
"Pick an artifact with --artifact <id> or --slug <slug> (or --json to list them). Interactive selection needs a terminal."
|
|
2581
|
-
);
|
|
2582
|
-
}
|
|
2583
|
-
chosen = await pickArtifact(artifacts);
|
|
2584
|
-
}
|
|
2585
|
-
const dir = path8.resolve(opts.dir);
|
|
2586
|
-
writeConfig(dir, {
|
|
2587
|
-
apiUrl: apiUrl2,
|
|
2588
|
-
artifactId: chosen.id,
|
|
2589
|
-
slug: chosen.slug,
|
|
2590
|
-
url: chosen.url
|
|
2591
|
-
// No publishToken — this folder authorizes via your login, not a secret.
|
|
2592
|
-
});
|
|
2593
|
-
if (opts.json) {
|
|
2594
|
-
console.log(
|
|
2595
|
-
JSON.stringify(
|
|
2596
|
-
{
|
|
2597
|
-
artifactId: chosen.id,
|
|
2598
|
-
linked: true,
|
|
2599
|
-
slug: chosen.slug,
|
|
2600
|
-
url: chosen.url
|
|
2601
|
-
},
|
|
2602
|
-
null,
|
|
2603
|
-
2
|
|
2604
|
-
)
|
|
2605
|
-
);
|
|
2606
|
-
return;
|
|
2607
|
-
}
|
|
2608
|
-
console.log(`
|
|
2609
|
-
\u2713 Linked ${dir} \u2192 "${chosen.title}" \u2014 ${chosen.url}`);
|
|
2610
|
-
console.log(
|
|
2611
|
-
" Owner actions (publish, comments --wait, protect) use your login.\n"
|
|
2601
|
+
|
|
2602
|
+
// src/list.ts
|
|
2603
|
+
async function teamGroups(client) {
|
|
2604
|
+
const { workspaces: workspaces3 } = await client.listWorkspaces();
|
|
2605
|
+
return await Promise.all(
|
|
2606
|
+
workspaces3.filter((workspace) => !workspace.isPersonal).map(async (workspace) => ({
|
|
2607
|
+
artifacts: (await client.listWorkspaceArtifacts(workspace.id)).artifacts,
|
|
2608
|
+
handle: workspace.handle,
|
|
2609
|
+
id: workspace.id,
|
|
2610
|
+
name: workspace.name
|
|
2611
|
+
}))
|
|
2612
2612
|
);
|
|
2613
2613
|
}
|
|
2614
|
-
function
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
)
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2614
|
+
async function reachableArtifacts(client) {
|
|
2615
|
+
const [own, groups] = await Promise.all([
|
|
2616
|
+
client.listArtifacts(),
|
|
2617
|
+
teamGroups(client)
|
|
2618
|
+
]);
|
|
2619
|
+
return [
|
|
2620
|
+
...own.artifacts.map((artifact) => ({
|
|
2621
|
+
currentVersionNumber: artifact.currentVersionNumber,
|
|
2622
|
+
id: artifact.id,
|
|
2623
|
+
slug: artifact.slug,
|
|
2624
|
+
title: artifact.title,
|
|
2625
|
+
url: artifact.url,
|
|
2626
|
+
workspaceHandle: null
|
|
2627
|
+
})),
|
|
2628
|
+
...groups.flatMap(
|
|
2629
|
+
(group) => group.artifacts.map((artifact) => ({
|
|
2630
|
+
currentVersionNumber: artifact.currentVersionNumber,
|
|
2631
|
+
id: artifact.id,
|
|
2632
|
+
slug: artifact.slug,
|
|
2633
|
+
title: artifact.title,
|
|
2634
|
+
url: artifact.url,
|
|
2635
|
+
workspaceHandle: group.handle
|
|
2636
|
+
}))
|
|
2637
|
+
)
|
|
2638
|
+
];
|
|
2635
2639
|
}
|
|
2636
|
-
|
|
2637
|
-
// src/list.ts
|
|
2638
2640
|
async function list(opts) {
|
|
2639
2641
|
const apiUrl2 = (process.env.ARTIFACT_CAFE_URL ?? DEFAULT_API_URL).replace(
|
|
2640
2642
|
/\/$/,
|
|
@@ -2651,22 +2653,44 @@ async function list(opts) {
|
|
|
2651
2653
|
await listWorkspace(client, opts);
|
|
2652
2654
|
return;
|
|
2653
2655
|
}
|
|
2654
|
-
const data = await
|
|
2656
|
+
const [data, groups] = await Promise.all([
|
|
2657
|
+
client.listArtifacts(),
|
|
2658
|
+
teamGroups(client)
|
|
2659
|
+
]);
|
|
2655
2660
|
if (opts.json) {
|
|
2656
|
-
console.log(
|
|
2661
|
+
console.log(
|
|
2662
|
+
JSON.stringify({ artifacts: data.artifacts, workspaces: groups }, null, 2)
|
|
2663
|
+
);
|
|
2657
2664
|
return;
|
|
2658
2665
|
}
|
|
2659
|
-
|
|
2666
|
+
const total = data.artifacts.length + groups.reduce((sum, group) => sum + group.artifacts.length, 0);
|
|
2667
|
+
if (total === 0) {
|
|
2660
2668
|
console.log(
|
|
2661
|
-
"No artifacts
|
|
2669
|
+
"No artifacts you can publish to yet \u2014 publish while logged in, or claim one via its claim link."
|
|
2662
2670
|
);
|
|
2663
2671
|
return;
|
|
2664
2672
|
}
|
|
2665
|
-
|
|
2666
|
-
|
|
2673
|
+
if (data.artifacts.length > 0) {
|
|
2674
|
+
const plural = data.artifacts.length === 1 ? "" : "s";
|
|
2675
|
+
console.log(`${data.artifacts.length} artifact${plural}
|
|
2667
2676
|
`);
|
|
2668
|
-
|
|
2669
|
-
|
|
2677
|
+
for (const artifact of data.artifacts) {
|
|
2678
|
+
printArtifact(artifact);
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
for (const group of groups) {
|
|
2682
|
+
if (group.artifacts.length === 0) {
|
|
2683
|
+
continue;
|
|
2684
|
+
}
|
|
2685
|
+
const plural = group.artifacts.length === 1 ? "" : "s";
|
|
2686
|
+
console.log(
|
|
2687
|
+
`${group.artifacts.length} artifact${plural} in ${group.handle}
|
|
2688
|
+
`
|
|
2689
|
+
);
|
|
2690
|
+
for (const artifact of group.artifacts) {
|
|
2691
|
+
printWorkspaceArtifact(artifact);
|
|
2692
|
+
}
|
|
2693
|
+
console.log("");
|
|
2670
2694
|
}
|
|
2671
2695
|
}
|
|
2672
2696
|
async function listWorkspace(client, opts) {
|
|
@@ -2759,6 +2783,101 @@ function relativeTime(iso) {
|
|
|
2759
2783
|
return iso.slice(0, 10);
|
|
2760
2784
|
}
|
|
2761
2785
|
|
|
2786
|
+
// src/link.ts
|
|
2787
|
+
async function link(opts) {
|
|
2788
|
+
const apiUrl2 = (process.env.ARTIFACT_CAFE_URL ?? DEFAULT_API_URL).replace(
|
|
2789
|
+
/\/$/,
|
|
2790
|
+
""
|
|
2791
|
+
);
|
|
2792
|
+
const key = resolveApiKey(apiUrl2, opts.apiKey);
|
|
2793
|
+
if (!key) {
|
|
2794
|
+
throw new Error(
|
|
2795
|
+
`Linking needs an account \u2014 run \`artifact-cafe login\` first (no API key for ${apiOrigin(apiUrl2)}).`
|
|
2796
|
+
);
|
|
2797
|
+
}
|
|
2798
|
+
const artifacts = await reachableArtifacts(createApiClient(apiUrl2, key));
|
|
2799
|
+
if (artifacts.length === 0) {
|
|
2800
|
+
throw new Error(
|
|
2801
|
+
"No artifacts you can publish to yet \u2014 publish one first, or claim one via its claim link."
|
|
2802
|
+
);
|
|
2803
|
+
}
|
|
2804
|
+
const selector = opts.artifact ?? opts.slug;
|
|
2805
|
+
let chosen;
|
|
2806
|
+
if (opts.artifact) {
|
|
2807
|
+
chosen = artifacts.find((a) => a.id === opts.artifact);
|
|
2808
|
+
} else if (opts.slug) {
|
|
2809
|
+
chosen = artifacts.find((a) => a.slug === opts.slug);
|
|
2810
|
+
}
|
|
2811
|
+
if (selector && !chosen) {
|
|
2812
|
+
throw new Error(
|
|
2813
|
+
`No artifact "${selector}" you can publish to \u2014 run \`artifact-cafe list\` to see them.`
|
|
2814
|
+
);
|
|
2815
|
+
}
|
|
2816
|
+
if (opts.json && !chosen) {
|
|
2817
|
+
console.log(JSON.stringify({ artifacts }, null, 2));
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
if (!chosen) {
|
|
2821
|
+
if (!process.stdin.isTTY) {
|
|
2822
|
+
throw new Error(
|
|
2823
|
+
"Pick an artifact with --artifact <id> or --slug <slug> (or --json to list them). Interactive selection needs a terminal."
|
|
2824
|
+
);
|
|
2825
|
+
}
|
|
2826
|
+
chosen = await pickArtifact(artifacts);
|
|
2827
|
+
}
|
|
2828
|
+
const dir = path8.resolve(opts.dir);
|
|
2829
|
+
writeConfig(dir, {
|
|
2830
|
+
apiUrl: apiUrl2,
|
|
2831
|
+
artifactId: chosen.id,
|
|
2832
|
+
slug: chosen.slug,
|
|
2833
|
+
url: chosen.url
|
|
2834
|
+
// No publishToken — this folder authorizes via your login, not a secret.
|
|
2835
|
+
});
|
|
2836
|
+
if (opts.json) {
|
|
2837
|
+
console.log(
|
|
2838
|
+
JSON.stringify(
|
|
2839
|
+
{
|
|
2840
|
+
artifactId: chosen.id,
|
|
2841
|
+
linked: true,
|
|
2842
|
+
slug: chosen.slug,
|
|
2843
|
+
url: chosen.url
|
|
2844
|
+
},
|
|
2845
|
+
null,
|
|
2846
|
+
2
|
|
2847
|
+
)
|
|
2848
|
+
);
|
|
2849
|
+
return;
|
|
2850
|
+
}
|
|
2851
|
+
console.log(`
|
|
2852
|
+
\u2713 Linked ${dir} \u2192 "${chosen.title}" \u2014 ${chosen.url}`);
|
|
2853
|
+
console.log(
|
|
2854
|
+
" Owner actions (publish, comments --wait, protect) use your login.\n"
|
|
2855
|
+
);
|
|
2856
|
+
}
|
|
2857
|
+
function pickArtifact(artifacts) {
|
|
2858
|
+
console.log("Artifacts you can publish to:\n");
|
|
2859
|
+
artifacts.forEach((a, i) => {
|
|
2860
|
+
const v = a.currentVersionNumber ? `v${a.currentVersionNumber}` : "\u2014";
|
|
2861
|
+
const where = a.workspaceHandle ? ` \xB7 ${a.workspaceHandle}` : "";
|
|
2862
|
+
console.log(
|
|
2863
|
+
` ${String(i + 1).padStart(2)}. ${a.title} \xB7 ${v}${where} \xB7 ${a.url}`
|
|
2864
|
+
);
|
|
2865
|
+
});
|
|
2866
|
+
const rl = createInterface2({ input: process.stdin, output: process.stdout });
|
|
2867
|
+
return new Promise((resolve2, reject) => {
|
|
2868
|
+
rl.question(`
|
|
2869
|
+
Link which? [1-${artifacts.length}]: `, (answer) => {
|
|
2870
|
+
rl.close();
|
|
2871
|
+
const n = Number(answer.trim());
|
|
2872
|
+
if (!(Number.isInteger(n) && n >= 1 && n <= artifacts.length)) {
|
|
2873
|
+
reject(new Error(`Enter a number between 1 and ${artifacts.length}.`));
|
|
2874
|
+
return;
|
|
2875
|
+
}
|
|
2876
|
+
resolve2(artifacts[n - 1]);
|
|
2877
|
+
});
|
|
2878
|
+
});
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2762
2881
|
// src/login.ts
|
|
2763
2882
|
import { createInterface as createInterface3 } from "readline";
|
|
2764
2883
|
function apiUrl() {
|
|
@@ -3343,18 +3462,18 @@ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as rea
|
|
|
3343
3462
|
import { createRequire } from "module";
|
|
3344
3463
|
import { homedir as homedir2 } from "os";
|
|
3345
3464
|
import path18 from "path";
|
|
3346
|
-
import { z as
|
|
3465
|
+
import { z as z22 } from "zod";
|
|
3347
3466
|
var REGISTRY_LATEST_URL = "https://registry.npmjs.org/artifact-cafe/latest";
|
|
3348
3467
|
var SKILL_SOURCE_URL = "https://raw.githubusercontent.com/Artifact-Cafe/skill/main/artifact-cafe/SKILL.md";
|
|
3349
3468
|
var SKILL_UPDATE_COMMAND = "npx skills add artifact-cafe/skill --skill artifact-cafe -g";
|
|
3350
3469
|
var CHECK_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
3351
3470
|
var FETCH_TIMEOUT_MS = 2e3;
|
|
3352
3471
|
var SKILL_VERSION_PATTERN = /\*\*Skill version:\s*(\d+\.\d+\.\d+)\*\*/;
|
|
3353
|
-
var cacheSchema =
|
|
3354
|
-
checkedAt:
|
|
3355
|
-
cliLatest:
|
|
3356
|
-
skillLatest:
|
|
3357
|
-
version:
|
|
3472
|
+
var cacheSchema = z22.object({
|
|
3473
|
+
checkedAt: z22.number(),
|
|
3474
|
+
cliLatest: z22.string().nullable(),
|
|
3475
|
+
skillLatest: z22.string().nullable(),
|
|
3476
|
+
version: z22.literal(1)
|
|
3358
3477
|
});
|
|
3359
3478
|
function cliVersion() {
|
|
3360
3479
|
const pkg = createRequire(import.meta.url)("../package.json");
|
|
@@ -3409,7 +3528,7 @@ async function fetchText(url) {
|
|
|
3409
3528
|
}
|
|
3410
3529
|
async function fetchLatestVersions(previous) {
|
|
3411
3530
|
const [cli, skill] = await Promise.all([
|
|
3412
|
-
fetchJson(REGISTRY_LATEST_URL).then((body) =>
|
|
3531
|
+
fetchJson(REGISTRY_LATEST_URL).then((body) => z22.object({ version: z22.string() }).parse(body).version).catch(() => null),
|
|
3413
3532
|
fetchText(SKILL_SOURCE_URL).then((body) => SKILL_VERSION_PATTERN.exec(body)?.[1] ?? null).catch(() => null)
|
|
3414
3533
|
]);
|
|
3415
3534
|
return {
|
|
@@ -3540,7 +3659,7 @@ function readStringArg(argv, flag) {
|
|
|
3540
3659
|
var publish2 = defineCommand({
|
|
3541
3660
|
args: {
|
|
3542
3661
|
"api-key": {
|
|
3543
|
-
description: "Publish with an account
|
|
3662
|
+
description: "Publish with an account key or agent token (default: env or login)",
|
|
3544
3663
|
type: "string"
|
|
3545
3664
|
},
|
|
3546
3665
|
artifact: {
|
|
@@ -3673,7 +3792,7 @@ var list2 = defineCommand({
|
|
|
3673
3792
|
}
|
|
3674
3793
|
},
|
|
3675
3794
|
meta: {
|
|
3676
|
-
description: "List the artifacts your account
|
|
3795
|
+
description: "List the artifacts your account can publish to",
|
|
3677
3796
|
name: "list"
|
|
3678
3797
|
},
|
|
3679
3798
|
async run({ args }) {
|
|
@@ -3827,7 +3946,7 @@ var link2 = defineCommand({
|
|
|
3827
3946
|
}
|
|
3828
3947
|
},
|
|
3829
3948
|
meta: {
|
|
3830
|
-
description: "Link a folder to
|
|
3949
|
+
description: "Link a folder to an artifact you can publish to (yours or a teammate's)",
|
|
3831
3950
|
name: "link"
|
|
3832
3951
|
},
|
|
3833
3952
|
async run({ args }) {
|
|
@@ -3848,7 +3967,7 @@ var link2 = defineCommand({
|
|
|
3848
3967
|
var comments2 = defineCommand({
|
|
3849
3968
|
args: {
|
|
3850
3969
|
"api-key": {
|
|
3851
|
-
description: "Authorize with an account
|
|
3970
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
3852
3971
|
type: "string"
|
|
3853
3972
|
},
|
|
3854
3973
|
artifact: {
|
|
@@ -3912,7 +4031,7 @@ var comments2 = defineCommand({
|
|
|
3912
4031
|
var listen = defineCommand({
|
|
3913
4032
|
args: {
|
|
3914
4033
|
"api-key": {
|
|
3915
|
-
description: "Authorize with an account
|
|
4034
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
3916
4035
|
type: "string"
|
|
3917
4036
|
},
|
|
3918
4037
|
artifact: {
|
|
@@ -3972,7 +4091,7 @@ var listen = defineCommand({
|
|
|
3972
4091
|
var statusCmd = defineCommand({
|
|
3973
4092
|
args: {
|
|
3974
4093
|
"api-key": {
|
|
3975
|
-
description: "Authorize with an account
|
|
4094
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
3976
4095
|
type: "string"
|
|
3977
4096
|
},
|
|
3978
4097
|
artifact: {
|
|
@@ -4013,7 +4132,7 @@ var statusCmd = defineCommand({
|
|
|
4013
4132
|
var protect2 = defineCommand({
|
|
4014
4133
|
args: {
|
|
4015
4134
|
"api-key": {
|
|
4016
|
-
description: "Authorize with an account
|
|
4135
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
4017
4136
|
type: "string"
|
|
4018
4137
|
},
|
|
4019
4138
|
artifact: {
|
|
@@ -4052,7 +4171,7 @@ var protect2 = defineCommand({
|
|
|
4052
4171
|
var review2 = defineCommand({
|
|
4053
4172
|
args: {
|
|
4054
4173
|
"api-key": {
|
|
4055
|
-
description: "Authorize with an account
|
|
4174
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
4056
4175
|
type: "string"
|
|
4057
4176
|
},
|
|
4058
4177
|
artifact: {
|
|
@@ -4093,7 +4212,7 @@ var review2 = defineCommand({
|
|
|
4093
4212
|
var threadStatusCommand = (action) => defineCommand({
|
|
4094
4213
|
args: {
|
|
4095
4214
|
"api-key": {
|
|
4096
|
-
description: "Authorize with an account
|
|
4215
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
4097
4216
|
type: "string"
|
|
4098
4217
|
},
|
|
4099
4218
|
artifact: {
|
|
@@ -4142,7 +4261,7 @@ var ack = threadStatusCommand("ack");
|
|
|
4142
4261
|
var reply = defineCommand({
|
|
4143
4262
|
args: {
|
|
4144
4263
|
"api-key": {
|
|
4145
|
-
description: "Authorize with an account
|
|
4264
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
4146
4265
|
type: "string"
|
|
4147
4266
|
},
|
|
4148
4267
|
artifact: {
|
|
@@ -4268,7 +4387,7 @@ var comment2 = defineCommand({
|
|
|
4268
4387
|
var edit = defineCommand({
|
|
4269
4388
|
args: {
|
|
4270
4389
|
"api-key": {
|
|
4271
|
-
description: "Authorize with an account
|
|
4390
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
4272
4391
|
type: "string"
|
|
4273
4392
|
},
|
|
4274
4393
|
artifact: {
|
|
@@ -4311,7 +4430,7 @@ var edit = defineCommand({
|
|
|
4311
4430
|
var del = defineCommand({
|
|
4312
4431
|
args: {
|
|
4313
4432
|
"api-key": {
|
|
4314
|
-
description: "Authorize with an account
|
|
4433
|
+
description: "Authorize with an account key or agent token (default: env or login)",
|
|
4315
4434
|
type: "string"
|
|
4316
4435
|
},
|
|
4317
4436
|
artifact: {
|