@playdrop/playdrop-cli 0.12.17 → 0.12.18
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/config/client-meta.json +1 -1
- package/dist/commands/worker.d.ts +2 -0
- package/dist/commands/worker.js +30 -1
- package/node_modules/@playdrop/config/client-meta.json +1 -1
- package/node_modules/@playdrop/types/dist/instrument-evidence.d.ts +4 -2
- package/node_modules/@playdrop/types/dist/instrument-evidence.d.ts.map +1 -1
- package/node_modules/@playdrop/types/dist/instrument-evidence.js +28 -10
- package/package.json +1 -1
package/config/client-meta.json
CHANGED
|
@@ -137,6 +137,8 @@ export declare function resolveWorkerClaimTaskAssignment(claim: WorkerClaimAgent
|
|
|
137
137
|
export declare function nextClaimBackoffMs(currentMs: number): number;
|
|
138
138
|
export declare function claimBackoffDelayMs(currentMs: number, random?: () => number): number;
|
|
139
139
|
export declare function resolveWorkerHomeDir(): string;
|
|
140
|
+
export declare const WORKER_TASK_WORKSPACE_RETENTION = 20;
|
|
141
|
+
export declare function pruneWorkerTaskWorkspaces(incomingWorkspaceDir: string, retention?: number): Promise<string[]>;
|
|
140
142
|
export declare function hasAgentTaskUploadedArtifact(task: Pick<AgentTaskResponse, 'appId' | 'appVersionId'>): boolean;
|
|
141
143
|
export declare function appendWorkerTranscriptChunks(input: {
|
|
142
144
|
client: Pick<ApiClient, 'workerAppendAgentTaskTranscriptChunks'>;
|
package/dist/commands/worker.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = exports.WORKER_SESSION_EXPIRED_MESSAGE = exports.runLoggedProcess = exports.readEnvBoolean = exports.readCodexSandboxMode = exports.readCodexRolloutTokenUsageForThread = exports.extractCodexTokensUsed = exports.extractCodexThreadId = exports.extractCodexRolloutTokenUsage = exports.extractAgentTokenUsage = exports.DEFAULT_WORKER_TOKEN_CAP = exports.DEFAULT_CODEX_TIMEOUT_MS = exports.buildWorkerChildEnv = exports.buildCodexExecArgs = exports.buildClaudePermissionSettings = exports.buildClaudeExecArgs = exports.assertWorkerTokenUsageWithinCap = void 0;
|
|
6
|
+
exports.WORKER_TASK_WORKSPACE_RETENTION = exports.WORKER_CONTEXT_COMMAND_NOT_ALLOWED_MESSAGE = exports.WORKER_SESSION_EXPIRED_MESSAGE = exports.runLoggedProcess = exports.readEnvBoolean = exports.readCodexSandboxMode = exports.readCodexRolloutTokenUsageForThread = exports.extractCodexTokensUsed = exports.extractCodexThreadId = exports.extractCodexRolloutTokenUsage = exports.extractAgentTokenUsage = exports.DEFAULT_WORKER_TOKEN_CAP = exports.DEFAULT_CODEX_TIMEOUT_MS = exports.buildWorkerChildEnv = exports.buildCodexExecArgs = exports.buildClaudePermissionSettings = exports.buildClaudeExecArgs = exports.assertWorkerTokenUsageWithinCap = void 0;
|
|
7
7
|
exports.allocateWorkerDevPort = allocateWorkerDevPort;
|
|
8
8
|
exports.isWorkerContextCommandAllowed = isWorkerContextCommandAllowed;
|
|
9
9
|
exports.resolveWorkerExecutionTargetFromRole = resolveWorkerExecutionTargetFromRole;
|
|
@@ -11,6 +11,7 @@ exports.resolveWorkerClaimTaskAssignment = resolveWorkerClaimTaskAssignment;
|
|
|
11
11
|
exports.nextClaimBackoffMs = nextClaimBackoffMs;
|
|
12
12
|
exports.claimBackoffDelayMs = claimBackoffDelayMs;
|
|
13
13
|
exports.resolveWorkerHomeDir = resolveWorkerHomeDir;
|
|
14
|
+
exports.pruneWorkerTaskWorkspaces = pruneWorkerTaskWorkspaces;
|
|
14
15
|
exports.hasAgentTaskUploadedArtifact = hasAgentTaskUploadedArtifact;
|
|
15
16
|
exports.appendWorkerTranscriptChunks = appendWorkerTranscriptChunks;
|
|
16
17
|
exports.readTaskNextStepsFile = readTaskNextStepsFile;
|
|
@@ -412,6 +413,33 @@ function workerStateFilePath() {
|
|
|
412
413
|
function workerTaskWorkspaceDirFromAssignment(assignment) {
|
|
413
414
|
return node_path_1.default.join(resolveWorkerHomeDir(), 'tasks', assignment.workspace.folderName);
|
|
414
415
|
}
|
|
416
|
+
exports.WORKER_TASK_WORKSPACE_RETENTION = 20;
|
|
417
|
+
// Task workspaces (including retained failed ones) otherwise grow without bound on a long-lived
|
|
418
|
+
// worker host. Keep only the most recently touched ones; the incoming task's own directory is
|
|
419
|
+
// never a prune candidate.
|
|
420
|
+
async function pruneWorkerTaskWorkspaces(incomingWorkspaceDir, retention = exports.WORKER_TASK_WORKSPACE_RETENTION) {
|
|
421
|
+
const tasksRoot = node_path_1.default.dirname(node_path_1.default.resolve(incomingWorkspaceDir));
|
|
422
|
+
if (!(0, node_fs_1.existsSync)(tasksRoot)) {
|
|
423
|
+
return [];
|
|
424
|
+
}
|
|
425
|
+
const incoming = node_path_1.default.resolve(incomingWorkspaceDir);
|
|
426
|
+
const entries = (0, node_fs_1.readdirSync)(tasksRoot, { withFileTypes: true })
|
|
427
|
+
.filter((entry) => entry.isDirectory())
|
|
428
|
+
.map((entry) => node_path_1.default.join(tasksRoot, entry.name))
|
|
429
|
+
.filter((dir) => dir !== incoming)
|
|
430
|
+
.map((dir) => ({ dir, mtimeMs: (0, node_fs_1.statSync)(dir).mtimeMs }))
|
|
431
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
432
|
+
const stale = entries.slice(Math.max(0, retention - 1));
|
|
433
|
+
const removed = [];
|
|
434
|
+
for (const entry of stale) {
|
|
435
|
+
await (0, promises_1.rm)(entry.dir, { recursive: true, force: true });
|
|
436
|
+
removed.push(entry.dir);
|
|
437
|
+
}
|
|
438
|
+
if (removed.length > 0) {
|
|
439
|
+
console.error(`pruned ${removed.length} stale task workspace(s), keeping the ${retention} most recent`);
|
|
440
|
+
}
|
|
441
|
+
return removed;
|
|
442
|
+
}
|
|
415
443
|
function buildWorkerTaskContext(claim, assignment) {
|
|
416
444
|
const task = claim.task;
|
|
417
445
|
if (!task) {
|
|
@@ -3870,6 +3898,7 @@ async function startWorker(options = {}) {
|
|
|
3870
3898
|
reasoningEffort = codexModel?.reasoningEffort ?? claudeModel?.effort ?? null;
|
|
3871
3899
|
const taskContext = buildWorkerTaskContext(claim, assignment);
|
|
3872
3900
|
workspaceDir = workerTaskWorkspaceDirFromAssignment(assignment);
|
|
3901
|
+
await pruneWorkerTaskWorkspaces(workspaceDir);
|
|
3873
3902
|
await (0, promises_1.rm)(workspaceDir, { recursive: true, force: true });
|
|
3874
3903
|
await (0, promises_1.mkdir)(workspaceDir, { recursive: true });
|
|
3875
3904
|
const eventDir = node_path_1.default.join(workspaceDir, '.playdrop-task-events');
|
|
@@ -28,7 +28,9 @@ export type InstrumentEvidenceManifest = {
|
|
|
28
28
|
};
|
|
29
29
|
export declare const PLAYWRIGHT_MCP_SCREENSHOT_TOOL = "mcp__playwright__browser_take_screenshot";
|
|
30
30
|
export declare const PLAYWRIGHT_MCP_CONTROLLED_TAB_ID = 1;
|
|
31
|
+
export declare const PLAYWRIGHT_MCP_SCREENSHOT_BUDGET = 100;
|
|
31
32
|
export declare function isInstrumentScreenshotId(value: string): boolean;
|
|
33
|
+
export declare function normalizePlaywrightScreenshotId(value: unknown): string | null;
|
|
32
34
|
export declare class ClaudeChromeScreenshotStreamParser {
|
|
33
35
|
private readonly onScreenshot;
|
|
34
36
|
private buffer;
|
|
@@ -44,9 +46,9 @@ export declare class ClaudeChromeScreenshotStreamParser {
|
|
|
44
46
|
export declare class PlaywrightMcpScreenshotStreamParser {
|
|
45
47
|
private readonly onScreenshot;
|
|
46
48
|
private buffer;
|
|
47
|
-
private readonly
|
|
49
|
+
private readonly pendingScreenshotFilenames;
|
|
48
50
|
private readonly handledToolUseIds;
|
|
49
|
-
private
|
|
51
|
+
private screenshotCallCount;
|
|
50
52
|
constructor(onScreenshot: (screenshot: ClaudeChromeScreenshot) => void);
|
|
51
53
|
push(chunk: string): number;
|
|
52
54
|
finish(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument-evidence.d.ts","sourceRoot":"","sources":["../src/instrument-evidence.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,iDAK5B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,YAAY,GAAG,WAAW,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,YAAY,GAAG,WAAW,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,CAAC,CAAC;CAC9E,CAAC;AAMF,eAAO,MAAM,8BAA8B,6CAA6C,CAAC;AACzF,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAGlD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AA+CD,qBAAa,kCAAkC;IAKjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAJzC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA+B;IACzE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqB;gBAE7B,YAAY,EAAE,CAAC,UAAU,EAAE,sBAAsB,KAAK,IAAI;IAEvF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAqB3B,MAAM,IAAI,MAAM;IAMhB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,iBAAiB;CAiE1B;AAMD,qBAAa,mCAAmC;IAMlC,OAAO,CAAC,QAAQ,CAAC,YAAY;IALzC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"instrument-evidence.d.ts","sourceRoot":"","sources":["../src/instrument-evidence.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,iDAK5B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,YAAY,GAAG,WAAW,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,YAAY,GAAG,WAAW,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,CAAC,CAAC;CAC9E,CAAC;AAMF,eAAO,MAAM,8BAA8B,6CAA6C,CAAC;AACzF,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAGlD,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAKpD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAG7E;AA+CD,qBAAa,kCAAkC;IAKjC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAJzC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAA+B;IACzE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAqB;gBAE7B,YAAY,EAAE,CAAC,UAAU,EAAE,sBAAsB,KAAK,IAAI;IAEvF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAqB3B,MAAM,IAAI,MAAM;IAMhB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,iBAAiB;CAiE1B;AAMD,qBAAa,mCAAmC;IAMlC,OAAO,CAAC,QAAQ,CAAC,YAAY;IALzC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAA6B;IACxE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqB;IACvD,OAAO,CAAC,mBAAmB,CAAK;gBAEH,YAAY,EAAE,CAAC,UAAU,EAAE,sBAAsB,KAAK,IAAI;IAEvF,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAqB3B,MAAM,IAAI,MAAM;IAMhB,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,iBAAiB;CA+C1B"}
|
|
@@ -20,9 +20,11 @@ __export(instrument_evidence_exports, {
|
|
|
20
20
|
ClaudeChromeScreenshotStreamParser: () => ClaudeChromeScreenshotStreamParser,
|
|
21
21
|
INSTRUMENT_EVIDENCE_NAMES: () => INSTRUMENT_EVIDENCE_NAMES,
|
|
22
22
|
PLAYWRIGHT_MCP_CONTROLLED_TAB_ID: () => PLAYWRIGHT_MCP_CONTROLLED_TAB_ID,
|
|
23
|
+
PLAYWRIGHT_MCP_SCREENSHOT_BUDGET: () => PLAYWRIGHT_MCP_SCREENSHOT_BUDGET,
|
|
23
24
|
PLAYWRIGHT_MCP_SCREENSHOT_TOOL: () => PLAYWRIGHT_MCP_SCREENSHOT_TOOL,
|
|
24
25
|
PlaywrightMcpScreenshotStreamParser: () => PlaywrightMcpScreenshotStreamParser,
|
|
25
|
-
isInstrumentScreenshotId: () => isInstrumentScreenshotId
|
|
26
|
+
isInstrumentScreenshotId: () => isInstrumentScreenshotId,
|
|
27
|
+
normalizePlaywrightScreenshotId: () => normalizePlaywrightScreenshotId
|
|
26
28
|
});
|
|
27
29
|
module.exports = __toCommonJS(instrument_evidence_exports);
|
|
28
30
|
const INSTRUMENT_EVIDENCE_NAMES = [
|
|
@@ -36,10 +38,15 @@ const SCREENSHOT_ID_IN_TEXT_PATTERN = /\bID:\s*(ss_[A-Za-z0-9_-]+)\b/g;
|
|
|
36
38
|
const MAX_STREAM_LINE_LENGTH = 20 * 1024 * 1024;
|
|
37
39
|
const PLAYWRIGHT_MCP_SCREENSHOT_TOOL = "mcp__playwright__browser_take_screenshot";
|
|
38
40
|
const PLAYWRIGHT_MCP_CONTROLLED_TAB_ID = 1;
|
|
39
|
-
const
|
|
41
|
+
const PLAYWRIGHT_MCP_SCREENSHOT_BUDGET = 100;
|
|
42
|
+
const PLAYWRIGHT_SCREENSHOT_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}\.(png|jpe?g)$/;
|
|
40
43
|
function isInstrumentScreenshotId(value) {
|
|
41
44
|
return SCREENSHOT_ID_PATTERN.test(value) || PLAYWRIGHT_SCREENSHOT_ID_PATTERN.test(value);
|
|
42
45
|
}
|
|
46
|
+
function normalizePlaywrightScreenshotId(value) {
|
|
47
|
+
const id = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
48
|
+
return PLAYWRIGHT_SCREENSHOT_ID_PATTERN.test(id) ? id : null;
|
|
49
|
+
}
|
|
43
50
|
function asRecord(value) {
|
|
44
51
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
45
52
|
}
|
|
@@ -221,9 +228,9 @@ class ClaudeChromeScreenshotStreamParser {
|
|
|
221
228
|
class PlaywrightMcpScreenshotStreamParser {
|
|
222
229
|
onScreenshot;
|
|
223
230
|
buffer = "";
|
|
224
|
-
|
|
231
|
+
pendingScreenshotFilenames = /* @__PURE__ */ new Map();
|
|
225
232
|
handledToolUseIds = /* @__PURE__ */ new Set();
|
|
226
|
-
|
|
233
|
+
screenshotCallCount = 0;
|
|
227
234
|
constructor(onScreenshot) {
|
|
228
235
|
this.onScreenshot = onScreenshot;
|
|
229
236
|
}
|
|
@@ -287,7 +294,16 @@ class PlaywrightMcpScreenshotStreamParser {
|
|
|
287
294
|
if (item?.["type"] !== "tool_use" || !id || name !== PLAYWRIGHT_MCP_SCREENSHOT_TOOL) {
|
|
288
295
|
continue;
|
|
289
296
|
}
|
|
290
|
-
this.
|
|
297
|
+
this.screenshotCallCount += 1;
|
|
298
|
+
if (this.screenshotCallCount > PLAYWRIGHT_MCP_SCREENSHOT_BUDGET) {
|
|
299
|
+
throw new Error(`playwright_screenshot_budget_exceeded:${PLAYWRIGHT_MCP_SCREENSHOT_BUDGET}`);
|
|
300
|
+
}
|
|
301
|
+
const input = asRecord(item?.["input"]);
|
|
302
|
+
const filename = normalizePlaywrightScreenshotId(input?.["filename"]);
|
|
303
|
+
if (!filename) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
this.pendingScreenshotFilenames.set(id, filename);
|
|
291
307
|
}
|
|
292
308
|
}
|
|
293
309
|
recordToolResults(payload) {
|
|
@@ -300,11 +316,12 @@ class PlaywrightMcpScreenshotStreamParser {
|
|
|
300
316
|
continue;
|
|
301
317
|
}
|
|
302
318
|
const toolUseId = typeof toolResult["tool_use_id"] === "string" ? toolResult["tool_use_id"].trim() : "";
|
|
303
|
-
|
|
319
|
+
const screenshotId = this.pendingScreenshotFilenames.get(toolUseId);
|
|
320
|
+
if (!screenshotId || this.handledToolUseIds.has(toolUseId)) {
|
|
304
321
|
continue;
|
|
305
322
|
}
|
|
306
323
|
this.handledToolUseIds.add(toolUseId);
|
|
307
|
-
this.
|
|
324
|
+
this.pendingScreenshotFilenames.delete(toolUseId);
|
|
308
325
|
const resultContent = Array.isArray(toolResult["content"]) ? toolResult["content"] : [];
|
|
309
326
|
const images = resultContent.map(asRecord).filter((item) => item?.["type"] === "image");
|
|
310
327
|
if (images.length === 0) {
|
|
@@ -319,9 +336,8 @@ class PlaywrightMcpScreenshotStreamParser {
|
|
|
319
336
|
if (mediaType !== "image/jpeg" && mediaType !== "image/png" || !dataBase64) {
|
|
320
337
|
throw new Error(`invalid_playwright_screenshot_payload:${toolUseId}`);
|
|
321
338
|
}
|
|
322
|
-
this.sequence += 1;
|
|
323
339
|
this.onScreenshot({
|
|
324
|
-
screenshotId
|
|
340
|
+
screenshotId,
|
|
325
341
|
tabId: PLAYWRIGHT_MCP_CONTROLLED_TAB_ID,
|
|
326
342
|
toolUseId,
|
|
327
343
|
mediaType,
|
|
@@ -339,7 +355,9 @@ class PlaywrightMcpScreenshotStreamParser {
|
|
|
339
355
|
ClaudeChromeScreenshotStreamParser,
|
|
340
356
|
INSTRUMENT_EVIDENCE_NAMES,
|
|
341
357
|
PLAYWRIGHT_MCP_CONTROLLED_TAB_ID,
|
|
358
|
+
PLAYWRIGHT_MCP_SCREENSHOT_BUDGET,
|
|
342
359
|
PLAYWRIGHT_MCP_SCREENSHOT_TOOL,
|
|
343
360
|
PlaywrightMcpScreenshotStreamParser,
|
|
344
|
-
isInstrumentScreenshotId
|
|
361
|
+
isInstrumentScreenshotId,
|
|
362
|
+
normalizePlaywrightScreenshotId
|
|
345
363
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playdrop/playdrop-cli",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.18",
|
|
4
4
|
"description": "Official Playdrop CLI for publishing browser games, creator apps, and AI-generated game assets on playdrop.ai",
|
|
5
5
|
"homepage": "https://www.playdrop.ai",
|
|
6
6
|
"repository": {
|