Skip to content

feat: dxedit — declarative docx edit CLI + library (manifest-driven, ooxml-swift direct, peer to che-word-mcp MCP front-end) #92

@kiki830621

Description

@kiki830621

Problem

che-word-mcp exposes ~218 OOXML editing tools over MCP stdio JSON-RPC. Two real-world workflows have hit the limits of going through the MCP transport:

  1. Replicable docx-edit pipelines — running the same edit plan against different docx baselines (e.g. template-population, content backfill, batch caption fix-ups) currently means either:
    • Manually re-driving 30+ MCP calls per run (lossy, error-prone), or
    • Writing one-off Python/Bash scripts that wrap MCP stdio (fragile, JSON-escape pain especially for CJK anchor text).
  2. che-word-mcp integration testingRealWorldDocxRoundTripSmokeTests covers open → save round-trip but not edit-path tests with non-trivial sequences (insert+replace+insert with anchors). A scriptable surface that drives the same ooxml-swift API che-word-mcp uses would let us assert end-to-end behaviour declaratively.

Both share the same need: a declarative way to describe a docx edit plan and execute it against ooxml-swift directly (no MCP transport overhead, no JSON escaping). MCP and this CLI become two front-ends on the same library.

Type

feature

Proposal

A new CLI + library inside macdoc/, sibling to mcp/che-word-mcp/:

macdoc/
├── mcp/che-word-mcp/         # existing (MCP front-end)
└── cli/dxedit/               # NEW
    ├── Package.swift         # depends on ooxml-swift (same dep as che-word-mcp)
    ├── Sources/
    │   ├── DxEditLib/        # library target — importable
    │   │   ├── Manifest.swift   # YAML/JSON decoding
    │   │   ├── Step.swift       # InsertImage / ReplaceText / InsertParagraph / InsertEquation / Verify
    │   │   ├── Executor.swift   # plan → execute → verify
    │   │   └── Verify.swift     # part-count, libxml2 validity, bookmark, font preservation checks
    │   └── dxedit/           # executable target — `dxedit` binary
    │       └── main.swift    # ArgumentParser → DxEditLib calls
    └── Tests/DxEditLibTests/

CLI surface

dxedit apply manifest.yaml --in baseline.docx --out output.docx
dxedit plan  manifest.yaml --in baseline.docx          # dry-run
dxedit verify --in baseline.docx --out output.docx     # post-condition assertions
dxedit diff a.docx b.docx                              # uses ooxml-swift compare API

Manifest sketch

baseline: archived/baseline.docx
output: docs/output.docx
steps:
  - insert_image:
      path: assets/figure_1.png
      anchor: { before_text: "<unique caption substring>" }
      width: 520
      name: fig_1
  - replace_text_batch:
      - { find: "<old>", replace: "<new>" }
  - insert_paragraph:
      anchor: { after_text: "<unique sentence>" }
      text: "<paragraph body>"
verify:
  expected_images: 23
  expected_bookmarks_min: 44
  libxml2_valid: true
  byte_preserved_parts:
    - word/header*.xml
    - word/footer*.xml
    - word/fontTable.xml
    - word/theme/*.xml

Why this lives in macdoc/ rather than a separate repo

  • Same SPM dep graph as che-word-mcp (both depend on ooxml-swift)
  • CLI changes often co-evolve with ooxml-swift API changes — atomic commits possible
  • che-word-mcp integration tests can shell out to dxedit for declarative E2E coverage
  • Workspace-style monorepo already established (macdoc/mcp/, macdoc/lib/, etc.)

A separate repo can be extracted later if the CLI grows beyond docx (e.g. unified dxedit / pxedit / pptedit toolkit), following the same pattern as #78 (NoteCore extraction) and #79 (pdf-to-latex-swift extraction).

Use cases

  1. Template population — given a docx template with anchor markers, populate with structured content from a manifest.
  2. Batch fix-up — apply caption format normalization across many docx files.
  3. Reproducible workflows — a docx-edit pipeline checked into a project repo (scripts/edit/manifest.yaml + dxedit apply) is replayable and version-controlled.
  4. che-word-mcp integration tests — declarative assertions about edit-path behaviour that supplement the existing round-trip XCTest suite.

Implementation phases

  • Phase 1: minimal apply command, supports insert_image, replace_text, replace_text_batch, insert_paragraph steps. YAML manifest. SPM library target.
  • Phase 2: verify command with post-condition harness (libxml2 validity, byte-preservation checks, content presence).
  • Phase 3: plan (dry-run), diff (using ooxml-swift compare), archive-first integration (auto-snapshot baseline before mutating writes).
  • Phase 4: extend step types as ooxml-swift API matures — insert_equation, wrap_caption_seq (depends on P2: helper to wrap plain-text captions in SEQ field for downstream TOF/TOT generation che-word-mcp#62), section/header/footer manipulation.

Caveats

Priority

P2 — useful for downstream replicable workflows; not blocking any current work.

Related


Current Status

Phase: verified / Spectra proposal ready
Last updated: 2026-05-02 by Codex

Key Decisions

Spectra Proposal

  • Change: macdoc-docx-workflow-cli
  • PR: Propose macdoc docx workflow CLI #94
  • Files: openspec/changes/macdoc-docx-workflow-cli/proposal.md, design.md, tasks.md, and specs/docx-workflow-cli/spec.md
  • Validation passed: spectra analyze macdoc-docx-workflow-cli --json, spectra validate macdoc-docx-workflow-cli, and git diff --check -- openspec/changes/macdoc-docx-workflow-cli

Blocking

Commits

  • 08d55b0 docs: propose macdoc docx workflow spec

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions