@taloswork/ose-shared 0.1.11 → 0.1.12

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 (119) hide show
  1. package/package.json +3 -3
  2. package/skills/document/SKILL.md +143 -215
  3. package/skills/document/art-directions/base.css +27 -2
  4. package/skills/document/art-directions/cinematic-depth.css +3 -1
  5. package/skills/document/art-directions/collage-paper.css +5 -1
  6. package/skills/document/art-directions/editorial-cut.css +5 -1
  7. package/skills/document/art-directions/geometric-pop.css +6 -0
  8. package/skills/document/art-directions/gradient-mesh.css +5 -1
  9. package/skills/document/art-directions/illustrated-doodle.css +5 -0
  10. package/skills/document/art-directions/luxury-ornament.css +4 -1
  11. package/skills/document/art-directions/maximalist-blocks.css +6 -0
  12. package/skills/document/art-directions/technical-grid.css +4 -0
  13. package/skills/document/assets/fonts/fonts.json +2 -2
  14. package/skills/document/assets/pdf-fonts/NotoSansSC-PDF-Bold.ttf +0 -0
  15. package/skills/document/assets/pdf-fonts/NotoSansSC-PDF-Regular.ttf +0 -0
  16. package/skills/document/assets/pdf-fonts/OFL.txt +93 -0
  17. package/skills/document/assets/pdf-fonts/README.md +35 -0
  18. package/skills/document/assets/tessdata/LICENSE-Apache-2.0.txt +202 -0
  19. package/skills/document/assets/tessdata/README.md +21 -0
  20. package/skills/document/assets/tessdata/chi_sim.traineddata.gz +0 -0
  21. package/skills/document/assets/tessdata/eng.traineddata.gz +0 -0
  22. package/skills/document/bin/deck-build.cjs +2311 -41
  23. package/skills/document/bin/deck-chart.cjs +762 -0
  24. package/skills/document/bin/deck-plan.cjs +802 -0
  25. package/skills/document/bin/deck-qa.cjs +984 -249
  26. package/skills/document/bin/deck-scenario.cjs +1346 -0
  27. package/skills/document/bin/doc-convert.cjs +130 -39
  28. package/skills/document/bin/doc-fill.cjs +73121 -170
  29. package/skills/document/bin/doc-gen.cjs +625 -68
  30. package/skills/document/bin/doc-run.cjs +162 -24
  31. package/skills/document/bin/doc-scan.cjs +13 -0
  32. package/skills/document/bin/doc-text.cjs +13 -0
  33. package/skills/document/bin/doc-validate.cjs +718 -23
  34. package/skills/document/bin/doc-xml.cjs +9 -5
  35. package/skills/document/bin/docx-annotate.cjs +95 -19
  36. package/skills/document/bin/fontkit.cjs +1 -0
  37. package/skills/document/bin/html2pptx.cjs +1372 -121
  38. package/skills/document/bin/ocr-worker.cjs +1 -0
  39. package/skills/document/bin/ocr.cjs +131 -40
  40. package/skills/document/bin/pdf-form.cjs +674 -177
  41. package/skills/document/bin/pdf-images.cjs +13 -0
  42. package/skills/document/bin/pdf-ops.cjs +634 -199
  43. package/skills/document/bin/pdf-render.cjs +19 -3
  44. package/skills/document/bin/pdf-tables.cjs +13 -0
  45. package/skills/document/bin/pptx-clone.cjs +3 -3
  46. package/skills/document/bin/pptx-slide.cjs +3 -3
  47. package/skills/document/bin/xlsx-query.cjs +192 -61
  48. package/skills/document/bin-reference.md +56 -33
  49. package/skills/document/content-pipeline.md +129 -242
  50. package/skills/document/deck-design.md +355 -638
  51. package/skills/document/layouts/README.md +46 -33
  52. package/skills/document/layouts/capacity.json +1 -0
  53. package/skills/document/layouts/slots.json +1 -1
  54. package/skills/document/layouts/toc-panel.tpl +1 -1
  55. package/skills/document/motion/README.md +3 -2
  56. package/skills/document/office.md +3 -3
  57. package/skills/document/packs/board-brief/backdrop.html +2 -0
  58. package/skills/document/packs/board-brief/pack.css +2 -1
  59. package/skills/document/packs/mckinsey-photo/backdrop.html +2 -0
  60. package/skills/document/packs/mckinsey-photo/pack.css +2 -1
  61. package/skills/document/packs/press-room/backdrop.html +2 -0
  62. package/skills/document/packs/press-room/pack.css +2 -1
  63. package/skills/document/packs/prismatic-3d/backdrop.html +2 -0
  64. package/skills/document/packs/prismatic-3d/pack.css +4 -1
  65. package/skills/document/pdf.md +53 -49
  66. package/skills/document/rewrite.md +241 -308
  67. package/skills/document/scenarios.json +1290 -0
  68. package/skills/document/scenarios.schema.json +103 -0
  69. package/skills/document/styles/README.md +15 -25
  70. package/skills/document/styles/_contract-defaults.css +25 -1
  71. package/skills/document/styles/anthropic/skin.css +6 -3
  72. package/skills/document/styles/apple/skin.css +4 -3
  73. package/skills/document/styles/bistro-warm/backdrop.html +2 -0
  74. package/skills/document/styles/bistro-warm/skin.css +4 -1
  75. package/skills/document/styles/black-gold/skin.css +6 -5
  76. package/skills/document/styles/bold-clash/backdrop.html +2 -0
  77. package/skills/document/styles/bold-clash/skin.css +2 -1
  78. package/skills/document/styles/branding/skin.css +4 -4
  79. package/skills/document/styles/campus-teal/backdrop.html +2 -0
  80. package/skills/document/styles/campus-teal/skin.css +2 -1
  81. package/skills/document/styles/cinereel/skin.css +7 -3
  82. package/skills/document/styles/clinic-care/backdrop.html +2 -0
  83. package/skills/document/styles/clinic-care/skin.css +2 -1
  84. package/skills/document/styles/cool/skin.css +6 -5
  85. package/skills/document/styles/dark-glass/backdrop.html +2 -0
  86. package/skills/document/styles/dark-glass/skin.css +2 -1
  87. package/skills/document/styles/gov-brief/backdrop.html +2 -0
  88. package/skills/document/styles/gov-brief/skin.css +2 -1
  89. package/skills/document/styles/grid-tech/backdrop.html +2 -0
  90. package/skills/document/styles/grid-tech/skin.css +2 -1
  91. package/skills/document/styles/hand-drawn/skin.css +3 -3
  92. package/skills/document/styles/ivory-gold/skin.css +7 -6
  93. package/skills/document/styles/legal-slate/backdrop.html +2 -0
  94. package/skills/document/styles/legal-slate/skin.css +2 -1
  95. package/skills/document/styles/magazine-ink/skin.css +4 -3
  96. package/skills/document/styles/mckinsey/skin.css +2 -1
  97. package/skills/document/styles/memphis/backdrop.html +2 -0
  98. package/skills/document/styles/memphis/skin.css +2 -1
  99. package/skills/document/styles/mono/skin.css +6 -2
  100. package/skills/document/styles/neon-cyber/backdrop.html +2 -0
  101. package/skills/document/styles/neon-cyber/skin.css +2 -1
  102. package/skills/document/styles/olive-gold/skin.css +7 -6
  103. package/skills/document/styles/organic-earth/backdrop.html +2 -0
  104. package/skills/document/styles/organic-earth/skin.css +2 -1
  105. package/skills/document/styles/pastel-saas/backdrop.html +2 -0
  106. package/skills/document/styles/pastel-saas/skin.css +2 -1
  107. package/skills/document/styles/portfolio-noir/backdrop.html +2 -0
  108. package/skills/document/styles/portfolio-noir/skin.css +2 -1
  109. package/skills/document/styles/retro-press/backdrop.html +2 -0
  110. package/skills/document/styles/retro-press/skin.css +2 -1
  111. package/skills/document/styles/sport-arena/backdrop.html +2 -0
  112. package/skills/document/styles/sport-arena/skin.css +4 -1
  113. package/skills/document/styles/swiss-grid/skin.css +10 -5
  114. package/skills/document/styles/wedding-blush/backdrop.html +2 -0
  115. package/skills/document/styles/wedding-blush/skin.css +4 -1
  116. package/skills/document/theme-system.md +85 -77
  117. package/skills/document/themes/README.md +7 -5
  118. package/skills/document/vision.md +8 -5
  119. package/skills/document/xlsx.md +15 -25
@@ -58096,8 +58096,8 @@ var require_graceful_fs = __commonJS({
58096
58096
  }
58097
58097
  }
58098
58098
  var fs$writeFile = fs2.writeFile;
58099
- fs2.writeFile = writeFile2;
58100
- function writeFile2(path, data, options, cb2) {
58099
+ fs2.writeFile = writeFile3;
58100
+ function writeFile3(path, data, options, cb2) {
58101
58101
  if (typeof options === "function")
58102
58102
  cb2 = options, options = null;
58103
58103
  return go$writeFile(path, data, options, cb2);
@@ -59600,7 +59600,7 @@ var require_old = __commonJS({
59600
59600
  splitRootRe = /^[\/]*/;
59601
59601
  }
59602
59602
  var splitRootRe;
59603
- exports2.realpathSync = function realpathSync(p, cache) {
59603
+ exports2.realpathSync = function realpathSync2(p, cache) {
59604
59604
  p = pathModule.resolve(p);
59605
59605
  if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
59606
59606
  return cache[p];
@@ -59753,8 +59753,8 @@ var require_fs = __commonJS({
59753
59753
  "node_modules/fs.realpath/index.js"(exports2, module2) {
59754
59754
  module2.exports = realpath;
59755
59755
  realpath.realpath = realpath;
59756
- realpath.sync = realpathSync;
59757
- realpath.realpathSync = realpathSync;
59756
+ realpath.sync = realpathSync2;
59757
+ realpath.realpathSync = realpathSync2;
59758
59758
  realpath.monkeypatch = monkeypatch;
59759
59759
  realpath.unmonkeypatch = unmonkeypatch;
59760
59760
  var fs = require("fs");
@@ -59782,7 +59782,7 @@ var require_fs = __commonJS({
59782
59782
  }
59783
59783
  });
59784
59784
  }
59785
- function realpathSync(p, cache) {
59785
+ function realpathSync2(p, cache) {
59786
59786
  if (ok) {
59787
59787
  return origRealpathSync(p, cache);
59788
59788
  }
@@ -59798,7 +59798,7 @@ var require_fs = __commonJS({
59798
59798
  }
59799
59799
  function monkeypatch() {
59800
59800
  fs.realpath = realpath;
59801
- fs.realpathSync = realpathSync;
59801
+ fs.realpathSync = realpathSync2;
59802
59802
  }
59803
59803
  function unmonkeypatch() {
59804
59804
  fs.realpath = origRealpath;
@@ -85503,7 +85503,7 @@ var require_dir_writer = __commonJS({
85503
85503
  module2.exports = DirWriter;
85504
85504
  var Writer = require_writer2();
85505
85505
  var inherits2 = require_inherits();
85506
- var mkdir2 = require_mkdirp();
85506
+ var mkdir3 = require_mkdirp();
85507
85507
  var path = require("path");
85508
85508
  var collect = require_collect();
85509
85509
  inherits2(DirWriter, Writer);
@@ -85519,7 +85519,7 @@ var require_dir_writer = __commonJS({
85519
85519
  }
85520
85520
  DirWriter.prototype._create = function() {
85521
85521
  var self2 = this;
85522
- mkdir2(self2._path, Writer.dirmode, function(er) {
85522
+ mkdir3(self2._path, Writer.dirmode, function(er) {
85523
85523
  if (er) return self2.error(er);
85524
85524
  self2.ready = true;
85525
85525
  self2.emit("ready");
@@ -85864,7 +85864,7 @@ var require_writer2 = __commonJS({
85864
85864
  var fs = require_graceful_fs();
85865
85865
  var inherits2 = require_inherits();
85866
85866
  var rimraf = require_rimraf();
85867
- var mkdir2 = require_mkdirp();
85867
+ var mkdir3 = require_mkdirp();
85868
85868
  var path = require("path");
85869
85869
  var umask = process.platform === "win32" ? 0 : process.umask();
85870
85870
  var getType = require_get_type();
@@ -85970,7 +85970,7 @@ var require_writer2 = __commonJS({
85970
85970
  }
85971
85971
  };
85972
85972
  function create2(self2) {
85973
- mkdir2(path.dirname(self2._path), Writer.dirmode, function(er, made) {
85973
+ mkdir3(path.dirname(self2._path), Writer.dirmode, function(er, made) {
85974
85974
  if (er) return self2.error(er);
85975
85975
  self2._madeDir = made;
85976
85976
  return self2._create();
@@ -103048,6 +103048,10 @@ async function convertToPdfViaSoffice(inputPath, options = {}) {
103048
103048
  const profileDir = await (0, import_promises.mkdtemp)((0, import_node_path.join)((0, import_node_os.tmpdir)(), "talos-lo-profile-"));
103049
103049
  const outDir = await (0, import_promises.mkdtemp)((0, import_node_path.join)((0, import_node_os.tmpdir)(), "talos-lo-out-"));
103050
103050
  try {
103051
+ if (isMacAppSoffice(soffice)) {
103052
+ await (0, import_promises.mkdir)((0, import_node_path.join)(profileDir, "user"), { recursive: true });
103053
+ await (0, import_promises.writeFile)((0, import_node_path.join)(profileDir, "user", "registrymodifications.xcu"), macFontReplacementXcu(missingWebFonts()));
103054
+ }
103051
103055
  await runSoffice(soffice, [
103052
103056
  "--headless",
103053
103057
  "--norestore",
@@ -103073,6 +103077,83 @@ async function convertToPdfViaSoffice(inputPath, options = {}) {
103073
103077
  });
103074
103078
  }
103075
103079
  }
103080
+ function isMacAppSoffice(bin, platform = process.platform) {
103081
+ if (platform !== "darwin")
103082
+ return false;
103083
+ let real = bin;
103084
+ try {
103085
+ real = (0, import_node_fs.realpathSync)(bin);
103086
+ } catch {
103087
+ }
103088
+ return /\.app\/Contents\/MacOS\/soffice(\.bin)?$/.test(real);
103089
+ }
103090
+ var MAC_CJK_FONT_REPLACEMENT_XCU = `<?xml version="1.0" encoding="UTF-8"?>
103091
+ <oor:items xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
103092
+ <item oor:path="/org.openoffice.Office.Common/Font/Substitution"><prop oor:name="Replacement" oor:op="fuse"><value>true</value></prop></item>
103093
+ <item oor:path="/org.openoffice.Office.Common/Font/Substitution/FontPairs"><node oor:name="_0" oor:op="replace"><prop oor:name="Always" oor:op="fuse"><value>true</value></prop><prop oor:name="OnScreenOnly" oor:op="fuse"><value>false</value></prop><prop oor:name="ReplaceFont" oor:op="fuse"><value>Microsoft YaHei</value></prop><prop oor:name="SubstituteFont" oor:op="fuse"><value>\u51AC\u9752\u9ED1\u4F53\u7B80\u4F53\u4E2D\u6587</value></prop></node><node oor:name="_1" oor:op="replace"><prop oor:name="Always" oor:op="fuse"><value>true</value></prop><prop oor:name="OnScreenOnly" oor:op="fuse"><value>false</value></prop><prop oor:name="ReplaceFont" oor:op="fuse"><value>Microsoft JhengHei</value></prop><prop oor:name="SubstituteFont" oor:op="fuse"><value>\u9ED1\u4F53-\u7E41</value></prop></node></item>
103094
+ </oor:items>
103095
+ `;
103096
+ var SANS = { group: "sans", mac: "Arial", cloud: "Liberation Sans" };
103097
+ var SERIF_TIMES = { group: "serif", mac: "Times New Roman", cloud: "Liberation Serif" };
103098
+ var SERIF_GEORGIA = { group: "serif", mac: "Georgia", cloud: "Liberation Serif" };
103099
+ var CONDENSED = { group: "display", mac: "Arial Narrow", cloud: "Liberation Sans Narrow" };
103100
+ var WEB_FONT_SUBSTITUTES = {
103101
+ // sans — the neutral grotesques
103102
+ "Inter": SANS,
103103
+ "Jost": SANS,
103104
+ "Public Sans": SANS,
103105
+ "Manrope": SANS,
103106
+ "Karla": SANS,
103107
+ "Sora": SANS,
103108
+ "IBM Plex Sans": SANS,
103109
+ "Archivo": SANS,
103110
+ "Space Grotesk": SANS,
103111
+ "Quicksand": SANS,
103112
+ "Lexend": SANS,
103113
+ "Nunito": SANS,
103114
+ // serif
103115
+ "Playfair Display": SERIF_TIMES,
103116
+ "Bodoni Moda": SERIF_TIMES,
103117
+ "Zilla Slab": SERIF_TIMES,
103118
+ "Fraunces": SERIF_TIMES,
103119
+ "Cormorant Garamond": SERIF_TIMES,
103120
+ "Lora": SERIF_GEORGIA,
103121
+ "Marcellus": SERIF_GEORGIA,
103122
+ "DM Serif Display": SERIF_GEORGIA,
103123
+ // display
103124
+ "Anton": CONDENSED,
103125
+ "Big Shoulders Display": CONDENSED,
103126
+ "Syne": { group: "display", mac: "Arial", cloud: "Liberation Sans" },
103127
+ "Chakra Petch": { group: "display", mac: "Arial", cloud: "Liberation Sans" },
103128
+ "Gochi Hand": { group: "display", mac: "Noteworthy", cloud: "Liberation Sans" }
103129
+ };
103130
+ var WEB_GROTESQUE_FAMILIES = Object.keys(WEB_FONT_SUBSTITUTES).filter((f) => WEB_FONT_SUBSTITUTES[f].group === "sans");
103131
+ var MAC_FONT_DIRS = ["/System/Library/Fonts", "/System/Library/Fonts/Supplemental", "/Library/Fonts"];
103132
+ function missingWebFonts(fontFiles = macFontFiles()) {
103133
+ const names = fontFiles.map((f) => (0, import_node_path.basename)(f).toLowerCase());
103134
+ return Object.keys(WEB_FONT_SUBSTITUTES).filter((family) => {
103135
+ const stem = family.replace(/\s+/g, "").toLowerCase();
103136
+ return !names.some((n) => n.startsWith(stem) && /^[-_. \[]/.test(n.slice(stem.length)));
103137
+ });
103138
+ }
103139
+ function macFontFiles() {
103140
+ const dirs = [...MAC_FONT_DIRS, (0, import_node_path.join)(process.env.HOME ?? "", "Library/Fonts")];
103141
+ const out = [];
103142
+ for (const d of dirs) {
103143
+ try {
103144
+ out.push(...(0, import_node_fs.readdirSync)(d));
103145
+ } catch {
103146
+ }
103147
+ }
103148
+ return out;
103149
+ }
103150
+ var fontPair = (i, from, to) => `<node oor:name="_${i}" oor:op="replace"><prop oor:name="Always" oor:op="fuse"><value>true</value></prop><prop oor:name="OnScreenOnly" oor:op="fuse"><value>false</value></prop><prop oor:name="ReplaceFont" oor:op="fuse"><value>${from}</value></prop><prop oor:name="SubstituteFont" oor:op="fuse"><value>${to}</value></prop></node>`;
103151
+ function macFontReplacementXcu(missing) {
103152
+ if (!missing.length)
103153
+ return MAC_CJK_FONT_REPLACEMENT_XCU;
103154
+ const extra = missing.map((f, i) => fontPair(i + 2, f, WEB_FONT_SUBSTITUTES[f]?.mac ?? "Arial")).join("");
103155
+ return MAC_CJK_FONT_REPLACEMENT_XCU.replace("</node></item>", `</node>${extra}</item>`);
103156
+ }
103076
103157
  function runSoffice(bin, args, timeoutMs) {
103077
103158
  return new Promise((resolve, reject2) => {
103078
103159
  const child = (0, import_node_child_process.spawn)(bin, args, { stdio: ["ignore", "pipe", "pipe"] });
@@ -103180,6 +103261,11 @@ async function fontManifest() {
103180
103261
  }
103181
103262
  return _fontManifest;
103182
103263
  }
103264
+ var _faceB64 = /* @__PURE__ */ new Map();
103265
+ async function faceBase64(path) {
103266
+ if (!_faceB64.has(path)) _faceB64.set(path, (await (0, import_promises2.readFile)(path).catch(() => null))?.toString("base64") ?? null);
103267
+ return _faceB64.get(path);
103268
+ }
103183
103269
  async function faceCss(entries, range2, doc) {
103184
103270
  const { dir } = await fontManifest();
103185
103271
  const rules = [];
@@ -103188,7 +103274,7 @@ async function faceCss(entries, range2, doc) {
103188
103274
  if (!families.length) continue;
103189
103275
  const path = (0, import_node_path2.join)(dir, entry.file);
103190
103276
  if (!(0, import_node_fs2.existsSync)(path)) continue;
103191
- const b64 = (await (0, import_promises2.readFile)(path).catch(() => null))?.toString("base64");
103277
+ const b64 = await faceBase64(path);
103192
103278
  if (!b64) continue;
103193
103279
  for (const family of families) {
103194
103280
  rules.push(
@@ -103198,22 +103284,21 @@ async function faceCss(entries, range2, doc) {
103198
103284
  }
103199
103285
  return rules.join("");
103200
103286
  }
103201
- var _cjkFontCss;
103287
+ var _faceCssBySet = /* @__PURE__ */ new Map();
103288
+ async function cachedFaceCss(group2, entries, range2, doc) {
103289
+ const named = (entries ?? []).flatMap((e) => (e.families ?? []).filter((f) => doc.includes(f)));
103290
+ const key = `${group2}|${named.join("|")}`;
103291
+ if (!_faceCssBySet.has(key)) _faceCssBySet.set(key, await faceCss(entries, range2, doc));
103292
+ return _faceCssBySet.get(key);
103293
+ }
103202
103294
  async function cjkFontFaceCss(doc) {
103203
- if (_cjkFontCss === void 0) {
103204
- const m = await fontManifest();
103205
- _cjkFontCss = await faceCss(m.cjk, m.cjkUnicodeRange, doc);
103206
- }
103207
- return _cjkFontCss;
103295
+ if (process.env.TALOS_CJK_FONTS === "system") return "";
103296
+ const m = await fontManifest();
103297
+ return cachedFaceCss("cjk", m.cjk, m.cjkUnicodeRange, doc);
103208
103298
  }
103209
- var _latinFontCss;
103210
103299
  async function latinFontFaceCss(doc) {
103211
- if (_latinFontCss === void 0) {
103212
- const m = await fontManifest();
103213
- const wanted = (m.latin ?? []).filter((e) => (e.families ?? []).some((f) => doc.includes(f)));
103214
- _latinFontCss = await faceCss(wanted, void 0);
103215
- }
103216
- return _latinFontCss;
103300
+ const m = await fontManifest();
103301
+ return cachedFaceCss("latin", m.latin, void 0, doc);
103217
103302
  }
103218
103303
  function injectStyle(html, css) {
103219
103304
  const tag = `<style>${css}</style>`;
@@ -103300,32 +103385,29 @@ async function renderViaSoffice(input, cachePath) {
103300
103385
  });
103301
103386
  return { bytes, cached: false };
103302
103387
  } catch (e) {
103303
- process.stderr.write(`doc-convert: LibreOffice failed (${e.message}); falling back to HTML render
103304
- `);
103305
- return null;
103388
+ return { failed: `LibreOffice failed (${e.message})` };
103306
103389
  }
103307
103390
  }
103308
103391
  async function renderViaOfficeService(input, raw) {
103309
103392
  const url = process.env.TALOS_OFFICE_URL;
103310
103393
  if (!url) return null;
103311
103394
  try {
103312
- return await convertViaOfficeService(raw, (0, import_node_path3.basename)(input), url, {
103395
+ return { bytes: await convertViaOfficeService(raw, (0, import_node_path3.basename)(input), url, {
103313
103396
  token: process.env.TALOS_OFFICE_TOKEN,
103314
103397
  timeoutMs: 12e4
103315
- });
103398
+ }) };
103316
103399
  } catch (e) {
103317
- process.stderr.write(`doc-convert: office service failed (${e.message}); falling back
103318
- `);
103319
- return null;
103400
+ return { failed: `office service failed (${e.message})` };
103320
103401
  }
103321
103402
  }
103322
103403
  async function main() {
103323
103404
  const args = process.argv.slice(2);
103405
+ const requireOffice = args.includes("--require-office");
103324
103406
  const cacheIdx = args.indexOf("--cache-dir");
103325
103407
  const cacheDir = cacheIdx >= 0 ? args[cacheIdx + 1] : process.env.TALOS_OFFICE_CACHE_DIR;
103326
- const consumed = /* @__PURE__ */ new Set([cacheIdx, cacheIdx >= 0 ? cacheIdx + 1 : -1]);
103408
+ const consumed = /* @__PURE__ */ new Set([cacheIdx, cacheIdx >= 0 ? cacheIdx + 1 : -1, args.indexOf("--require-office")]);
103327
103409
  const [input, out] = args.filter((_4, i) => !consumed.has(i));
103328
- if (!input || !out) die("usage: doc-convert <in.docx|pptx|xlsx> <out.pdf> [--cache-dir <dir>]", 64);
103410
+ if (!input || !out) die("usage: doc-convert <in.docx|pptx|xlsx> <out.pdf> [--cache-dir <dir>] [--require-office]", 64);
103329
103411
  if (cacheIdx >= 0 && !cacheDir) die("--cache-dir requires a directory", 64);
103330
103412
  if (!/\.pdf$/i.test(out)) die("output must be a .pdf path", 64);
103331
103413
  let raw;
@@ -103336,20 +103418,29 @@ async function main() {
103336
103418
  }
103337
103419
  const buffer = raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength);
103338
103420
  const cachePath = await faithfulCachePath(cacheDir, input, raw).catch((e) => die(`cannot prepare cache: ${e.message}`, 73));
103421
+ const failures = [];
103339
103422
  const loResult = await renderViaSoffice(input, cachePath);
103340
- if (loResult) {
103423
+ if (loResult?.bytes) {
103341
103424
  await (0, import_promises3.writeFile)(out, Buffer.from(loResult.bytes));
103342
103425
  process.stdout.write(`wrote ${out} [pdf (libreoffice${loResult.cached ? ", cache hit" : ""})]
103343
103426
  `);
103344
103427
  return;
103345
103428
  }
103346
- const svcBytes = await renderViaOfficeService(input, raw);
103347
- if (svcBytes) {
103348
- await (0, import_promises3.writeFile)(out, Buffer.from(svcBytes));
103429
+ if (loResult?.failed) failures.push(loResult.failed);
103430
+ const svc = await renderViaOfficeService(input, raw);
103431
+ if (svc?.bytes) {
103432
+ await (0, import_promises3.writeFile)(out, Buffer.from(svc.bytes));
103349
103433
  process.stdout.write(`wrote ${out} [pdf (libreoffice service)]
103350
103434
  `);
103351
103435
  return;
103352
103436
  }
103437
+ if (svc?.failed) failures.push(svc.failed);
103438
+ if (requireOffice) {
103439
+ if (failures.length) die(`${failures.join("; ")} \u2014 --require-office does not fall back to a Chromium reconstruction (its layout is not Office's); retry, a timeout under load is the usual cause`, 75);
103440
+ die("--require-office: no LibreOffice engine here (no local soffice, TALOS_OFFICE_URL unset) \u2014 only a Chromium reconstruction is available, which is not an Office render", 69);
103441
+ }
103442
+ for (const f of failures) process.stderr.write(`doc-convert: ${f}; falling back to HTML render
103443
+ `);
103353
103444
  if (/\.(xlsx|xls|ods)$/i.test(input)) {
103354
103445
  die("xlsx\u2192PDF \u9700\u8981\u672C\u673A LibreOffice \u6216 TALOS_OFFICE_URL sidecar,\u5F53\u524D\u90FD\u4E0D\u53EF\u7528", 69);
103355
103446
  }