@taloswork/ose-shared 0.1.12 → 0.1.14

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 (71) hide show
  1. package/package.json +3 -3
  2. package/skills/document/SKILL.md +33 -45
  3. package/skills/document/bin/deck-build.cjs +10482 -272
  4. package/skills/document/bin/deck-chart.cjs +21 -12
  5. package/skills/document/bin/deck-plan.cjs +11654 -42
  6. package/skills/document/bin/deck-qa.cjs +107 -23
  7. package/skills/document/bin/deck-scenario.cjs +20 -3
  8. package/skills/document/bin/deck-styles.cjs +1604 -0
  9. package/skills/document/bin/doc-convert.cjs +200 -260
  10. package/skills/document/bin/doc-fill.cjs +140 -19
  11. package/skills/document/bin/doc-gen.cjs +1909 -282
  12. package/skills/document/bin/doc-scan.cjs +6 -1
  13. package/skills/document/bin/doc-text.cjs +6 -1
  14. package/skills/document/bin/doc-validate.cjs +139 -54
  15. package/skills/document/bin/docx-defaults.cjs +9907 -0
  16. package/skills/document/bin/html2pptx.cjs +35960 -31973
  17. package/skills/document/bin/pdf-form.cjs +14 -1
  18. package/skills/document/bin/pdf-images.cjs +6 -1
  19. package/skills/document/bin/pdf-ops.cjs +14 -1
  20. package/skills/document/bin/pdf-render.cjs +6 -1
  21. package/skills/document/bin/pdf-tables.cjs +6 -1
  22. package/skills/document/bin/pptx-notes.cjs +10038 -0
  23. package/skills/document/bin/pptx-tokenize.cjs +19 -4
  24. package/skills/document/bin/template-skin.cjs +10915 -0
  25. package/skills/document/bin-reference.md +15 -10
  26. package/skills/document/catalog.json +33 -32
  27. package/skills/document/content-pipeline.md +79 -44
  28. package/skills/document/deck-design.md +55 -32
  29. package/skills/document/generated-visuals.md +99 -0
  30. package/skills/document/layouts/MAINTAINERS.md +33 -0
  31. package/skills/document/layouts/README.md +20 -20
  32. package/skills/document/layouts/big-stat.tpl +1 -1
  33. package/skills/document/layouts/capacity.json +1 -1
  34. package/skills/document/layouts/cards-3.tpl +1 -1
  35. package/skills/document/layouts/chart-full.tpl +1 -1
  36. package/skills/document/layouts/chart-kpi.tpl +1 -1
  37. package/skills/document/layouts/comparison.tpl +1 -1
  38. package/skills/document/layouts/data-table.tpl +1 -1
  39. package/skills/document/layouts/funnel.tpl +1 -1
  40. package/skills/document/layouts/gantt.tpl +1 -1
  41. package/skills/document/layouts/hub-flow.tpl +4 -0
  42. package/skills/document/layouts/icon-row.tpl +1 -1
  43. package/skills/document/layouts/image-grid.tpl +1 -1
  44. package/skills/document/layouts/matrix-2x2.tpl +1 -1
  45. package/skills/document/layouts/mock-qa.tpl +4 -0
  46. package/skills/document/layouts/profiles.json +2 -2
  47. package/skills/document/layouts/pyramid.tpl +1 -1
  48. package/skills/document/layouts/radar.tpl +1 -1
  49. package/skills/document/layouts/ring-progress.tpl +1 -1
  50. package/skills/document/layouts/slots.json +1 -1
  51. package/skills/document/layouts/steps-vertical.tpl +1 -1
  52. package/skills/document/layouts/steps.tpl +1 -1
  53. package/skills/document/layouts/three-kpi.tpl +1 -1
  54. package/skills/document/layouts/timeline.tpl +1 -1
  55. package/skills/document/layouts/toc-panel.tpl +1 -1
  56. package/skills/document/layouts/two-kpi.tpl +2 -2
  57. package/skills/document/layouts/versus.tpl +1 -1
  58. package/skills/document/packs/README.md +1 -1
  59. package/skills/document/pdf.md +13 -0
  60. package/skills/document/rewrite.md +23 -8
  61. package/skills/document/scenarios.json +19 -2
  62. package/skills/document/scenarios.schema.json +1 -0
  63. package/skills/document/styles/_backdrops/rimlight.html +3 -2
  64. package/skills/document/styles/_contract-defaults.css +6 -1
  65. package/skills/document/styles/_samples/_groups/biz-premium.webp +0 -0
  66. package/skills/document/styles/_samples/mckinsey.webp +0 -0
  67. package/skills/document/styles/mckinsey/backdrop.html +7 -5
  68. package/skills/grill-me/SKILL.md +6 -0
  69. package/skills/grill-me/agents/openai.yaml +5 -0
  70. package/skills/grilling/SKILL.md +28 -0
  71. package/skills/grilling/agents/openai.yaml +3 -0
@@ -5,8 +5,8 @@
5
5
  - New .docx / .pdf / .xlsx → **Generate** (lines 14–55); a formula in a workbook → also **Formulas** (lines 57–73); a particular look, theme or brand → also **Themes** (lines 75–125)
6
6
  - Fill a `{{placeholder}}` .docx / .pptx / .xlsx template → **Fill a template** (lines 127–146)
7
7
  - Change an existing .docx — text, structure, comments, tracked changes → **Edit an existing .docx** (lines 148–199)
8
- - New content in an existing deck's look, or restructure a .pptx → **Template decks** (lines 201–271)
9
- - Nothing above fits → **Custom scripts** (lines 273–293)
8
+ - New content in an existing deck's look, or restructure a .pptx → **Template decks** (lines 201–281)
9
+ - Nothing above fits → **Custom scripts** (lines 283–308)
10
10
 
11
11
  A PDF's forms, page ops and stamps are in pdf.md; a deck from scratch is the deck route
12
12
  (SKILL.md) — `doc-gen` makes no decks. `<skill>` below is this skill's directory.
@@ -200,27 +200,29 @@ Pick the least lossy path, and tell the user which trade-off you took:
200
200
 
201
201
  ## Template decks — fill or restructure an existing .pptx
202
202
 
203
- **Which tool**: keep an uploaded deck's LAYOUTS for new content → `pptx-tokenize` →
204
- `doc-fill`; repeat one styled slide per data item → `pptx-clone`; add, duplicate, drop or
203
+ **Which tool**: a template's STYLE → `template-skin` (deck-design.md "Custom skins");
204
+ its ORIGINAL PAGES refilled, only when asked → `pptx-tokenize` → `doc-fill`; repeat one styled slide per data item → `pptx-clone`; add, duplicate, drop or
205
205
  reorder slides → `pptx-slide`; only its COLOURS → `pptx-theme` into a user skin
206
206
  (deck-design.md "Custom skins"). Always `doc-validate` the result, then render-and-look.
207
207
 
208
208
  ### Reuse an uploaded deck — `pptx-tokenize` → `doc-fill`
209
209
 
210
- Only when the user chose the deck as their **style** (the picker's "使用我的模板文件"); a
211
- deck handed in as **content** is read for its text and authored fresh in the chosen skin.
210
+ Only when the user wants the deck's ORIGINAL PAGES refilled ("就用原页面改字"). A deck
211
+ chosen as a **style** (the picker's "使用我的模板文件") goes through `template-skin`
212
+ (deck-design.md "Custom skins"). On this route: never restyle text globally (font, size,
213
+ colour), never remove the template's logo, footer or other fixed elements without asking.
212
214
 
213
215
  1. **Tokenize** — every content slot's text (placeholders and plain text boxes) becomes a
214
216
  clean single-run `{{token}}`; styling/master/layouts stay verbatim:
215
217
  ```
216
218
  node <skill>/bin/pptx-tokenize.cjs user.pptx template.pptx schema.json
217
219
  ```
218
- `schema.json` = `{ slides: [{ index, tokens: [{ token, role, type, multiline?,
220
+ `schema.json` = `{ slides: [{ index, tokens: [{ token, role, type, multiline?, leadStyle?,
219
221
  original?, capacityChars?, rel? }] }] }` — `role` is title / subtitle / body / text /
220
222
  pic / chart; `type` is `text`, `image` or `chart`.
221
223
  2. **Fill** — `values.json` has one key per `text` token (the key is the token name, no
222
224
  braces). **Fill EVERY token**: a slot you keep gets its `original` back (an unfilled
223
- token renders EMPTY). `multiline:true` takes a `\n`-joined string. Respect
225
+ token renders EMPTY). `multiline:true` takes a `\n`-joined string (each line becomes a paragraph). `leadStyle:true` = a bold lead line + body: fill `lead\nbody…` — line 1 takes the lead style, the rest the body style; a single line makes the whole paragraph the lead style. Respect
224
226
  `capacityChars` (CJK-width units; a Latin letter ≈ ½) — rewrite shorter rather than
225
227
  overflow. `unfilled` in the output names tokens you missed — add them and refill.
226
228
  ```
@@ -233,6 +235,14 @@ deck handed in as **content** is read for its text and authored fresh in the cho
233
235
  The frame stays put; a different aspect ratio STRETCHES — pre-crop to the slot's ratio.
234
236
  4. **Charts** keep the source deck's embedded data (`type:"chart"`, not a fill token) —
235
237
  edit the chart part separately, or tell the user the numbers are still theirs.
238
+ 5. **Speaker notes** — one call, never hand-written notes XML:
239
+ ```
240
+ node <skill>/bin/pptx-notes.cjs final.pptx notes.json final.pptx
241
+ # notes.json: { "1": "开场定位…", "3": "来源:…" } (slide positions as shown)
242
+ ```
243
+ A hand-written notes slide (2026-10-08: a body placeholder, no `<p:clrMapOvr>`) opened
244
+ in PowerPoint and LibreOffice and made Keynote refuse the whole file.
245
+ 6. **Sign off** with `doc-validate --strict`.
236
246
 
237
247
  ### One styled slide per data item — `pptx-clone`
238
248
 
@@ -291,3 +301,8 @@ other package, never `npm install`. Theme the output by reading a theme JSON you
291
301
  Order of escalation: built-in verbs → `doc-run` → raw XML (`doc-xml`). Custom code has no
292
302
  safety net but the gate: **`doc-validate --strict` every file it produces** (the full
293
303
  ECMA-376 schema check).
304
+
305
+ A .docx from a `docx` script lacks a default paragraph style (docx.js writes none), and
306
+ Pages then lays every body paragraph out like the heading before it (huge, centred):
307
+ run `bin/docx-defaults.cjs <out.docx> <out.docx>` on it — `doc-validate` fails it as
308
+ `docx-default-style` until you do. A plain document → `doc-gen`, which already has it.
@@ -10,8 +10,8 @@
10
10
  "故事驱动"
11
11
  ],
12
12
  "density": [
13
- "稀疏",
14
- "大数字"
13
+ "中",
14
+ "大数字+一句解释"
15
15
  ],
16
16
  "requiredSections": [
17
17
  {
@@ -487,6 +487,11 @@
487
487
  {
488
488
  "id": "工作汇报",
489
489
  "subtitle": "周月季报",
490
+ "aliases": [
491
+ "周报",
492
+ "月报",
493
+ "季报"
494
+ ],
490
495
  "tone": [
491
496
  "客观",
492
497
  "简洁",
@@ -609,6 +614,9 @@
609
614
  },
610
615
  {
611
616
  "id": "项目立项/评审",
617
+ "aliases": [
618
+ "立项"
619
+ ],
612
620
  "tone": [
613
621
  "严谨",
614
622
  "说服"
@@ -678,6 +686,9 @@
678
686
  },
679
687
  {
680
688
  "id": "年度总结/年会",
689
+ "aliases": [
690
+ "年终总结"
691
+ ],
681
692
  "tone": [
682
693
  "振奋",
683
694
  "仪式感"
@@ -881,6 +892,9 @@
881
892
  },
882
893
  {
883
894
  "id": "政务/党政汇报",
895
+ "aliases": [
896
+ "政务汇报"
897
+ ],
884
898
  "tone": [
885
899
  "严肃",
886
900
  "规范"
@@ -941,6 +955,9 @@
941
955
  },
942
956
  {
943
957
  "id": "公司/产品介绍",
958
+ "aliases": [
959
+ "公司介绍"
960
+ ],
944
961
  "tone": [
945
962
  "品牌",
946
963
  "自信",
@@ -24,6 +24,7 @@
24
24
  "properties": {
25
25
  "id": { "$ref": "#/$defs/text", "description": "Scenario name as the clarify gate records it; no whitespace." },
26
26
  "subtitle": { "$ref": "#/$defs/text", "description": "Alias / gloss shown after the bold id in the md row." },
27
+ "aliases": { "$ref": "#/$defs/textList", "description": "Other names users call it (周报, 年终总结) that id and subtitle do not split into — findScenario only, not in the md row." },
27
28
  "tone": { "$ref": "#/$defs/textList" },
28
29
  "density": { "$ref": "#/$defs/textList" },
29
30
  "densityEmphasis": { "type": "boolean" },
@@ -3,5 +3,6 @@
3
3
  (渐变两端渐隐 + feGaussianBlur 打底,跟皮肤默认线 _lines/arc-band.html 同款,包进 .bd-arc,可被
4
4
  --line 摘除/替换)。原先用"中心透明→边缘上色"的反向径向渐变会在画面中央糊出一圈突兀的暗色椭圆,
5
5
  已弃用,改成方向性更清楚的顶部通栏衰减。变量驱动(__ACCENT__ 自动上色)、明暗中性,可原样复制到
6
- 任意 styles/<skin>/。 -->
7
- <svg width="1280" height="720" viewBox="0 0 1280 720" style="position:absolute;inset:0;pointer-events:none"><defs><linearGradient id="rlg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".22"/><stop offset=".16" stop-color="__ACCENT__" stop-opacity=".08"/><stop offset=".38" stop-color="__ACCENT__" stop-opacity="0"/></linearGradient></defs><rect width="1280" height="720" fill="url(#rlg)"/></svg><div class="bd-arc" style="position:absolute;inset:0;pointer-events:none"><svg width="100%" height="100%" viewBox="0 0 1280 720"><defs><linearGradient id="rll" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".16"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".42"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".16"/></linearGradient><filter id="rllb"><feGaussianBlur stdDeviation="1.2"/></filter></defs><path d="M-80 8 C 300 2,980 2,1360 8" fill="none" stroke="url(#rll)" stroke-width="1.8" filter="url(#rllb)"/><path d="M-80 8 C 300 2,980 2,1360 8" fill="none" stroke="url(#rll)" stroke-width=".8"/></svg></div>
6
+ 任意 styles/<skin>/。高光边线离顶边 24–32px(贴着顶边 2–8px 时读起来像没对齐的边框),
7
+ 透明度 __LINE_ALPHA__ 由 html2pptx 按强调色亮度填(白色/浅色强调色调低,深色保持)。 -->
8
+ <svg width="1280" height="720" viewBox="0 0 1280 720" style="position:absolute;inset:0;pointer-events:none"><defs><linearGradient id="rlg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".22"/><stop offset=".16" stop-color="__ACCENT__" stop-opacity=".08"/><stop offset=".38" stop-color="__ACCENT__" stop-opacity="0"/></linearGradient></defs><rect width="1280" height="720" fill="url(#rlg)"/></svg><div class="bd-arc" style="position:absolute;inset:0;pointer-events:none;opacity:__LINE_ALPHA__"><svg width="100%" height="100%" viewBox="0 0 1280 720"><defs><linearGradient id="rll" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".16"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".42"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".16"/></linearGradient><filter id="rllb"><feGaussianBlur stdDeviation="1.2"/></filter></defs><path d="M-80 32 C 300 24,980 24,1360 32" fill="none" stroke="url(#rll)" stroke-width="1.8" filter="url(#rllb)"/><path d="M-80 32 C 300 24,980 24,1360 32" fill="none" stroke="url(#rll)" stroke-width=".8"/></svg></div>
@@ -28,7 +28,7 @@
28
28
  `.cmp-col` 规则里定了边(同特异性、位置在后),仍然赢过兜底。
29
29
  改完必须重跑 `node scripts/deck/deck-fidelity.mjs`(它现在会注入本文件,此前不注入,
30
30
  所以这个文件曾经完全在像素闸门的视野之外),并按
31
- `.claude/skills/ppt-tpl-prod/SKILL.md`"改 _contract-defaults.css"一节做
31
+ `docs/ppt-template-tooling.md`"改 _contract-defaults.css"一节做
32
32
  注入/不注入的对照渲染 —— deck-fidelity 的 32x18 签名对这类细微改动不够敏感。 */
33
33
 
34
34
  /* compare */
@@ -77,3 +77,8 @@
77
77
  .gantt-bar{background:var(--c1)}
78
78
  .map-pin{background:var(--accent)}
79
79
  .ring-fill{stroke:var(--accent)}
80
+ /* 可阅读型内容页(2026-10-09):标题下的口径/副标题行与页底的「启示」条。新选择器,
81
+ 没有任何现役皮肤定义它们;槽位为空时整块不渲染,不改变既有版式的观感。 */
82
+ .deck-subhead{color:var(--muted)}
83
+ .deck-takeaway{color:var(--title);border-left:3px solid var(--accent)}
84
+ .deck-subhead:empty,.deck-takeaway:empty{display:none}
@@ -1,5 +1,7 @@
1
- <!-- signature: the consulting binder — a solid top rule with a file-tab stub, the
2
- four-piece chrome deck-design.md calls the strongest "consulting-grade" signal. -->
3
- <div style="position:absolute;left:0;right:0;top:0;height:5px;background:var(--accent);opacity:.92;pointer-events:none"></div>
4
- <div style="position:absolute;left:0;top:0;width:60px;height:16px;background:var(--accent);pointer-events:none"></div>
5
- <div style="position:absolute;right:56px;top:34px;bottom:34px;width:1px;background:var(--hair);pointer-events:none"></div>
1
+ <!-- signature: a soft accent glow from the top-right corner over white, a faint grey
2
+ vignette at the foot — nothing else.
3
+ 2026-10-09 (user's call): replaces the consulting-binder chrome this skin carried
4
+ since 7306d8e5 (a 5px full-width top rule, a 60×16 file-tab stub, a right-edge
5
+ hairline). The glow is the 2026-07-22 shared backdrop's, without its two bottom
6
+ curves. A deliberate change to the frozen classic-v1 look of original-13. -->
7
+ <svg width="1280" height="720" viewBox="0 0 1280 720" style="position:absolute;inset:0;pointer-events:none" preserveAspectRatio="none"><defs><radialGradient id="bsg" cx="86%" cy="6%" r="54%"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".16"/><stop offset="1" stop-color="__ACCENT__" stop-opacity="0"/></radialGradient></defs><rect width="1280" height="720" fill="url(#bsg)"/></svg><div style="position:absolute;inset:0;background:radial-gradient(130% 92% at 50% 128%,rgba(127,127,127,.10),transparent 46%);pointer-events:none"></div>
@@ -0,0 +1,6 @@
1
+ ---
2
+ name: grill-me
3
+ description: A relentless interview to sharpen a plan or design.
4
+ ---
5
+
6
+ Call load_skill with name "grilling".
@@ -0,0 +1,5 @@
1
+ interface:
2
+ display_name: "Grill Me"
3
+ short_description: "Sharpen a plan through interview"
4
+ policy:
5
+ allow_implicit_invocation: false
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: grilling
3
+ description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
4
+ ---
5
+
6
+ Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it.
7
+
8
+ Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
9
+
10
+ Format a round like so:
11
+
12
+ ```
13
+ ❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
14
+
15
+ ➡️ <your recommended answer>
16
+
17
+ ---
18
+
19
+ ❓ **Q2** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
20
+
21
+ ➡️ <your recommended answer>
22
+ ```
23
+
24
+ Each round the user answers reshapes the tree: settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one.
25
+
26
+ Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it; don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report; ask the rest of the frontier now. The _decisions_ are the user's: put each to them and wait.
27
+
28
+ The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "Grilling"
3
+ short_description: "Stress-test thinking a round of questions at a time"