[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F1MZEG3FBCAHNSP3GR7RQ6":3,"skill-same:01M6F1MZEG3FBCAHNSP3GR7RQ6":52},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":24,"linkOnly":25,"markdownContent":26,"markdownBody":27,"frontMatter":28,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":33,"repositoryHtmlUrl":34,"repositoryHomepageUrl":35,"ownerHtmlUrl":36,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":37,"install":38,"resources":51},"01M6F1MZEG3FBCAHNSP3GR7RQ6","book_chapter.update_from_source",null,"Update a book's content to match changes in its source file","causify-ai\u002Fhelpers","causify-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F121828442?v=4","01M6BZFTHW2MQR7FWK8CDW0DRA","Causify.AI","01M6F1K6CCKKF8YKTBN4ZV509G",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Fbook_chapter.update_from_source\u002FSKILL.md",[],[19,20,21,22,23],"update","book chapter update from source","content","file","match","2026-11-10 10:12:30",false,"---\ndescription: Update a book's content to match changes in its source file\nmodel: opus\n---\n\n# Goal\n- Given the content of a book in the form of a markdown or tex file `\u003CTARGET>` and\n  a source file `\u003CSOURCE>`, find and incorporate the changes from `\u003CSOURCE>` into\n  `\u003CTARGET>`\n\n# Workflow\n\n## Read the Version Header\n- The file `\u003CSOURCE>` contains a header with the last version, in terms of Git hash\n  and timestamp, of the material used to generate the current version of\n  `\u003CTARGET>`\n  - E.g.,\n    ```text\n    % git_hash=\u003CGIT_HASH>, timestamp=\u003CTIMESTAMP>\n    % \u003CSOURCE>\n    ```\n  - E.g.,\n    ```text\n    % git_hash=f15bc6b9, timestamp=2026-07-15 14:41:12 EDT\n    % book_springer\u002Flectures_source\u002FLesson02.1_From_Data_Science_To_Decision_Science.txt\n    ```\n- Get the diff of `\u003CSOURCE>` since `\u003CGIT_HASH>` once, up front, instead of re-diffing\n  piecemeal per section:\n  ```bash\n  > git diff \u003CGIT_HASH> -- \u003CSOURCE>\n  ```\n\n## Incorporate Changes\n- Find what changed in `\u003CSOURCE>` from `\u003CGIT_HASH>` to now, and modify `\u003CTARGET>` to\n  incorporate those changes\n- Follow the same style as `\u003CTARGET>` (e.g., read the corresponding\n  `.claude\u002Fskills\u002F*.rules.md`)\n- `\u003CTARGET>` is allowed to be a superset of `\u003CSOURCE>` (e.g., a `.typ` book chapter\n  routinely has headings, diagrams, or explanatory paragraphs that group or expand\n  several flat `.smd` slides, per `typst.rules.md`'s \"Structural Hierarchy\"). When\n  `\u003CSOURCE>` drops a heading or a diagram that `\u003CTARGET>` already built on, do not\n  delete the corresponding `\u003CTARGET>` content just because it no longer has a direct\n  counterpart: only remove it if the diff shows the underlying fact\u002Fexample was\n  itself changed or retracted, not merely reorganized out of the slide deck\n- Update the header at the top of `\u003CTARGET>` to the new hash\u002Ftimestamp once done:\n  ```text\n  \u002F\u002F git_hash=\u003CNEW_GIT_HASH> timestamp=\u003CNEW_TIMESTAMP>\n  ```\n\n## Compare Entire Flow\n- Make sure the flow of the `\u003CTARGET>` book chapter (in typst, latex, md format)\n  follows the flow of the `\u003CSOURCE>`\n- E.g., you can run `extract_toc_from_txt.py` on `\u003CSOURCE>` and `\u003CTARGET>` and\n  compare\n  ```bash\n  > extract_toc_from_txt.py -i msml610\u002Flectures_source\u002FLesson03.3-Non_classical_logics.smd\n\n  > extract_toc_from_txt.py -i msml610\u002Fbook\u002FLesson03.3-Non_classical_logics.typ\n  ```\n- Ensure that the flow of `\u003CTARGET>` is consistent with `\u003CSOURCE>`\n\n## Update Source-Line References\n- A `.typ` `\u003CTARGET>` carries a `\u002F\u002F From: \u003CSOURCE>:\u003CLINE> '\u003Cslide title>'` comment\n  above each section, pointing at the exact `\u003CSOURCE>` line it was generated from\n- Any edit to `\u003CSOURCE>` above a given slide shifts every later line number: after\n  incorporating the changes, re-walk `\u003CTARGET>`'s `\u002F\u002F From:` comments top to bottom\n  and update each `\u003CLINE>` to match the slide's current position in `\u003CSOURCE>` (grep\n  `\u003CSOURCE>` for the slide's `*`\u002F`#` title to find it)\n\n## Update Rendered Images\n- When `\u003CSOURCE>`'s diff changes a `graphviz`\u002F`mermaid`\u002F`tikz`\u002F... code block (new\n  styling, new nodes, a swapped static image for a rendered diagram, or vice versa),\n  carry that same code change into `\u003CTARGET>`'s matching\n  `rendered_images:begin`\u002F`rendered_images:end` placeholder (see\n  `typst.rules.md`'s \"Diagram Placeholders and `wrap-content`\")\n- Never touch the numbered `.png` filenames\n  (`\u003CChapter>.typ.figs\u002F\u003CChapter>.\u003CN>.png`) or the figure `#figure(image(...))` calls\n  by hand for content that already renders correctly: `render_images.py` regenerates\n  both the images and their numbering from the placeholders on the next render\n- If a section gains or loses a rendered figure, every later figure's `\u003CN>` shifts;\n  after editing the placeholders, grep `\u003CTARGET>` for\n  `\\.typ\\.figs\u002F.*\\.[0-9]+\\.png` and renumber every `#figure(image(...))` call (and\n  its matching `label=`\u002F`caption=` metadata line) sequentially from 1, in document\n  order, so the bare `#figure(...)` blocks stay in sync with what the next render\n  will produce\n- Carry over caption\u002Flabel wording changes the same way you would prose: if\n  `\u003CSOURCE>`'s diff renames or rewords what a diagram depicts, update the figure's\n  `caption=`\u002F`caption:` to match, following `typst.rules.md`'s \"Figures: Required\n  Elements\" (sentence case, one plain line, no node-by-node listing)\n\n# Verification\n- [ ] Confirm every change in `\u003CSOURCE>` since `\u003CGIT_HASH>` is reflected in\n  `\u003CTARGET>`\n- [ ] Confirm `\u003CTARGET>` still follows the style of its corresponding\n  `.claude\u002Fskills\u002F*.rules.md` (`typst.rules.md`, `latex.rules.md`, or\n  `markdown.rules.md`, depending on `\u003CTARGET>`'s format)\n- [ ] Confirm `\u003CTARGET>` compiles\n  - For a `.typ` `\u003CTARGET>`, use `render_book_chapter.py -i \u003CTARGET>` when a working\n    Docker\u002Fgraphviz setup is available\n  - As a lighter syntax-only check that doesn't need Docker (and avoids\n    `render_book_chapter.py`'s Docker\u002Fgraphviz image-tagging bug, and its\n    side-effect of re-rendering other `.typ` files if a `gen_slides.py --daemon` is\n    watching the same book directory), stub out any not-yet-rendered figure PNGs\n    and compile directly:\n    ```bash\n    > typst compile --root . \u003CTARGET> \u002Ftmp\u002Fcheck.pdf\n    ```\n  - After either check, `git status`\u002F`git diff` the whole book directory, not just\n    `\u003CTARGET>`, to catch an unintended side effect on a sibling chapter\n- [ ] Confirm every `\u002F\u002F From: \u003CSOURCE>:\u003CLINE>` comment in `\u003CTARGET>` points at the\n  correct, current line in `\u003CSOURCE>`\n- [ ] Confirm every figure's numbered `.png` filename is sequential in document\n  order with no gaps or duplicates\n","# Goal\n- Given the content of a book in the form of a markdown or tex file `\u003CTARGET>` and\n  a source file `\u003CSOURCE>`, find and incorporate the changes from `\u003CSOURCE>` into\n  `\u003CTARGET>`\n\n# Workflow\n\n## Read the Version Header\n- The file `\u003CSOURCE>` contains a header with the last version, in terms of Git hash\n  and timestamp, of the material used to generate the current version of\n  `\u003CTARGET>`\n  - E.g.,\n    ```text\n    % git_hash=\u003CGIT_HASH>, timestamp=\u003CTIMESTAMP>\n    % \u003CSOURCE>\n    ```\n  - E.g.,\n    ```text\n    % git_hash=f15bc6b9, timestamp=2026-07-15 14:41:12 EDT\n    % book_springer\u002Flectures_source\u002FLesson02.1_From_Data_Science_To_Decision_Science.txt\n    ```\n- Get the diff of `\u003CSOURCE>` since `\u003CGIT_HASH>` once, up front, instead of re-diffing\n  piecemeal per section:\n  ```bash\n  > git diff \u003CGIT_HASH> -- \u003CSOURCE>\n  ```\n\n## Incorporate Changes\n- Find what changed in `\u003CSOURCE>` from `\u003CGIT_HASH>` to now, and modify `\u003CTARGET>` to\n  incorporate those changes\n- Follow the same style as `\u003CTARGET>` (e.g., read the corresponding\n  `.claude\u002Fskills\u002F*.rules.md`)\n- `\u003CTARGET>` is allowed to be a superset of `\u003CSOURCE>` (e.g., a `.typ` book chapter\n  routinely has headings, diagrams, or explanatory paragraphs that group or expand\n  several flat `.smd` slides, per `typst.rules.md`'s \"Structural Hierarchy\"). When\n  `\u003CSOURCE>` drops a heading or a diagram that `\u003CTARGET>` already built on, do not\n  delete the corresponding `\u003CTARGET>` content just because it no longer has a direct\n  counterpart: only remove it if the diff shows the underlying fact\u002Fexample was\n  itself changed or retracted, not merely reorganized out of the slide deck\n- Update the header at the top of `\u003CTARGET>` to the new hash\u002Ftimestamp once done:\n  ```text\n  \u002F\u002F git_hash=\u003CNEW_GIT_HASH> timestamp=\u003CNEW_TIMESTAMP>\n  ```\n\n## Compare Entire Flow\n- Make sure the flow of the `\u003CTARGET>` book chapter (in typst, latex, md format)\n  follows the flow of the `\u003CSOURCE>`\n- E.g., you can run `extract_toc_from_txt.py` on `\u003CSOURCE>` and `\u003CTARGET>` and\n  compare\n  ```bash\n  > extract_toc_from_txt.py -i msml610\u002Flectures_source\u002FLesson03.3-Non_classical_logics.smd\n\n  > extract_toc_from_txt.py -i msml610\u002Fbook\u002FLesson03.3-Non_classical_logics.typ\n  ```\n- Ensure that the flow of `\u003CTARGET>` is consistent with `\u003CSOURCE>`\n\n## Update Source-Line References\n- A `.typ` `\u003CTARGET>` carries a `\u002F\u002F From: \u003CSOURCE>:\u003CLINE> '\u003Cslide title>'` comment\n  above each section, pointing at the exact `\u003CSOURCE>` line it was generated from\n- Any edit to `\u003CSOURCE>` above a given slide shifts every later line number: after\n  incorporating the changes, re-walk `\u003CTARGET>`'s `\u002F\u002F From:` comments top to bottom\n  and update each `\u003CLINE>` to match the slide's current position in `\u003CSOURCE>` (grep\n  `\u003CSOURCE>` for the slide's `*`\u002F`#` title to find it)\n\n## Update Rendered Images\n- When `\u003CSOURCE>`'s diff changes a `graphviz`\u002F`mermaid`\u002F`tikz`\u002F... code block (new\n  styling, new nodes, a swapped static image for a rendered diagram, or vice versa),\n  carry that same code change into `\u003CTARGET>`'s matching\n  `rendered_images:begin`\u002F`rendered_images:end` placeholder (see\n  `typst.rules.md`'s \"Diagram Placeholders and `wrap-content`\")\n- Never touch the numbered `.png` filenames\n  (`\u003CChapter>.typ.figs\u002F\u003CChapter>.\u003CN>.png`) or the figure `#figure(image(...))` calls\n  by hand for content that already renders correctly: `render_images.py` regenerates\n  both the images and their numbering from the placeholders on the next render\n- If a section gains or loses a rendered figure, every later figure's `\u003CN>` shifts;\n  after editing the placeholders, grep `\u003CTARGET>` for\n  `\\.typ\\.figs\u002F.*\\.[0-9]+\\.png` and renumber every `#figure(image(...))` call (and\n  its matching `label=`\u002F`caption=` metadata line) sequentially from 1, in document\n  order, so the bare `#figure(...)` blocks stay in sync with what the next render\n  will produce\n- Carry over caption\u002Flabel wording changes the same way you would prose: if\n  `\u003CSOURCE>`'s diff renames or rewords what a diagram depicts, update the figure's\n  `caption=`\u002F`caption:` to match, following `typst.rules.md`'s \"Figures: Required\n  Elements\" (sentence case, one plain line, no node-by-node listing)\n\n# Verification\n- [ ] Confirm every change in `\u003CSOURCE>` since `\u003CGIT_HASH>` is reflected in\n  `\u003CTARGET>`\n- [ ] Confirm `\u003CTARGET>` still follows the style of its corresponding\n  `.claude\u002Fskills\u002F*.rules.md` (`typst.rules.md`, `latex.rules.md`, or\n  `markdown.rules.md`, depending on `\u003CTARGET>`'s format)\n- [ ] Confirm `\u003CTARGET>` compiles\n  - For a `.typ` `\u003CTARGET>`, use `render_book_chapter.py -i \u003CTARGET>` when a working\n    Docker\u002Fgraphviz setup is available\n  - As a lighter syntax-only check that doesn't need Docker (and avoids\n    `render_book_chapter.py`'s Docker\u002Fgraphviz image-tagging bug, and its\n    side-effect of re-rendering other `.typ` files if a `gen_slides.py --daemon` is\n    watching the same book directory), stub out any not-yet-rendered figure PNGs\n    and compile directly:\n    ```bash\n    > typst compile --root . \u003CTARGET> \u002Ftmp\u002Fcheck.pdf\n    ```\n  - After either check, `git status`\u002F`git diff` the whole book directory, not just\n    `\u003CTARGET>`, to catch an unintended side effect on a sibling chapter\n- [ ] Confirm every `\u002F\u002F From: \u003CSOURCE>:\u003CLINE>` comment in `\u003CTARGET>` points at the\n  correct, current line in `\u003CSOURCE>`\n- [ ] Confirm every figure's numbered `.png` filename is sequential in document\n  order with no gaps or duplicates\n",{"model":29,"description":7},"opus","master","804ae3e928c04740cec553be0eb28c8d06ff420e",".claude\u002Fskills\u002Fbook_chapter.update_from_source",1,"https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers","https:\u002F\u002Fcausify-ai.github.io\u002Fhelpers\u002F","https:\u002F\u002Fgithub.com\u002Fcausify-ai","2026-11-02 21:54:29",{"source":8,"skillName":5,"commands":39,"prompt":49,"zipAvailable":50},[40,43,46],{"tool":41,"command":42},"npx","npx skills add causify-ai\u002Fhelpers --skill book_chapter.update_from_source",{"tool":44,"command":45},"bunx","bunx skills add causify-ai\u002Fhelpers --skill book_chapter.update_from_source",{"tool":47,"command":48},"pnpm","pnpm dlx skills add causify-ai\u002Fhelpers --skill book_chapter.update_from_source","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Fbook_chapter.update_from_source\u002FSKILL.md",true,[],[53,74,90,102,111,125],{"skillNo":54,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":57,"categories":58,"keywords":64,"publishedAt":24},"01M6F209RASRBEK7GBNG5M00K0","tutorial_in_60_mins.propagate_docker_changes","Sync tutorial and class-project Docker files to match project_template","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.propagate_docker_changes\u002FSKILL.md",[59],{"categoryNo":60,"categoryName":61,"taxonomyType":62,"taxonomyTypeDesc":63},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[65,66,67,68,69,70,71,72,73,23],"docker","tutorial","tutorial in 60 mins propagate docker changes","propagate","template","sync","haiku","files","project",{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":83,"publishedAt":24},"01M6F207XZ5YDAJ0KNDRE6EN0R","tutorial_in_60_mins.merge_markdown","Merge the content of a markdown file into a Jupyter notebook","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.merge_markdown\u002FSKILL.md",[80],{"categoryNo":81,"categoryName":82,"taxonomyType":62,"taxonomyTypeDesc":63},"01JBSEEDCAT000000000000002","文档处理",[84,85,66,86,87,88,71,22,89,21],"markdown","merge","tutorial in 60 mins merge markdown","notebook","jupyter","jupyter notebook",{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":24},"01M6F2059X95Q1A13HD67E9JRF","tutorial_in_60_mins.format","Format a directory to follow the \"Learn X in 60 Minutes\" tutorial conventions","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.format\u002FSKILL.md",[],[97,66,98,99,100,71,101],"tutorial in 60 mins format","format","directory","learn","conventions",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":108,"publishedAt":24},"01M6F202MDHMNYD5S1YHG2PKZD","tutorial_in_60_mins.create","Create a tutorial directory for the Learn X in 60 Minutes conventions","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.create\u002FSKILL.md",[],[109,66,110,100,99,101],"tutorial in 60 mins create","create",{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":117,"publishedAt":24},"01M6F2004BW13GQ59N3RGSAYVN","todo.reorg_in_progress","Reorganize ai_task_queue.md so in-progress tasks, not-started tasks, and mislabeled topic headers sit under the right H1 stage","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftodo.reorg_in_progress\u002FSKILL.md",[],[118,119,120,121,122,123,124],"progress","todo","todo reorg in progress","tasks","queue","task","stage",{"skillNo":126,"name":127,"nameZh":6,"description":128,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":129,"categories":130,"keywords":131,"publishedAt":24},"01M6F1ZXN0G6HBD08GT8HE5FYA","todo.reorg_headers","Reorganize ai_task_queue.md .md so every H2 topic matches ALL TOPICS and every H3 task sits under the right topic, keeping its H1 stage","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftodo.reorg_headers\u002FSKILL.md",[],[132,119,122,123,124],"todo reorg headers"]