@nextclaw/x-harness 0.2.2 → 0.2.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/SOURCE.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Corresponding source
|
|
2
2
|
|
|
3
|
-
Version 0.2.
|
|
3
|
+
Version 0.2.3, commit 51c80ceb827a4eb28c4fbbd78b9182ba3332156d.
|
|
4
4
|
|
|
5
|
-
Complete source, build scripts and dependencies: https://github.com/Peiiii/x-harness/tree/
|
|
5
|
+
Complete source, build scripts and dependencies: https://github.com/Peiiii/x-harness/tree/51c80ceb827a4eb28c4fbbd78b9182ba3332156d
|
|
6
6
|
|
|
7
7
|
Clone this revision, run npm ci, npm run bootstrap and npm run release:build.
|
|
8
8
|
|
|
@@ -248,12 +248,26 @@ export class DOMEditing {
|
|
|
248
248
|
if (query.view !== "composer" ||
|
|
249
249
|
result.needsStateCheck ||
|
|
250
250
|
command.assets?.length !== 1)
|
|
251
|
-
throw new Error("
|
|
251
|
+
throw new Error("仅上传已观察编辑器的一张图片或一个MP4视频");
|
|
252
252
|
const asset = command.assets[0];
|
|
253
|
-
|
|
253
|
+
const isVideo = /\.mp4$/i.test(asset.path ?? "");
|
|
254
|
+
if (!isVideo && !asset.alt?.trim())
|
|
254
255
|
throw new Error("图片须有完整ALT");
|
|
255
256
|
this.#session.current = null;
|
|
256
257
|
await attachImage(this.#tab, { path: asset.path });
|
|
258
|
+
if (isVideo) {
|
|
259
|
+
await this.#tab.playwright
|
|
260
|
+
.locator('[data-testid="videoPlayer"],video')
|
|
261
|
+
.first()
|
|
262
|
+
.waitFor({ state: "visible", timeoutMs: 60000 });
|
|
263
|
+
const composer = await this.#observe({ view: "composer" });
|
|
264
|
+
if (composer.needsStateCheck || !composer.videos?.length)
|
|
265
|
+
throw new Error("上传视频预览未确认");
|
|
266
|
+
return {
|
|
267
|
+
completed: true,
|
|
268
|
+
value: { assets: [asset], mediaEvidence: composer.videos, composer },
|
|
269
|
+
};
|
|
270
|
+
}
|
|
257
271
|
await this.#tab.playwright
|
|
258
272
|
.getByRole("button", {
|
|
259
273
|
name: /^(?:编辑|Edit)(?:图片|照片|媒体| image| photo| media)?(?: \d+)?$/i,
|
package/dist/platform-writing.js
CHANGED
|
@@ -128,7 +128,9 @@ export class PlatformWriting {
|
|
|
128
128
|
samePublishedText(post.body, action.text) &&
|
|
129
129
|
/^\d+$/.test(post.id ?? "") &&
|
|
130
130
|
(!action.assets?.length ||
|
|
131
|
-
action.assets.every((asset) =>
|
|
131
|
+
action.assets.every((asset) => /\.mp4$/i.test(asset.path ?? "")
|
|
132
|
+
? post.media?.some((media) => media.kind === "video")
|
|
133
|
+
: post.images?.some((image) => image.alt === asset.alt))) &&
|
|
132
134
|
!(action.beforeIds ?? []).includes(post.id) &&
|
|
133
135
|
Number.isFinite(Date.parse(post.datetime)) &&
|
|
134
136
|
Date.parse(post.datetime) >= Date.parse(action.intentAt) &&
|
package/dist/readers-actions.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { readComposer } from "./readers-composer.js";
|
|
2
2
|
import { readPosts } from "./readers-posts.js";
|
|
3
|
-
// Upload only through the observed
|
|
3
|
+
// Upload only through the observed media button and browser file chooser.
|
|
4
4
|
export async function attachImage(tab, { path } = {}) {
|
|
5
|
-
if (!/^\/.*\.(?:png|jpe?g|webp)$/i.test(path ?? ""))
|
|
6
|
-
throw new Error("
|
|
5
|
+
if (!/^\/.*\.(?:png|jpe?g|webp|mp4)$/i.test(path ?? ""))
|
|
6
|
+
throw new Error("需要绝对图片或MP4路径");
|
|
7
7
|
if (typeof tab?.playwright?.evaluate !== "function" ||
|
|
8
8
|
typeof tab?.playwright?.getByRole !== "function" ||
|
|
9
9
|
typeof tab?.playwright?.waitForEvent !== "function")
|
package/dist/readers-composer.js
CHANGED
|
@@ -95,6 +95,12 @@ export function readComposer() {
|
|
|
95
95
|
images: Array.from(scope.querySelectorAll("img"))
|
|
96
96
|
.filter(visible)
|
|
97
97
|
.map((el) => ({ alt: el.alt })),
|
|
98
|
+
videos: Array.from(scope.querySelectorAll('[data-testid="videoPlayer"],video'))
|
|
99
|
+
.filter(visible)
|
|
100
|
+
.map((el) => ({
|
|
101
|
+
kind: "video",
|
|
102
|
+
label: el.getAttribute("aria-label"),
|
|
103
|
+
})),
|
|
98
104
|
needsStateCheck: false,
|
|
99
105
|
};
|
|
100
106
|
}
|
|
@@ -285,6 +285,12 @@ export const readXObservation = (query) => {
|
|
|
285
285
|
images: Array.from(scope.querySelectorAll("img"))
|
|
286
286
|
.filter(visible)
|
|
287
287
|
.map((el) => ({ alt: el.alt })),
|
|
288
|
+
videos: Array.from(scope.querySelectorAll('[data-testid="videoPlayer"],video'))
|
|
289
|
+
.filter(visible)
|
|
290
|
+
.map((el) => ({
|
|
291
|
+
kind: "video",
|
|
292
|
+
label: el.getAttribute("aria-label"),
|
|
293
|
+
})),
|
|
288
294
|
needsStateCheck: false,
|
|
289
295
|
};
|
|
290
296
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/x-harness",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed X task harness with compact business results and explicit diagnostics.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "51c80ceb827a4eb28c4fbbd78b9182ba3332156d"
|
|
46
46
|
}
|
|
@@ -12,7 +12,7 @@ Action APIs return status/actionId/publicURL/evidenceRef and reason/missing/resu
|
|
|
12
12
|
|
|
13
13
|
## Publish
|
|
14
14
|
|
|
15
|
-
Additional fields: kind:'original', draftPath (existing .post.md), text (complete approved text), composeURL, composeEvidenceRef; optional assets:[{path,alt}], activation:'click'|'keyboard'. Every media path must exist and be reviewed.
|
|
15
|
+
Additional fields: kind:'original', draftPath (existing .post.md), text (complete approved text), composeURL, composeEvidenceRef; optional assets:[{path,alt}], activation:'click'|'keyboard'. Every media path must exist and be reviewed. The DOM uploader supports one absolute PNG/JPEG/WebP image with required ALT, or one absolute MP4 video. Video uploads wait for a visible preview and public settlement requires a video on the exact fresh post; image ALT controls are not applied to videos.
|
|
16
16
|
|
|
17
17
|
```js
|
|
18
18
|
var result = await x.publishPost({ taskId, draftPath, preparedAction: {
|