@kortix/sandbox 0.4.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.
- package/config/customize.sh +143 -0
- package/config/kortix-env-setup.sh +25 -0
- package/kortix-master/package.json +22 -0
- package/kortix-master/src/config.ts +22 -0
- package/kortix-master/src/index.ts +44 -0
- package/kortix-master/src/routes/env.ts +65 -0
- package/kortix-master/src/routes/proxy.ts +108 -0
- package/kortix-master/src/routes/update.ts +185 -0
- package/kortix-master/src/services/proxy.ts +43 -0
- package/kortix-master/src/services/secret-store.ts +156 -0
- package/kortix-master/tsconfig.json +14 -0
- package/opencode/agents/kortix-browser.md +142 -0
- package/opencode/agents/kortix-build.md +62 -0
- package/opencode/agents/kortix-explore.md +66 -0
- package/opencode/agents/kortix-image-gen.md +33 -0
- package/opencode/agents/kortix-main.md +450 -0
- package/opencode/agents/kortix-plan.md +100 -0
- package/opencode/agents/kortix-research.md +84 -0
- package/opencode/agents/kortix-sheets.md +61 -0
- package/opencode/agents/kortix-slides.md +64 -0
- package/opencode/agents/kortix-web-dev.md +572 -0
- package/opencode/commands/email.md +36 -0
- package/opencode/commands/init.md +43 -0
- package/opencode/commands/journal.md +44 -0
- package/opencode/commands/memory-init.md +81 -0
- package/opencode/commands/memory-search.md +50 -0
- package/opencode/commands/memory-status.md +56 -0
- package/opencode/commands/research.md +36 -0
- package/opencode/commands/search.md +38 -0
- package/opencode/commands/slides.md +32 -0
- package/opencode/commands/spreadsheet.md +30 -0
- package/opencode/memory.json +37 -0
- package/opencode/ocx.jsonc +10 -0
- package/opencode/opencode.jsonc +103 -0
- package/opencode/package.json +25 -0
- package/opencode/patches/apply.sh +19 -0
- package/opencode/patches/opencode-pty-spawn.txt +49 -0
- package/opencode/plugin/background-agents.ts.disabled +483 -0
- package/opencode/plugin/kdco-primitives/get-project-id.ts +172 -0
- package/opencode/plugin/kdco-primitives/index.ts +26 -0
- package/opencode/plugin/kdco-primitives/log-warn.ts +51 -0
- package/opencode/plugin/kdco-primitives/mutex.ts +122 -0
- package/opencode/plugin/kdco-primitives/shell.ts +138 -0
- package/opencode/plugin/kdco-primitives/temp.ts +36 -0
- package/opencode/plugin/kdco-primitives/terminal-detect.ts +34 -0
- package/opencode/plugin/kdco-primitives/types.ts +13 -0
- package/opencode/plugin/kdco-primitives/with-timeout.ts +84 -0
- package/opencode/plugin/memory.ts +306 -0
- package/opencode/plugin/worktree/state.ts +412 -0
- package/opencode/plugin/worktree/terminal.ts +1002 -0
- package/opencode/plugin/worktree.ts +861 -0
- package/opencode/skills/KORTIX-browser/SKILL.md +478 -0
- package/opencode/skills/KORTIX-cron-triggers/SKILL.md +173 -0
- package/opencode/skills/KORTIX-deep-research/SKILL.md +278 -0
- package/opencode/skills/KORTIX-docx/SKILL.md +398 -0
- package/opencode/skills/KORTIX-docx/scripts/__init__.py +1 -0
- package/opencode/skills/KORTIX-docx/scripts/accept_changes.py +104 -0
- package/opencode/skills/KORTIX-docx/scripts/comment.py +244 -0
- package/opencode/skills/KORTIX-docx/scripts/office/helpers/__init__.py +0 -0
- package/opencode/skills/KORTIX-docx/scripts/office/helpers/merge_runs.py +199 -0
- package/opencode/skills/KORTIX-docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/opencode/skills/KORTIX-docx/scripts/office/pack.py +159 -0
- package/opencode/skills/KORTIX-docx/scripts/office/soffice.py +183 -0
- package/opencode/skills/KORTIX-docx/scripts/office/unpack.py +132 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validate.py +111 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/__init__.py +15 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/base.py +847 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/docx.py +446 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/pptx.py +275 -0
- package/opencode/skills/KORTIX-docx/scripts/office/validators/redlining.py +247 -0
- package/opencode/skills/KORTIX-docx/scripts/render_docx.py +179 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/comments.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/commentsExtended.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/commentsExtensible.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/commentsIds.xml +3 -0
- package/opencode/skills/KORTIX-docx/scripts/templates/people.xml +3 -0
- package/opencode/skills/KORTIX-domain-research/SKILL.md +96 -0
- package/opencode/skills/KORTIX-domain-research/scripts/domain-lookup.py +810 -0
- package/opencode/skills/KORTIX-elevenlabs/SKILL.md +230 -0
- package/opencode/skills/KORTIX-elevenlabs/scripts/tts.py +389 -0
- package/opencode/skills/KORTIX-email/SKILL.md +145 -0
- package/opencode/skills/KORTIX-legal-writer/SKILL.md +409 -0
- package/opencode/skills/KORTIX-legal-writer/references/bluebook.md +152 -0
- package/opencode/skills/KORTIX-legal-writer/references/document-types.md +416 -0
- package/opencode/skills/KORTIX-legal-writer/scripts/courtlistener.py +291 -0
- package/opencode/skills/KORTIX-legal-writer/scripts/ecfr_lookup.py +299 -0
- package/opencode/skills/KORTIX-legal-writer/scripts/verify-legal.py +507 -0
- package/opencode/skills/KORTIX-logo-creator/SKILL.md +293 -0
- package/opencode/skills/KORTIX-logo-creator/references/prompt-patterns.md +134 -0
- package/opencode/skills/KORTIX-logo-creator/scripts/compose_logo.py +406 -0
- package/opencode/skills/KORTIX-logo-creator/scripts/create_logo_sheet.py +258 -0
- package/opencode/skills/KORTIX-logo-creator/scripts/remove_bg.py +96 -0
- package/opencode/skills/KORTIX-memory/SKILL.md +261 -0
- package/opencode/skills/KORTIX-memory/scripts/export-sessions.py +409 -0
- package/opencode/skills/KORTIX-paper-creator/SKILL.md +549 -0
- package/opencode/skills/KORTIX-paper-creator/assets/template.tex +101 -0
- package/opencode/skills/KORTIX-paper-creator/scripts/compile.sh +177 -0
- package/opencode/skills/KORTIX-paper-creator/scripts/openalex_to_bibtex.py +220 -0
- package/opencode/skills/KORTIX-paper-creator/scripts/verify.sh +354 -0
- package/opencode/skills/KORTIX-paper-search/SKILL.md +418 -0
- package/opencode/skills/KORTIX-pdf/SKILL.md +232 -0
- package/opencode/skills/KORTIX-pdf/forms.md +36 -0
- package/opencode/skills/KORTIX-pdf/reference.md +105 -0
- package/opencode/skills/KORTIX-pdf/scripts/check_bounding_boxes.py +65 -0
- package/opencode/skills/KORTIX-pdf/scripts/check_fillable_fields.py +11 -0
- package/opencode/skills/KORTIX-pdf/scripts/convert_pdf_to_images.py +33 -0
- package/opencode/skills/KORTIX-pdf/scripts/create_validation_image.py +37 -0
- package/opencode/skills/KORTIX-pdf/scripts/extract_form_field_info.py +122 -0
- package/opencode/skills/KORTIX-pdf/scripts/extract_form_structure.py +115 -0
- package/opencode/skills/KORTIX-pdf/scripts/fill_fillable_fields.py +98 -0
- package/opencode/skills/KORTIX-pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/opencode/skills/KORTIX-plan/SKILL.md +228 -0
- package/opencode/skills/KORTIX-presentation-viewer/SKILL.md +87 -0
- package/opencode/skills/KORTIX-presentation-viewer/serve.ts +136 -0
- package/opencode/skills/KORTIX-presentation-viewer/viewer.html +559 -0
- package/opencode/skills/KORTIX-presentations/SKILL.md +344 -0
- package/opencode/skills/KORTIX-remotion/SKILL.md +56 -0
- package/opencode/skills/KORTIX-remotion/rules/3d.md +86 -0
- package/opencode/skills/KORTIX-remotion/rules/animations.md +29 -0
- package/opencode/skills/KORTIX-remotion/rules/assets.md +78 -0
- package/opencode/skills/KORTIX-remotion/rules/audio-visualization.md +198 -0
- package/opencode/skills/KORTIX-remotion/rules/audio.md +169 -0
- package/opencode/skills/KORTIX-remotion/rules/calculate-metadata.md +104 -0
- package/opencode/skills/KORTIX-remotion/rules/can-decode.md +75 -0
- package/opencode/skills/KORTIX-remotion/rules/charts.md +120 -0
- package/opencode/skills/KORTIX-remotion/rules/compositions.md +141 -0
- package/opencode/skills/KORTIX-remotion/rules/display-captions.md +184 -0
- package/opencode/skills/KORTIX-remotion/rules/extract-frames.md +229 -0
- package/opencode/skills/KORTIX-remotion/rules/ffmpeg.md +38 -0
- package/opencode/skills/KORTIX-remotion/rules/fonts.md +152 -0
- package/opencode/skills/KORTIX-remotion/rules/get-audio-duration.md +58 -0
- package/opencode/skills/KORTIX-remotion/rules/get-video-dimensions.md +68 -0
- package/opencode/skills/KORTIX-remotion/rules/get-video-duration.md +58 -0
- package/opencode/skills/KORTIX-remotion/rules/gifs.md +141 -0
- package/opencode/skills/KORTIX-remotion/rules/images.md +130 -0
- package/opencode/skills/KORTIX-remotion/rules/import-srt-captions.md +69 -0
- package/opencode/skills/KORTIX-remotion/rules/light-leaks.md +73 -0
- package/opencode/skills/KORTIX-remotion/rules/lottie.md +68 -0
- package/opencode/skills/KORTIX-remotion/rules/maps.md +401 -0
- package/opencode/skills/KORTIX-remotion/rules/measuring-dom-nodes.md +35 -0
- package/opencode/skills/KORTIX-remotion/rules/measuring-text.md +143 -0
- package/opencode/skills/KORTIX-remotion/rules/parameters.md +98 -0
- package/opencode/skills/KORTIX-remotion/rules/sequencing.md +118 -0
- package/opencode/skills/KORTIX-remotion/rules/subtitles.md +36 -0
- package/opencode/skills/KORTIX-remotion/rules/tailwind.md +11 -0
- package/opencode/skills/KORTIX-remotion/rules/text-animations.md +20 -0
- package/opencode/skills/KORTIX-remotion/rules/timing.md +179 -0
- package/opencode/skills/KORTIX-remotion/rules/transcribe-captions.md +70 -0
- package/opencode/skills/KORTIX-remotion/rules/transitions.md +197 -0
- package/opencode/skills/KORTIX-remotion/rules/transparent-videos.md +106 -0
- package/opencode/skills/KORTIX-remotion/rules/trimming.md +53 -0
- package/opencode/skills/KORTIX-remotion/rules/videos.md +171 -0
- package/opencode/skills/KORTIX-secrets/SKILL.md +280 -0
- package/opencode/skills/KORTIX-semantic-search/SKILL.md +213 -0
- package/opencode/skills/KORTIX-session-search/SKILL.md +807 -0
- package/opencode/skills/KORTIX-session-search/Untitled +1 -0
- package/opencode/skills/KORTIX-skill-creator/SKILL.md +163 -0
- package/opencode/skills/KORTIX-web-research/SKILL.md +69 -0
- package/opencode/skills/KORTIX-xlsx/LICENSE.txt +30 -0
- package/opencode/skills/KORTIX-xlsx/SKILL.md +549 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/helpers/__init__.py +0 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/helpers/merge_runs.py +199 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/pack.py +159 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/soffice.py +183 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/unpack.py +132 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validate.py +111 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/__init__.py +15 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/base.py +847 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/docx.py +446 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/pptx.py +275 -0
- package/opencode/skills/KORTIX-xlsx/scripts/office/validators/redlining.py +247 -0
- package/opencode/skills/KORTIX-xlsx/scripts/recalc.py +184 -0
- package/opencode/tools/image-gen.ts +342 -0
- package/opencode/tools/image-search.ts +190 -0
- package/opencode/tools/memory-get.ts +168 -0
- package/opencode/tools/memory-search.ts +247 -0
- package/opencode/tools/presentation-gen.ts +723 -0
- package/opencode/tools/scrape-webpage.ts +115 -0
- package/opencode/tools/scripts/.python-version +1 -0
- package/opencode/tools/scripts/convert_pdf.py +184 -0
- package/opencode/tools/scripts/convert_pptx.py +562 -0
- package/opencode/tools/scripts/pyproject.toml +11 -0
- package/opencode/tools/scripts/uv.lock +287 -0
- package/opencode/tools/scripts/validate_slide.py +74 -0
- package/opencode/tools/show-user.ts +217 -0
- package/opencode/tools/tests/e2e-presentation-fix.ts +277 -0
- package/opencode/tools/tests/image-gen.test.ts +215 -0
- package/opencode/tools/tests/image-search.test.ts +125 -0
- package/opencode/tools/tests/memory-system-benchmark.ts +1076 -0
- package/opencode/tools/tests/presentation-gen.test.ts +389 -0
- package/opencode/tools/tests/scrape-webpage.test.ts +74 -0
- package/opencode/tools/tests/show-user.test.ts +241 -0
- package/opencode/tools/tests/video-gen.test.ts +110 -0
- package/opencode/tools/tests/web-search.test.ts +106 -0
- package/opencode/tools/video-gen.ts +200 -0
- package/opencode/tools/web-search.ts +153 -0
- package/opencode/tsconfig.json +29 -0
- package/package.json +36 -0
- package/patch-agent-browser.js +100 -0
- package/postinstall.sh +88 -0
- package/services/KORTIX-presentation-viewer/run +37 -0
- package/services/agent-browser-viewer/run +48 -0
- package/services/kortix-master/run +16 -0
- package/services/lss-sync/run +22 -0
- package/services/opencode-serve/run +25 -0
- package/services/opencode-web/run +21 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kortix-deep-research
|
|
3
|
+
description: "Deep research agent skill. Use when the user needs thorough, scientific, truth-seeking research on any topic -- investigating claims, finding primary sources, synthesizing evidence, producing cited reports. Triggers on: 'research this', 'investigate', 'deep dive', 'find sources', 'what does the evidence say', 'literature review', 'fact check', 'analyze the research on', any request requiring multi-source investigation with citations."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deep Research
|
|
7
|
+
|
|
8
|
+
Systematic, evidence-based research that produces cited, source-backed reports. Uses the **filesystem as working memory** -- scraped content, extracted notes, and source metadata are saved to disk rather than held in context. This keeps the context window lean and makes research resumable, searchable, and reusable.
|
|
9
|
+
|
|
10
|
+
## Architecture
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
research/{topic-slug}/
|
|
14
|
+
plan.md # Research plan with sub-questions
|
|
15
|
+
sources-index.md # URL registry: what's been scraped, metadata
|
|
16
|
+
sources/ # Raw scraped content (one file per source)
|
|
17
|
+
001-source-slug.md
|
|
18
|
+
002-source-slug.md
|
|
19
|
+
...
|
|
20
|
+
notes/ # Extracted findings per sub-question
|
|
21
|
+
question-1.md
|
|
22
|
+
question-2.md
|
|
23
|
+
...
|
|
24
|
+
report.md # Final compiled report
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Core principle:** Write to disk aggressively, read back selectively. Never hold raw scraped content in context longer than it takes to extract findings. The LLM context should contain only the current working set -- not the entire research corpus.
|
|
28
|
+
|
|
29
|
+
## Research Parameters
|
|
30
|
+
|
|
31
|
+
- **Breadth** (default: 3): Parallel search queries per sub-question. Range: 2-6.
|
|
32
|
+
- **Depth** (default: 2): Recursive deepening rounds. Range: 1-4.
|
|
33
|
+
|
|
34
|
+
Estimate: breadth=3, depth=2 -> ~12-20 web searches, ~8-15 pages read, 3-8 minute runtime.
|
|
35
|
+
|
|
36
|
+
For quick fact-checks: breadth=2, depth=1.
|
|
37
|
+
For exhaustive reviews: breadth=5, depth=3.
|
|
38
|
+
|
|
39
|
+
## Step-by-Step Workflow
|
|
40
|
+
|
|
41
|
+
### Phase 0: Initialize
|
|
42
|
+
|
|
43
|
+
1. **Create the research directory:**
|
|
44
|
+
```bash
|
|
45
|
+
mkdir -p research/{topic-slug}/sources research/{topic-slug}/notes
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. **Search local filesystem first.** Before any web search, check if relevant content already exists:
|
|
49
|
+
- Past research in `workspace/.kortix/research/` and `workspace/.kortix/memory/`
|
|
50
|
+
- Relevant files in the working directory or project
|
|
51
|
+
- Use `grep`, `glob`, or semantic search (`lss`) as appropriate for the task
|
|
52
|
+
- If prior research exists on this topic, read it and build on it -- don't start from scratch
|
|
53
|
+
|
|
54
|
+
3. **Initialize `sources-index.md`:**
|
|
55
|
+
```markdown
|
|
56
|
+
# Sources Index
|
|
57
|
+
|
|
58
|
+
| # | URL | Title | Date | Type | Credibility | File |
|
|
59
|
+
|---|-----|-------|------|------|-------------|------|
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Phase 1: Planning
|
|
63
|
+
|
|
64
|
+
1. Analyze the query. Identify:
|
|
65
|
+
- Core research question(s)
|
|
66
|
+
- Required evidence types (empirical data, expert opinion, primary sources, statistics)
|
|
67
|
+
- Potential biases to watch for
|
|
68
|
+
|
|
69
|
+
2. Decompose into 2-5 independently researchable sub-questions.
|
|
70
|
+
|
|
71
|
+
3. Write `plan.md` with the sub-questions, search strategy, and scope decisions.
|
|
72
|
+
|
|
73
|
+
4. Create a todo list tracking each sub-question.
|
|
74
|
+
|
|
75
|
+
### Phase 2: Search-Read-Extract Loop
|
|
76
|
+
|
|
77
|
+
For each sub-question, execute this loop:
|
|
78
|
+
|
|
79
|
+
#### 2a. Generate Search Queries
|
|
80
|
+
|
|
81
|
+
Generate `breadth` distinct queries. Vary:
|
|
82
|
+
- Phrasing (synonyms, technical vs. lay terms)
|
|
83
|
+
- Angle (supporting evidence, counter-evidence, meta-analyses)
|
|
84
|
+
- Source type (academic `site:scholar.google.com`, government `site:gov`, news, industry)
|
|
85
|
+
- Recency (add year filters for time-sensitive topics)
|
|
86
|
+
|
|
87
|
+
**Batch search with `search_depth: "advanced"`:**
|
|
88
|
+
```
|
|
89
|
+
web-search("query1 ||| query2 ||| query3", search_depth="advanced")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### 2b. Read and Extract
|
|
93
|
+
|
|
94
|
+
For each promising search result:
|
|
95
|
+
|
|
96
|
+
1. **Check `sources-index.md` first.** If the URL is already scraped, skip it. Do not re-scrape pages already processed in this session.
|
|
97
|
+
|
|
98
|
+
2. **Scrape the page.** Batch URLs for efficiency:
|
|
99
|
+
```
|
|
100
|
+
scrape-webpage("url1, url2, url3")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
3. **Save raw content to disk immediately:**
|
|
104
|
+
```bash
|
|
105
|
+
# Write scraped content to sources/NNN-slug.md
|
|
106
|
+
```
|
|
107
|
+
Include a header with the URL, title, and scrape date. This gets the raw content out of your context.
|
|
108
|
+
|
|
109
|
+
4. **Extract key findings** from the scraped content and append to `notes/question-N.md`:
|
|
110
|
+
- Key claims and findings (with brief quotes when important)
|
|
111
|
+
- Data points: numbers, statistics, dates
|
|
112
|
+
- The source number (for citation mapping later)
|
|
113
|
+
- Methodology notes if relevant (sample size, study design)
|
|
114
|
+
|
|
115
|
+
5. **Update `sources-index.md`** with the new source entry:
|
|
116
|
+
```
|
|
117
|
+
| 003 | https://example.com/article | Article Title | 2025-06-15 | news | medium | sources/003-article-title.md |
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
6. **Free your context.** After extracting findings and saving to disk, you do not need to retain the raw scraped content. Move on to the next source.
|
|
121
|
+
|
|
122
|
+
#### 2c. Deepen (Recursive)
|
|
123
|
+
|
|
124
|
+
After processing results for a sub-question:
|
|
125
|
+
|
|
126
|
+
1. **Read `notes/question-N.md`** to assess coverage.
|
|
127
|
+
2. Identify gaps: what remains unanswered? What claims lack corroboration?
|
|
128
|
+
3. Generate follow-up questions based on findings.
|
|
129
|
+
4. If `depth > 0`: recurse with follow-up questions at `depth - 1` and `ceil(breadth / 2)`.
|
|
130
|
+
5. If `depth == 0`: stop, move to next sub-question.
|
|
131
|
+
|
|
132
|
+
### Phase 3: Synthesis
|
|
133
|
+
|
|
134
|
+
After all sub-questions are researched:
|
|
135
|
+
|
|
136
|
+
1. **Read all `notes/*.md` files** (not raw sources -- the notes are already distilled).
|
|
137
|
+
2. **Cross-reference claims** -- flag where sources agree vs. contradict.
|
|
138
|
+
3. **Resolve contradictions** by source quality:
|
|
139
|
+
- Peer-reviewed > government data > industry reports > news > blogs
|
|
140
|
+
- Meta-analyses > individual studies
|
|
141
|
+
- Multiple independent sources > single source
|
|
142
|
+
4. **Identify consensus vs. uncertainty.** Be explicit about what is well-established vs. debated vs. unknown.
|
|
143
|
+
5. **Check for bias:** Did search results skew toward one viewpoint? Are key perspectives missing?
|
|
144
|
+
|
|
145
|
+
### Phase 4: Report Generation
|
|
146
|
+
|
|
147
|
+
Compile `report.md` using findings from notes and metadata from `sources-index.md`.
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
# [Research Title]
|
|
151
|
+
|
|
152
|
+
## Executive Summary
|
|
153
|
+
[2-3 paragraph overview of key findings and conclusions]
|
|
154
|
+
|
|
155
|
+
## Key Findings
|
|
156
|
+
|
|
157
|
+
### [Finding 1 Title]
|
|
158
|
+
[Discussion with inline citations [1][2]]
|
|
159
|
+
|
|
160
|
+
### [Finding 2 Title]
|
|
161
|
+
[Discussion with inline citations [3][4]]
|
|
162
|
+
|
|
163
|
+
## Analysis
|
|
164
|
+
[Cross-cutting patterns, contradictions, consensus areas]
|
|
165
|
+
|
|
166
|
+
## Limitations & Caveats
|
|
167
|
+
[What this research couldn't determine, methodological limitations]
|
|
168
|
+
|
|
169
|
+
## Conclusions
|
|
170
|
+
[Evidence-based conclusions with confidence levels]
|
|
171
|
+
|
|
172
|
+
## Sources
|
|
173
|
+
|
|
174
|
+
[1] Author (Date). "Title." *Publication*. URL
|
|
175
|
+
[2] Author (Date). "Title." *Publication*. URL
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Build citations from `sources-index.md`** at report time. During the search phase, you only needed to track `{url, title, source_number}`. Now format the full bibliography by reading back source metadata from the index and source files as needed.
|
|
179
|
+
|
|
180
|
+
### Phase 5: Finalize
|
|
181
|
+
|
|
182
|
+
1. Save `report.md` in the research directory.
|
|
183
|
+
2. Copy the report to `workspace/.kortix/memory/research-{topic-slug}.md` for long-term memory.
|
|
184
|
+
3. Report to user: main conclusions (2-3 sentences), number of sources, confidence levels, file path.
|
|
185
|
+
|
|
186
|
+
## Citation Rules
|
|
187
|
+
|
|
188
|
+
1. **Every factual claim must have a citation.** No uncited assertions of fact.
|
|
189
|
+
2. **Use numbered inline citations** `[1]`, `[2]` that map to the Sources section.
|
|
190
|
+
3. **Never fabricate sources.** Every URL in Sources must be a real page you actually visited and read.
|
|
191
|
+
4. **Quote directly** when the exact wording matters. Use `> blockquote` for direct quotes.
|
|
192
|
+
5. **Distinguish levels of evidence:**
|
|
193
|
+
- "Studies show..." (cite the studies)
|
|
194
|
+
- "According to [Source]..." (single source, acknowledge it)
|
|
195
|
+
- "The evidence suggests..." (multiple corroborating sources)
|
|
196
|
+
- "It remains debated whether..." (conflicting evidence)
|
|
197
|
+
6. **Date every source.** If no date is found, write "(n.d.)".
|
|
198
|
+
7. **Note source type** in the bibliography: academic paper, government report, news article, blog post, etc.
|
|
199
|
+
|
|
200
|
+
## Scientific Rigor Standards
|
|
201
|
+
|
|
202
|
+
- **Falsifiability:** Actively search for counter-evidence. Don't just confirm priors.
|
|
203
|
+
- **Replication:** A claim supported by multiple independent sources is stronger than one from a single source.
|
|
204
|
+
- **Recency awareness:** Newer isn't always better. Note when older foundational work is more relevant.
|
|
205
|
+
- **Correlation vs. causation:** Flag when sources conflate the two.
|
|
206
|
+
- **Sample size and methodology:** Note these for empirical claims.
|
|
207
|
+
- **Conflicts of interest:** Note when a source has a stake in its conclusions.
|
|
208
|
+
|
|
209
|
+
## Tool Usage Patterns
|
|
210
|
+
|
|
211
|
+
### Search (always use search_depth "advanced" for deep research)
|
|
212
|
+
```
|
|
213
|
+
web-search("topic aspect1 ||| topic aspect2 ||| topic counter-evidence", search_depth="advanced")
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Scrape (batch URLs)
|
|
217
|
+
```
|
|
218
|
+
scrape-webpage("https://source1.com/article, https://source2.com/study")
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Save scraped content to disk
|
|
222
|
+
```bash
|
|
223
|
+
# After scraping, immediately write to file and extract findings
|
|
224
|
+
# This is critical -- do not hold raw scraped content in context
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Academic Paper Search (OpenAlex)
|
|
228
|
+
|
|
229
|
+
Load the `kortix-paper-search` skill for full API reference. Quick patterns:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Find highly-cited papers on a topic
|
|
233
|
+
curl -s "https://api.openalex.org/works?search=topic+keywords&filter=cited_by_count:>50,type:article,has_abstract:true&sort=cited_by_count:desc&per_page=15&select=id,display_name,publication_year,cited_by_count,doi,authorships,abstract_inverted_index&mailto=agent@kortix.ai"
|
|
234
|
+
|
|
235
|
+
# Find recent preprints
|
|
236
|
+
curl -s "https://api.openalex.org/works?search=topic&filter=type:preprint,publication_year:2025&sort=publication_date:desc&per_page=10&mailto=agent@kortix.ai"
|
|
237
|
+
|
|
238
|
+
# Find review/survey papers
|
|
239
|
+
curl -s "https://api.openalex.org/works?search=topic&filter=type:review,cited_by_count:>20&sort=cited_by_count:desc&per_page=10&mailto=agent@kortix.ai"
|
|
240
|
+
|
|
241
|
+
# Follow citation chains: who cites a seminal paper?
|
|
242
|
+
curl -s "https://api.openalex.org/works?filter=cites:WORK_ID&sort=cited_by_count:desc&per_page=10&mailto=agent@kortix.ai"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Save paper metadata to `sources-index.md` and raw API responses to `sources/` for later processing.
|
|
246
|
+
|
|
247
|
+
### Web Source Hunting
|
|
248
|
+
```
|
|
249
|
+
web-search("topic site:scholar.google.com ||| topic site:arxiv.org ||| topic systematic review OR meta-analysis", search_depth="advanced")
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Data Source Hunting
|
|
253
|
+
```
|
|
254
|
+
web-search("topic statistics site:data.gov ||| topic data site:worldbank.org ||| topic survey results", search_depth="advanced")
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Fact-Checking Pattern
|
|
258
|
+
```
|
|
259
|
+
web-search("claim fact check ||| claim evidence ||| claim debunked OR confirmed", search_depth="advanced")
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Local FS Search (check before web search)
|
|
263
|
+
```bash
|
|
264
|
+
# Search past research and memory
|
|
265
|
+
grep -r "keyword" workspace/.kortix/research/ workspace/.kortix/memory/
|
|
266
|
+
|
|
267
|
+
# Semantic search if available
|
|
268
|
+
lss "research question" -p /workspace/.kortix/ --json -k 10
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Handling Edge Cases
|
|
272
|
+
|
|
273
|
+
- **No good results found:** State what was searched and that evidence is lacking. This is a valid finding.
|
|
274
|
+
- **Highly technical topics:** Search for both technical papers and accessible explainers.
|
|
275
|
+
- **Rapidly evolving topics:** Prioritize recency. Note publication dates prominently.
|
|
276
|
+
- **Controversial topics:** Present all major viewpoints with evidence. Don't editorialize.
|
|
277
|
+
- **Paywalled sources:** Extract what's available from abstracts and secondary reporting. Note when full text was not accessible.
|
|
278
|
+
- **Resuming prior research:** If a research directory already exists, read the existing plan, notes, and sources-index. Continue from where the previous session left off rather than starting over.
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kortix-docx
|
|
3
|
+
description: "Use this skill whenever the user wants to create, read, edit, or manipulate Word documents (.docx files). Triggers include: any mention of \"Word doc\", \"word document\", \".docx\", or requests to produce professional documents with formatting like tables of contents, headings, page numbers, or letterheads. Also use when extracting or reorganizing content from .docx files, inserting or replacing images in documents, performing find-and-replace in Word files, working with tracked changes or comments, or converting content into a polished Word document. If the user asks for a \"report\", \"memo\", \"letter\", \"template\", or similar deliverable as a Word or .docx file, use this skill. Do NOT use for PDFs, spreadsheets, or general coding tasks unrelated to document generation."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DOCX Creation, Editing, and Analysis
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
A .docx file is a ZIP archive containing XML files.
|
|
11
|
+
|
|
12
|
+
## Quick Reference
|
|
13
|
+
|
|
14
|
+
| Task | Approach |
|
|
15
|
+
|------|----------|
|
|
16
|
+
| Read/analyze content | `pandoc` or unpack for raw XML |
|
|
17
|
+
| Create new document | Use `docx-js` -- see Creating New Documents below |
|
|
18
|
+
| Edit existing document | Unpack -> edit XML -> repack -- see Editing Existing Documents below |
|
|
19
|
+
| Visual review | Convert DOCX -> PDF -> PNGs via `soffice` + `pdftoppm` or `scripts/render_docx.py` |
|
|
20
|
+
|
|
21
|
+
### Converting .doc to .docx
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python scripts/office/soffice.py --headless --convert-to docx document.doc
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Reading Content
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pandoc --track-changes=all document.docx -o output.md
|
|
31
|
+
python scripts/office/unpack.py document.docx unpacked/
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Converting to Images
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python scripts/office/soffice.py --headless --convert-to pdf document.docx
|
|
38
|
+
pdftoppm -jpeg -r 150 document.pdf page
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or use the bundled render script:
|
|
42
|
+
```bash
|
|
43
|
+
python scripts/render_docx.py /path/to/file.docx --output_dir /tmp/docx_pages
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Accepting Tracked Changes
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python scripts/accept_changes.py input.docx output.docx
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Creating New Documents
|
|
55
|
+
|
|
56
|
+
Generate .docx files with JavaScript, then validate. Install: `npm install -g docx`
|
|
57
|
+
|
|
58
|
+
### Setup
|
|
59
|
+
```javascript
|
|
60
|
+
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun,
|
|
61
|
+
Header, Footer, AlignmentType, PageOrientation, LevelFormat, ExternalHyperlink,
|
|
62
|
+
TableOfContents, HeadingLevel, BorderStyle, WidthType, ShadingType,
|
|
63
|
+
VerticalAlign, PageNumber, PageBreak } = require('docx');
|
|
64
|
+
|
|
65
|
+
const doc = new Document({ sections: [{ children: [/* content */] }] });
|
|
66
|
+
Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Validation
|
|
70
|
+
After creating the file, validate it. If validation fails, unpack, fix the XML, and repack.
|
|
71
|
+
```bash
|
|
72
|
+
python scripts/office/validate.py doc.docx
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Page Size
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
// CRITICAL: docx-js defaults to A4, not US Letter
|
|
79
|
+
// Always set page size explicitly
|
|
80
|
+
sections: [{
|
|
81
|
+
properties: {
|
|
82
|
+
page: {
|
|
83
|
+
size: {
|
|
84
|
+
width: 12240, // 8.5 inches in DXA
|
|
85
|
+
height: 15840 // 11 inches in DXA
|
|
86
|
+
},
|
|
87
|
+
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
children: [/* content */]
|
|
91
|
+
}]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Paper | Width | Height | Content Width (1" margins) |
|
|
95
|
+
|-------|-------|--------|---------------------------|
|
|
96
|
+
| US Letter | 12,240 | 15,840 | 9,360 |
|
|
97
|
+
| A4 (default) | 11,906 | 16,838 | 9,026 |
|
|
98
|
+
|
|
99
|
+
**Landscape**: pass portrait dimensions and let docx-js swap:
|
|
100
|
+
```javascript
|
|
101
|
+
size: { width: 12240, height: 15840, orientation: PageOrientation.LANDSCAPE }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Styles (Override Built-in Headings)
|
|
105
|
+
|
|
106
|
+
Use Arial as default font. Keep titles black for readability.
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const doc = new Document({
|
|
110
|
+
styles: {
|
|
111
|
+
default: { document: { run: { font: "Arial", size: 24 } } },
|
|
112
|
+
paragraphStyles: [
|
|
113
|
+
{ id: "Heading1", name: "Heading 1", basedOn: "Normal", next: "Normal", quickFormat: true,
|
|
114
|
+
run: { size: 32, bold: true, font: "Arial" },
|
|
115
|
+
paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } },
|
|
116
|
+
{ id: "Heading2", name: "Heading 2", basedOn: "Normal", next: "Normal", quickFormat: true,
|
|
117
|
+
run: { size: 28, bold: true, font: "Arial" },
|
|
118
|
+
paragraph: { spacing: { before: 180, after: 180 }, outlineLevel: 1 } },
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
sections: [{ children: [
|
|
122
|
+
new Paragraph({ heading: HeadingLevel.HEADING_1, children: [new TextRun("Title")] }),
|
|
123
|
+
]}]
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Lists (NEVER use unicode bullets)
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
// WRONG
|
|
131
|
+
new Paragraph({ children: [new TextRun("\u2022 Item")] })
|
|
132
|
+
|
|
133
|
+
// CORRECT - use numbering config
|
|
134
|
+
const doc = new Document({
|
|
135
|
+
numbering: {
|
|
136
|
+
config: [
|
|
137
|
+
{ reference: "bullets",
|
|
138
|
+
levels: [{ level: 0, format: LevelFormat.BULLET, text: "\u2022", alignment: AlignmentType.LEFT,
|
|
139
|
+
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
|
|
140
|
+
{ reference: "numbers",
|
|
141
|
+
levels: [{ level: 0, format: LevelFormat.DECIMAL, text: "%1.", alignment: AlignmentType.LEFT,
|
|
142
|
+
style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] },
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
sections: [{ children: [
|
|
146
|
+
new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [new TextRun("Item")] }),
|
|
147
|
+
]}]
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Tables
|
|
152
|
+
|
|
153
|
+
**CRITICAL: Set both `columnWidths` on the table AND `width` on each cell.**
|
|
154
|
+
|
|
155
|
+
```javascript
|
|
156
|
+
const border = { style: BorderStyle.SINGLE, size: 1, color: "CCCCCC" };
|
|
157
|
+
const borders = { top: border, bottom: border, left: border, right: border };
|
|
158
|
+
|
|
159
|
+
new Table({
|
|
160
|
+
width: { size: 9360, type: WidthType.DXA },
|
|
161
|
+
columnWidths: [4680, 4680],
|
|
162
|
+
rows: [
|
|
163
|
+
new TableRow({
|
|
164
|
+
children: [
|
|
165
|
+
new TableCell({
|
|
166
|
+
borders,
|
|
167
|
+
width: { size: 4680, type: WidthType.DXA },
|
|
168
|
+
shading: { fill: "D5E8F0", type: ShadingType.CLEAR }, // CLEAR not SOLID
|
|
169
|
+
margins: { top: 80, bottom: 80, left: 120, right: 120 },
|
|
170
|
+
children: [new Paragraph({ children: [new TextRun("Cell")] })]
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
})
|
|
174
|
+
]
|
|
175
|
+
})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Always use `WidthType.DXA`** -- never `WidthType.PERCENTAGE` (breaks in Google Docs).
|
|
179
|
+
|
|
180
|
+
### Images
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
new Paragraph({
|
|
184
|
+
children: [new ImageRun({
|
|
185
|
+
type: "png", // Required: png, jpg, jpeg, gif, bmp, svg
|
|
186
|
+
data: fs.readFileSync("image.png"),
|
|
187
|
+
transformation: { width: 200, height: 150 },
|
|
188
|
+
altText: { title: "Title", description: "Desc", name: "Name" }
|
|
189
|
+
})]
|
|
190
|
+
})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Page Breaks
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
new Paragraph({ children: [new PageBreak()] })
|
|
197
|
+
// Or: new Paragraph({ pageBreakBefore: true, children: [new TextRun("New page")] })
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Table of Contents
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
new TableOfContents("Table of Contents", { hyperlink: true, headingStyleRange: "1-3" })
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Headers/Footers
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
sections: [{
|
|
210
|
+
headers: {
|
|
211
|
+
default: new Header({ children: [new Paragraph({ children: [new TextRun("Header")] })] })
|
|
212
|
+
},
|
|
213
|
+
footers: {
|
|
214
|
+
default: new Footer({ children: [new Paragraph({
|
|
215
|
+
children: [new TextRun("Page "), new TextRun({ children: [PageNumber.CURRENT] })]
|
|
216
|
+
})] })
|
|
217
|
+
},
|
|
218
|
+
children: [/* content */]
|
|
219
|
+
}]
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Critical Rules for docx-js
|
|
223
|
+
|
|
224
|
+
- Set page size explicitly (defaults to A4)
|
|
225
|
+
- Landscape: pass portrait dimensions, set `orientation: PageOrientation.LANDSCAPE`
|
|
226
|
+
- Never use `\n` -- use separate Paragraph elements
|
|
227
|
+
- Never use unicode bullets -- use `LevelFormat.BULLET`
|
|
228
|
+
- PageBreak must be in Paragraph
|
|
229
|
+
- ImageRun requires `type`
|
|
230
|
+
- Always use `WidthType.DXA` for tables
|
|
231
|
+
- Tables need dual widths: `columnWidths` + cell `width`
|
|
232
|
+
- Use `ShadingType.CLEAR`, never SOLID
|
|
233
|
+
- TOC requires HeadingLevel only
|
|
234
|
+
- Override built-in styles with exact IDs: "Heading1", "Heading2", etc.
|
|
235
|
+
- Include `outlineLevel` for TOC (0 for H1, 1 for H2)
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Editing Existing Documents
|
|
240
|
+
|
|
241
|
+
**Follow all 3 steps in order.**
|
|
242
|
+
|
|
243
|
+
### Step 1: Unpack
|
|
244
|
+
```bash
|
|
245
|
+
python scripts/office/unpack.py document.docx unpacked/
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Step 2: Edit XML
|
|
249
|
+
|
|
250
|
+
Edit files in `unpacked/word/`. See XML Reference below.
|
|
251
|
+
|
|
252
|
+
**Use the Edit tool directly for string replacement. Do not write Python scripts.**
|
|
253
|
+
|
|
254
|
+
**Use smart quotes for new content:**
|
|
255
|
+
```xml
|
|
256
|
+
<w:t>Here’s a quote: “Hello”</w:t>
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
| Entity | Character |
|
|
260
|
+
|--------|-----------|
|
|
261
|
+
| `‘` | ' (left single) |
|
|
262
|
+
| `’` | ' (right single / apostrophe) |
|
|
263
|
+
| `“` | " (left double) |
|
|
264
|
+
| `”` | " (right double) |
|
|
265
|
+
|
|
266
|
+
**Adding comments:** Use `comment.py`:
|
|
267
|
+
```bash
|
|
268
|
+
python scripts/comment.py unpacked/ 0 "Comment text with & and ’"
|
|
269
|
+
python scripts/comment.py unpacked/ 1 "Reply text" --parent 0
|
|
270
|
+
python scripts/comment.py unpacked/ 0 "Text" --author "Kortix Agent"
|
|
271
|
+
```
|
|
272
|
+
Then add markers to document.xml (see Comments in XML Reference).
|
|
273
|
+
|
|
274
|
+
### Step 3: Pack
|
|
275
|
+
```bash
|
|
276
|
+
python scripts/office/pack.py unpacked/ output.docx --original document.docx
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Common Pitfalls
|
|
280
|
+
|
|
281
|
+
- Replace entire `<w:r>` elements when adding tracked changes
|
|
282
|
+
- Preserve `<w:rPr>` formatting -- copy original run's formatting into tracked change runs
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## XML Reference
|
|
287
|
+
|
|
288
|
+
### Schema Compliance
|
|
289
|
+
|
|
290
|
+
- Element order in `<w:pPr>`: `<w:pStyle>`, `<w:numPr>`, `<w:spacing>`, `<w:ind>`, `<w:jc>`, `<w:rPr>` last
|
|
291
|
+
- Whitespace: Add `xml:space="preserve"` to `<w:t>` with leading/trailing spaces
|
|
292
|
+
- RSIDs: Must be 8-digit hex (e.g., `00AB1234`)
|
|
293
|
+
|
|
294
|
+
### Tracked Changes
|
|
295
|
+
|
|
296
|
+
**Insertion:**
|
|
297
|
+
```xml
|
|
298
|
+
<w:ins w:id="1" w:author="Kortix Agent" w:date="2025-01-01T00:00:00Z">
|
|
299
|
+
<w:r><w:t>inserted text</w:t></w:r>
|
|
300
|
+
</w:ins>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Deletion:**
|
|
304
|
+
```xml
|
|
305
|
+
<w:del w:id="2" w:author="Kortix Agent" w:date="2025-01-01T00:00:00Z">
|
|
306
|
+
<w:r><w:delText>deleted text</w:delText></w:r>
|
|
307
|
+
</w:del>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Inside `<w:del>`: use `<w:delText>` instead of `<w:t>`.
|
|
311
|
+
|
|
312
|
+
**Minimal edits** -- only mark what changes:
|
|
313
|
+
```xml
|
|
314
|
+
<w:r><w:t>The term is </w:t></w:r>
|
|
315
|
+
<w:del w:id="1" w:author="Kortix Agent" w:date="...">
|
|
316
|
+
<w:r><w:delText>30</w:delText></w:r>
|
|
317
|
+
</w:del>
|
|
318
|
+
<w:ins w:id="2" w:author="Kortix Agent" w:date="...">
|
|
319
|
+
<w:r><w:t>60</w:t></w:r>
|
|
320
|
+
</w:ins>
|
|
321
|
+
<w:r><w:t> days.</w:t></w:r>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Deleting entire paragraphs** -- also mark paragraph mark as deleted:
|
|
325
|
+
```xml
|
|
326
|
+
<w:p>
|
|
327
|
+
<w:pPr>
|
|
328
|
+
<w:rPr>
|
|
329
|
+
<w:del w:id="1" w:author="Kortix Agent" w:date="2025-01-01T00:00:00Z"/>
|
|
330
|
+
</w:rPr>
|
|
331
|
+
</w:pPr>
|
|
332
|
+
<w:del w:id="2" w:author="Kortix Agent" w:date="2025-01-01T00:00:00Z">
|
|
333
|
+
<w:r><w:delText>Entire paragraph content...</w:delText></w:r>
|
|
334
|
+
</w:del>
|
|
335
|
+
</w:p>
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Rejecting another author's insertion:**
|
|
339
|
+
```xml
|
|
340
|
+
<w:ins w:author="Jane" w:id="5">
|
|
341
|
+
<w:del w:author="Kortix Agent" w:id="10">
|
|
342
|
+
<w:r><w:delText>their inserted text</w:delText></w:r>
|
|
343
|
+
</w:del>
|
|
344
|
+
</w:ins>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Restoring another author's deletion:**
|
|
348
|
+
```xml
|
|
349
|
+
<w:del w:author="Jane" w:id="5">
|
|
350
|
+
<w:r><w:delText>deleted text</w:delText></w:r>
|
|
351
|
+
</w:del>
|
|
352
|
+
<w:ins w:author="Kortix Agent" w:id="10">
|
|
353
|
+
<w:r><w:t>deleted text</w:t></w:r>
|
|
354
|
+
</w:ins>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Comments
|
|
358
|
+
|
|
359
|
+
Markers are direct children of `w:p`, never inside `w:r`:
|
|
360
|
+
|
|
361
|
+
```xml
|
|
362
|
+
<w:commentRangeStart w:id="0"/>
|
|
363
|
+
<w:r><w:t>commented text</w:t></w:r>
|
|
364
|
+
<w:commentRangeEnd w:id="0"/>
|
|
365
|
+
<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="0"/></w:r>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Images
|
|
369
|
+
|
|
370
|
+
1. Add image file to `word/media/`
|
|
371
|
+
2. Add relationship to `word/_rels/document.xml.rels`
|
|
372
|
+
3. Add content type to `[Content_Types].xml`
|
|
373
|
+
4. Reference in document.xml with `<w:drawing>`
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Visual Review Workflow
|
|
378
|
+
|
|
379
|
+
1. Convert DOCX -> PDF -> PNGs
|
|
380
|
+
2. Use `scripts/render_docx.py` (requires `pdf2image` and Poppler)
|
|
381
|
+
3. After each meaningful change, re-render and inspect
|
|
382
|
+
4. If visual review is not possible, extract text with `python-docx` as fallback
|
|
383
|
+
|
|
384
|
+
## Quality Expectations
|
|
385
|
+
|
|
386
|
+
- Deliver client-ready documents: consistent typography, spacing, margins, clear hierarchy
|
|
387
|
+
- Avoid formatting defects: clipped/overlapping text, broken tables, unreadable characters
|
|
388
|
+
- Use ASCII hyphens only. Avoid U+2011 and other Unicode dashes
|
|
389
|
+
- Re-render and inspect every page at 100% zoom before final delivery
|
|
390
|
+
|
|
391
|
+
## Dependencies
|
|
392
|
+
|
|
393
|
+
- **pandoc**: Text extraction
|
|
394
|
+
- **docx**: `npm install -g docx` (new documents)
|
|
395
|
+
- **LibreOffice**: PDF conversion (via `scripts/office/soffice.py`)
|
|
396
|
+
- **Poppler**: `pdftoppm` for images
|
|
397
|
+
- **python-docx**: Reading/analysis (`pip install python-docx`)
|
|
398
|
+
- **pdf2image**: Rendering (`pip install pdf2image`)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|