sheafmd 1.0.0__py3-none-any.whl
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.
- sheafmd/__init__.py +48 -0
- sheafmd/__main__.py +6 -0
- sheafmd/_pandoc.py +20 -0
- sheafmd/agent_files/agents-snippet.md +5 -0
- sheafmd/agent_files/claude-skill.md +65 -0
- sheafmd/agent_setup.py +633 -0
- sheafmd/agents/__init__.py +1 -0
- sheafmd/agents/base.py +100 -0
- sheafmd/agents/claude_code.py +377 -0
- sheafmd/agents/detect.py +63 -0
- sheafmd/agents/generic.py +57 -0
- sheafmd/agents/prompts.py +45 -0
- sheafmd/agents/registry.py +42 -0
- sheafmd/atomic.py +36 -0
- sheafmd/blocks.py +341 -0
- sheafmd/charts.py +399 -0
- sheafmd/cli.py +1013 -0
- sheafmd/comments.py +618 -0
- sheafmd/config.py +232 -0
- sheafmd/diagnostics.py +135 -0
- sheafmd/edit.py +1834 -0
- sheafmd/hub/__init__.py +1 -0
- sheafmd/hub/asktell.py +547 -0
- sheafmd/hub/auth.py +190 -0
- sheafmd/hub/client.py +518 -0
- sheafmd/hub/core.py +482 -0
- sheafmd/hub/events.py +106 -0
- sheafmd/hub/handler.py +890 -0
- sheafmd/hub/index.py +567 -0
- sheafmd/hub/jobs.py +223 -0
- sheafmd/hub/live.py +526 -0
- sheafmd/hub/peer.py +123 -0
- sheafmd/hub/proxy.py +301 -0
- sheafmd/hub/recover.py +242 -0
- sheafmd/hub/roots.py +569 -0
- sheafmd/hub/sender.py +113 -0
- sheafmd/hub/server.py +498 -0
- sheafmd/hub/service.py +280 -0
- sheafmd/hub/sock.py +118 -0
- sheafmd/hub/state.py +507 -0
- sheafmd/images.py +126 -0
- sheafmd/lifecycle.py +284 -0
- sheafmd/links.py +124 -0
- sheafmd/mcp.py +722 -0
- sheafmd/page/index.css +53 -0
- sheafmd/page/index.js +78 -0
- sheafmd/page/page.css +175 -0
- sheafmd/page/page.js +3101 -0
- sheafmd/paths.py +233 -0
- sheafmd/pdf.py +189 -0
- sheafmd/render.py +1189 -0
- sheafmd/sanitize.py +182 -0
- sheafmd/seat.py +52 -0
- sheafmd/source.py +259 -0
- sheafmd/theme.py +178 -0
- sheafmd/themes/plain/theme.css +32 -0
- sheafmd/themes/plain/theme.toml +1 -0
- sheafmd-1.0.0.dist-info/METADATA +163 -0
- sheafmd-1.0.0.dist-info/RECORD +62 -0
- sheafmd-1.0.0.dist-info/WHEEL +4 -0
- sheafmd-1.0.0.dist-info/entry_points.txt +2 -0
- sheafmd-1.0.0.dist-info/licenses/LICENSE +21 -0
sheafmd/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""sheaf: a working page for a markdown document, shared between a person and their agent.
|
|
2
|
+
|
|
3
|
+
The library API (SPEC 16). These names stay stable through 1.x; everything else in
|
|
4
|
+
the package is internal.
|
|
5
|
+
|
|
6
|
+
html = sheafmd.render(path, share=True, theme=None, title=None, toc="auto",
|
|
7
|
+
max_image_width=1400, by=None, for_=None, credit=None, log=None)
|
|
8
|
+
sheafmd.write_pdf(html, out) # raises sheafmd.PdfError
|
|
9
|
+
src = sheafmd.Source(path); text, digest = src.read(); src.update(change)
|
|
10
|
+
sheafmd.strip_comments(text) # the share copy's comment removal
|
|
11
|
+
sheafmd.comments.parse(text) # comments and malformed
|
|
12
|
+
sheafmd.load_root_config(root); sheafmd.load_theme(spec, root)
|
|
13
|
+
"""
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
__version__ = "1.0.0"
|
|
17
|
+
|
|
18
|
+
# `render` below is the public function, and it hides the module sheafmd/render.py as
|
|
19
|
+
# an attribute of the package: inside the package import from it (`from .render import
|
|
20
|
+
# build`), never `from . import render` or `import sheafmd.render as r`.
|
|
21
|
+
|
|
22
|
+
from . import comments
|
|
23
|
+
from .config import ConfigError, RootConfig, load_root_config
|
|
24
|
+
from .pdf import PdfError, write_pdf
|
|
25
|
+
from .render import RenderError, UnclosedComment, render_file, strip_comments
|
|
26
|
+
from .source import Source, StaleError
|
|
27
|
+
from .theme import Theme, load_theme
|
|
28
|
+
|
|
29
|
+
__all__ = ["render", "write_pdf", "Source", "strip_comments", "comments", "load_root_config",
|
|
30
|
+
"load_theme", "RootConfig", "Theme", "PdfError", "StaleError", "ConfigError",
|
|
31
|
+
"RenderError", "UnclosedComment", "__version__"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def render(path, *, share: bool = True, theme=None, title: str | None = None,
|
|
35
|
+
toc: str = "auto", max_image_width: int = 1400, by: str | None = None,
|
|
36
|
+
for_: str | None = None, credit: bool | None = None,
|
|
37
|
+
log: list[str] | None = None) -> str:
|
|
38
|
+
"""The HTML of the markdown file at `path`: a share copy by default, with every
|
|
39
|
+
comment removed and no script; `share=False` gives the page as the hub would serve
|
|
40
|
+
it, without the hub's meta values.
|
|
41
|
+
|
|
42
|
+
Reads the root's `.sheaf.toml` itself (`for`, `links`, `credit`, the theme). `for_`
|
|
43
|
+
replaces its `for` for this render; an empty string leaves the "for" out.
|
|
44
|
+
Every render-log line (`+` added, `!` warning, `-` removed), font failures
|
|
45
|
+
included, is appended to `log`; without one, the warnings go to stderr."""
|
|
46
|
+
return render_file(Path(path), share=share, theme=theme, title=title, toc=toc,
|
|
47
|
+
max_image_width=max_image_width, by=by, for_=for_, credit=credit,
|
|
48
|
+
log=log)
|
sheafmd/__main__.py
ADDED
sheafmd/_pandoc.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""The one place the bundled pandoc is started (SPEC 3.2).
|
|
2
|
+
|
|
3
|
+
A document can make pandoc run without end and grow without bound (pandoc 3.9: a footnote
|
|
4
|
+
that cites itself, `[^1]: a [^1]`), so every call has a heap cap and a time limit. A run that
|
|
5
|
+
hits either one comes back as a failed run, like a document pandoc cannot read."""
|
|
6
|
+
import subprocess
|
|
7
|
+
|
|
8
|
+
import pypandoc
|
|
9
|
+
|
|
10
|
+
HEAP = "-M1g" # a 470 KB document needs about 180 MB
|
|
11
|
+
TIMEOUT = 120 # seconds
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def run(args: list[str], text: str) -> subprocess.CompletedProcess:
|
|
15
|
+
cmd = [pypandoc.get_pandoc_path(), *args, "+RTS", HEAP, "-RTS"]
|
|
16
|
+
try:
|
|
17
|
+
return subprocess.run(cmd, input=text, capture_output=True, text=True,
|
|
18
|
+
encoding="utf-8", timeout=TIMEOUT)
|
|
19
|
+
except subprocess.TimeoutExpired:
|
|
20
|
+
return subprocess.CompletedProcess(cmd, 124, "", f"pandoc did not finish in {TIMEOUT} seconds")
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
This project keeps documents in markdown and uses sheaf: `sheaf FILE.md` opens a page for the person and prints its URL, which you give them. Do not render text meant for pasting somewhere else (an email, a post, a commit message, a prompt, a config file): put it in the conversation.
|
|
2
|
+
Before you revise a document, read its comments with `sheaf comments FILE.md`.
|
|
3
|
+
After you handle a comment, reply with `sheaf reply FILE.md ID "what you did" --resolve`; never delete a comment. A message that starts "Tell from sheaf" is a comment to act on: do it, then reply with `--role action`.
|
|
4
|
+
Record what goes wrong with `sheaf diag note "what went wrong"`. Never run `sheaf signin-url` yourself: it prints the hub's key; ask the person to run it.
|
|
5
|
+
Every page, article, tool or document you name is a markdown link to its URL, checked with curl that it answers.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sheaf
|
|
3
|
+
description: Show a markdown document to the person as a page in their browser and work through the comments they leave on it. Use when the person wants to read, review or edit a .md document on a page, when a document has open comments to answer, or when a message that starts "Tell from sheaf" arrives.
|
|
4
|
+
---
|
|
5
|
+
<!-- written by sheaf init; sheaf may replace it -->
|
|
6
|
+
|
|
7
|
+
# sheaf
|
|
8
|
+
|
|
9
|
+
sheaf turns a markdown file into a working page for the person: they read it, edit it and leave
|
|
10
|
+
comments on passages. The `.md` stays the source; whatever they do on the page lands back in it.
|
|
11
|
+
You work on the same file, and you see their comments in it.
|
|
12
|
+
|
|
13
|
+
## Show a document
|
|
14
|
+
|
|
15
|
+
`sheaf <file>` (for example `sheaf plan.md`) starts the hub if none runs, opens the page in the
|
|
16
|
+
person's browser and prints its URL. Give them that URL in your reply. Do it for what they will
|
|
17
|
+
read or review: plans, reports, comparisons, specifications, handoff notes. If they would have to
|
|
18
|
+
read it twice in the terminal, render it once.
|
|
19
|
+
|
|
20
|
+
Do not render text meant for pasting somewhere else (an email, a post, a commit message, a
|
|
21
|
+
prompt, a config file). A page gets in the way of the paste: put it in the conversation.
|
|
22
|
+
|
|
23
|
+
`sheaf <file> --share` writes a copy with no comments and no script, one HTML file to send on.
|
|
24
|
+
|
|
25
|
+
## Before you revise a document, read its comments
|
|
26
|
+
|
|
27
|
+
sheaf comments plan.md # the open comments: id, author, line, the passage, the thread
|
|
28
|
+
sheaf comments plan.md --all # the resolved ones too
|
|
29
|
+
|
|
30
|
+
If the sheaf tools are connected to you (`documents`, `threads`, `reply`, `resolve`), they do the
|
|
31
|
+
same. A comment sits in the `.md` right after the passage it is about. Edit the text around it
|
|
32
|
+
freely; never write, change or delete a comment by hand, because the commands keep the format the
|
|
33
|
+
page reads.
|
|
34
|
+
|
|
35
|
+
## After you handle a comment, reply and resolve it
|
|
36
|
+
|
|
37
|
+
sheaf reply plan.md c3 "Moved the date to March and said why." --resolve
|
|
38
|
+
|
|
39
|
+
Reply in the thread, and resolve it when it is done. Never delete a comment: the person reads the
|
|
40
|
+
answers comment by comment. Add a comment of your own on a passage with
|
|
41
|
+
`sheaf comment plan.md "the exact passage" "your note"`.
|
|
42
|
+
|
|
43
|
+
## A message that starts "Tell from sheaf"
|
|
44
|
+
|
|
45
|
+
The person pressed Tell on a comment: act on it in this conversation, then answer in the thread
|
|
46
|
+
with the role `action`, so the page shows that you did it:
|
|
47
|
+
|
|
48
|
+
sheaf reply plan.md c3 "What you did." --role action
|
|
49
|
+
|
|
50
|
+
With the tools: `reply(doc=..., id=..., text=..., role="action")`. A reply with no role is an
|
|
51
|
+
answer (use it when you only answer a question and change nothing). If you cannot do what the
|
|
52
|
+
comment asks, say so in the thread.
|
|
53
|
+
|
|
54
|
+
## Links
|
|
55
|
+
|
|
56
|
+
Every page, article, tool or document you name, in text you write into the document or in a reply, is a markdown link [words](https://full-url) to its URL, checked with curl that it answers. Link only what the text names, and never a generic page (a home page, a search page) where a specific one is meant.
|
|
57
|
+
|
|
58
|
+
## When something goes wrong
|
|
59
|
+
|
|
60
|
+
Record what only you can see, for the person who looks after sheaf: `sheaf diag note "what went
|
|
61
|
+
wrong, and what you were doing"`. It goes to the diagnostics log on their machine, nowhere else.
|
|
62
|
+
|
|
63
|
+
`sheaf signin-url` prints a URL that signs a browser in and holds the hub's key. Never run it
|
|
64
|
+
yourself: the key would be in your transcript. If the person needs one, ask the person to run it
|
|
65
|
+
in their own terminal. Never paste such a URL into a conversation or a file.
|