@webskill/sdk 0.28.1 → 0.30.0-next.1

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 (37) hide show
  1. package/dist/agent.d.ts +2 -2
  2. package/dist/agent.js +32 -766
  3. package/dist/{approval-5BmspsRi.js → approval-DnUytrkq.js} +6 -1
  4. package/dist/browser.d.ts +9 -9
  5. package/dist/browser.js +131 -38
  6. package/dist/controller.d.ts +88 -0
  7. package/dist/controller.js +3 -0
  8. package/dist/device-DMUgqNzr.js +1782 -0
  9. package/dist/{dist-CTsxblSD.js → dist-Ww6TChcf.js} +2 -2
  10. package/dist/{geometry-BXMPNuM6.js → geometry-1xQbK4hB.js} +14 -78
  11. package/dist/governance.d.ts +3 -3
  12. package/dist/{index-DJeYqzlE.d.ts → index-1ASrUwzn.d.ts} +2 -2
  13. package/dist/{index-CkauSvus.d.ts → index-Cj2HedfL.d.ts} +4 -3
  14. package/dist/{index-DU8sKyQq.d.ts → index-UbNuzd2a.d.ts} +4 -2
  15. package/dist/index.d.ts +4 -4
  16. package/dist/index.js +5 -6
  17. package/dist/{linkedDocument-0iiVPd5t.js → linkedDocument-GE-VV_Gj.js} +112 -2
  18. package/dist/mcp.d.ts +2 -2
  19. package/dist/node.d.ts +3 -3
  20. package/dist/node.js +2 -2
  21. package/dist/{openUiLibrary-BnhYUlqY.js → openUiLibrary-BjRDYyTe.js} +1 -1
  22. package/dist/{skillVersionStore-S4_HJ_Fl-DzZM_UIw.d.ts → skillVersionStore-S4_HJ_Fl-5K8jrAg_.d.ts} +1 -1
  23. package/dist/testing.d.ts +88 -2
  24. package/dist/testing.js +1287 -1
  25. package/dist/toolSource-DMCTnSVg.js +743 -0
  26. package/dist/types-BXRIoabj.js +76 -0
  27. package/dist/types-DmcXN3qR-Dy7ZDstc.d.ts +265 -0
  28. package/dist/{types-wKp3YBSM-167azx1H.d.ts → types-wKp3YBSM-CSeFUL9R.d.ts} +3 -2
  29. package/dist/ui-react.css +2687 -0
  30. package/dist/ui-react.d.ts +1045 -5
  31. package/dist/ui-react.js +5878 -820
  32. package/dist/ui-vue.d.ts +1 -1
  33. package/dist/ui.d.ts +3 -3
  34. package/dist/ui.js +1 -1
  35. package/dist/{webSkillApi-rX2e3SVB.js → webSkillApi-TeWPPFDn.js} +1 -1
  36. package/package.json +18 -4
  37. package/dist/kind-Dc8x0HWz.js +0 -110
@@ -2,8 +2,8 @@ import { n as messageOf, t as WebSkillError } from "./errors-BDZNpC13.js";
2
2
  import { b as parseSkillMarkdown, i as buildCatalog, n as SkillDiscovery, r as SkillReader } from "./skill-WSUDp6A1.js";
3
3
  import { o as atomicWriteText, r as resolveInsideRoot, t as assertSafePathSegment } from "./pathSecurity-CirkQwWP.js";
4
4
  import { t as assertRemoteUrlAllowed } from "./urlSafety-CiSuCJvX.js";
5
+ import { O as XLS_MIME, a as UNSUPPORTED_DOCUMENT_MESSAGE, c as toBase64, f as SPREADSHEET_MIME_TYPE, g as DEFAULT_MAX_DOCUMENT_TEXT_BYTES, h as DEFAULT_MAX_DOCUMENT_BYTES, i as SUPPORTED_DOCUMENT_MIME, l as encodeSpreadsheet, n as READ_LINKED_DOCUMENT_TOOL, o as fromBase64, r as READ_LINKED_DOCUMENT_TOOL_NAME, s as isBytesOnlyDocument, v as TEXT_BUDGETED_CONTENT_TYPES } from "./linkedDocument-GE-VV_Gj.js";
5
6
  import { c as findUnpairedToolCalls, d as partsToText, f as promptText, l as interruptedToolResult, p as textParts, u as sealToolCallPairs } from "./llm-eIQNO9tr.js";
6
- import { a as UNSUPPORTED_DOCUMENT_MESSAGE, c as toBase64, f as SPREADSHEET_MIME_TYPE, g as DEFAULT_MAX_DOCUMENT_TEXT_BYTES, h as DEFAULT_MAX_DOCUMENT_BYTES, i as SUPPORTED_DOCUMENT_MIME, l as encodeSpreadsheet, n as READ_LINKED_DOCUMENT_TOOL, o as fromBase64, r as READ_LINKED_DOCUMENT_TOOL_NAME, s as isBytesOnlyDocument, v as TEXT_BUDGETED_CONTENT_TYPES } from "./linkedDocument-0iiVPd5t.js";
7
7
  import { t as mergeCatalogEntries } from "./external-_ZRQe-V9.js";
8
8
  import { i as isArtifactCardHidden, n as extractChartSpec, r as admitArtifactMetadata, t as buildRenderResult } from "./renderResult-2v3WQzs_.js";
9
9
  import { t as extractUiSpecEvents } from "./surface-DVGiCmwq.js";
@@ -2704,6 +2704,11 @@ var AgentLoop = class {
2704
2704
  label: "Excel workbooks",
2705
2705
  ...this.#deps.xlsxExtractor ? { extractor: this.#deps.xlsxExtractor } : {}
2706
2706
  },
2707
+ [XLS_MIME]: {
2708
+ kind: "xls",
2709
+ label: "Legacy Excel workbooks",
2710
+ ...this.#deps.xlsxExtractor ? { extractor: this.#deps.xlsxExtractor } : {}
2711
+ },
2707
2712
  [SUPPORTED_DOCUMENT_MIME.pptx]: {
2708
2713
  kind: "pptx",
2709
2714
  label: "PowerPoint presentations",
package/dist/browser.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { G as FileStat, It as VerifyResult, K as FileSystemProvider, Lt as WebSkillError, N as ArchiveLimits, Ot as SkillsLockfile, Pt as UnsignedPolicy, S as UiBridge, St as SkillManifest, b as RenderResultRequest, c as InteractionResponse, jt as TrustedKeyStore, l as LlmClient, m as LlmStreamEvent, o as InteractionPolicy, p as LlmResponse, q as FileWriteStream, s as InteractionRequest, u as LlmCompleteInput, v as MemoryStore, vt as SkillInstallSource } from "./types-wKp3YBSM-167azx1H.js";
2
- import { $ as ImageOmission, B as ExternalToolSource, C as BridgeResponse, N as DocumentSurfaceHost, Pn as ToolResult, S as BridgeRequest, Sr as bridgeError, Yr as parseBridgeRequest, b as BridgeCapabilities, ct as LinkedDocumentReader, en as ScriptExecutionContext, jn as ToolDefinition, m as ApprovalScope, mr as WebSkillApi, sr as ViewerImageFact, tn as ScriptExecutor, ut as NetworkPolicy, z as ExternalSkillProvider } from "./index-DU8sKyQq.js";
3
- import { In as PerceptionScopeInput, K as DocxDocumentContent, Ln as PptxDocumentContent, Pn as PerceptionResult, Rn as PptxDocumentReader, Tn as PdfDocumentReader, Ut as NestedFrameRef, cn as PageActionRequest, dn as PageActionTarget, ii as XlsxDocumentReader, in as PageActionOutcome, jn as PerceptionCaptureOptions, kn as PerceivedNode, mn as PageAuditSink, nn as PageActionExecutor, q as DocxDocumentReader, ri as XlsxDocumentContent, si as XlsxTableReader, u as ConsentUi, un as PageActionScopeInput, xn as PagePerceptionReader, yn as PagePerceptionPolicy, yr as SubtreeRejection } from "./index-CkauSvus.js";
1
+ import { G as FileStat, It as VerifyResult, K as FileSystemProvider, Lt as WebSkillError, N as ArchiveLimits, Ot as SkillsLockfile, Pt as UnsignedPolicy, S as UiBridge, St as SkillManifest, b as RenderResultRequest, c as InteractionResponse, jt as TrustedKeyStore, l as LlmClient, m as LlmStreamEvent, o as InteractionPolicy, p as LlmResponse, q as FileWriteStream, s as InteractionRequest, u as LlmCompleteInput, v as MemoryStore, vt as SkillInstallSource } from "./types-wKp3YBSM-CSeFUL9R.js";
2
+ import { $ as ImageOmission, B as ExternalToolSource, C as BridgeResponse, N as DocumentSurfaceHost, Pn as ToolResult, S as BridgeRequest, Sr as bridgeError, Yr as parseBridgeRequest, b as BridgeCapabilities, ct as LinkedDocumentReader, en as ScriptExecutionContext, jn as ToolDefinition, m as ApprovalScope, mr as WebSkillApi, sr as ViewerImageFact, tn as ScriptExecutor, ut as NetworkPolicy, z as ExternalSkillProvider } from "./index-UbNuzd2a.js";
3
+ import { In as PerceptionScopeInput, K as DocxDocumentContent, Ln as PptxDocumentContent, Pn as PerceptionResult, Rn as PptxDocumentReader, Tn as PdfDocumentReader, Ut as NestedFrameRef, cn as PageActionRequest, dn as PageActionTarget, ii as XlsxDocumentReader, in as PageActionOutcome, jn as PerceptionCaptureOptions, kn as PerceivedNode, mn as PageAuditSink, nn as PageActionExecutor, q as DocxDocumentReader, ri as XlsxDocumentContent, si as XlsxTableReader, u as ConsentUi, un as PageActionScopeInput, xn as PagePerceptionReader, yn as PagePerceptionPolicy, yr as SubtreeRejection } from "./index-Cj2HedfL.js";
4
4
  //#region ../browser/dist/index.d.ts
5
5
  //#region src/fs/featureDetection.d.ts
6
6
  /** 检测当前环境是否可用 OPFS(navigator.storage.getDirectory) */
@@ -1599,9 +1599,9 @@ declare function extractDocxText(bytes: Uint8Array): Promise<string>;
1599
1599
  /**
1600
1600
  * xlsx 文本抽取(0.13.0 分册 12)。
1601
1601
  *
1602
- * **零新增依赖**:xlsx 和 docx 是同一种容器(OPC = zip + XML),
1603
- * 所以沿用 docx 那条路 —— zip 走仓内既有的 `unzipWithLimits`(fflate,
1604
- * 自带解压体积上限,顺带挡住 zip 炸弹),XML 走浏览器原生 `DOMParser`。
1602
+ * xlsx 和 docx 是同一种容器(OPC = zip + XML),所以沿用 docx 那条路 ——
1603
+ * zip 走仓内既有的 `unzipWithLimits`(fflate,自带解压体积上限,顺带挡住 zip 炸弹),
1604
+ * XML 走浏览器原生 `DOMParser`。旧版 xls 先由 `xlsConversion` 在内存中转成 xlsx。
1605
1605
  *
1606
1606
  * ⚠️ `DOMParser` 是浏览器 API,Node 没有 —— 所以这个模块只在 `@webskill/browser`。
1607
1607
  * Node 宿主没有 xlsx 能力,与 docx 同一条**显式声明**的限制,不是静默降级(备案 D55)。
@@ -1615,7 +1615,7 @@ declare const XLSX_UNEXTRACTED: readonly ["styles", "conditional formatting", "m
1615
1615
  /**
1616
1616
  * 从 xlsx 字节里抽出文本,每个工作表一段、段首是表名。
1617
1617
  *
1618
- * @throws WebSkillError 归档损坏、旧版 `.xls`、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
1618
+ * @throws WebSkillError 归档损坏、旧版 `.xls` 转换失败、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
1619
1619
  */
1620
1620
  declare function extractXlsxText(bytes: Uint8Array): Promise<string>;
1621
1621
  //#endregion
@@ -1644,14 +1644,14 @@ declare const XLSX_IMAGE_MIN_ROWS = 3;
1644
1644
  /** @experimental */
1645
1645
  declare function createXlsxBlockReader(): XlsxDocumentReader;
1646
1646
  /**
1647
- * @throws WebSkillError 归档损坏、旧版 `.xls`、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
1647
+ * @throws WebSkillError 归档损坏、旧版 `.xls` 转换失败、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
1648
1648
  * @experimental
1649
1649
  */
1650
1650
  declare function readXlsxBlocks(bytes: Uint8Array): Promise<XlsxDocumentContent>;
1651
1651
  //#endregion
1652
1652
  //#region src/document/xlsxTable.d.ts
1653
1653
  /**
1654
- * xlsx → 单元格网格或可重复扫描的行流。
1654
+ * xls(x) → 单元格网格或可重复扫描的行流;旧版 xls 先在内存中转换成 xlsx。
1655
1655
  *
1656
1656
  * `read` 保留既有网格契约;`readStreaming` 用 SAX 逐行解析工作表,不受整包解压的 64 MiB 条目上限约束。
1657
1657
  * 两条路径使用同一套单元格取值、日期换算与空格补位规则,错误均带 `WebSkillError`。
package/dist/browser.js CHANGED
@@ -2,13 +2,13 @@ import { n as messageOf$1, t as WebSkillError } from "./errors-BDZNpC13.js";
2
2
  import { A as SKILL_MANIFEST_FILE, D as verifySkillSignature, M as buildManifest, O as MANIFEST_EXCLUDED_FILES, P as verifyManifest, b as parseSkillMarkdown, c as unzipWithLimits, f as SKILL_PACK_FILE, i as buildCatalog, k as SKILLS_LOCKFILE, m as parseSkillPackManifest, n as SkillDiscovery, o as readResponseWithLimit, p as exportSkills, t as validateSkills, u as detectSkillArchiveShapeFromFs, w as readSkillSignature, y as isValidSkillName } from "./skill-WSUDp6A1.js";
3
3
  import { o as atomicWriteText, r as resolveInsideRoot, s as isAtomicTempPath } from "./pathSecurity-CirkQwWP.js";
4
4
  import { t as assertRemoteUrlAllowed } from "./urlSafety-CiSuCJvX.js";
5
- import { t as ATTACHMENT_TEXT_LIMIT } from "./kind-Dc8x0HWz.js";
6
- import { _ as FsRunSnapshotStore, a as networkPolicyLibSource, c as bridgeError, ct as ProgressiveRouter, d as FsMemoryStore, l as parseBridgeRequest, m as AgentLoop, r as normalizeToolError, s as UPLOAD_FILES_UNAVAILABLE, t as CapabilityApproval, u as FsArtifactStore } from "./approval-5BmspsRi.js";
5
+ import { c as toBase64$1, f as SPREADSHEET_MIME_TYPE, y as ATTACHMENT_TEXT_LIMIT } from "./linkedDocument-GE-VV_Gj.js";
6
+ import { _ as FsRunSnapshotStore, a as networkPolicyLibSource, c as bridgeError, ct as ProgressiveRouter, d as FsMemoryStore, l as parseBridgeRequest, m as AgentLoop, r as normalizeToolError, s as UPLOAD_FILES_UNAVAILABLE, t as CapabilityApproval, u as FsArtifactStore } from "./approval-DnUytrkq.js";
7
7
  import { a as GoogleGenAiClient, o as AnthropicClient, s as OpenAiCompatibleClient, t as MockLlmClient } from "./llm-eIQNO9tr.js";
8
- import { c as toBase64$1, f as SPREADSHEET_MIME_TYPE } from "./linkedDocument-0iiVPd5t.js";
9
8
  import { n as normalizeToolContent, t as mergeCatalogEntries } from "./external-_ZRQe-V9.js";
10
- import { t as createWebSkillApi } from "./webSkillApi-rX2e3SVB.js";
11
- import { A as frameSteps, D as SCROLL_DIRECTIONS, E as toActionFrameScopes, O as toFrameScopes, _ as defersImage, a as columnWidthToPixels, b as isPdfTextTrustworthy, c as isRangeTopLeft, d as rangeContains, f as readImageSize, k as frameLabel, l as parseCellAddress, n as EMU_PER_POINT, o as fitWithin, p as PDF_LARGE_IMAGE_RATIO, r as EMU_PER_TWIP$1, s as formatCellAddress, t as EMU_PER_PIXEL, u as parseCellRange, v as takesImage } from "./geometry-BXMPNuM6.js";
9
+ import { t as createWebSkillApi } from "./webSkillApi-TeWPPFDn.js";
10
+ import { T as frameSteps, _ as defersImage, a as columnWidthToPixels, b as isPdfTextTrustworthy, c as isRangeTopLeft, d as rangeContains, f as readImageSize, l as parseCellAddress, n as EMU_PER_POINT, o as fitWithin, p as PDF_LARGE_IMAGE_RATIO, r as EMU_PER_TWIP$1, s as formatCellAddress, t as EMU_PER_PIXEL, u as parseCellRange, v as takesImage, w as frameLabel } from "./geometry-1xQbK4hB.js";
11
+ import { a as toFrameScopes, i as SCROLL_DIRECTIONS, r as toActionFrameScopes } from "./types-BXRIoabj.js";
12
12
  import { Unzip, UnzipInflate, zipSync } from "fflate";
13
13
  import { SaxesParser } from "saxes";
14
14
 
@@ -6424,14 +6424,129 @@ async function extractDocxText(bytes) {
6424
6424
  return blocks.join("\n").replace(/\n{3,}/g, "\n\n").trim();
6425
6425
  }
6426
6426
 
6427
+ //#endregion
6428
+ //#region ../browser/src/document/xlsConversion.ts
6429
+ const OLE2_SIGNATURE = [
6430
+ 208,
6431
+ 207,
6432
+ 17,
6433
+ 224,
6434
+ 161,
6435
+ 177,
6436
+ 26,
6437
+ 225
6438
+ ];
6439
+ function isLegacyXls(bytes) {
6440
+ return OLE2_SIGNATURE.every((byte, index) => bytes[index] === byte);
6441
+ }
6442
+ /** 旧 BIFF/OLE2 工作簿只在内存中转换;原件与上传落盘内容都不改写。 */
6443
+ async function convertXlsToXlsx(bytes) {
6444
+ if (!isLegacyXls(bytes)) throw new WebSkillError("TOOL_EXECUTION_FAILED", "The file is not a legacy OLE2 .xls workbook.");
6445
+ try {
6446
+ const [XLSX, codepage] = await Promise.all([import("@e965/xlsx"), import("@e965/xlsx/dist/cpexcel.full.mjs")]);
6447
+ const { cptable } = codepage;
6448
+ const { utils } = codepage;
6449
+ XLSX.set_cptable({
6450
+ ...cptable,
6451
+ utils
6452
+ });
6453
+ const workbook = XLSX.read(bytes, {
6454
+ type: "array",
6455
+ cellDates: false,
6456
+ cellNF: true
6457
+ });
6458
+ const output = XLSX.write(workbook, {
6459
+ type: "array",
6460
+ bookType: "xlsx",
6461
+ compression: true
6462
+ });
6463
+ if (output instanceof Uint8Array) return output;
6464
+ if (output instanceof ArrayBuffer) return new Uint8Array(output);
6465
+ throw new Error("The converter returned an unsupported binary output.");
6466
+ } catch (error) {
6467
+ throw new WebSkillError("TOOL_EXECUTION_FAILED", `The legacy .xls workbook could not be converted to .xlsx: ${error instanceof Error ? error.message : String(error)}`, error);
6468
+ }
6469
+ }
6470
+ async function normalizeExcelBytes(bytes) {
6471
+ return isLegacyXls(bytes) ? convertXlsToXlsx(bytes) : bytes;
6472
+ }
6473
+ async function collect(chunks) {
6474
+ const parts = [];
6475
+ let length = 0;
6476
+ for await (const chunk of chunks) {
6477
+ parts.push(chunk);
6478
+ length += chunk.byteLength;
6479
+ }
6480
+ const bytes = new Uint8Array(length);
6481
+ let offset = 0;
6482
+ for (const part of parts) {
6483
+ bytes.set(part, offset);
6484
+ offset += part.byteLength;
6485
+ }
6486
+ return bytes;
6487
+ }
6488
+ /**
6489
+ * 流式读取先复用首段判断魔数。普通 xlsx 的首段会原样接回流,不整份缓存;
6490
+ * 只有必须整体转换的 xls 才收集全部字节。
6491
+ */
6492
+ async function normalizeExcelSource(source) {
6493
+ if (typeof source !== "function") return normalizeExcelBytes(source);
6494
+ const iterator = (await source())[Symbol.asyncIterator]();
6495
+ const prefix = [];
6496
+ let prefixLength = 0;
6497
+ let done = false;
6498
+ while (prefixLength < OLE2_SIGNATURE.length && !done) {
6499
+ const next = await iterator.next();
6500
+ if (next.done === true) done = true;
6501
+ else {
6502
+ prefix.push(next.value);
6503
+ prefixLength += next.value.byteLength;
6504
+ }
6505
+ }
6506
+ const replay = async function* () {
6507
+ yield* prefix;
6508
+ try {
6509
+ while (!done) {
6510
+ const next = await iterator.next();
6511
+ if (next.done === true) {
6512
+ done = true;
6513
+ break;
6514
+ }
6515
+ yield next.value;
6516
+ }
6517
+ } finally {
6518
+ if (!done) await iterator.return?.();
6519
+ }
6520
+ };
6521
+ const head = new Uint8Array(Math.min(prefixLength, OLE2_SIGNATURE.length));
6522
+ let offset = 0;
6523
+ for (const chunk of prefix) {
6524
+ head.set(chunk.subarray(0, head.byteLength - offset), offset);
6525
+ offset = Math.min(head.byteLength, offset + chunk.byteLength);
6526
+ if (offset === head.byteLength) break;
6527
+ }
6528
+ if (!isLegacyXls(head)) {
6529
+ let pending = replay();
6530
+ return async () => {
6531
+ if (pending !== void 0) {
6532
+ const first = pending;
6533
+ pending = void 0;
6534
+ return first;
6535
+ }
6536
+ return await source();
6537
+ };
6538
+ }
6539
+ return convertXlsToXlsx(await collect(replay()));
6540
+ }
6541
+
6427
6542
  //#endregion
6428
6543
  //#region ../browser/src/document/xlsx.ts
6429
6544
  /**
6430
6545
  * xlsx 文本抽取(0.13.0 分册 12)。
6431
6546
  *
6432
- * **零新增依赖**:xlsx 和 docx 是同一种容器(OPC = zip + XML),
6433
- * 所以沿用 docx 那条路 —— zip 走仓内既有的 `unzipWithLimits`(fflate,
6434
- * 自带解压体积上限,顺带挡住 zip 炸弹),XML 走浏览器原生 `DOMParser`。
6547
+ * xlsx 和 docx 是同一种容器(OPC = zip + XML),所以沿用 docx 那条路 ——
6548
+ * zip 走仓内既有的 `unzipWithLimits`(fflate,自带解压体积上限,顺带挡住 zip 炸弹),
6549
+ * XML 走浏览器原生 `DOMParser`。旧版 xls 先由 `xlsConversion` 在内存中转成 xlsx。
6435
6550
  *
6436
6551
  * ⚠️ `DOMParser` 是浏览器 API,Node 没有 —— 所以这个模块只在 `@webskill/browser`。
6437
6552
  * Node 宿主没有 xlsx 能力,与 docx 同一条**显式声明**的限制,不是静默降级(备案 D55)。
@@ -6457,17 +6572,6 @@ const WORKBOOK$1 = "xl/workbook.xml";
6457
6572
  const WORKBOOK_RELS$1 = "xl/_rels/workbook.xml.rels";
6458
6573
  const SHARED_STRINGS$1 = "xl/sharedStrings.xml";
6459
6574
  const STYLES$1 = "xl/styles.xml";
6460
- /** OLE2 复合文档签名:旧版 .xls 的开头,它不是 zip,走不到解压那一步 */
6461
- const OLE2_SIGNATURE$1 = [
6462
- 208,
6463
- 207,
6464
- 17,
6465
- 224,
6466
- 161,
6467
- 177,
6468
- 26,
6469
- 225
6470
- ];
6471
6575
  /** 内建的日期/时间数字格式 id(ECMA-376 §18.8.30) */
6472
6576
  const BUILTIN_DATE_FORMATS = /* @__PURE__ */ new Set([
6473
6577
  14,
@@ -6630,7 +6734,6 @@ function sheetRows(doc, shared, dateStyles, date1904) {
6630
6734
  }
6631
6735
  /** 一行的文本:单元格用制表符分隔(与 docx 的表格同口径),行尾制表符不留 */
6632
6736
  const rowLine = (cells) => cells.join(" ").replace(/\t+$/, "");
6633
- const looksLikeOle2 = (bytes) => bytes.length >= OLE2_SIGNATURE$1.length && OLE2_SIGNATURE$1.every((byte, i) => bytes[i] === byte);
6634
6737
  /** rels 里的 Target 可能是相对 `xl/` 的,也可能是包根绝对路径 */
6635
6738
  function resolveSheetPath$1(target) {
6636
6739
  const clean = target.replace(/^\.\//, "");
@@ -6639,13 +6742,13 @@ function resolveSheetPath$1(target) {
6639
6742
  /**
6640
6743
  * 把 xlsx 拆成「每张表的每一行文本」。
6641
6744
  *
6642
- * @throws WebSkillError 归档损坏、旧版 `.xls`、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
6745
+ * @throws WebSkillError 归档损坏、旧版 `.xls` 转换失败、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
6643
6746
  */
6644
6747
  async function readXlsxWorkbook(bytes) {
6645
- if (looksLikeOle2(bytes)) fail$1("This is a legacy .xls workbook, which is not supported. Save it as .xlsx and try again.");
6748
+ const normalized = await normalizeExcelBytes(bytes);
6646
6749
  let entries;
6647
6750
  try {
6648
- entries = await unzipWithLimits(bytes);
6751
+ entries = await unzipWithLimits(normalized);
6649
6752
  } catch {
6650
6753
  fail$1("This file could not be read as an Excel workbook: the archive is damaged or not a .xlsx file.");
6651
6754
  }
@@ -6693,7 +6796,7 @@ async function readXlsxWorkbook(bytes) {
6693
6796
  /**
6694
6797
  * 从 xlsx 字节里抽出文本,每个工作表一段、段首是表名。
6695
6798
  *
6696
- * @throws WebSkillError 归档损坏、旧版 `.xls`、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
6799
+ * @throws WebSkillError 归档损坏、旧版 `.xls` 转换失败、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
6697
6800
  */
6698
6801
  async function extractXlsxText(bytes) {
6699
6802
  const { sheets } = await readXlsxWorkbook(bytes);
@@ -6942,7 +7045,7 @@ function createXlsxBlockReader() {
6942
7045
  return { read: readXlsxBlocks };
6943
7046
  }
6944
7047
  /**
6945
- * @throws WebSkillError 归档损坏、旧版 `.xls`、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
7048
+ * @throws WebSkillError 归档损坏、旧版 `.xls` 转换失败、缺 `xl/workbook.xml`、工作表关系解不开、XML 解析失败
6946
7049
  * @experimental
6947
7050
  */
6948
7051
  async function readXlsxBlocks(bytes) {
@@ -6973,16 +7076,6 @@ const WORKBOOK = "xl/workbook.xml";
6973
7076
  const WORKBOOK_RELS = "xl/_rels/workbook.xml.rels";
6974
7077
  const SHARED_STRINGS = "xl/sharedStrings.xml";
6975
7078
  const STYLES = "xl/styles.xml";
6976
- const OLE2_SIGNATURE = [
6977
- 208,
6978
- 207,
6979
- 17,
6980
- 224,
6981
- 161,
6982
- 177,
6983
- 26,
6984
- 225
6985
- ];
6986
7079
  function fail(message) {
6987
7080
  throw new WebSkillError("TOOL_EXECUTION_FAILED", message);
6988
7081
  }
@@ -7260,8 +7353,8 @@ function resolveSheetPath(target) {
7260
7353
  const clean = target.replace(/^\.\//, "");
7261
7354
  return clean.startsWith("/") ? clean.slice(1) : `xl/${clean}`;
7262
7355
  }
7263
- async function readStreamingXlsxWorkbook(source) {
7264
- if (typeof source !== "function" && OLE2_SIGNATURE.every((byte, index) => source[index] === byte)) fail("This is a legacy .xls workbook, which is not supported. Save it as .xlsx and try again.");
7356
+ async function readStreamingXlsxWorkbook(input) {
7357
+ const source = await normalizeExcelSource(input);
7265
7358
  const workbookBytes = await entryBytes(source, WORKBOOK);
7266
7359
  if (workbookBytes === void 0) fail(`This file is not an Excel workbook: it has no ${WORKBOOK} entry.`);
7267
7360
  const workbook = parseXml$1(workbookBytes, "index");
@@ -7318,7 +7411,7 @@ async function readStreamingXlsxWorkbook(source) {
7318
7411
  //#endregion
7319
7412
  //#region ../browser/src/document/xlsxTable.ts
7320
7413
  /**
7321
- * xlsx → 单元格网格或可重复扫描的行流。
7414
+ * xls(x) → 单元格网格或可重复扫描的行流;旧版 xls 先在内存中转换成 xlsx。
7322
7415
  *
7323
7416
  * `read` 保留既有网格契约;`readStreaming` 用 SAX 逐行解析工作表,不受整包解压的 64 MiB 条目上限约束。
7324
7417
  * 两条路径使用同一套单元格取值、日期换算与空格补位规则,错误均带 `WebSkillError`。
@@ -0,0 +1,88 @@
1
+ import { Bt as LIST_PAGE_TABS_TOOL, Jt as PAGE_ACTION_TOOL, Qt as PERCEIVE_PAGE_TOOL, jt as FOCUS_PAGE_TAB_TOOL, s as CLOSE_PAGE_TAB_TOOL } from "./index-Cj2HedfL.js";
2
+ import { A as PairConfirmResult, B as WebSocketLike, C as InvocationMeta, D as OriginsParams, E as Origin, F as PingResult, I as Principal, L as ProtocolVersion, M as PairStartParams, N as PairStartResult, O as PairApprovedParams, P as PingParams, R as ReadyParams, S as HumanControlParams, T as JsonRpcRequest, _ as ControllerPairingCode, a as AuthRenewParams, b as HelloParams, c as Base64Url, d as ControllerAuditEvent, f as ControllerDevice, g as ControllerPairingApproval, h as ControllerDeviceStore, i as AuthPresentResult, j as PairRejectedParams, k as PairConfirmParams, l as BoundedString, m as ControllerDeviceState, n as AuthChallengeResult, o as AuthRenewResult, p as ControllerDeviceOptions, r as AuthPresentParams, s as AuthRevokedParams, t as AuthChallengeParams, u as ByeParams, v as ControllerPairingRecord, w as IsoDateTime, x as HelloResult, y as ControllerWriteState, z as WebSocketConstructor } from "./types-DmcXN3qR-Dy7ZDstc.js";
3
+ //#region ../controller/dist/index.d.ts
4
+ //#region src/constants.d.ts
5
+ /** @stable */
6
+ declare const CONTROLLER_PROTOCOL_VERSION: "0.1";
7
+ /** @experimental */
8
+ type ControllerToolName = 'browser_status' | typeof PERCEIVE_PAGE_TOOL | typeof PAGE_ACTION_TOOL | typeof LIST_PAGE_TABS_TOOL | typeof FOCUS_PAGE_TAB_TOOL | typeof CLOSE_PAGE_TAB_TOOL;
9
+ /** @experimental */
10
+ declare const CONTROLLER_TOOL_NAMES: readonly ControllerToolName[];
11
+ interface ControllerProtocolLimits {
12
+ readonly maxMessageBytes: number;
13
+ readonly oversizeWindowMs: number;
14
+ readonly oversizeThreshold: number;
15
+ readonly invocationContextMaxBytes: number;
16
+ readonly pairingCodeTtlMaxMs: number;
17
+ readonly pairingAttemptsMax: number;
18
+ readonly deviceConfirmTimeoutMs: number;
19
+ readonly grantTtlMaxMs: number;
20
+ readonly heartbeatIntervalMs: number;
21
+ readonly heartbeatTimeoutMs: number;
22
+ readonly reconnectMaxDelayMs: number;
23
+ readonly localAuthorizationTimeoutMs: number;
24
+ readonly idempotencyCacheEntries: number;
25
+ readonly idempotencyCacheTtlMs: number;
26
+ }
27
+ /** @experimental */
28
+ declare const CONTROLLER_PROTOCOL_LIMITS: ControllerProtocolLimits;
29
+ //#endregion
30
+ //#region src/validate.d.ts
31
+ /** @experimental */
32
+ interface ControllerValidation {
33
+ readonly valid: boolean;
34
+ readonly errors: readonly string[];
35
+ }
36
+ /** @experimental */
37
+ declare const CONTROLLER_PROTOCOL_SCHEMA: Readonly<Record<string, unknown>>;
38
+ /** @experimental */
39
+ declare function validateControllerMessage(method: string, kind: 'params' | 'result', value: unknown): ControllerValidation;
40
+ //#endregion
41
+ //#region src/transport.d.ts
42
+ /** @experimental */
43
+ type ControllerRequestHandler = (method: string, params: unknown) => Promise<unknown> | unknown;
44
+ /** @experimental */
45
+ type ControllerNotificationHandler = (method: string, params: unknown) => void | Promise<void>;
46
+ /** @experimental */
47
+ type McpMessageHandler = (message: JsonRpcRequest) => void;
48
+ /** @experimental */
49
+ interface ControllerTransportOptions {
50
+ readonly url: string;
51
+ readonly socket?: WebSocketLike;
52
+ readonly WebSocket?: WebSocketConstructor;
53
+ readonly isAuthorized?: () => boolean;
54
+ readonly maxMessageBytes?: number;
55
+ readonly requestTimeoutMs?: number;
56
+ onControlRequest?: ControllerRequestHandler;
57
+ onControlNotification?: ControllerNotificationHandler;
58
+ onmessage?: McpMessageHandler;
59
+ onerror?: (error: Error) => void;
60
+ onclose?: () => void;
61
+ }
62
+ /** @experimental */
63
+ interface ControllerTransport {
64
+ readonly connected: boolean;
65
+ onControlRequest?: ControllerRequestHandler;
66
+ onControlNotification?: ControllerNotificationHandler;
67
+ onmessage?: McpMessageHandler;
68
+ onerror?: (error: Error) => void;
69
+ onclose?: () => void;
70
+ connect(): Promise<void>;
71
+ start(): Promise<void>;
72
+ request<T = unknown>(method: string, params?: unknown, timeoutMs?: number): Promise<T>;
73
+ notify(method: string, params?: unknown): Promise<void>;
74
+ send(message: JsonRpcRequest): Promise<void>;
75
+ close(code?: number, reason?: string): Promise<void>;
76
+ }
77
+ /** @experimental */
78
+ declare function createWebSocketControllerTransport(options: ControllerTransportOptions): ControllerTransport;
79
+ //#endregion
80
+ //#region src/device/crypto.d.ts
81
+ /** @experimental */
82
+ declare function instanceFingerprint(instanceId: string): Promise<string>;
83
+ //#endregion
84
+ //#region src/device/index.d.ts
85
+ /** @experimental */
86
+ declare function createControllerDevice(options: ControllerDeviceOptions): ControllerDevice;
87
+ //#endregion
88
+ export { type AuthChallengeParams, type AuthChallengeResult, type AuthPresentParams, type AuthPresentResult, type AuthRenewParams, type AuthRenewResult, type AuthRevokedParams, type Base64Url, type BoundedString, type ByeParams, CONTROLLER_PROTOCOL_LIMITS, CONTROLLER_PROTOCOL_SCHEMA, CONTROLLER_PROTOCOL_VERSION, CONTROLLER_TOOL_NAMES, type ControllerAuditEvent, type ControllerDevice, type ControllerDeviceOptions, type ControllerDeviceState, type ControllerDeviceStore, ControllerNotificationHandler, type ControllerPairingApproval, type ControllerPairingCode, type ControllerPairingRecord, type ControllerProtocolLimits, ControllerRequestHandler, type ControllerToolName, ControllerTransport, ControllerTransportOptions, ControllerValidation, type ControllerWriteState, type HelloParams, type HelloResult, type HumanControlParams, type InvocationMeta, type IsoDateTime, McpMessageHandler, type Origin, type OriginsParams, type PairApprovedParams, type PairConfirmParams, type PairConfirmResult, type PairRejectedParams, type PairStartParams, type PairStartResult, type PingParams, type PingResult, type Principal, type ProtocolVersion, type ReadyParams, createControllerDevice, createWebSocketControllerTransport, instanceFingerprint, validateControllerMessage };
@@ -0,0 +1,3 @@
1
+ import { a as createWebSocketControllerTransport, d as CONTROLLER_PROTOCOL_VERSION, f as CONTROLLER_TOOL_NAMES, o as CONTROLLER_PROTOCOL_SCHEMA, r as instanceFingerprint, s as validateControllerMessage, t as createControllerDevice, u as CONTROLLER_PROTOCOL_LIMITS } from "./device-DMUgqNzr.js";
2
+
3
+ export { CONTROLLER_PROTOCOL_LIMITS, CONTROLLER_PROTOCOL_SCHEMA, CONTROLLER_PROTOCOL_VERSION, CONTROLLER_TOOL_NAMES, createControllerDevice, createWebSocketControllerTransport, instanceFingerprint, validateControllerMessage };