@mkterswingman/5mghost-wonder 0.0.16 → 0.0.17

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.
@@ -159,6 +159,8 @@ export async function runBrowserNoExportRead(options) {
159
159
  evidence.push("opendoc-response");
160
160
  if (extracted?.text)
161
161
  evidence.push("initial-attributed-text");
162
+ if (extracted?.structureHints)
163
+ evidence.push("structure-hints");
162
164
  const images = options.saveDir && extracted?.imageUrls
163
165
  ? await downloadImageResources(extracted.imageUrls, options.saveDir)
164
166
  : (extracted?.imageUrls ?? []).map((url) => ({
@@ -180,6 +182,7 @@ export async function runBrowserNoExportRead(options) {
180
182
  textLength: extracted?.text.length,
181
183
  imageUrls: extracted?.imageUrls,
182
184
  images,
185
+ structureHints: extracted?.structureHints,
183
186
  extraction: extracted?.text ? "opendoc-initial-attributed-text" : "none",
184
187
  evidence,
185
188
  warnings: extracted?.warnings ?? [
@@ -305,16 +308,24 @@ export function extractTextFromOpendoc(body) {
305
308
  const decodedChunks = chunks
306
309
  .filter((chunk) => typeof chunk === "string")
307
310
  .flatMap((chunk) => extractInitialAttributedTextCandidates(chunk));
311
+ const decodedText = decodedChunks.join("\n");
308
312
  const textCandidate = chooseTextCandidate(decodedChunks);
309
- const text = normalizeExtractedText(textCandidate ?? decodedChunks.join("\n"));
313
+ const text = normalizeExtractedText(textCandidate ?? decodedText);
310
314
  if (!text)
311
315
  return null;
312
- const imageUrls = extractImageUrls(decodedChunks.join("\n"));
316
+ const imageUrls = extractImageUrls(decodedText);
317
+ const structureHints = analyzeOpendocStructure({
318
+ opendocBody: body,
319
+ htmlData: typeof payload.htmlData === "string" ? payload.htmlData : "",
320
+ decodedText,
321
+ decodedCandidateCount: decodedChunks.length,
322
+ });
313
323
  return {
314
324
  title: payload.clientVars?.title ?? payload.clientVars?.initialTitle,
315
325
  padType: payload.clientVars?.padType ?? payload.padType,
316
326
  text,
317
327
  imageUrls,
328
+ structureHints,
318
329
  warnings: [
319
330
  "No-export text is decoded from opendoc initialAttributedText; rich styles are not reconstructed yet.",
320
331
  ...(imageUrls.length > 0
@@ -323,6 +334,27 @@ export function extractTextFromOpendoc(body) {
323
334
  ],
324
335
  };
325
336
  }
337
+ function analyzeOpendocStructure(input) {
338
+ return {
339
+ opendoc: summarizeStructureSignals(input.opendocBody),
340
+ htmlData: {
341
+ ...summarizeStructureSignals(input.htmlData),
342
+ hasTableMarkup: /<\/?(table|tr|td|th)\b/i.test(input.htmlData),
343
+ },
344
+ initialAttributedText: {
345
+ ...summarizeStructureSignals(input.decodedText),
346
+ decodedCandidateCount: input.decodedCandidateCount,
347
+ },
348
+ };
349
+ }
350
+ function summarizeStructureSignals(value) {
351
+ return {
352
+ length: value.length,
353
+ hasTableSignals: /\b(table|cell|row|column|sheet|workbook)\b/i.test(value),
354
+ hasMergeSignals: /\b(merge|merged|rowspan|colspan|mergeCell|mergeCells)\b/i.test(value),
355
+ hasImageSignals: /\b(image|img|pic|picture|media|download_url|qpic)\b/i.test(value),
356
+ };
357
+ }
326
358
  function extractInitialAttributedTextCandidates(chunk) {
327
359
  let decoded;
328
360
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mkterswingman/5mghost-wonder",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "description": "企微文档读取 CLI — WeCom document reader",
5
5
  "type": "module",
6
6
  "engines": {
@@ -7,9 +7,9 @@ description: Use this skill when the user wants to install or set up wonder, say
7
7
 
8
8
  ## Skill version
9
9
 
10
- This skill matches **wonder 0.0.16**.
10
+ This skill matches **wonder 0.0.17**.
11
11
 
12
- Once the CLI is installed in Step 1, run `wonder --version`. If the output does not equal `0.0.16`, the CLI on disk has drifted from the skill text loaded in this session. Ask the user to run `/update-5mghost-wonder`, then **start a fresh AI session** (`/exit` and re-enter, or open a new chat) — skill text already loaded into a running session does not refresh after `wonder update`, even though the file on disk has been replaced.
12
+ Once the CLI is installed in Step 1, run `wonder --version`. If the output does not equal `0.0.17`, the CLI on disk has drifted from the skill text loaded in this session. Ask the user to run `/update-5mghost-wonder`, then **start a fresh AI session** (`/exit` and re-enter, or open a new chat) — skill text already loaded into a running session does not refresh after `wonder update`, even though the file on disk has been replaced.
13
13
 
14
14
  After a successful first install, also remind the user to start a fresh AI session before invoking `/use-5mghost-wonder` for the first time. The skill files were just written to disk; the current session never loaded them.
15
15
 
@@ -7,7 +7,7 @@ description: Use this skill when the user wants to update or upgrade wonder, say
7
7
 
8
8
  ## Skill version
9
9
 
10
- This skill matches **wonder 0.0.16**.
10
+ This skill matches **wonder 0.0.17**.
11
11
 
12
12
  ---
13
13
 
@@ -10,10 +10,10 @@ the referenced workflow files needed for the current task.
10
10
 
11
11
  ## Version Gate
12
12
 
13
- This skill matches **wonder 0.0.16**.
13
+ This skill matches **wonder 0.0.17**.
14
14
 
15
15
  On first use in a session, follow `references/session-init.md`. If the installed
16
- CLI version differs from `0.0.16`, stop and ask the user to run
16
+ CLI version differs from `0.0.17`, stop and ask the user to run
17
17
  `/update-5mghost-wonder`, then start a fresh AI session.
18
18
 
19
19
  ## Hard Rules
@@ -37,8 +37,10 @@ wonder browser read <url> --save /tmp/wonder-browser-read
37
37
  ```
38
38
 
39
39
  This currently attempts text extraction from the browser `opendoc`
40
- `initialAttributedText`. Treat it as `partial` unless it also proves image and
41
- table structure.
40
+ `initialAttributedText`, downloads detected image resources when `--save` is
41
+ present, and returns safe `structureHints` for `htmlData`,
42
+ `initialAttributedText`, and the full `opendoc` body. Treat it as `partial`
43
+ unless it also proves actual table cells, merge ranges, and image anchors.
42
44
 
43
45
  3. If the read is insufficient, run the evidence probe:
44
46
 
@@ -59,6 +61,8 @@ Use `--headed` only when login/debug visibility is needed.
59
61
  - WebSocket messages if they expose structured document operations
60
62
  - screenshots only as a fallback or visual cross-check
61
63
  6. For tables, specifically look for:
64
+ - `structureHints.*.hasTableSignals` and `hasMergeSignals`
65
+ - `structureHints.htmlData.hasTableMarkup`
62
66
  - cell coordinates
63
67
  - displayed text
64
68
  - merge ranges
@@ -82,6 +86,12 @@ Return a concise result:
82
86
  "mergeRangesAvailable": true,
83
87
  "imagesAvailable": true,
84
88
  "imageAnchorsAvailable": true,
89
+ "structureHints": {
90
+ "htmlData": {
91
+ "hasTableMarkup": true,
92
+ "hasMergeSignals": true
93
+ }
94
+ },
85
95
  "evidence": ["runtime-store", "network-response", "websocket", "screenshot"],
86
96
  "missing": []
87
97
  }