@nextclaw/x-harness 0.2.46 → 0.2.48

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.46, commit c242fc8d8d9b935668cf4093bb4cb9bda14edf16.
3
+ Version 0.2.48, commit 036e19cbc6ce3e5f4ee944b887336aea0dc73231.
4
4
 
5
- Complete source, build scripts and dependencies: https://github.com/Peiiii/x-harness/tree/c242fc8d8d9b935668cf4093bb4cb9bda14edf16
5
+ Complete source, build scripts and dependencies: https://github.com/Peiiii/x-harness/tree/036e19cbc6ce3e5f4ee944b887336aea0dc73231
6
6
 
7
7
  Clone this revision, run npm ci, npm run bootstrap and npm run release:build.
8
8
 
@@ -146,6 +146,7 @@ export class DOMCapabilities {
146
146
  if (typeof this.#tab?.playwright?.getByRole === "function")
147
147
  base.push(...missingMethods(this.#tab.playwright.getByRole("article"), [
148
148
  "first",
149
+ "filter",
149
150
  "waitFor",
150
151
  ]));
151
152
  if (operation === "readBookmarks" &&
@@ -198,7 +198,7 @@ export class DOMEditing {
198
198
  .locator(`a[href=${JSON.stringify(primary)}]`)
199
199
  .filter({ visible: true }));
200
200
  this.#session.current = null;
201
- await anchor.press("PageDown");
201
+ await anchor.press("End");
202
202
  return { completed: true };
203
203
  return { completed: false, loc, submittedEditor };
204
204
  }
@@ -100,6 +100,20 @@ export class DOMNavigation {
100
100
  .waitFor({ state: "visible", timeoutMs: 5000 });
101
101
  return;
102
102
  }
103
+ if (command.excludeIds) {
104
+ if (!Array.isArray(command.excludeIds) ||
105
+ command.excludeIds.some((id) => !/^\d+$/.test(id)))
106
+ throw Error("source-pagination-wait-ids-invalid");
107
+ let articles = this.#tab.playwright.getByRole("article");
108
+ if (command.excludeIds.length)
109
+ articles = articles.filter({
110
+ hasNot: this.#tab.playwright.locator(command.excludeIds
111
+ .map((id) => `a[href$="/status/${id}"]`)
112
+ .join(",")),
113
+ });
114
+ await articles.first().waitFor({ state: "visible", timeoutMs: 5000 });
115
+ return;
116
+ }
103
117
  const offset = command.offset ?? 0;
104
118
  if (!Number.isInteger(offset) || offset < 0)
105
119
  throw Error("帖子等待窗口须为非负整数offset");
@@ -279,10 +293,7 @@ export class DOMNavigation {
279
293
  // Native observation settles the real loading transition when the tab exposes it.
280
294
  if (typeof this.#tab.getAXState === "function")
281
295
  await this.#tab.getAXState({ emit: false });
282
- await this.#tab.playwright
283
- .getByRole("article")
284
- .first()
285
- .waitFor({ state: "visible", timeoutMs: 5000 });
296
+ await this.handleWaitPublicArticle(this.#tab.playwright.getByRole("article").first(), command.url);
286
297
  return;
287
298
  }
288
299
  }
@@ -118,6 +118,26 @@ export class PlatformCollections {
118
118
  offset += 5;
119
119
  else {
120
120
  await this.#browser.act({ operation: "nextPosts" });
121
+ const scrolled = await this.#ready({ view: "posts", limit: 5 });
122
+ if (scrolled.needsStateCheck || scrolled.alerts?.length)
123
+ return {
124
+ ...scrolled,
125
+ sources,
126
+ complete: false,
127
+ missing: ["source-page-unconfirmed"],
128
+ };
129
+ // Scroll and lazy loading settle asynchronously. Existing cards are
130
+ // already visible, so waiting for the first article proves nothing.
131
+ try {
132
+ await this.#browser.act({
133
+ operation: "waitForPosts",
134
+ excludeIds: [...seen],
135
+ });
136
+ }
137
+ catch (error) {
138
+ if (!/timed out|timeout/i.test(error.message))
139
+ throw error;
140
+ }
121
141
  const advanced = await this.#ready({ view: "posts", limit: 5 });
122
142
  // Retained DOM prefixes include a partial final window too; skip
123
143
  // exactly the consumed cards, while virtualized replacements restart.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/x-harness",
3
- "version": "0.2.46",
3
+ "version": "0.2.48",
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": "c242fc8d8d9b935668cf4093bb4cb9bda14edf16"
45
+ "gitHead": "036e19cbc6ce3e5f4ee944b887336aea0dc73231"
46
46
  }
@@ -4,8 +4,8 @@
4
4
  | --- | --- | --- |
5
5
  | readIncomingReplies | none | processedIds, limit (5), maxPages (3), mode |
6
6
  | readCreator | handle | target (10;1–50), maxScrolls, navigate, expand, mode |
7
- | readBookmarks | folder (observed name), or discoverOnly:true | processedIds, limit, maxPages, mode |
8
- | searchSources | query | processedIds, limit, maxPages, mode |
7
+ | readBookmarks | folder (observed name), or discoverOnly:true | processedIds, limit (1–5), maxPages (1–10), mode |
8
+ | searchSources | query | processedIds, limit (1–5), maxPages (1–10), mode |
9
9
  | readPost | target: {postId,url,evidenceRef} | includeContext, resolveQuote, mode |
10
10
  | readPerson | target: {handle,url,evidenceRef} | mode |
11
11
  | readPeople | target: {url,evidenceRef} | offset, limit (1–5), advance, mode |