Metadata-Version: 2.4
Name: throughline-ms-copilot
Version: 0.3.0
Summary: Hand a throughline requirements graph to Microsoft 365 Copilot as a folder it reads whole — one file per register — and apply the change set it sends back through tl apply. Ships the tl-ms-copilot CLI.
Author-email: Henry J Grech-Cini <henry.grechcini@gmail.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/rhodium-org/throughline-ms-copilot
Project-URL: Repository, https://github.com/rhodium-org/throughline-ms-copilot
Project-URL: Issues, https://github.com/rhodium-org/throughline-ms-copilot/issues
Keywords: requirements,requirements-management,copilot,microsoft-365-copilot,traceability,idd,intent-driven-development,throughline
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: throughline>=3.19.2
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Dynamic: license-file

# throughline-ms-copilot

Work on a [throughline](https://github.com/rhodium-org/throughline) requirements
graph with **Microsoft 365 Copilot**, in an environment where Copilot is the only
assistant you have: it reads at most fifty files, runs no command and answers
only in text. `tl-ms-copilot` writes the graph as a folder Copilot reads whole,
and carries the changes Copilot sends back into the graph as proposals, through
`tl apply`, all or nothing.

```bash
pipx install throughline-ms-copilot
tl-ms-copilot export -C idd ~/OneDrive/graph-exchange      # the folder Copilot reads
#   … give Copilot every file in graph-exchange/export/, ask for changes,
#   save each answer into graph-exchange/inbox/ …
tl-ms-copilot ingest -C idd ~/OneDrive/graph-exchange --dry-run
tl-ms-copilot ingest -C idd ~/OneDrive/graph-exchange      # carried out by tl apply
tl -C idd check
```

The graph's content moves only between your computer and GitHub. The package
runs `tl` in-process and starts no process, so it runs unchanged under Pyodide
in a browser tab beside the folder you chose — which is how
[sync.iddn.uk](https://sync.iddn.uk/) offers it on a laptop where nothing can be
installed.

## The exchange folder

```
graph-exchange/
├── 00-START-HERE.md       what Copilot reads first: how to work with you (rewritten by each export)
├── export/                written by `export`, replaced whole each time
│   ├── manifest.json      what the export was true of, and how to answer
│   ├── INT.json  REQ.json  TEST.json …   one file per register
│   └── source-<ns>.json   the clauses an adopted source lends
└── inbox/                 Copilot's answers, saved by you
    ├── new/REQ.md         new items for one register
    ├── updates/REQ.md     amend, link, unlink, delete on one register's items
    ├── anything.md        a whole change set, any registers
    └── applied/<when>/    where `ingest` moves what it carried out
```

**What to tell Copilot.** Give it `00-START-HERE.md`, every file in `export/`, and one line:
*"Read 00-START-HERE.md first and follow it. I want to work on …"*. That file,
rewritten at the top of the exchange folder by every export, tells Copilot to report how many items it read in
each file against the manifest's counts, to talk in plain words until you say
"draft it", to send one register's change set at a time naming the inbox file to
save it as, to prefer amending to near-duplicates, never to ratify, and how to
recover from a refused or cut-off set. It ends with the change-set form exactly
as `tl apply --describe` states it, so it never drifts from what will apply the
answer. Change the guidance in the tool (`GUIDE` in `export.py`), not in a
prompt.

**Why one file per register.** Copilot's cap counts files, not items. A graph
holds hundreds of item files but fewer than fifty registers, so one file per
register is the smallest layout Copilot can read whole. `--wrap md` writes each
file as Markdown holding one fenced JSON block, for a Copilot that will not read
`.json` files. `--only UID,…` narrows the export to the items named.

**Why changes come back as a change set, not as files.** Copilot's answer is
length-capped: a rewritten register file cut off half-way would read as the
deletion of everything after the cut. A change set names only what changes, and
`tl apply` refuses the whole set if any item it touches changed since the export.
The manifest carries the form, as `tl apply --describe` states it, and tells
Copilot to answer in one fenced `json` block.

**Why answers are saved by register.** For long work, ask Copilot for one
register at a time — the new items for REQ, then the changes to REQ's items —
and save each answer as `inbox/new/REQ.md` or `inbox/updates/REQ.md`. Paste the
whole answer; the change set is found inside it. `ingest` gathers every file into
one change set: new items first, each after any new item it links to, then the
updates, then whole sets. It checks each file holds what its place says, and
moves what it applied into `inbox/applied/` so nothing is applied twice.

**Why there are no ID conflicts.** Copilot never chooses a UID. A new item is
named by a `label`, and another item in any answer links to it as `$label`;
`tl` allocates the real UID when the set is carried out, against the graph as it
then stands.

Everything Copilot drafts arrives with origin `ai` and waits as `proposed`: a
person decides. Decisions — ratifying, withdrawing — are never in a change set.

## Commands

| Command | What it does |
| --- | --- |
| `export [-C DIR] EXCHANGE [--wrap json\|md] [--only UID,…]` | Writes `EXCHANGE/export/` and creates `EXCHANGE/inbox/new` and `inbox/updates`. |
| `ingest [-C DIR] EXCHANGE [--dry-run]` | Gathers `EXCHANGE/inbox/` into one change set and has `tl apply` carry it out. |
| `apply [-C DIR] [REPLY\|-] [--dry-run] [--extract]` | The same for one saved reply. `--extract` prints the change set found and stops. |

`export` reads the repository, ref, commit and working-tree state from git;
`--repository`, `--ref`, `--commit` and `--tree` state them instead, as a host
with no git — the browser — does.

## Working on it

Its requirements live in [`idd/`](idd); see [AGENTS.md](AGENTS.md).

```bash
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest -q
tl -C idd check
```

Apache-2.0. Microsoft 365 Copilot is a product of Microsoft Corporation; this
project is not affiliated with or endorsed by Microsoft.
