@jay-framework/aiditor 0.16.4 → 0.16.5
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/actions/submit-task.jay-action +0 -1
- package/dist/actions/submit-task.jay-action.d.ts +0 -1
- package/dist/index.client.js +20 -34
- package/dist/index.d.ts +1 -2
- package/dist/index.js +206 -53
- package/dist/pages/aiditor/page.jay-html +2 -2
- package/package.json +9 -8
- package/dist/pages/aiditor/page.jay-html.d.ts +0 -331
package/dist/index.client.js
CHANGED
|
@@ -19,10 +19,10 @@ function countAttachmentFiles(m) {
|
|
|
19
19
|
function validateMultipartPartBudget(options) {
|
|
20
20
|
const { video, distinctMoments, attachmentFileCount } = options;
|
|
21
21
|
const n = distinctMoments;
|
|
22
|
-
const p = (video ? 1 : 0) +
|
|
22
|
+
const p = (video ? 1 : 0) + 2 * n + attachmentFileCount;
|
|
23
23
|
if (p > CHANNEL_MAX_FILE_PARTS) {
|
|
24
24
|
const videoPhrase = video ? "1 video + " : "";
|
|
25
|
-
return `Too many files for one task (${p} parts). Max is ${CHANNEL_MAX_FILE_PARTS} (${videoPhrase}
|
|
25
|
+
return `Too many files for one task (${p} parts). Max is ${CHANNEL_MAX_FILE_PARTS} (${videoPhrase}2 × ${n} moment(s) + ${attachmentFileCount} attachment(s)). Reduce distinct moments or attachments.`;
|
|
26
26
|
}
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
@@ -38,7 +38,7 @@ function submitAndStreamTask(notes, visual, callbacks) {
|
|
|
38
38
|
const includeVideo = Boolean(v.video);
|
|
39
39
|
const err = validateMultipartPartBudget({
|
|
40
40
|
video: includeVideo,
|
|
41
|
-
distinctMoments: v.
|
|
41
|
+
distinctMoments: v.frameDuals.length,
|
|
42
42
|
attachmentFileCount: attCount
|
|
43
43
|
});
|
|
44
44
|
if (err) {
|
|
@@ -55,13 +55,8 @@ function submitAndStreamTask(notes, visual, callbacks) {
|
|
|
55
55
|
}
|
|
56
56
|
if (!includeVideo) input.videoFramesOnly = "1";
|
|
57
57
|
const extraFiles = {};
|
|
58
|
-
for (let i = 0; i < v.
|
|
59
|
-
const t = v.
|
|
60
|
-
extraFiles[`frame_${i}_full`] = new File(
|
|
61
|
-
[t.full],
|
|
62
|
-
`frame-${i}-full.png`,
|
|
63
|
-
{ type: "image/png" }
|
|
64
|
-
);
|
|
58
|
+
for (let i = 0; i < v.frameDuals.length; i++) {
|
|
59
|
+
const t = v.frameDuals[i];
|
|
65
60
|
extraFiles[`frame_${i}_markers_only`] = new File(
|
|
66
61
|
[t.markersOnly],
|
|
67
62
|
`frame-${i}-markers.png`,
|
|
@@ -81,20 +76,17 @@ function submitAndStreamTask(notes, visual, callbacks) {
|
|
|
81
76
|
}
|
|
82
77
|
}
|
|
83
78
|
input.extraFiles = extraFiles;
|
|
84
|
-
} else if (visual?.
|
|
79
|
+
} else if (visual?.dual) {
|
|
85
80
|
const v = visual;
|
|
86
81
|
input.visualTask = visualModeToForm[v.mode];
|
|
87
82
|
input.pageRoute = v.pageRoute;
|
|
88
83
|
input.renderedUrl = v.renderedUrl;
|
|
89
|
-
input.screenshot_full = new File([v.triple.full], "full.png", {
|
|
90
|
-
type: "image/png"
|
|
91
|
-
});
|
|
92
84
|
input.screenshot_markers_only = new File(
|
|
93
|
-
[v.
|
|
85
|
+
[v.dual.markersOnly],
|
|
94
86
|
"markers-only.png",
|
|
95
87
|
{ type: "image/png" }
|
|
96
88
|
);
|
|
97
|
-
input.screenshot_clean = new File([v.
|
|
89
|
+
input.screenshot_clean = new File([v.dual.clean], "clean.png", {
|
|
98
90
|
type: "image/png"
|
|
99
91
|
});
|
|
100
92
|
const extraFiles = {};
|
|
@@ -8178,11 +8170,10 @@ function canvasToPng(canvas) {
|
|
|
8178
8170
|
);
|
|
8179
8171
|
});
|
|
8180
8172
|
}
|
|
8181
|
-
async function
|
|
8182
|
-
const full = await capturePreviewForTask(rootEl, "full");
|
|
8183
|
-
const markersOnly = await capturePreviewForTask(rootEl, "markersOnly");
|
|
8173
|
+
async function capturePreviewDual(rootEl) {
|
|
8184
8174
|
const clean = await capturePreviewForTask(rootEl, "clean");
|
|
8185
|
-
|
|
8175
|
+
const markersOnly = await capturePreviewForTask(rootEl, "markersOnly");
|
|
8176
|
+
return { clean, markersOnly };
|
|
8186
8177
|
}
|
|
8187
8178
|
const DEFAULT_SEEK_TIMEOUT_MS = 15e3;
|
|
8188
8179
|
async function seekVideoToTime(video, timeSec, options) {
|
|
@@ -8292,15 +8283,14 @@ async function capturePreviewForVideoFrame(rootEl, videoEl, mode = "full") {
|
|
|
8292
8283
|
if (mode === "full" && popoversEl) await drawLayer(popoversEl);
|
|
8293
8284
|
return canvasToPng(canvas);
|
|
8294
8285
|
}
|
|
8295
|
-
async function
|
|
8296
|
-
const
|
|
8286
|
+
async function captureVideoInstantDual(rootEl, videoEl) {
|
|
8287
|
+
const clean = await capturePreviewForVideoFrame(rootEl, videoEl, "clean");
|
|
8297
8288
|
const markersOnly = await capturePreviewForVideoFrame(
|
|
8298
8289
|
rootEl,
|
|
8299
8290
|
videoEl,
|
|
8300
8291
|
"markersOnly"
|
|
8301
8292
|
);
|
|
8302
|
-
|
|
8303
|
-
return { full, markersOnly, clean };
|
|
8293
|
+
return { clean, markersOnly };
|
|
8304
8294
|
}
|
|
8305
8295
|
function getRestrictionTargetCtor() {
|
|
8306
8296
|
const g = globalThis;
|
|
@@ -9919,7 +9909,7 @@ function aiditorConstructor(_props, refs) {
|
|
|
9919
9909
|
if (!gotRoot || !rootEl) {
|
|
9920
9910
|
throw new Error("Preview container not ready.");
|
|
9921
9911
|
}
|
|
9922
|
-
const
|
|
9912
|
+
const dual = await capturePreviewDual(rootEl);
|
|
9923
9913
|
const attachmentsByAnnotationId = /* @__PURE__ */ new Map();
|
|
9924
9914
|
for (const a2 of list) {
|
|
9925
9915
|
if (a2.attachments.length > 0) {
|
|
@@ -9931,11 +9921,7 @@ function aiditorConstructor(_props, refs) {
|
|
|
9931
9921
|
mode: "multi",
|
|
9932
9922
|
pageRoute: route,
|
|
9933
9923
|
renderedUrl: rendered,
|
|
9934
|
-
|
|
9935
|
-
full: triple.full,
|
|
9936
|
-
markersOnly: triple.markersOnly,
|
|
9937
|
-
clean: triple.clean
|
|
9938
|
-
},
|
|
9924
|
+
dual,
|
|
9939
9925
|
attachmentsByAnnotationId: attachmentsByAnnotationId.size > 0 ? attachmentsByAnnotationId : void 0
|
|
9940
9926
|
});
|
|
9941
9927
|
} catch (err) {
|
|
@@ -10388,15 +10374,15 @@ function aiditorConstructor(_props, refs) {
|
|
|
10388
10374
|
setIsRunning(true);
|
|
10389
10375
|
setVideoSubmitError("");
|
|
10390
10376
|
setVideoSubmitProgress("");
|
|
10391
|
-
const
|
|
10377
|
+
const frameDuals = [];
|
|
10392
10378
|
const nFrames = distinctTimes.length;
|
|
10393
10379
|
let frameIdx = 0;
|
|
10394
10380
|
for (const t of distinctTimes) {
|
|
10395
10381
|
frameIdx += 1;
|
|
10396
10382
|
setVideoSubmitProgress(`Capturing annotated frames (${frameIdx}/${nFrames})…`);
|
|
10397
10383
|
await seekVideoToTime(videoEl, t);
|
|
10398
|
-
const
|
|
10399
|
-
|
|
10384
|
+
const dual = await captureVideoInstantDual(captureRoot, videoEl);
|
|
10385
|
+
frameDuals.push({ timeSec: t, ...dual });
|
|
10400
10386
|
}
|
|
10401
10387
|
const attachmentsByPin = /* @__PURE__ */ new Map();
|
|
10402
10388
|
for (const a2 of list) {
|
|
@@ -10417,7 +10403,7 @@ function aiditorConstructor(_props, refs) {
|
|
|
10417
10403
|
pageRoute: route,
|
|
10418
10404
|
renderedUrl: rendered,
|
|
10419
10405
|
...uploadFullRecording ? { video: blob, videoFileName: "recording.webm" } : {},
|
|
10420
|
-
|
|
10406
|
+
frameDuals,
|
|
10421
10407
|
attachmentsByPin: attachmentsByPin.size > 0 ? attachmentsByPin : void 0
|
|
10422
10408
|
});
|
|
10423
10409
|
} catch (err) {
|
package/dist/index.d.ts
CHANGED
|
@@ -412,7 +412,6 @@ interface SubmitTaskActionInput {
|
|
|
412
412
|
renderedUrl?: string;
|
|
413
413
|
visualTask?: string;
|
|
414
414
|
videoFramesOnly?: string;
|
|
415
|
-
screenshot_full?: JayFile;
|
|
416
415
|
screenshot_markers_only?: JayFile;
|
|
417
416
|
screenshot_clean?: JayFile;
|
|
418
417
|
video?: JayFile;
|
|
@@ -429,7 +428,7 @@ interface SubmitTaskActionOutput {
|
|
|
429
428
|
duration?: number;
|
|
430
429
|
}
|
|
431
430
|
|
|
432
|
-
declare const submitTaskAction: _jay_framework_fullstack_component.JayStreamAction<SubmitTaskActionInput, SubmitTaskActionOutput> & _jay_framework_fullstack_component.JayStreamActionDefinition<SubmitTaskActionInput, SubmitTaskActionOutput, [
|
|
431
|
+
declare const submitTaskAction: _jay_framework_fullstack_component.JayStreamAction<SubmitTaskActionInput, SubmitTaskActionOutput> & _jay_framework_fullstack_component.JayStreamActionDefinition<SubmitTaskActionInput, SubmitTaskActionOutput, []>;
|
|
433
432
|
|
|
434
433
|
interface AiditorShellCarry {
|
|
435
434
|
headline: string;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { makeJayQuery, makeJayStream, makeJayStackComponent, phaseOutput, RenderPipeline } from "@jay-framework/fullstack-component";
|
|
2
2
|
import { DEV_SERVER_SERVICE } from "@jay-framework/dev-server";
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
3
|
+
import fs, { readFile } from "fs/promises";
|
|
4
4
|
import path, { extname } from "path";
|
|
5
5
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
6
|
-
import fs from "fs";
|
|
6
|
+
import fs$1 from "fs";
|
|
7
|
+
import crypto from "crypto";
|
|
7
8
|
import { setActionCallerOptions } from "@jay-framework/stack-client-runtime";
|
|
8
9
|
const getAiditorBootstrap = makeJayQuery(
|
|
9
10
|
"aiditor.getAiditorBootstrap"
|
|
@@ -118,6 +119,112 @@ function* transformSDKMessage(message) {
|
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
}
|
|
122
|
+
const inFlightRoutes = /* @__PURE__ */ new Set();
|
|
123
|
+
function tryBeginRouteQuery(routeKey) {
|
|
124
|
+
if (inFlightRoutes.has(routeKey)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
inFlightRoutes.add(routeKey);
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
function endRouteQuery(routeKey) {
|
|
131
|
+
inFlightRoutes.delete(routeKey);
|
|
132
|
+
}
|
|
133
|
+
const ROUTE_SESSION_MAP_VERSION = 1;
|
|
134
|
+
function normalizePageRoute(raw) {
|
|
135
|
+
let s = (raw ?? "/").trim();
|
|
136
|
+
if (s === "") {
|
|
137
|
+
return "/";
|
|
138
|
+
}
|
|
139
|
+
if (!s.startsWith("/")) {
|
|
140
|
+
s = `/${s}`;
|
|
141
|
+
}
|
|
142
|
+
const q = s.indexOf("?");
|
|
143
|
+
if (q !== -1) {
|
|
144
|
+
s = s.slice(0, q);
|
|
145
|
+
}
|
|
146
|
+
while (s.length > 1 && s.endsWith("/")) {
|
|
147
|
+
s = s.slice(0, -1);
|
|
148
|
+
}
|
|
149
|
+
return s || "/";
|
|
150
|
+
}
|
|
151
|
+
function getRouteSessionsFilePath(projectDir) {
|
|
152
|
+
return path.join(projectDir, "build", "aditor", "route-sessions.json");
|
|
153
|
+
}
|
|
154
|
+
function emptyMap() {
|
|
155
|
+
return { version: ROUTE_SESSION_MAP_VERSION, routes: {} };
|
|
156
|
+
}
|
|
157
|
+
let mapMutexChain = Promise.resolve();
|
|
158
|
+
async function withRouteSessionMapLock(fn) {
|
|
159
|
+
const previous = mapMutexChain;
|
|
160
|
+
let release;
|
|
161
|
+
mapMutexChain = new Promise((resolve) => {
|
|
162
|
+
release = resolve;
|
|
163
|
+
});
|
|
164
|
+
await previous;
|
|
165
|
+
try {
|
|
166
|
+
return await fn();
|
|
167
|
+
} finally {
|
|
168
|
+
release();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function readMap(projectDir) {
|
|
172
|
+
const filePath = getRouteSessionsFilePath(projectDir);
|
|
173
|
+
try {
|
|
174
|
+
const raw = await fs.readFile(filePath, "utf-8");
|
|
175
|
+
const parsed = JSON.parse(raw);
|
|
176
|
+
if (parsed.version !== ROUTE_SESSION_MAP_VERSION || typeof parsed.routes !== "object" || parsed.routes === null) {
|
|
177
|
+
return emptyMap();
|
|
178
|
+
}
|
|
179
|
+
const routes = {};
|
|
180
|
+
for (const [k, v] of Object.entries(parsed.routes)) {
|
|
181
|
+
if (typeof v === "string") {
|
|
182
|
+
routes[k] = v.toLowerCase();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
version: ROUTE_SESSION_MAP_VERSION,
|
|
187
|
+
routes
|
|
188
|
+
};
|
|
189
|
+
} catch (e) {
|
|
190
|
+
const code = e && typeof e === "object" && "code" in e ? e.code : void 0;
|
|
191
|
+
if (code === "ENOENT") {
|
|
192
|
+
return emptyMap();
|
|
193
|
+
}
|
|
194
|
+
throw e;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async function writeRouteSessionMapAtomic(projectDir, map) {
|
|
198
|
+
const filePath = getRouteSessionsFilePath(projectDir);
|
|
199
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
200
|
+
const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
201
|
+
const body = `${JSON.stringify(map, null, 2)}
|
|
202
|
+
`;
|
|
203
|
+
await fs.writeFile(tmp, body, "utf-8");
|
|
204
|
+
await fs.rename(tmp, filePath);
|
|
205
|
+
}
|
|
206
|
+
async function getOrCreateSessionIdForRoute(projectDir, routeKey) {
|
|
207
|
+
return withRouteSessionMapLock(async () => {
|
|
208
|
+
const map = await readMap(projectDir);
|
|
209
|
+
const existing = map.routes[routeKey];
|
|
210
|
+
if (existing) {
|
|
211
|
+
return { sessionId: existing, useResume: true };
|
|
212
|
+
}
|
|
213
|
+
const sessionId = crypto.randomUUID();
|
|
214
|
+
map.routes[routeKey] = sessionId;
|
|
215
|
+
await writeRouteSessionMapAtomic(projectDir, map);
|
|
216
|
+
return { sessionId, useResume: false };
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async function replaceRouteSessionAfterStaleResume(projectDir, routeKey) {
|
|
220
|
+
return withRouteSessionMapLock(async () => {
|
|
221
|
+
const map = await readMap(projectDir);
|
|
222
|
+
const sessionId = crypto.randomUUID();
|
|
223
|
+
map.routes[routeKey] = sessionId;
|
|
224
|
+
await writeRouteSessionMapAtomic(projectDir, map);
|
|
225
|
+
return { sessionId };
|
|
226
|
+
});
|
|
227
|
+
}
|
|
121
228
|
function buildNonVisualPrompt(config, notes, imagePath) {
|
|
122
229
|
const lines = [
|
|
123
230
|
`Project directory: ${config.projectDir}`,
|
|
@@ -185,21 +292,20 @@ function parseNotesField(notes) {
|
|
|
185
292
|
}
|
|
186
293
|
return empty();
|
|
187
294
|
}
|
|
188
|
-
function
|
|
295
|
+
function buildVisualPromptDual(config, pageRoute, renderedUrl, dual, parsed, attachmentPathsByAnnotationId) {
|
|
189
296
|
const preamble = [
|
|
190
297
|
`Project directory: ${config.projectDir}`,
|
|
191
298
|
"",
|
|
192
299
|
`Implement the requested changes on page route ${pageRoute}. The captures correspond to this rendered URL: ${renderedUrl}.`,
|
|
193
300
|
"",
|
|
194
|
-
"
|
|
195
|
-
`- Screenshot 1 —
|
|
196
|
-
`- Screenshot 2 —
|
|
197
|
-
`- Screenshot 3 — Clean page (no markers; use to see underlying layout and align pin positions from Screenshot 2): ${triple.clean}`,
|
|
301
|
+
"Reference images (use together):",
|
|
302
|
+
`- Screenshot 1 — Clean page (no markers; shows the current page layout and content): ${dual.clean}`,
|
|
303
|
+
`- Screenshot 2 — Markers only (numbered annotation markers on the page; use to locate which UI element each annotation refers to): ${dual.markersOnly}`,
|
|
198
304
|
"",
|
|
199
305
|
"How to use these screenshots:",
|
|
200
|
-
"- Use Screenshot 1
|
|
201
|
-
"- Use Screenshot 2 to
|
|
202
|
-
"-
|
|
306
|
+
"- Use Screenshot 1 to understand the current page structure, typography, and layout.",
|
|
307
|
+
"- Use Screenshot 2 to identify which UI element each numbered annotation targets.",
|
|
308
|
+
"- The annotation instructions and attachments are listed below in text — do NOT rely on screenshot text.",
|
|
203
309
|
"",
|
|
204
310
|
ANNOTATION_TARGETING_RULES,
|
|
205
311
|
""
|
|
@@ -217,7 +323,7 @@ function buildVisualPromptTriple(config, pageRoute, renderedUrl, triple, parsed,
|
|
|
217
323
|
body.push(`Instruction: ${ann.instruction.trim()}`);
|
|
218
324
|
if (paths.length > 0) {
|
|
219
325
|
body.push(
|
|
220
|
-
"Attachments (read these files; they belong to this
|
|
326
|
+
"Attachments (read these files; they belong to this annotation only):"
|
|
221
327
|
);
|
|
222
328
|
for (const p of paths) {
|
|
223
329
|
body.push(`- ${p}`);
|
|
@@ -272,13 +378,12 @@ function buildVisualPromptVideo(config, pageRoute, renderedUrl, videoPath, frame
|
|
|
272
378
|
for (const [i, a] of pinOrder(sv.annotations).entries()) {
|
|
273
379
|
pinById.set(a.id, String(i + 1));
|
|
274
380
|
}
|
|
275
|
-
const body = ["Per-moment captures
|
|
381
|
+
const body = ["Per-moment captures:", ""];
|
|
276
382
|
for (const fr of frames) {
|
|
277
383
|
body.push(
|
|
278
384
|
`Moment ${fr.frameIndex + 1} — t=${fr.timeSec.toFixed(2)}s`,
|
|
279
|
-
`-
|
|
385
|
+
`- Clean page (no markers): ${fr.clean}`,
|
|
280
386
|
`- Markers only (numbered pins): ${fr.markersOnly}`,
|
|
281
|
-
`- Clean (no markers): ${fr.clean}`,
|
|
282
387
|
""
|
|
283
388
|
);
|
|
284
389
|
const atT = sv.annotations.filter((a) => a.timeSec === fr.timeSec);
|
|
@@ -310,17 +415,17 @@ function buildVisualPromptVideo(config, pageRoute, renderedUrl, videoPath, frame
|
|
|
310
415
|
return [...preamble, ...body].join("\n");
|
|
311
416
|
}
|
|
312
417
|
function persistFile(file, destDir, fileName) {
|
|
313
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
418
|
+
fs$1.mkdirSync(destDir, { recursive: true });
|
|
314
419
|
const dest = path.join(destDir, fileName ?? file.name);
|
|
315
|
-
fs.copyFileSync(file.path, dest);
|
|
420
|
+
fs$1.copyFileSync(file.path, dest);
|
|
316
421
|
return dest;
|
|
317
422
|
}
|
|
318
|
-
const submitTaskAction = makeJayStream("aiditor.submitTask").
|
|
423
|
+
const submitTaskAction = makeJayStream("aiditor.submitTask").withFiles({ maxFileSize: 2e7, maxFiles: 300 }).withHandler(async function* (input) {
|
|
319
424
|
const projectDir = process.cwd();
|
|
320
|
-
const buildFolder =
|
|
425
|
+
const buildFolder = path.join(projectDir, "build");
|
|
321
426
|
const taskId = Math.random().toString(36).slice(2, 10);
|
|
322
427
|
const taskDir = path.join(buildFolder, "aditor", taskId);
|
|
323
|
-
fs.mkdirSync(taskDir, { recursive: true });
|
|
428
|
+
fs$1.mkdirSync(taskDir, { recursive: true });
|
|
324
429
|
yield { type: "status", message: "Preparing task..." };
|
|
325
430
|
const config = { projectDir };
|
|
326
431
|
const parsed = parseNotesField(input.notes);
|
|
@@ -336,10 +441,9 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withServices(DEV_SE
|
|
|
336
441
|
const extra = input.extraFiles ?? {};
|
|
337
442
|
const frames = [];
|
|
338
443
|
for (let i = 0; ; i++) {
|
|
339
|
-
const full = extra[`frame_${i}_full`];
|
|
340
444
|
const markers = extra[`frame_${i}_markers_only`];
|
|
341
445
|
const clean = extra[`frame_${i}_clean`];
|
|
342
|
-
if (!
|
|
446
|
+
if (!markers && !clean) break;
|
|
343
447
|
const frameDir = path.join(taskDir, "frames", String(i));
|
|
344
448
|
const timeSec = parsed.structuredVideo?.annotations.find(
|
|
345
449
|
(a, idx) => idx === i || a.timeSec !== void 0
|
|
@@ -347,9 +451,8 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withServices(DEV_SE
|
|
|
347
451
|
frames.push({
|
|
348
452
|
timeSec,
|
|
349
453
|
frameIndex: i,
|
|
350
|
-
|
|
351
|
-
markersOnly: markers ? persistFile(markers, frameDir, "markers-only.png") : ""
|
|
352
|
-
clean: clean ? persistFile(clean, frameDir, "clean.png") : ""
|
|
454
|
+
clean: clean ? persistFile(clean, frameDir, "clean.png") : "",
|
|
455
|
+
markersOnly: markers ? persistFile(markers, frameDir, "markers-only.png") : ""
|
|
353
456
|
});
|
|
354
457
|
}
|
|
355
458
|
const attachmentPathsByPin = /* @__PURE__ */ new Map();
|
|
@@ -371,20 +474,19 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withServices(DEV_SE
|
|
|
371
474
|
parsed,
|
|
372
475
|
attachmentPathsByPin
|
|
373
476
|
);
|
|
374
|
-
} else if (isVisual && input.
|
|
477
|
+
} else if (isVisual && input.screenshot_markers_only) {
|
|
375
478
|
const ssDir = path.join(taskDir, "screenshots");
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
markersOnly:
|
|
479
|
+
const dual = {
|
|
480
|
+
clean: input.screenshot_clean ? persistFile(input.screenshot_clean, ssDir, "clean.png") : "",
|
|
481
|
+
markersOnly: persistFile(
|
|
379
482
|
input.screenshot_markers_only,
|
|
380
483
|
ssDir,
|
|
381
484
|
"markers-only.png"
|
|
382
|
-
)
|
|
383
|
-
clean: input.screenshot_clean ? persistFile(input.screenshot_clean, ssDir, "clean.png") : ""
|
|
485
|
+
)
|
|
384
486
|
};
|
|
385
|
-
const
|
|
487
|
+
const extraFiles = input.extraFiles ?? {};
|
|
386
488
|
const attachmentPathsByAnnotationId = /* @__PURE__ */ new Map();
|
|
387
|
-
for (const [key, file] of Object.entries(
|
|
489
|
+
for (const [key, file] of Object.entries(extraFiles)) {
|
|
388
490
|
if (!key.startsWith("attachment_")) continue;
|
|
389
491
|
const pinId = key.split("_")[1];
|
|
390
492
|
const attDir = path.join(taskDir, `annotation-${pinId}`);
|
|
@@ -393,11 +495,11 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withServices(DEV_SE
|
|
|
393
495
|
existing.push(filePath);
|
|
394
496
|
attachmentPathsByAnnotationId.set(pinId, existing);
|
|
395
497
|
}
|
|
396
|
-
promptContent =
|
|
498
|
+
promptContent = buildVisualPromptDual(
|
|
397
499
|
config,
|
|
398
500
|
input.pageRoute ?? "/",
|
|
399
501
|
input.renderedUrl ?? "",
|
|
400
|
-
|
|
502
|
+
dual,
|
|
401
503
|
parsed,
|
|
402
504
|
attachmentPathsByAnnotationId
|
|
403
505
|
);
|
|
@@ -412,30 +514,81 @@ const submitTaskAction = makeJayStream("aiditor.submitTask").withServices(DEV_SE
|
|
|
412
514
|
"designer",
|
|
413
515
|
"INSTRUCTIONS.md"
|
|
414
516
|
);
|
|
415
|
-
if (fs.existsSync(agentKitPath)) {
|
|
416
|
-
systemPrompt = fs.readFileSync(agentKitPath, "utf-8");
|
|
517
|
+
if (fs$1.existsSync(agentKitPath)) {
|
|
518
|
+
systemPrompt = fs$1.readFileSync(agentKitPath, "utf-8");
|
|
519
|
+
}
|
|
520
|
+
const routeKey = normalizePageRoute(input.pageRoute);
|
|
521
|
+
const sessionPlan = await getOrCreateSessionIdForRoute(
|
|
522
|
+
projectDir,
|
|
523
|
+
routeKey
|
|
524
|
+
);
|
|
525
|
+
if (!tryBeginRouteQuery(routeKey)) {
|
|
526
|
+
yield {
|
|
527
|
+
type: "error",
|
|
528
|
+
message: "Another agent task is already running for this page. Wait for it to finish, then try again."
|
|
529
|
+
};
|
|
530
|
+
yield { type: "done" };
|
|
531
|
+
return;
|
|
417
532
|
}
|
|
533
|
+
const sharedOptions = {
|
|
534
|
+
cwd: projectDir,
|
|
535
|
+
tools: ["Read", "Edit", "Write", "Bash", "Glob", "Grep"],
|
|
536
|
+
allowedTools: ["Read", "Edit", "Write", "Bash", "Glob", "Grep"],
|
|
537
|
+
maxTurns: 30,
|
|
538
|
+
persistSession: true,
|
|
539
|
+
systemPrompt
|
|
540
|
+
};
|
|
418
541
|
try {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
542
|
+
async function* streamAgentQuery(opts) {
|
|
543
|
+
for await (const message of query({
|
|
544
|
+
prompt: promptContent,
|
|
545
|
+
options: {
|
|
546
|
+
...sharedOptions,
|
|
547
|
+
...opts
|
|
548
|
+
}
|
|
549
|
+
})) {
|
|
550
|
+
for (const chunk of transformSDKMessage(message)) {
|
|
551
|
+
yield chunk;
|
|
552
|
+
}
|
|
428
553
|
}
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
|
|
554
|
+
}
|
|
555
|
+
let didStaleResumeRetry = false;
|
|
556
|
+
try {
|
|
557
|
+
if (sessionPlan.useResume) {
|
|
558
|
+
yield* streamAgentQuery({ resume: sessionPlan.sessionId });
|
|
559
|
+
} else {
|
|
560
|
+
yield* streamAgentQuery({
|
|
561
|
+
sessionId: sessionPlan.sessionId,
|
|
562
|
+
title: routeKey
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
} catch (err) {
|
|
566
|
+
if (sessionPlan.useResume && !didStaleResumeRetry) {
|
|
567
|
+
didStaleResumeRetry = true;
|
|
568
|
+
const fresh = await replaceRouteSessionAfterStaleResume(
|
|
569
|
+
projectDir,
|
|
570
|
+
routeKey
|
|
571
|
+
);
|
|
572
|
+
try {
|
|
573
|
+
yield* streamAgentQuery({
|
|
574
|
+
sessionId: fresh.sessionId,
|
|
575
|
+
title: routeKey
|
|
576
|
+
});
|
|
577
|
+
} catch (err2) {
|
|
578
|
+
yield {
|
|
579
|
+
type: "error",
|
|
580
|
+
message: err2 instanceof Error ? err2.message : String(err2)
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
} else {
|
|
584
|
+
yield {
|
|
585
|
+
type: "error",
|
|
586
|
+
message: err instanceof Error ? err.message : String(err)
|
|
587
|
+
};
|
|
432
588
|
}
|
|
433
589
|
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
type: "error",
|
|
437
|
-
message: err instanceof Error ? err.message : String(err)
|
|
438
|
-
};
|
|
590
|
+
} finally {
|
|
591
|
+
endRouteQuery(routeKey);
|
|
439
592
|
}
|
|
440
593
|
yield { type: "done" };
|
|
441
594
|
});
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
.visual-error { font-size: 12px; color: #f48771; }
|
|
86
86
|
.visual-submit-error { font-size: 12px; color: #f48771; margin: 0; padding: 0 2px; }
|
|
87
87
|
.visual-submit-progress { font-size: 12px; color: #9cdcfe; margin: 0; padding: 0 2px; }
|
|
88
|
-
.bottom-panel { flex-shrink: 0; display: flex; flex-direction: column; background: #1e1e1e; border-top: 1px solid #3e3e3e; min-height: 32px; max-height: 80vh; }
|
|
88
|
+
.bottom-panel { flex-shrink: 0; display: flex; flex-direction: column; background: #1e1e1e; border-top: 1px solid #3e3e3e; min-height: 32px; max-height: 80vh; height: 200px; }
|
|
89
89
|
.bottom-panel-collapsed { max-height: 32px; overflow: hidden; }
|
|
90
90
|
.bottom-panel-resize { height: 4px; cursor: ns-resize; background: transparent; flex-shrink: 0; }
|
|
91
91
|
.bottom-panel-resize:hover, .bottom-panel-resize:active { background: #007acc; }
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
.bottom-panel-spacer { flex: 1; }
|
|
99
99
|
.bottom-panel-clear { background: none; border: none; color: #666; font-size: 11px; cursor: pointer; padding: 2px 6px; }
|
|
100
100
|
.bottom-panel-clear:hover { color: #ccc; }
|
|
101
|
-
.output-panel { overflow-y: auto; padding: 8px 12px; font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 12px; line-height: 1.5; white-space: pre-wrap; word-break: break-word;
|
|
101
|
+
.output-panel { overflow-y: auto; padding: 8px 12px; font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 12px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; flex: 1; min-height: 0; }
|
|
102
102
|
.chunk { color: #d4d4d4; }
|
|
103
103
|
.chunk-status { color: #888; font-style: italic; }
|
|
104
104
|
.chunk-tool { color: #569cd6; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/aiditor",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AIditor — visual AI-driven code editor plugin for Jay Framework",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -38,24 +38,25 @@
|
|
|
38
38
|
"build:types": "tsup lib/index.ts lib/index.client.ts --dts-only --format esm",
|
|
39
39
|
"build:check-types": "tsc",
|
|
40
40
|
"clean": "rimraf dist",
|
|
41
|
-
"test": "
|
|
41
|
+
"test": "vitest run"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@anthropic-ai/claude-agent-sdk": "0.2.119",
|
|
45
|
-
"@jay-framework/fullstack-component": "^0.16.
|
|
46
|
-
"@jay-framework/stack-client-runtime": "^0.16.
|
|
47
|
-
"@jay-framework/stack-server-runtime": "^0.16.
|
|
45
|
+
"@jay-framework/fullstack-component": "^0.16.5",
|
|
46
|
+
"@jay-framework/stack-client-runtime": "^0.16.5",
|
|
47
|
+
"@jay-framework/stack-server-runtime": "^0.16.5",
|
|
48
48
|
"busboy": "^1.6.0",
|
|
49
49
|
"html2canvas": "^1.4.1",
|
|
50
50
|
"zod": "^4.3.6"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@jay-framework/compiler-jay-stack": "^0.16.
|
|
54
|
-
"@jay-framework/jay-cli": "^0.16.
|
|
53
|
+
"@jay-framework/compiler-jay-stack": "^0.16.5",
|
|
54
|
+
"@jay-framework/jay-cli": "^0.16.5",
|
|
55
55
|
"@types/busboy": "^1",
|
|
56
56
|
"rimraf": "^5.0.5",
|
|
57
57
|
"tsup": "^8.5.1",
|
|
58
58
|
"typescript": "^5.3.3",
|
|
59
|
-
"vite": "^5.0.11"
|
|
59
|
+
"vite": "^5.0.11",
|
|
60
|
+
"vitest": "^3.2.4"
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import {JayElement, RenderElement, HTMLElementCollectionProxy, HTMLElementProxy, RenderElementOptions, JayContract} from "@jay-framework/runtime";
|
|
2
|
-
|
|
3
|
-
import './page.css';
|
|
4
|
-
|
|
5
|
-
export interface ChunkOfPageViewState {
|
|
6
|
-
text: string,
|
|
7
|
-
cssClass: string,
|
|
8
|
-
filePath: string,
|
|
9
|
-
toolName: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface PageSelectOptionOfPageViewState {
|
|
13
|
-
url: string,
|
|
14
|
-
label: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface PreviewPathOptionOfPageViewState {
|
|
18
|
-
path: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface VisualPointDisplayItemOfPageViewState {
|
|
22
|
-
id: string,
|
|
23
|
-
leftPct: number,
|
|
24
|
-
topPct: number,
|
|
25
|
-
indexLabel: string
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface VisualAreaDisplayItemOfPageViewState {
|
|
29
|
-
id: string,
|
|
30
|
-
leftPct: number,
|
|
31
|
-
topPct: number,
|
|
32
|
-
widthPct: number,
|
|
33
|
-
heightPct: number,
|
|
34
|
-
indexLabel: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface VisualArrowDisplayItemOfPageViewState {
|
|
38
|
-
id: string,
|
|
39
|
-
x1Pct: number,
|
|
40
|
-
y1Pct: number,
|
|
41
|
-
x2Pct: number,
|
|
42
|
-
y2Pct: number
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface VisualArrowPinItemOfPageViewState {
|
|
46
|
-
id: string,
|
|
47
|
-
leftPct: number,
|
|
48
|
-
topPct: number,
|
|
49
|
-
indexLabel: string
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface AttachmentChipOfVisualAnnotationRowOfPageViewState {
|
|
53
|
-
key: string,
|
|
54
|
-
name: string,
|
|
55
|
-
thumbUrl: string,
|
|
56
|
-
annotationId: string
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface VisualAnnotationRowOfPageViewState {
|
|
60
|
-
id: string,
|
|
61
|
-
kindLabel: string,
|
|
62
|
-
instruction: string,
|
|
63
|
-
runDisabled: boolean,
|
|
64
|
-
leftPct: number,
|
|
65
|
-
topPct: number,
|
|
66
|
-
popoverFlipX: boolean,
|
|
67
|
-
popoverFlipY: boolean,
|
|
68
|
-
attachmentChips: Array<AttachmentChipOfVisualAnnotationRowOfPageViewState>
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface AttachmentChipOfRecordingDraftUiOfPageViewState {
|
|
72
|
-
key: string,
|
|
73
|
-
name: string,
|
|
74
|
-
thumbUrl: string,
|
|
75
|
-
annotationId: string
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface RecordingDraftUiOfPageViewState {
|
|
79
|
-
id: string,
|
|
80
|
-
kindLabel: string,
|
|
81
|
-
instruction: string,
|
|
82
|
-
leftPct: number,
|
|
83
|
-
topPct: number,
|
|
84
|
-
popoverFlipX: boolean,
|
|
85
|
-
popoverFlipY: boolean,
|
|
86
|
-
attachmentChips: Array<AttachmentChipOfRecordingDraftUiOfPageViewState>
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export interface RecordingDraftAttachmentChipOfPageViewState {
|
|
90
|
-
key: string,
|
|
91
|
-
name: string,
|
|
92
|
-
thumbUrl: string,
|
|
93
|
-
annotationId: string
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export interface VideoPointDisplayItemOfPageViewState {
|
|
97
|
-
id: string,
|
|
98
|
-
leftPct: number,
|
|
99
|
-
topPct: number,
|
|
100
|
-
indexLabel: string
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export interface VideoAreaDisplayItemOfPageViewState {
|
|
104
|
-
id: string,
|
|
105
|
-
leftPct: number,
|
|
106
|
-
topPct: number,
|
|
107
|
-
widthPct: number,
|
|
108
|
-
heightPct: number,
|
|
109
|
-
indexLabel: string
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface VideoArrowDisplayItemOfPageViewState {
|
|
113
|
-
id: string,
|
|
114
|
-
x1Pct: number,
|
|
115
|
-
y1Pct: number,
|
|
116
|
-
x2Pct: number,
|
|
117
|
-
y2Pct: number
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface VideoArrowPinItemOfPageViewState {
|
|
121
|
-
id: string,
|
|
122
|
-
leftPct: number,
|
|
123
|
-
topPct: number,
|
|
124
|
-
indexLabel: string
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface AttachmentChipOfVideoAnnotationRowOfPageViewState {
|
|
128
|
-
key: string,
|
|
129
|
-
name: string,
|
|
130
|
-
thumbUrl: string,
|
|
131
|
-
annotationId: string
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export interface VideoAnnotationRowOfPageViewState {
|
|
135
|
-
id: string,
|
|
136
|
-
kindLabel: string,
|
|
137
|
-
instruction: string,
|
|
138
|
-
runDisabled: boolean,
|
|
139
|
-
leftPct: number,
|
|
140
|
-
topPct: number,
|
|
141
|
-
popoverFlipX: boolean,
|
|
142
|
-
popoverFlipY: boolean,
|
|
143
|
-
attachmentChips: Array<AttachmentChipOfVideoAnnotationRowOfPageViewState>
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export interface VideoTimelineMarkerOfPageViewState {
|
|
147
|
-
key: string,
|
|
148
|
-
timeSec: number,
|
|
149
|
-
leftPct: number,
|
|
150
|
-
label: string
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export interface PageViewState {
|
|
154
|
-
isBootstrapping: boolean,
|
|
155
|
-
showBootstrapError: boolean,
|
|
156
|
-
bootstrapErrorText: string,
|
|
157
|
-
canRetryBootstrap: boolean,
|
|
158
|
-
isMainVisible: boolean,
|
|
159
|
-
projectName: string,
|
|
160
|
-
notes: string,
|
|
161
|
-
hasImage: boolean,
|
|
162
|
-
isRunning: boolean,
|
|
163
|
-
chunks: Array<ChunkOfPageViewState>,
|
|
164
|
-
hasChunks: boolean,
|
|
165
|
-
outputEmpty: boolean,
|
|
166
|
-
pageSelectOptions: Array<PageSelectOptionOfPageViewState>,
|
|
167
|
-
selectedRouteSelectValue: string,
|
|
168
|
-
hasPages: boolean,
|
|
169
|
-
isPreviewMode: boolean,
|
|
170
|
-
previewUrlBar: string,
|
|
171
|
-
previewLoading: boolean,
|
|
172
|
-
paramsLoadingHint: string,
|
|
173
|
-
previewError: string,
|
|
174
|
-
showPathSelect: boolean,
|
|
175
|
-
previewPathOptions: Array<PreviewPathOptionOfPageViewState>,
|
|
176
|
-
selectedPreviewPath: string,
|
|
177
|
-
showPreviewIframe: boolean,
|
|
178
|
-
previewSrc: string,
|
|
179
|
-
showOutputChunks: boolean,
|
|
180
|
-
showOutputEmpty: boolean,
|
|
181
|
-
outputEmptyHint: string,
|
|
182
|
-
bottomPanelClass: string,
|
|
183
|
-
bottomPanelToggleGlyph: string,
|
|
184
|
-
showBottomPanelRunning: boolean,
|
|
185
|
-
showFilePreview: boolean,
|
|
186
|
-
filePreviewPath: string,
|
|
187
|
-
filePreviewContent: string,
|
|
188
|
-
filePreviewIsImage: boolean,
|
|
189
|
-
filePreviewImageSrc: string,
|
|
190
|
-
filePreviewLoading: boolean,
|
|
191
|
-
showVisualToolbar: boolean,
|
|
192
|
-
visualToolNoneOn: boolean,
|
|
193
|
-
visualToolPointOn: boolean,
|
|
194
|
-
visualToolAreaOn: boolean,
|
|
195
|
-
visualToolArrowOn: boolean,
|
|
196
|
-
visualPointDisplayItems: Array<VisualPointDisplayItemOfPageViewState>,
|
|
197
|
-
showVisualPointMarkers: boolean,
|
|
198
|
-
visualAreaDisplayItems: Array<VisualAreaDisplayItemOfPageViewState>,
|
|
199
|
-
showVisualAreaItems: boolean,
|
|
200
|
-
areaDraftLeftPct: number,
|
|
201
|
-
areaDraftTopPct: number,
|
|
202
|
-
areaDraftWidthPct: number,
|
|
203
|
-
areaDraftHeightPct: number,
|
|
204
|
-
showAreaDraftRect: boolean,
|
|
205
|
-
visualArrowDisplayItems: Array<VisualArrowDisplayItemOfPageViewState>,
|
|
206
|
-
visualArrowPinItems: Array<VisualArrowPinItemOfPageViewState>,
|
|
207
|
-
hasVisualArrowLines: boolean,
|
|
208
|
-
showArrowPending: boolean,
|
|
209
|
-
arrowPendingLeftPct: number,
|
|
210
|
-
arrowPendingTopPct: number,
|
|
211
|
-
visualAnnotationRows: Array<VisualAnnotationRowOfPageViewState>,
|
|
212
|
-
recordingDraftUi: RecordingDraftUiOfPageViewState,
|
|
213
|
-
recordingDraftAttachmentChips: Array<RecordingDraftAttachmentChipOfPageViewState>,
|
|
214
|
-
showRecordingDraftPopover: boolean,
|
|
215
|
-
showVisualAnnotationsPanel: boolean,
|
|
216
|
-
showVisualSubmitError: boolean,
|
|
217
|
-
visualSubmitError: string,
|
|
218
|
-
visualOverlayPointerNone: boolean,
|
|
219
|
-
showVideoRecordUi: boolean,
|
|
220
|
-
isVideoRecording: boolean,
|
|
221
|
-
videoRecordLabel: string,
|
|
222
|
-
videoRecordDisabled: boolean,
|
|
223
|
-
freezeDisabled: boolean,
|
|
224
|
-
showVideoReviewModal: boolean,
|
|
225
|
-
videoReviewPreparing: boolean,
|
|
226
|
-
videoReviewReady: boolean,
|
|
227
|
-
videoReviewError: boolean,
|
|
228
|
-
videoReviewErrorText: string,
|
|
229
|
-
videoReviewObjectUrl: string,
|
|
230
|
-
videoModalToolNoneOn: boolean,
|
|
231
|
-
videoModalToolPointOn: boolean,
|
|
232
|
-
videoModalToolAreaOn: boolean,
|
|
233
|
-
videoModalToolArrowOn: boolean,
|
|
234
|
-
videoPointDisplayItems: Array<VideoPointDisplayItemOfPageViewState>,
|
|
235
|
-
showVideoPointMarkers: boolean,
|
|
236
|
-
videoAreaDisplayItems: Array<VideoAreaDisplayItemOfPageViewState>,
|
|
237
|
-
showVideoAreaItems: boolean,
|
|
238
|
-
videoAreaDraftLeftPct: number,
|
|
239
|
-
videoAreaDraftTopPct: number,
|
|
240
|
-
videoAreaDraftWidthPct: number,
|
|
241
|
-
videoAreaDraftHeightPct: number,
|
|
242
|
-
showVideoAreaDraftRect: boolean,
|
|
243
|
-
videoArrowDisplayItems: Array<VideoArrowDisplayItemOfPageViewState>,
|
|
244
|
-
videoArrowPinItems: Array<VideoArrowPinItemOfPageViewState>,
|
|
245
|
-
hasVideoArrowLines: boolean,
|
|
246
|
-
showVideoArrowPending: boolean,
|
|
247
|
-
videoArrowPendingLeftPct: number,
|
|
248
|
-
videoArrowPendingTopPct: number,
|
|
249
|
-
videoAnnotationRows: Array<VideoAnnotationRowOfPageViewState>,
|
|
250
|
-
showVideoAnnotationsPanel: boolean,
|
|
251
|
-
videoModalOverlayPointerNone: boolean,
|
|
252
|
-
videoSubmitError: string,
|
|
253
|
-
showVideoSubmitError: boolean,
|
|
254
|
-
videoSubmitProgress: string,
|
|
255
|
-
showVideoSubmitProgress: boolean,
|
|
256
|
-
videoTimelineMarkers: Array<VideoTimelineMarkerOfPageViewState>,
|
|
257
|
-
showVideoAnnotationPopoversAtPlayhead: boolean,
|
|
258
|
-
videoTimeLabel: string,
|
|
259
|
-
videoSendDisabled: boolean,
|
|
260
|
-
videoPlayPauseGlyph: string,
|
|
261
|
-
breakpointDesktopOn: boolean,
|
|
262
|
-
breakpointTabletOn: boolean,
|
|
263
|
-
breakpointMobileOn: boolean
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
export interface PageElementRefs {
|
|
268
|
-
retryBootstrapBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
269
|
-
pageRouteSelect: HTMLElementProxy<PageViewState, HTMLSelectElement>,
|
|
270
|
-
previewPathSelect: HTMLElementProxy<PageViewState, HTMLSelectElement>,
|
|
271
|
-
breakpointDesktopBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
272
|
-
breakpointTabletBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
273
|
-
breakpointMobileBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
274
|
-
visualToolNoneBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
275
|
-
visualToolPointBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
276
|
-
visualToolAreaBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
277
|
-
visualToolArrowBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
278
|
-
videoRecordBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
279
|
-
freezeBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
280
|
-
visualAttachFileInput: HTMLElementProxy<PageViewState, HTMLInputElement>,
|
|
281
|
-
previewIframe: HTMLElementProxy<PageViewState, HTMLIFrameElement>,
|
|
282
|
-
visualOverlay: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
283
|
-
recordingDraftPopover: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
284
|
-
previewCaptureRoot: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
285
|
-
bottomPanelResize: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
286
|
-
bottomPanelClearBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
287
|
-
bottomPanelToggleBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
288
|
-
bottomPanelHeader: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
289
|
-
outputScroll: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
290
|
-
filePreviewCloseBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
291
|
-
filePreviewBackdrop: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
292
|
-
videoReviewCloseBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
293
|
-
videoModalToolNoneBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
294
|
-
videoModalToolPointBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
295
|
-
videoModalToolAreaBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
296
|
-
videoModalToolArrowBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
297
|
-
videoReviewAttachFileInput: HTMLElementProxy<PageViewState, HTMLInputElement>,
|
|
298
|
-
videoReviewPlayer: HTMLElementProxy<PageViewState, HTMLVideoElement>,
|
|
299
|
-
videoReviewOverlay: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
300
|
-
videoReviewCaptureRoot: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
301
|
-
videoPlayPauseBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
302
|
-
videoTimeline: HTMLElementProxy<PageViewState, HTMLInputElement>,
|
|
303
|
-
videoReviewTimelineWrap: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
304
|
-
videoReviewDiscardBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
305
|
-
videoReviewSendBtn: HTMLElementProxy<PageViewState, HTMLButtonElement>,
|
|
306
|
-
videoReviewBackdrop: HTMLElementProxy<PageViewState, HTMLDivElement>,
|
|
307
|
-
visualAnnotationRows: {
|
|
308
|
-
annotationRow: HTMLElementCollectionProxy<VisualAnnotationRowOfPageViewState, HTMLDivElement>
|
|
309
|
-
},
|
|
310
|
-
videoAnnotationRows: {
|
|
311
|
-
videoAnnotationRow: HTMLElementCollectionProxy<VideoAnnotationRowOfPageViewState, HTMLDivElement>
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
export type PageSlowViewState = {};
|
|
316
|
-
export type PageFastViewState = PageViewState;
|
|
317
|
-
export type PageInteractiveViewState = PageViewState;
|
|
318
|
-
|
|
319
|
-
export type PageElement = JayElement<PageViewState, PageElementRefs>
|
|
320
|
-
export type PageElementRender = RenderElement<PageViewState, PageElementRefs, PageElement>
|
|
321
|
-
export type PageElementPreRender = [PageElementRefs, PageElementRender]
|
|
322
|
-
export type PageContract = JayContract<
|
|
323
|
-
PageViewState,
|
|
324
|
-
PageElementRefs,
|
|
325
|
-
PageSlowViewState,
|
|
326
|
-
PageFastViewState,
|
|
327
|
-
PageInteractiveViewState
|
|
328
|
-
>;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
export declare function render(options?: RenderElementOptions): PageElementPreRender
|