@gavin-hu/my-pi-agent 0.14.0 → 0.15.0

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.
Files changed (222) hide show
  1. package/README.md +55 -33
  2. package/README.zh-CN.md +44 -27
  3. package/extensions/bytefly/README.md +193 -140
  4. package/extensions/bytefly/block/component.ts +7 -15
  5. package/extensions/bytefly/block/register.ts +6 -1
  6. package/extensions/bytefly/doctor/register.ts +24 -5
  7. package/extensions/bytefly/doctor/tools.ts +4 -0
  8. package/extensions/bytefly/footer/collect/snapshot.ts +6 -1
  9. package/extensions/bytefly/footer/config.ts +10 -6
  10. package/extensions/bytefly/footer/price/price.ts +5 -3
  11. package/extensions/bytefly/footer/price/rates.ts +63 -26
  12. package/extensions/bytefly/footer/render/status.ts +3 -3
  13. package/extensions/bytefly/header/component.ts +3 -2
  14. package/extensions/bytefly/index.ts +3 -3
  15. package/extensions/bytefly/notice/component.ts +8 -3
  16. package/extensions/bytefly/notify/config.ts +6 -11
  17. package/extensions/bytefly/notify/dispatch.ts +13 -5
  18. package/extensions/bytefly/panel/commands.ts +21 -1
  19. package/extensions/bytefly/panel/format.ts +5 -2
  20. package/extensions/bytefly/panel/settings-runtime.ts +26 -6
  21. package/extensions/bytefly/panel/settings.ts +41 -4
  22. package/extensions/bytefly/panel/themes.ts +32 -0
  23. package/extensions/bytefly/panel/tui/editing.ts +77 -0
  24. package/extensions/bytefly/panel/tui/entries.ts +24 -0
  25. package/extensions/bytefly/panel/tui/extensions-view.ts +13 -8
  26. package/extensions/bytefly/panel/tui/frame.ts +121 -4
  27. package/extensions/bytefly/panel/tui/settings-view.ts +54 -15
  28. package/extensions/bytefly/panel/tui.ts +94 -152
  29. package/extensions/bytefly/picker/discovery.ts +1 -0
  30. package/extensions/bytefly/picker/types.ts +2 -0
  31. package/extensions/bytefly/separator/component.ts +14 -4
  32. package/extensions/bytefly/update/cache.ts +58 -19
  33. package/extensions/bytefly/update/check.ts +35 -0
  34. package/extensions/bytefly/update/format.ts +76 -35
  35. package/extensions/bytefly/update/register.ts +144 -55
  36. package/extensions/bytefly/update/state.ts +4 -2
  37. package/extensions/bytefly/update/suppress.ts +66 -0
  38. package/extensions/bytefly/update/types.ts +15 -0
  39. package/extensions/check/README.md +253 -0
  40. package/extensions/check/commands.ts +128 -0
  41. package/extensions/check/config.ts +39 -0
  42. package/extensions/check/detect.ts +269 -0
  43. package/extensions/check/failures.ts +230 -0
  44. package/extensions/check/format.ts +135 -0
  45. package/extensions/check/index.ts +26 -0
  46. package/extensions/check/render.ts +185 -0
  47. package/extensions/check/runner.ts +176 -0
  48. package/extensions/check/runtime.ts +244 -0
  49. package/extensions/check/source.ts +80 -0
  50. package/extensions/check/tools.ts +173 -0
  51. package/extensions/check/tui.ts +195 -0
  52. package/extensions/check/types.ts +99 -0
  53. package/extensions/document/README.md +1 -1
  54. package/extensions/document/extract/pdf.ts +8 -16
  55. package/extensions/document/formats.ts +2 -2
  56. package/extensions/file-browse/README.md +66 -32
  57. package/extensions/file-browse/client.ts +95 -32
  58. package/extensions/file-browse/config.ts +9 -9
  59. package/extensions/file-browse/git.ts +37 -47
  60. package/extensions/file-browse/html.ts +39 -58
  61. package/extensions/file-browse/markdown.ts +110 -92
  62. package/extensions/file-browse/raw-html.ts +478 -0
  63. package/extensions/file-browse/router.ts +32 -70
  64. package/extensions/file-browse/server.ts +18 -56
  65. package/extensions/file-browse/urls.ts +80 -0
  66. package/extensions/goal/README.md +103 -47
  67. package/extensions/goal/clarify-parse.ts +4 -9
  68. package/extensions/goal/clarify.ts +27 -4
  69. package/extensions/goal/commands.ts +24 -11
  70. package/extensions/goal/format.ts +41 -10
  71. package/extensions/goal/index.ts +39 -16
  72. package/extensions/goal/plan-route.ts +51 -0
  73. package/extensions/goal/schema.ts +6 -23
  74. package/extensions/goal/state.ts +39 -57
  75. package/extensions/goal/tools.ts +26 -20
  76. package/extensions/goal/types.ts +11 -1
  77. package/extensions/job/README.md +20 -6
  78. package/extensions/job/format.ts +18 -68
  79. package/extensions/job/index.ts +26 -41
  80. package/extensions/job/log-writer.ts +208 -0
  81. package/extensions/job/logs.ts +3 -2
  82. package/extensions/job/process.ts +6 -99
  83. package/extensions/job/runtime.ts +42 -181
  84. package/extensions/job/schema.ts +1 -4
  85. package/extensions/job/tools.ts +1 -15
  86. package/extensions/job/tui.ts +117 -307
  87. package/extensions/job/ui.ts +7 -33
  88. package/extensions/memory/README.md +1 -1
  89. package/extensions/memory/errors.ts +5 -6
  90. package/extensions/memory/tui.ts +14 -24
  91. package/extensions/plan/README.md +94 -18
  92. package/extensions/plan/commands.ts +9 -5
  93. package/extensions/plan/format.ts +87 -0
  94. package/extensions/plan/index.ts +31 -15
  95. package/extensions/plan/plans.ts +2 -3
  96. package/extensions/plan/policy.ts +0 -6
  97. package/extensions/plan/runtime.ts +4 -2
  98. package/extensions/plan/steps.ts +37 -8
  99. package/extensions/plan/todos.ts +44 -3
  100. package/extensions/plan/tools/enter.ts +94 -0
  101. package/extensions/plan/tools/exit.ts +296 -0
  102. package/extensions/plan/tools/nested.ts +21 -0
  103. package/extensions/plan/tools/steps.ts +136 -0
  104. package/extensions/plan/tools/todo-seed.ts +76 -0
  105. package/extensions/plan/tools/write.ts +127 -0
  106. package/extensions/plan/tools.ts +18 -703
  107. package/extensions/plan/web-client.ts +6 -22
  108. package/extensions/plan/web-page.ts +19 -30
  109. package/extensions/plan/web-router.ts +34 -71
  110. package/extensions/plan/web.ts +13 -40
  111. package/extensions/question/answers.ts +3 -8
  112. package/extensions/question/tui.ts +6 -6
  113. package/extensions/rewind/README.md +95 -22
  114. package/extensions/rewind/checklist.ts +185 -0
  115. package/extensions/rewind/commands.ts +8 -0
  116. package/extensions/rewind/config.ts +3 -11
  117. package/extensions/rewind/format.ts +220 -2
  118. package/extensions/rewind/git.ts +74 -7
  119. package/extensions/rewind/hunk-picker.ts +114 -0
  120. package/extensions/rewind/patch.ts +88 -0
  121. package/extensions/rewind/path-picker.ts +67 -100
  122. package/extensions/rewind/paths.ts +93 -19
  123. package/extensions/rewind/restore.ts +53 -10
  124. package/extensions/rewind/review-tui.ts +320 -0
  125. package/extensions/rewind/review.ts +397 -0
  126. package/extensions/rewind/rewind-tui.ts +4 -3
  127. package/extensions/rewind/runtime.ts +94 -17
  128. package/extensions/subagent/README.md +61 -6
  129. package/extensions/subagent/background-tui.ts +208 -0
  130. package/extensions/subagent/background.ts +470 -0
  131. package/extensions/subagent/commands.ts +80 -0
  132. package/extensions/subagent/config.ts +4 -0
  133. package/extensions/subagent/format.ts +24 -1
  134. package/extensions/subagent/index.ts +91 -2
  135. package/extensions/subagent/render.ts +13 -0
  136. package/extensions/subagent/run.ts +17 -16
  137. package/extensions/subagent/schema.ts +12 -0
  138. package/extensions/subagent/types.ts +11 -0
  139. package/extensions/subagent/ui.ts +50 -0
  140. package/extensions/todo/README.md +18 -13
  141. package/extensions/todo/format.ts +3 -2
  142. package/extensions/todo/runtime.ts +3 -2
  143. package/extensions/todo/schema.ts +8 -84
  144. package/extensions/todo/state.ts +5 -46
  145. package/extensions/todo/tools.ts +2 -1
  146. package/extensions/todo/types.ts +6 -15
  147. package/extensions/watch/README.md +14 -6
  148. package/extensions/watch/child.ts +150 -0
  149. package/extensions/watch/format.ts +8 -48
  150. package/extensions/watch/index.ts +42 -58
  151. package/extensions/watch/runtime.ts +49 -128
  152. package/extensions/watch/schema.ts +1 -4
  153. package/extensions/watch/tools.ts +1 -11
  154. package/extensions/watch/tui.ts +103 -273
  155. package/extensions/watch/ui.ts +5 -32
  156. package/extensions/web-access/README.md +1 -1
  157. package/extensions/web-access/fetch/page.ts +1 -1
  158. package/extensions/web-access/fetch/tool.ts +6 -2
  159. package/extensions/web-access/search/search.ts +2 -5
  160. package/extensions/wechat/README.md +1 -1
  161. package/extensions/wechat/client.ts +23 -0
  162. package/extensions/wechat/commands.ts +57 -42
  163. package/extensions/wechat/deliver.ts +5 -9
  164. package/extensions/wechat/errors.ts +3 -6
  165. package/extensions/wechat/inbound.ts +2 -5
  166. package/extensions/wechat/index.ts +2 -8
  167. package/extensions/wechat/outbound.ts +2 -4
  168. package/extensions/wechat/peer-worker.ts +3 -8
  169. package/extensions/wechat/poll.ts +10 -9
  170. package/extensions/wechat/presence.ts +35 -62
  171. package/extensions/wechat/reply-pipeline.ts +3 -1
  172. package/extensions/wechat/status-screen.ts +1 -1
  173. package/extensions/wechat/timer.ts +57 -0
  174. package/extensions/worktree/config.ts +8 -20
  175. package/extensions/worktree/enter.ts +7 -12
  176. package/extensions/worktree/git.ts +38 -69
  177. package/extensions/worktree/index.ts +5 -4
  178. package/extensions/worktree/registry.ts +7 -7
  179. package/extensions/worktree/root-tools.ts +2 -2
  180. package/extensions/worktree/status.ts +3 -2
  181. package/lib/README.md +22 -8
  182. package/lib/config.ts +50 -3
  183. package/lib/errors.ts +12 -0
  184. package/lib/format.ts +50 -0
  185. package/lib/git/read.ts +8 -0
  186. package/lib/goal-state.ts +23 -8
  187. package/lib/http/headers.ts +54 -0
  188. package/lib/http/index.ts +13 -0
  189. package/lib/http/response.ts +46 -0
  190. package/lib/http/router.ts +52 -0
  191. package/lib/http/server.ts +91 -0
  192. package/lib/lines.ts +77 -0
  193. package/lib/pdf.ts +82 -0
  194. package/lib/plan-entry.ts +71 -0
  195. package/lib/plan-state.ts +34 -0
  196. package/lib/report.ts +99 -0
  197. package/lib/requirements.ts +25 -19
  198. package/lib/spawn.ts +170 -0
  199. package/lib/todo-state.ts +110 -23
  200. package/lib/tool-names.ts +7 -0
  201. package/lib/tool-result.ts +33 -0
  202. package/lib/tui/README.md +68 -3
  203. package/lib/tui/chrome.ts +28 -4
  204. package/lib/tui/columns.ts +6 -1
  205. package/lib/tui/confirm.ts +65 -0
  206. package/lib/tui/dock-screen.ts +410 -0
  207. package/lib/tui/glyphs.ts +2 -1
  208. package/lib/tui/indent.ts +1 -1
  209. package/lib/tui/index.ts +2 -0
  210. package/lib/tui/rows.ts +21 -0
  211. package/lib/tui/status-controller.ts +35 -1
  212. package/lib/tui/tool.ts +59 -1
  213. package/lib/web/components.ts +20 -1
  214. package/lib/web/markup.ts +32 -0
  215. package/lib/web/runtime.ts +50 -0
  216. package/package.json +22 -5
  217. package/skills/init/SKILL.md +165 -0
  218. package/skills/init/references/agents-md-quality.md +103 -0
  219. package/skills/init/references/interview-questions.md +81 -0
  220. package/skills/refactor/SKILL.md +141 -0
  221. package/extensions/watch/process.ts +0 -63
  222. package/extensions/web-access/fetch/pdf.ts +0 -45
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: refactor
3
+ description: "Find and rank refactoring opportunities in a project or path: duplication, oversized modules, coupling, drift, and high-churn code with weak tests. Use when asked what to refactor, where the code is tangled, or for a refactor audit; discovery is read-only and returns an evidence-based shortlist."
4
+ ---
5
+
6
+ # Find refactoring opportunities
7
+
8
+ This is an audit, not an edit session. The deliverable is a ranked shortlist with
9
+ evidence; do not modify files while discovering. The skill is model-invoked when
10
+ a request matches the description; `/skill:refactor` is the explicit fallback.
11
+
12
+ A refactor changes structure without changing behavior. If the request changes
13
+ behavior, call it a behavior change and report it separately. Read the
14
+ repository's own instructions first; they win over this skill.
15
+
16
+ ## 1. Resolve the scope
17
+
18
+ The text after `/skill:refactor` is the task. It may contain a path (`@src`,
19
+ `src`, `packages/api`, or a path inside a sentence), a question, or both.
20
+
21
+ - Resolve each path from the working directory. A directory is the audit scope;
22
+ a file is the initial target. Audit multiple paths separately and report them
23
+ together.
24
+ - No path means the current project. If the project is large, propose a scope
25
+ from the documented layout instead of scanning everything blindly.
26
+ - If a path does not exist, say so and ask for a real one. Do not guess. Do not
27
+ leave the working directory unless the user explicitly supplied an outside
28
+ path.
29
+ - State the resolved scope and the number of files examined in the report.
30
+
31
+ ## 2. Learn the project's standards
32
+
33
+ - Read the repository's instruction files, contributor guide, architecture
34
+ notes, shared-helper documentation, and CI configuration.
35
+ - Record the languages, layout, test framework, documented check commands, size
36
+ or complexity thresholds, and ignore rules.
37
+ - Do not import an external style guide, install a tool, or apply a threshold the
38
+ project never stated. If there is no stated threshold, compare against the rest
39
+ of the scope and say that is the basis.
40
+ - Note the available evidence: tests, coverage, type checking, linting, git
41
+ history, and any scanner already installed.
42
+
43
+ ## 3. Inventory the scope
44
+
45
+ - Map source files, tests, exports, imports, and entry points. Mark public
46
+ surface versus internal modules.
47
+ - Measure cheap facts: file and function sizes, nesting depth, parameter counts,
48
+ export counts, fan-in and fan-out, and the distance to the nearest test.
49
+ - Read git history for churn (`git log --numstat`) inside the scope. Churn is
50
+ context, not a verdict: a frequently changed, tangled file is a stronger
51
+ candidate than a stable, isolated oddity.
52
+ - Skip version-control metadata, dependencies, build output, generated files,
53
+ vendored trees, and secrets unless the user explicitly includes them. Respect
54
+ the project's ignore files.
55
+ - For a large scope, delegate a read-only survey to a read-only helper if the
56
+ host provides one. Keep the filtering and ranking in the main session.
57
+
58
+ ## 4. Detect signals
59
+
60
+ For every signal, point at a file and line and explain why it matters here.
61
+
62
+ | Signal | What to look for | Evidence to cite |
63
+ |---|---|---|
64
+ | Duplication | The same body or a near-identical block in several places; copy-paste with tiny edits; a helper that already exists in a shared location | Paths and line ranges of each copy; the shared location it should use |
65
+ | Size and responsibility | A module or function past the project's limit, or a relative outlier; unrelated exports; deep nesting; long parameter lists | Measured size or responsibility list; the seams where it could split |
66
+ | Coupling | Circular or layer-crossing imports, high fan-in or fan-out, feature envy, repeated type switches | The import edge or repeated branch, with both sides named |
67
+ | Cohesion and drift | A grab-bag utility module; a name that no longer matches behavior; dead exports; commented-out code; two implementations of one concept | The mismatch or unused export, with its callers |
68
+ | Change pressure | High recent churn combined with complexity or weak tests | Churn count over a stated window plus the complexity or test gap |
69
+ | Test friction | Behavior with no direct test; tests that mock the unit heavily or assert internals; duplicated setup that hides a missing seam | The test path and the missing or brittle assertion |
70
+ | Boundary erosion | Leaking internal types, unchecked casts, mode-selecting boolean parameters, null-heavy returns | The boundary location and the caller that must know the internals |
71
+
72
+ ## 5. Verify and filter
73
+
74
+ A signal is not a candidate until it is confirmed.
75
+
76
+ - Read the callers and tests, not just the definition. Duplication may be
77
+ intentional for a protocol version; a large module may be cohesive; an
78
+ "unused" export may be public API.
79
+ - Require one concrete artifact: a path with line numbers, a counted duplicate, a
80
+ measured size, a dependency edge, or a test gap. If you cannot point at it,
81
+ drop it.
82
+ - Keep pure refactors separate from behavior changes and bugs. Report a bug as a
83
+ bug; do not smuggle it into the refactor list.
84
+ - Prefer candidates with an existing test that catches a regression. If the
85
+ behavior is untested, mark the candidate "tests first".
86
+ - Reject weak candidates explicitly. A short "not worth it" list proves the
87
+ audit was selective rather than a tour of everything unfamiliar.
88
+
89
+ ## 6. Rank
90
+
91
+ Use three tiers:
92
+
93
+ - **Do next:** safe, contained blast radius, high leverage, small or medium
94
+ effort, and a fast verification command.
95
+ - **Worth planning:** high leverage but more risk or effort, a public surface, or
96
+ missing tests.
97
+ - **Leave it:** low confidence, little leverage, or not worth the churn.
98
+
99
+ Within a tier, order by leverage first, then safety, then cost. Do not invent a
100
+ numeric score; the reasons must be readable.
101
+
102
+ ## 7. Report
103
+
104
+ Keep the report scannable. Use this shape:
105
+
106
+ - **Scope and method:** path, file count, tools used, and what was not examined.
107
+ - **Top three to five opportunities**, each with a title, tier, evidence at
108
+ `path:line`, the proposed structural change, expected benefit, risk and blast
109
+ radius, effort (S/M/L), and the narrow plus full verification command.
110
+ - **Rejected signals:** one line each with the reason it did not qualify.
111
+ - **Next step:** ask which candidate to take. Do not start editing.
112
+
113
+ ## 8. Stop conditions
114
+
115
+ - No worthwhile opportunities: say so with the evidence that was checked instead
116
+ of inventing work.
117
+ - The request is a specific refactor rather than an audit: skip the shortlist,
118
+ but use the handoff below.
119
+ - The request changes behavior or asks for a rewrite: treat it as an approved
120
+ design change, not this audit.
121
+ - The scope cannot be read (missing path, secrets, binary or generated files, or
122
+ an inaccessible tree): report the limitation.
123
+
124
+ ## After selection: safe handoff
125
+
126
+ If the user chooses a candidate, execution follows these rules:
127
+
128
+ - State the behavior contract and run the project's documented check to get a
129
+ baseline. Record pre-existing failures.
130
+ - If the behavior is untested, add characterization tests first.
131
+ - Enter plan mode when the host provides it and the change spans files, changes a
132
+ public surface, or has an unknown step list. Otherwise track the steps in a
133
+ todo list or a short written sequence.
134
+ - Make one structural change per step and verify each step. Never mix in
135
+ formatting, bug fixes, or unrelated cleanup.
136
+ - Finish with the full project check and report the diff, results, and remaining
137
+ risk. Do not commit unless the user asks.
138
+
139
+ The audit is done when the scope is stated, every candidate has `path:line`
140
+ evidence and a verification command, the shortlist is capped, rejected signals
141
+ are explained, and no files were modified.
@@ -1,63 +0,0 @@
1
- /**
2
- * Process plumbing for the watch extension's command sources.
3
- *
4
- * A command watcher outlives a single tool call, so it is spawned with Node's
5
- * `child_process` and its merged stdout/stderr are piped back as data events.
6
- * Every function here is injectable so tests can drive a scripted child without
7
- * launching a real process.
8
- *
9
- * On POSIX the child is started detached, making it a process-group leader;
10
- * signals go to the whole group (`-pid`) so a shell and its descendants die
11
- * together. On Windows the tree is killed with `taskkill /T`.
12
- */
13
-
14
- import { spawn as nodeSpawn, spawnSync } from "node:child_process";
15
- import type { Readable } from "node:stream";
16
-
17
- /** The subset of a spawned child the runtime uses. */
18
- export interface SpawnedProcess {
19
- pid?: number;
20
- stdout: Readable | null;
21
- stderr: Readable | null;
22
- on(event: "close", listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown;
23
- on(event: "error", listener: (error: Error) => void): unknown;
24
- kill(signal?: NodeJS.Signals): boolean;
25
- }
26
-
27
- export interface SpawnOptions {
28
- cwd: string;
29
- env?: NodeJS.ProcessEnv;
30
- }
31
-
32
- export type SpawnFn = (command: string, options: SpawnOptions) => SpawnedProcess;
33
-
34
- /** Send `signal` to a pid's process tree, escalating to SIGKILL when `force`. */
35
- export type KillTreeFn = (pid: number, signal: NodeJS.Signals, force?: boolean) => void;
36
-
37
- /** Default spawn: a shell command in its own process group, output piped. */
38
- export const defaultSpawn: SpawnFn = (command, options) =>
39
- nodeSpawn(command, {
40
- cwd: options.cwd,
41
- shell: true,
42
- detached: process.platform !== "win32",
43
- stdio: ["ignore", "pipe", "pipe"],
44
- env: options.env,
45
- });
46
-
47
- /** Default tree kill: process group on POSIX, `taskkill /T` on Windows. */
48
- export const defaultKillTree: KillTreeFn = (pid, signal, force = false) => {
49
- if (process.platform === "win32") {
50
- spawnSync("taskkill", ["/pid", String(pid), "/T", ...(force ? ["/F"] : [])], { stdio: "ignore" });
51
- return;
52
- }
53
- try {
54
- process.kill(-pid, signal);
55
- } catch (error) {
56
- if ((error as NodeJS.ErrnoException).code !== "ESRCH") throw error;
57
- try {
58
- process.kill(pid, signal);
59
- } catch {
60
- // Already gone.
61
- }
62
- }
63
- };
@@ -1,45 +0,0 @@
1
- /**
2
- * Optional PDF text extraction via the `unpdf` package.
3
- *
4
- * `unpdf` bundles a server-friendly build of PDF.js and is loaded lazily, so the
5
- * extension stays dependency-free unless PDF support is actually used. Callers
6
- * inject an extractor through `FetchDeps.pdf`.
7
- */
8
-
9
- import { pdfGuidance } from "../../../lib/requirements.ts";
10
-
11
- /** Raised when the optional `unpdf` package is missing or unusable. */
12
- export class PdfUnavailableError extends Error {
13
- constructor(message: string) {
14
- super(message);
15
- this.name = "PdfUnavailableError";
16
- }
17
- }
18
-
19
- export type PdfExtractor = (bytes: Uint8Array) => Promise<string>;
20
-
21
- /** Extract plain text from PDF bytes, merging all pages, using `extractor` when given. */
22
- export async function extractPdfText(bytes: Uint8Array, extractor?: PdfExtractor): Promise<string> {
23
- if (extractor) return extractor(bytes);
24
-
25
- let module: Record<string, unknown>;
26
- try {
27
- // A variable specifier keeps `tsc` from resolving the optional package's types.
28
- const name = "unpdf";
29
- module = (await import(name)) as Record<string, unknown>;
30
- } catch {
31
- throw new PdfUnavailableError(pdfGuidance());
32
- }
33
-
34
- const candidate = module.extractText ?? (module.default as Record<string, unknown> | undefined)?.extractText;
35
- if (typeof candidate !== "function") {
36
- throw new PdfUnavailableError("The installed 'unpdf' package does not export extractText.");
37
- }
38
-
39
- const result: unknown = await (candidate as (data: Uint8Array, options?: unknown) => Promise<unknown>)(bytes, {
40
- mergePages: true,
41
- });
42
- if (typeof result === "string") return result;
43
- const text = (result as { text?: unknown } | undefined)?.text;
44
- return typeof text === "string" ? text : "";
45
- }