Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions agent-harness/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__pycache__/
*.pyc
*.pyo
*.pyd
*.egg-info/
.pytest_cache/
33 changes: 33 additions & 0 deletions agent-harness/PYTHON_DOCX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# PYTHON_DOCX Harness

Target software: `python-docx`
Source path: `python-docx/`

## Scope

This harness exposes high-value document operations from `python-docx` as a stateful CLI:

- create/open/save documents
- add paragraph, heading, and table content
- insert template-driven frontpages/title pages
- update core metadata properties
- inspect summary and paragraph lists
- run with one-shot subcommands or interactive REPL
- emit machine-readable JSON output using `--json`
- support undo/redo in-session via in-memory `.docx` snapshots
- enforce a fixed visual palette (`#05206E` main, `#357AE9` secondary)

## Backend strategy

The harness wraps the real `python-docx` APIs in `utils/python_docx_backend.py` and does not reimplement `.docx` behavior.

## Session model

A `DocxSession` instance tracks:

- active in-memory document
- current path (if saved/opened)
- undo stack
- redo stack

Undo and redo operate on serialized `.docx` bytes captured before each mutating operation.
23 changes: 23 additions & 0 deletions agent-harness/TEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Test Plan

This harness includes two test layers:

1. `test_core.py`
- validates `DocxSession` state transitions
- confirms mutating operations alter document state correctly
- verifies undo/redo stack behavior
- checks save/open round-trip and metadata writes

2. `test_full_e2e.py`
- exercises the installed CLI command via subprocess
- verifies one-shot JSON output and persisted `.docx` edits
- verifies default REPL path and in-session undo

## Planned validation commands

From `python-docx/agent-harness`:

```bash
python -m pip install -e .
python -m pytest -q cli_anything/python_docx/tests
```
72 changes: 72 additions & 0 deletions agent-harness/cli_anything/python_docx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# CLI-Anything python-docx Harness

Stateful CLI harness for `python-docx` with one-shot commands, JSON output, and REPL-first workflow.

## Install

From `agent-harness/`:

```bash
python -m pip install -e .
```

## Usage

One-shot examples:

```bash
cli-anything-python-docx --json new ./demo.docx --title "Demo"
cli-anything-python-docx add-paragraph --doc ./demo.docx "Hello from CLI"
cli-anything-python-docx --json summary --doc ./demo.docx
cli-anything-python-docx frontpage-templates
cli-anything-python-docx add-frontpage --doc ./demo.docx --template clean --title "Operations Review" --subtitle "Q1 2026" --author "CLI Agent" --organization "Nordflint" --date-text "2026-03-26"
cli-anything-python-docx add-table --doc ./demo.docx --header Qty --header Id --header Desc --record "3|101|Spam" --record "7|422|Eggs" --record "4|631|Spam, spam, eggs, and spam"
cli-anything-python-docx add-table --doc ./demo.docx --header Qty --header Id --header Desc --record "3|101|Spam" --record "7|422|Eggs" --record "4|631|Spam, spam, eggs, and spam" --header-bold --row-lines --column-lines --outer-border --line-style single --line-size 8 --line-color main
```

REPL (default when no subcommand is provided):

```bash
cli-anything-python-docx
python-docx> new ./notes.docx --title "Notes"
python-docx> add-heading "Sprint" --level 2
python-docx> add-paragraph "Action item"
python-docx> undo
python-docx> save
python-docx> exit
```

## Commands

- `new [PATH] [--title TEXT]`
- `open PATH`
- `save [PATH]`
- `summary [--doc PATH]` (use global `--json` before the subcommand)
- `list-paragraphs [--doc PATH] [--limit N]` (use global `--json` before the subcommand)
- `add-paragraph [--doc PATH] [--style NAME] TEXT`
- `add-heading [--doc PATH] [--level N] TEXT`
- `frontpage-templates`
- `add-frontpage [--doc PATH] [--template NAME] --title TEXT [--subtitle TEXT] [--author TEXT] [--organization TEXT] [--date-text TEXT] [--page-break/--no-page-break] [--set-core-title/--no-set-core-title]`
- `add-table [--doc PATH] [--rows N] [--cols N] [--header TEXT ...] [--record TEXT ...] [--delimiter CHAR] [--header-bold] [--header-bg-color HEX] [--row-lines] [--column-lines] [--outer-border] [--line-style STYLE] [--line-size N] [--line-color COLOR]`
- `set-core [--doc PATH] KEY VALUE`
- `undo`
- `redo`
- `repl`

`--doc` on mutating commands enables one-shot edits that auto-save back to that file.

Structured table mode (`--header`/`--record`) is useful for record-style inserts.
Each `--record` line is parsed by `--delimiter` (default `|`).
Border formatting can be enabled independently for row separators (`--row-lines`) and column separators (`--column-lines`), and optional outside borders (`--outer-border`).
Header formatting defaults to `main` background with white text, and can be customized with `--header-bold` and `--header-bg-color`.
Frontpage templates let the agent insert a predefined title-page layout with a single command.
The `corporate` frontpage template uses a blue (`main`) background with white text.

## Palette

This harness enforces a fixed palette:

- `main`: `#05206E`
- `secondary`: `#357AE9`

Title/header fonts and table styling use these colors by default. Color options only accept `main`, `secondary`, or those exact hex values.
5 changes: 5 additions & 0 deletions agent-harness/cli_anything/python_docx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""CLI-Anything harness package for python-docx."""

__all__ = ["__version__"]

__version__ = "0.1.0"
9 changes: 9 additions & 0 deletions agent-harness/cli_anything/python_docx/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from cli_anything.python_docx.python_docx_cli import cli


def main() -> None:
cli(prog_name="cli-anything-python-docx")


if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions agent-harness/cli_anything/python_docx/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from cli_anything.python_docx.core.session import DocxSession, SessionError

__all__ = ["DocxSession", "SessionError"]
Loading