ryugi-artifacts 1.16.2 → 1.16.3
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/cli.cjs
CHANGED
|
@@ -281,10 +281,16 @@ async function comment(options, emit) {
|
|
|
281
281
|
throw new CliError(`The running artifacts server is older than this CLI. Run \`${invocation()} start --project-dir ${server.project}\` to replace it, then run this again.`);
|
|
282
282
|
}
|
|
283
283
|
if (status < 200 || status >= 300) throw new CliError(json.error || `HTTP ${status}`);
|
|
284
|
-
if (action === "list") emit({ type: "comments", artifact: options.artifact, threads: json.threads, ...options.all ? { all: true } : {} });
|
|
284
|
+
if (action === "list") emit({ type: "comments", artifact: options.artifact, threads: json.threads, ...json.groups ? { groups: json.groups } : {}, ...options.all ? { all: true } : {} });
|
|
285
285
|
else emit({ type: WRITTEN[action], artifact: options.artifact, threadId: json.threadId, ...json.messageId ? { messageId: json.messageId } : {} });
|
|
286
286
|
return 0;
|
|
287
287
|
}
|
|
288
|
+
var VERDICT_TEXT = { pass: "passed", reject: "rejected", pending: "waiting for a verdict" };
|
|
289
|
+
var plural = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
290
|
+
function groupText(group) {
|
|
291
|
+
const parts = [VERDICT_TEXT[group.verdict], group.evidenceUpdated ? "evidence replaced since the last verdict" : "", group.rejectThreads ? `${plural(group.rejectThreads, "open reject thread")}` : ""];
|
|
292
|
+
return ` ${group.id}${group.title ? ` (${group.title})` : ""}: ${parts.filter(Boolean).join(" \xB7 ")}`;
|
|
293
|
+
}
|
|
288
294
|
var clip = (text2, max) => text2.length > max ? `${text2.slice(0, max)}\u2026` : text2;
|
|
289
295
|
var percent = (value) => `${Math.round(value * 100)}%`;
|
|
290
296
|
function anchorLines(thread) {
|
|
@@ -312,8 +318,12 @@ function threadText(thread) {
|
|
|
312
318
|
function commentText(value) {
|
|
313
319
|
if (value.type === "comments") {
|
|
314
320
|
const threads = value.threads ?? [];
|
|
315
|
-
|
|
316
|
-
|
|
321
|
+
const groups = value.groups ?? [];
|
|
322
|
+
const head = threads.length ? threads.map(threadText).join("\n\n") : value.all ? `No comments on ${value.artifact}.` : `No new comments on ${value.artifact}.`;
|
|
323
|
+
return groups.length ? `${head}
|
|
324
|
+
|
|
325
|
+
Verify groups:
|
|
326
|
+
${groups.map(groupText).join("\n")}` : head;
|
|
317
327
|
}
|
|
318
328
|
if (value.type === "comment-added") return `Added thread ${value.threadId} (message ${value.messageId})`;
|
|
319
329
|
if (value.type === "comment-replied") return `Replied in thread ${value.threadId} (message ${value.messageId})`;
|
|
@@ -339,6 +349,7 @@ var import_node_path2 = __toESM(require("node:path"), 1);
|
|
|
339
349
|
// src/shared/validate.ts
|
|
340
350
|
var BOARD_NUMBERS = ["x", "y", "w", "h"];
|
|
341
351
|
var BOARD_REQUIRED = ["file", "page", ...BOARD_NUMBERS];
|
|
352
|
+
var MEDIA_REQUIRED = ["src", "page", ...BOARD_NUMBERS];
|
|
342
353
|
|
|
343
354
|
// src/server/state.ts
|
|
344
355
|
function writeJsonAtomic(file, value) {
|
|
@@ -911,7 +922,7 @@ async function main(argv) {
|
|
|
911
922
|
}, emit);
|
|
912
923
|
}
|
|
913
924
|
if (command === "--version" || command === "-v") {
|
|
914
|
-
console.log("1.16.
|
|
925
|
+
console.log("1.16.3");
|
|
915
926
|
return 0;
|
|
916
927
|
}
|
|
917
928
|
if (command === "--help" || command === "-h") {
|
package/dist/server.cjs
CHANGED
|
@@ -5182,6 +5182,8 @@ var import_node_path20 = __toESM(require("node:path"), 1);
|
|
|
5182
5182
|
|
|
5183
5183
|
// src/shared/types.ts
|
|
5184
5184
|
var ARTIFACT_TYPES = ["artboard", "document", "html"];
|
|
5185
|
+
var BOARD_TYPES = ["html", "image", "video"];
|
|
5186
|
+
var isMediaBoard = (board) => board.type === "image" || board.type === "video";
|
|
5185
5187
|
|
|
5186
5188
|
// src/server/artifacts.ts
|
|
5187
5189
|
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
@@ -17961,6 +17963,14 @@ function readBoardAnchor(value) {
|
|
|
17961
17963
|
if (!isName(value.board)) return null;
|
|
17962
17964
|
anchor.board = value.board;
|
|
17963
17965
|
}
|
|
17966
|
+
if (value.group !== void 0) {
|
|
17967
|
+
if (!isName(value.group)) return null;
|
|
17968
|
+
anchor.group = value.group;
|
|
17969
|
+
}
|
|
17970
|
+
if (value.verdict !== void 0) {
|
|
17971
|
+
if (!anchor.group || value.verdict !== "pass" && value.verdict !== "reject") return null;
|
|
17972
|
+
anchor.verdict = value.verdict;
|
|
17973
|
+
}
|
|
17964
17974
|
if (value.nodes !== void 0) {
|
|
17965
17975
|
const nodes = readNodes(value.nodes);
|
|
17966
17976
|
if (!nodes) return null;
|
|
@@ -17980,17 +17990,24 @@ function readBoardAnchor(value) {
|
|
|
17980
17990
|
}
|
|
17981
17991
|
var boardAnchors = {
|
|
17982
17992
|
read: readBoardAnchor,
|
|
17983
|
-
same: (a5, b6) => a5.page === b6.page && a5.board === b6.board && a5.x === b6.x && a5.y === b6.y,
|
|
17993
|
+
same: (a5, b6) => a5.page === b6.page && a5.board === b6.board && a5.group === b6.group && a5.verdict === b6.verdict && a5.x === b6.x && a5.y === b6.y,
|
|
17984
17994
|
missing: "a new thread needs a board anchor (page, x, y); dropped it"
|
|
17985
17995
|
};
|
|
17986
17996
|
var emptyBoardComments = () => ({ version: 1, threads: [] });
|
|
17987
17997
|
var savedBoardComments = (incoming) => savedComments(incoming, boardAnchors);
|
|
17988
17998
|
var mergeBoardComments = (base, incoming, origin, now, newId, name) => mergeComments(base, incoming, origin, now, newId, name, boardAnchors);
|
|
17989
17999
|
function applyBoardHumanOp(file, op, now, newId, who) {
|
|
17990
|
-
if (op.op
|
|
17991
|
-
|
|
18000
|
+
if (op.op !== "create") return applyThreadOp(file, op, now, newId, who);
|
|
18001
|
+
const thread = openThread(op.anchor, "human", op.text, now, newId, who);
|
|
18002
|
+
if (op.anchor.verdict !== "pass") return { ...file, threads: [...file.threads, thread] };
|
|
18003
|
+
const closed = { status: "resolved", statusAt: now, statusBy: "human" };
|
|
18004
|
+
const rejected = (t7) => t7.anchor.group === op.anchor.group && t7.anchor.verdict === "reject" && t7.status === "open";
|
|
18005
|
+
return { ...file, threads: [...file.threads.map((t7) => rejected(t7) ? { ...t7, ...closed } : t7), { ...thread, ...closed }] };
|
|
17992
18006
|
}
|
|
17993
18007
|
function applyBoardAgentOp(file, op, now, newId, name) {
|
|
18008
|
+
if (op.op === "resolve" && file.threads.find((t7) => t7.id === op.threadId)?.anchor.verdict === "reject") {
|
|
18009
|
+
throw new Error("a reject closes only when your human partner passes the group");
|
|
18010
|
+
}
|
|
17994
18011
|
if (op.op === "add") {
|
|
17995
18012
|
const thread = openThread(op.anchor, "agent", op.text, now, newId, { name });
|
|
17996
18013
|
return { file: { ...file, threads: [...file.threads, thread] }, threadId: thread.id, messageId: thread.messages[0].id };
|
|
@@ -17998,6 +18015,19 @@ function applyBoardAgentOp(file, op, now, newId, name) {
|
|
|
17998
18015
|
return applyAgentThreadOp(file, op, now, newId, name);
|
|
17999
18016
|
}
|
|
18000
18017
|
|
|
18018
|
+
// src/shared/verdicts.ts
|
|
18019
|
+
var openedAt = (thread) => thread.messages[0]?.at ?? thread.statusAt;
|
|
18020
|
+
function groupVerdict(threads, group, stale) {
|
|
18021
|
+
const own = threads.filter((thread) => thread.anchor.group === group && thread.anchor.verdict && thread.messages.some((m11) => !m11.deleted)).sort((a5, b6) => openedAt(a5) < openedAt(b6) ? -1 : openedAt(a5) > openedAt(b6) ? 1 : 0);
|
|
18022
|
+
const rejectThreads = own.filter((thread) => thread.anchor.verdict === "reject" && thread.status === "open").length;
|
|
18023
|
+
const latest = own.at(-1);
|
|
18024
|
+
if (!latest) return { state: "pending", evidenceUpdated: false, rejectThreads };
|
|
18025
|
+
const at7 = openedAt(latest);
|
|
18026
|
+
if (stale.has(latest.id)) return { state: "pending", at: at7, evidenceUpdated: true, rejectThreads };
|
|
18027
|
+
if (latest.anchor.verdict === "pass") return { state: "pass", at: at7, evidenceUpdated: false, rejectThreads };
|
|
18028
|
+
return { state: latest.status === "open" ? "reject" : "pending", at: at7, evidenceUpdated: false, rejectThreads };
|
|
18029
|
+
}
|
|
18030
|
+
|
|
18001
18031
|
// src/server/comment-cursors.ts
|
|
18002
18032
|
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
18003
18033
|
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
@@ -18093,6 +18123,9 @@ var intersects = (a5, b6) => a5.x < b6.x + b6.w && b6.x < a5.x + a5.w && a5.y <
|
|
|
18093
18123
|
// src/shared/validate.ts
|
|
18094
18124
|
var BOARD_NUMBERS = ["x", "y", "w", "h"];
|
|
18095
18125
|
var BOARD_REQUIRED = ["file", "page", ...BOARD_NUMBERS];
|
|
18126
|
+
var MEDIA_REQUIRED = ["src", "page", ...BOARD_NUMBERS];
|
|
18127
|
+
var fileOf = (board) => isMediaBoard(board) ? board.src ?? "" : board.file;
|
|
18128
|
+
var fileField = (board) => isMediaBoard(board) ? "src" : "file";
|
|
18096
18129
|
var isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
18097
18130
|
function structuralWarnings(raw) {
|
|
18098
18131
|
if (!isObject2(raw)) return ["canvas.json must be a JSON object"];
|
|
@@ -18122,6 +18155,16 @@ function structuralWarnings(raw) {
|
|
|
18122
18155
|
if (isObject2(board) && board.interactive !== void 0 && typeof board.interactive !== "boolean") {
|
|
18123
18156
|
warnings.push(`board "${id2}" field "interactive" must be a boolean`);
|
|
18124
18157
|
}
|
|
18158
|
+
if (isObject2(board) && board.type !== void 0 && !BOARD_TYPES.includes(board.type)) {
|
|
18159
|
+
warnings.push(`board "${id2}" field "type" must be "html", "image" or "video"`);
|
|
18160
|
+
}
|
|
18161
|
+
}
|
|
18162
|
+
}
|
|
18163
|
+
if (isObject2(raw.groups)) {
|
|
18164
|
+
for (const [id2, group] of Object.entries(raw.groups)) {
|
|
18165
|
+
if (isObject2(group) && group.verify !== void 0 && typeof group.verify !== "boolean") {
|
|
18166
|
+
warnings.push(`group "${id2}" field "verify" must be a boolean`);
|
|
18167
|
+
}
|
|
18125
18168
|
}
|
|
18126
18169
|
}
|
|
18127
18170
|
if (warnings.length > 0) return warnings;
|
|
@@ -18135,7 +18178,7 @@ function structuralWarnings(raw) {
|
|
|
18135
18178
|
warnings.push(`board "${id2}" must be an object`);
|
|
18136
18179
|
continue;
|
|
18137
18180
|
}
|
|
18138
|
-
for (const key2 of BOARD_REQUIRED) {
|
|
18181
|
+
for (const key2 of isMediaBoard(board) ? MEDIA_REQUIRED : BOARD_REQUIRED) {
|
|
18139
18182
|
if (board[key2] === void 0) warnings.push(`board "${id2}" is missing "${key2}"`);
|
|
18140
18183
|
}
|
|
18141
18184
|
for (const key2 of BOARD_NUMBERS) {
|
|
@@ -18143,7 +18186,7 @@ function structuralWarnings(raw) {
|
|
|
18143
18186
|
warnings.push(`board "${id2}" field "${key2}" must be a number`);
|
|
18144
18187
|
}
|
|
18145
18188
|
}
|
|
18146
|
-
for (const key2 of ["file", "page"]) {
|
|
18189
|
+
for (const key2 of ["file", "src", "page"]) {
|
|
18147
18190
|
if (board[key2] !== void 0 && typeof board[key2] !== "string") {
|
|
18148
18191
|
warnings.push(`board "${id2}" field "${key2}" must be a string`);
|
|
18149
18192
|
}
|
|
@@ -18174,10 +18217,11 @@ function validateCanvas(raw, fileExists, options = {}) {
|
|
|
18174
18217
|
const notes = Object.entries(canvas.notes ?? {});
|
|
18175
18218
|
for (const [id2, board] of boards) {
|
|
18176
18219
|
if (!pages.has(board.page)) warnings.push(`board "${id2}" uses unknown page "${board.page}"`);
|
|
18177
|
-
|
|
18178
|
-
|
|
18220
|
+
const file = fileOf(board);
|
|
18221
|
+
if (!file.startsWith("pages/")) warnings.push(`board "${id2}" ${fileField(board)} must start with "pages/": ${file}`);
|
|
18222
|
+
else if (!fileExists(file)) {
|
|
18179
18223
|
options.pending?.add(id2);
|
|
18180
|
-
if (!options.allowPending) warnings.push(`board "${id2}" file not found: ${
|
|
18224
|
+
if (!options.allowPending) warnings.push(`board "${id2}" file not found: ${file}`);
|
|
18181
18225
|
}
|
|
18182
18226
|
}
|
|
18183
18227
|
for (let i6 = 0; i6 < boards.length; i6++) {
|
|
@@ -18288,6 +18332,10 @@ function boardVersions(boardDir, canvas) {
|
|
|
18288
18332
|
}
|
|
18289
18333
|
try {
|
|
18290
18334
|
const stat = import_node_fs5.default.statSync(target);
|
|
18335
|
+
if (isMediaBoard(board)) {
|
|
18336
|
+
versions[board.file] = stat.size > 0 ? stat.mtimeMs : 0;
|
|
18337
|
+
continue;
|
|
18338
|
+
}
|
|
18291
18339
|
const html = import_node_fs5.default.readFileSync(target, "utf8");
|
|
18292
18340
|
const document2 = /<(?:!doctype|html)\b/i.test(html);
|
|
18293
18341
|
const ready = html.trim().length > 0 && (!document2 || /<\/html>\s*(?:<!--[\s\S]*?-->\s*)*$/i.test(html));
|
|
@@ -18309,6 +18357,7 @@ function readCanvas(boardDir) {
|
|
|
18309
18357
|
const structural = structuralWarnings(raw);
|
|
18310
18358
|
if (structural.length > 0) return { canvas: null, warnings: structural, pending: [], layout: null, versions: {} };
|
|
18311
18359
|
const canvas = { ...raw };
|
|
18360
|
+
canvas.boards = Object.fromEntries(Object.entries(canvas.boards).map(([id2, board]) => [id2, isMediaBoard(board) ? { ...board, file: board.src ?? "" } : board]));
|
|
18312
18361
|
const { versions, writing } = boardVersions(boardDir, canvas);
|
|
18313
18362
|
const pending = /* @__PURE__ */ new Set();
|
|
18314
18363
|
for (const [id2, board] of Object.entries(canvas.boards)) {
|
|
@@ -18487,6 +18536,7 @@ var boardRules = {
|
|
|
18487
18536
|
agent: applyBoardAgentOp
|
|
18488
18537
|
};
|
|
18489
18538
|
var withoutHashes = ({ hashes: _hashes, ...anchor }) => anchor;
|
|
18539
|
+
var withoutVerdict = ({ hashes: _hashes, group: _group, verdict: _verdict, ...anchor }) => anchor;
|
|
18490
18540
|
function asBoardHumanOp(value) {
|
|
18491
18541
|
if (typeof value !== "object" || value === null) return null;
|
|
18492
18542
|
const v6 = value;
|
|
@@ -18502,22 +18552,30 @@ function asBoardAgentOp(value) {
|
|
|
18502
18552
|
const v6 = value;
|
|
18503
18553
|
if (v6.op === "add") {
|
|
18504
18554
|
const anchor = readBoardAnchor(v6.anchor);
|
|
18505
|
-
return anchor && isText3(v6.text) && v6.text.length > 0 ? { op: "add", anchor:
|
|
18555
|
+
return anchor && isText3(v6.text) && v6.text.length > 0 ? { op: "add", anchor: withoutVerdict(anchor), text: v6.text } : null;
|
|
18506
18556
|
}
|
|
18507
18557
|
if (v6.op === "reply") return isId(v6.threadId) && isText3(v6.text) && v6.text.length > 0 ? { op: "reply", threadId: v6.threadId, text: v6.text } : null;
|
|
18508
18558
|
if (v6.op === "resolve") return isId(v6.threadId) ? { op: "resolve", threadId: v6.threadId } : null;
|
|
18509
18559
|
return null;
|
|
18510
18560
|
}
|
|
18511
|
-
function
|
|
18561
|
+
function readCanvasJson(dir) {
|
|
18512
18562
|
try {
|
|
18513
|
-
|
|
18514
|
-
return Object.fromEntries(Object.entries(canvas.boards ?? {}).flatMap(
|
|
18515
|
-
([id2, board]) => typeof board?.file === "string" ? [[id2, { file: board.file, page: typeof board.page === "string" ? board.page : "", w: typeof board.w === "number" ? board.w : 0 }]] : []
|
|
18516
|
-
));
|
|
18563
|
+
return JSON.parse(import_node_fs8.default.readFileSync(import_node_path7.default.join(dir, "canvas.json"), "utf8"));
|
|
18517
18564
|
} catch {
|
|
18518
18565
|
return {};
|
|
18519
18566
|
}
|
|
18520
18567
|
}
|
|
18568
|
+
function boardSpecs(dir) {
|
|
18569
|
+
return Object.fromEntries(Object.entries(readCanvasJson(dir).boards ?? {}).flatMap(([id2, board]) => {
|
|
18570
|
+
const file = board?.type === "image" || board?.type === "video" ? board.src : board?.file;
|
|
18571
|
+
return typeof file === "string" ? [[id2, { file, page: typeof board.page === "string" ? board.page : "", w: typeof board.w === "number" ? board.w : 0 }]] : [];
|
|
18572
|
+
}));
|
|
18573
|
+
}
|
|
18574
|
+
function groupSpecs(dir) {
|
|
18575
|
+
return Object.fromEntries(Object.entries(readCanvasJson(dir).groups ?? {}).flatMap(
|
|
18576
|
+
([id2, group]) => Array.isArray(group?.boards) ? [[id2, { ...typeof group.title === "string" ? { title: group.title } : {}, boards: group.boards.filter((b6) => typeof b6 === "string"), verify: group.verify === true }]] : []
|
|
18577
|
+
));
|
|
18578
|
+
}
|
|
18521
18579
|
var boardFiles = (dir) => Object.fromEntries(Object.entries(boardSpecs(dir)).map(([id2, spec]) => [id2, spec.file]));
|
|
18522
18580
|
function agentAddOnBoard(value, specs) {
|
|
18523
18581
|
if (typeof value !== "object" || value === null) return null;
|
|
@@ -18542,9 +18600,11 @@ function boardHashes(dir) {
|
|
|
18542
18600
|
return hash ? [[id2, hash]] : [];
|
|
18543
18601
|
}));
|
|
18544
18602
|
}
|
|
18545
|
-
var boardsOf = (anchor
|
|
18546
|
-
|
|
18547
|
-
|
|
18603
|
+
var boardsOf = (anchor, groups = {}) => [
|
|
18604
|
+
.../* @__PURE__ */ new Set([...anchor.board ? [anchor.board] : [], ...(anchor.nodes ?? []).map((node) => node.board), ...anchor.group ? groups[anchor.group]?.boards ?? [] : []])
|
|
18605
|
+
];
|
|
18606
|
+
function stamp(anchor, hashes, groups = {}) {
|
|
18607
|
+
const boards = boardsOf(anchor, groups);
|
|
18548
18608
|
if (!boards.length) return withoutHashes(anchor);
|
|
18549
18609
|
return { ...withoutHashes(anchor), hashes: Object.fromEntries(boards.map((board) => [board, hashes[board] ?? "missing"])) };
|
|
18550
18610
|
}
|
|
@@ -18586,11 +18646,12 @@ function createBoardCommentRegistry(options) {
|
|
|
18586
18646
|
};
|
|
18587
18647
|
const forAgent2 = (id2, staleIds) => {
|
|
18588
18648
|
const files = boardFiles(dirOf(id2));
|
|
18649
|
+
const groups = groupSpecs(dirOf(id2));
|
|
18589
18650
|
return (thread) => ({
|
|
18590
18651
|
...thread,
|
|
18591
18652
|
stale: staleIds.has(thread.id),
|
|
18592
18653
|
waitingOn: waitingOn(thread),
|
|
18593
|
-
files: Object.fromEntries(boardsOf(thread.anchor).flatMap((board) => files[board] ? [[board, files[board]]] : [])),
|
|
18654
|
+
files: Object.fromEntries(boardsOf(thread.anchor, groups).flatMap((board) => files[board] ? [[board, files[board]]] : [])),
|
|
18594
18655
|
messages: thread.messages.map(({ avatar: _avatar, ...message }) => message)
|
|
18595
18656
|
});
|
|
18596
18657
|
};
|
|
@@ -18599,7 +18660,9 @@ function createBoardCommentRegistry(options) {
|
|
|
18599
18660
|
stale,
|
|
18600
18661
|
warnings: (id2) => store(id2).warnings(),
|
|
18601
18662
|
apply: (id2, op) => {
|
|
18602
|
-
const
|
|
18663
|
+
const groups = groupSpecs(dirOf(id2));
|
|
18664
|
+
if (op.op === "create" && op.anchor.verdict && !groups[op.anchor.group]?.verify) throw new Error(`no verify group ${op.anchor.group} in artboard/${id2}`);
|
|
18665
|
+
const stamped = op.op === "create" ? { ...op, anchor: stamp(op.anchor, fresh(id2), groups) } : op;
|
|
18603
18666
|
store(id2).apply(stamped);
|
|
18604
18667
|
push2(id2);
|
|
18605
18668
|
return { comments: store(id2).current(), stale: stale(id2) };
|
|
@@ -18620,6 +18683,16 @@ function createBoardCommentRegistry(options) {
|
|
|
18620
18683
|
if (newest) cursors.set(id2, agent, newest);
|
|
18621
18684
|
return threads.map(format);
|
|
18622
18685
|
},
|
|
18686
|
+
groups: (id2) => {
|
|
18687
|
+
const specs = boardSpecs(dirOf(id2));
|
|
18688
|
+
const threads = store(id2).current().threads;
|
|
18689
|
+
const staleIds = new Set(stale(id2));
|
|
18690
|
+
return Object.entries(groupSpecs(dirOf(id2))).filter(([, group]) => group.verify).map(([groupId, group]) => {
|
|
18691
|
+
const { state, ...verdict } = groupVerdict(threads, groupId, staleIds);
|
|
18692
|
+
const page = group.boards.map((board) => specs[board]?.page).find(Boolean) ?? "";
|
|
18693
|
+
return { id: groupId, page, ...group.title ? { title: group.title } : {}, verdict: state, ...verdict, boards: group.boards };
|
|
18694
|
+
});
|
|
18695
|
+
},
|
|
18623
18696
|
sync: (id2) => {
|
|
18624
18697
|
if (store(id2).sync()) push2(id2);
|
|
18625
18698
|
},
|
|
@@ -88750,15 +88823,15 @@ function readAnySelection(value) {
|
|
|
88750
88823
|
function createSelectionStore(stateDir, exists) {
|
|
88751
88824
|
const tabs = /* @__PURE__ */ new Map();
|
|
88752
88825
|
let clock = 0;
|
|
88753
|
-
const
|
|
88826
|
+
const fileOf2 = (kind, id2) => import_node_path12.default.join(stateDir, kind, id2, "selection.json");
|
|
88754
88827
|
const write = (kind, id2) => {
|
|
88755
88828
|
let winner;
|
|
88756
88829
|
for (const tab of tabs.values()) {
|
|
88757
88830
|
if (tab.kind !== kind || tab.id !== id2) continue;
|
|
88758
88831
|
if (!winner || tab.humanAt > winner.humanAt || tab.humanAt === winner.humanAt && tab.seenAt > winner.seenAt) winner = tab;
|
|
88759
88832
|
}
|
|
88760
|
-
if (!winner?.state) import_node_fs12.default.rmSync(
|
|
88761
|
-
else writeJsonAtomic(
|
|
88833
|
+
if (!winner?.state) import_node_fs12.default.rmSync(fileOf2(kind, id2), { force: true });
|
|
88834
|
+
else writeJsonAtomic(fileOf2(kind, id2), { artifact: `${kind}/${id2}`, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), ...winner.state });
|
|
88762
88835
|
};
|
|
88763
88836
|
return {
|
|
88764
88837
|
accept(socket, value) {
|
|
@@ -88792,7 +88865,7 @@ function createSelectionStore(stateDir, exists) {
|
|
|
88792
88865
|
} catch {
|
|
88793
88866
|
continue;
|
|
88794
88867
|
}
|
|
88795
|
-
for (const id2 of ids) import_node_fs12.default.rmSync(
|
|
88868
|
+
for (const id2 of ids) import_node_fs12.default.rmSync(fileOf2(kind, id2), { force: true });
|
|
88796
88869
|
}
|
|
88797
88870
|
}
|
|
88798
88871
|
};
|
|
@@ -90348,7 +90421,11 @@ async function startArtifactsServer(options) {
|
|
|
90348
90421
|
sendJson(res, 400, { error: "not a comment op" });
|
|
90349
90422
|
return;
|
|
90350
90423
|
}
|
|
90351
|
-
|
|
90424
|
+
try {
|
|
90425
|
+
sendJson(res, 200, boardComments.apply(id2, op));
|
|
90426
|
+
} catch (err) {
|
|
90427
|
+
sendJson(res, 400, { error: err.message });
|
|
90428
|
+
}
|
|
90352
90429
|
};
|
|
90353
90430
|
const serveAgentBoardComments = async (req, res, id2) => {
|
|
90354
90431
|
const dir = resolveArtifactDir(root, "artboard", id2);
|
|
@@ -90360,7 +90437,8 @@ async function startArtifactsServer(options) {
|
|
|
90360
90437
|
const fields = typeof body === "object" && body !== null ? body : {};
|
|
90361
90438
|
const agent = typeof fields.agent === "string" && fields.agent.length > 0 && fields.agent.length <= 100 ? fields.agent : void 0;
|
|
90362
90439
|
if (fields.op === "list") {
|
|
90363
|
-
|
|
90440
|
+
const threads = boardComments.list(id2, agent ?? "Agent", fields.all === true);
|
|
90441
|
+
sendJson(res, 200, { type: "comments", artifact: `artboard/${id2}`, threads, groups: boardComments.groups(id2) });
|
|
90364
90442
|
return;
|
|
90365
90443
|
}
|
|
90366
90444
|
const shorthand = agentAddOnBoard(body, boardSpecs(dir));
|
|
@@ -90967,7 +91045,7 @@ function openReady(payload) {
|
|
|
90967
91045
|
}
|
|
90968
91046
|
|
|
90969
91047
|
// package.json
|
|
90970
|
-
var version = "1.16.
|
|
91048
|
+
var version = "1.16.3";
|
|
90971
91049
|
|
|
90972
91050
|
// src/server/main.ts
|
|
90973
91051
|
async function main() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,t as n}from"./jsx-runtime-CldxteV5.js";import{a as r}from"./useSandboxFrame-N5uRz7Cc.js";import{t as i}from"./index.js";import a from"./CloudDocument-DQ8BLzr7.js";import{DocumentView as o,t as s}from"./DocumentPage-CgCHoFVv.js";var c=e(t(),1),l=`1.16.
|
|
1
|
+
import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,t as n}from"./jsx-runtime-CldxteV5.js";import{a as r}from"./useSandboxFrame-N5uRz7Cc.js";import{t as i}from"./index.js";import a from"./CloudDocument-DQ8BLzr7.js";import{DocumentView as o,t as s}from"./DocumentPage-CgCHoFVv.js";var c=e(t(),1),l=`1.16.3`,u=e=>/^(\d+)\.(\d+)\./.exec(e??``)?.slice(1,3).join(`.`)??null;function d(e,t){let n=u(e);return n!==null&&n===u(t)}var f=(e,t)=>`电脑上的 ryugi 是 ${t??`未知版本`},网页是 ${e},版本对上之前只能评论`,p=n();function m({id:e,state:t,contentBase:n,liveContentBase:u,comments:m}){let{transport:h,presence:g}=s(e,u??n??``),_=g?.online??!1;r(e,{online:g?.online??null});let[v,y]=(0,c.useState)(!1);if((0,c.useEffect)(()=>{_&&y(!0)},[_]),!h||!(v||_))return!t||!n?(0,p.jsx)(i,{children:g===null?`正在连接…`:`还没发布。电脑在线时,这里会实时显示。`}):(0,p.jsx)(a,{id:e,state:t,contentBase:n,comments:m,offline:g!==null&&!_});let b=_&&d(l,g?.version??null),x=_&&!b?f(l,g?.version??null):null;return(0,p.jsx)(o,{id:e,transport:h,live:_,cloud:{online:_,canEdit:b,reason:x}})}export{m as default};
|