markback 0.2.1__tar.gz → 0.3.1__tar.gz

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.
Files changed (109) hide show
  1. {markback-0.2.1 → markback-0.3.1}/.gitignore +14 -0
  2. {markback-0.2.1 → markback-0.3.1}/.ishipped/card.md +3 -2
  3. markback-0.3.1/.ishipped/markback-icon.png +0 -0
  4. markback-0.3.1/AGENTS.md +213 -0
  5. {markback-0.2.1 → markback-0.3.1}/IMPLEMENTATION_NOTES.md +3 -3
  6. {markback-0.2.1 → markback-0.3.1}/PKG-INFO +78 -14
  7. {markback-0.2.1 → markback-0.3.1}/README.md +73 -9
  8. {markback-0.2.1 → markback-0.3.1}/SPEC.md +102 -21
  9. {markback-0.2.1 → markback-0.3.1}/markback/__init__.py +3 -1
  10. markback-0.3.1/markback/_headers.py +14 -0
  11. {markback-0.2.1 → markback-0.3.1}/markback/cli.py +4 -4
  12. {markback-0.2.1 → markback-0.3.1}/markback/linter.py +20 -6
  13. {markback-0.2.1 → markback-0.3.1}/markback/parser.py +81 -30
  14. {markback-0.2.1 → markback-0.3.1}/markback/types.py +25 -3
  15. {markback-0.2.1 → markback-0.3.1}/markback/writer.py +89 -44
  16. markback-0.3.1/packages/markback-vscode/.vscode/launch.json +17 -0
  17. markback-0.3.1/packages/markback-vscode/.vscode/tasks.json +15 -0
  18. markback-0.3.1/packages/markback-vscode/.vscodeignore +19 -0
  19. markback-0.3.1/packages/markback-vscode/CHANGELOG.md +128 -0
  20. markback-0.3.1/packages/markback-vscode/PUBLISH.md +76 -0
  21. markback-0.3.1/packages/markback-vscode/README.md +130 -0
  22. markback-0.3.1/packages/markback-vscode/esbuild.js +29 -0
  23. markback-0.3.1/packages/markback-vscode/icon.png +0 -0
  24. markback-0.3.1/packages/markback-vscode/media/SHOTLIST.md +66 -0
  25. markback-0.3.1/packages/markback-vscode/package-lock.json +2231 -0
  26. markback-0.3.1/packages/markback-vscode/package.json +318 -0
  27. markback-0.3.1/packages/markback-vscode/publish.ps1 +79 -0
  28. markback-0.3.1/packages/markback-vscode/src/actionState.ts +18 -0
  29. markback-0.3.1/packages/markback-vscode/src/author.ts +75 -0
  30. markback-0.3.1/packages/markback-vscode/src/commandLayer.ts +660 -0
  31. markback-0.3.1/packages/markback-vscode/src/commentControlPlane.ts +708 -0
  32. markback-0.3.1/packages/markback-vscode/src/excerpt.ts +134 -0
  33. markback-0.3.1/packages/markback-vscode/src/extension.ts +80 -0
  34. markback-0.3.1/packages/markback-vscode/src/focusCollision.ts +38 -0
  35. markback-0.3.1/packages/markback-vscode/src/ids.ts +12 -0
  36. markback-0.3.1/packages/markback-vscode/src/markdownItPlugin.ts +109 -0
  37. markback-0.3.1/packages/markback-vscode/src/output.ts +28 -0
  38. markback-0.3.1/packages/markback-vscode/src/preview/inject.css +193 -0
  39. markback-0.3.1/packages/markback-vscode/src/preview/inject.js +587 -0
  40. markback-0.3.1/packages/markback-vscode/src/projection.ts +153 -0
  41. markback-0.3.1/packages/markback-vscode/src/rangeCodec.ts +47 -0
  42. markback-0.3.1/packages/markback-vscode/src/sidecarPath.ts +25 -0
  43. markback-0.3.1/packages/markback-vscode/src/sidecarRepository.ts +350 -0
  44. markback-0.3.1/packages/markback-vscode/test/actionState.test.js +30 -0
  45. markback-0.3.1/packages/markback-vscode/test/excerpt.test.js +98 -0
  46. markback-0.3.1/packages/markback-vscode/test/focusCollision.test.js +59 -0
  47. markback-0.3.1/packages/markback-vscode/test/ids.test.js +15 -0
  48. markback-0.3.1/packages/markback-vscode/test/projection.test.js +109 -0
  49. markback-0.3.1/packages/markback-vscode/test/rangeCodec.test.js +105 -0
  50. markback-0.3.1/packages/markback-vscode/test/sidecarPath.test.js +45 -0
  51. markback-0.3.1/packages/markback-vscode/test/sidecarRepository.test.js +409 -0
  52. markback-0.3.1/packages/markback-vscode/test/wordDelete.test.js +79 -0
  53. markback-0.3.1/packages/markback-vscode/test-integration/runTest.js +37 -0
  54. markback-0.3.1/packages/markback-vscode/test-integration/suite/actions.test.js +92 -0
  55. markback-0.3.1/packages/markback-vscode/test-integration/suite/commentMultiAndCancel.test.js +155 -0
  56. markback-0.3.1/packages/markback-vscode/test-integration/suite/commentSelection.test.js +127 -0
  57. markback-0.3.1/packages/markback-vscode/test-integration/suite/index.js +30 -0
  58. markback-0.3.1/packages/markback-vscode/test-integration/suite/inlineExcerpt.test.js +152 -0
  59. {markback-0.2.1/packages/markbackjs → markback-0.3.1/packages/markback-vscode}/tsconfig.json +5 -5
  60. {markback-0.2.1 → markback-0.3.1}/pyproject.toml +5 -5
  61. markback-0.3.1/scripts/gen_headers.py +94 -0
  62. markback-0.3.1/shared/headers.json +7 -0
  63. markback-0.3.1/skills/README.md +26 -0
  64. markback-0.3.1/skills/markback/SKILL.md +432 -0
  65. markback-0.3.1/skills/markback/references/tooling.md +132 -0
  66. markback-0.3.1/tests/__init__.py +1 -0
  67. markback-0.3.1/tests/test_actions.py +98 -0
  68. {markback-0.2.1 → markback-0.3.1}/tests/test_cli.py +1 -1
  69. markback-0.3.1/tests/test_eol.py +75 -0
  70. markback-0.3.1/tests/test_headers_registry.py +56 -0
  71. {markback-0.2.1 → markback-0.3.1}/tests/test_linter.py +31 -1
  72. {markback-0.2.1 → markback-0.3.1}/tests/test_parser.py +72 -1
  73. {markback-0.2.1 → markback-0.3.1}/tests/test_types.py +1 -1
  74. {markback-0.2.1 → markback-0.3.1}/tests/test_writer.py +1 -1
  75. markback-0.2.1/.claude/settings.local.json +0 -34
  76. markback-0.2.1/AGENTS.md +0 -135
  77. markback-0.2.1/packages/markbackjs/README.md +0 -47
  78. markback-0.2.1/packages/markbackjs/package-lock.json +0 -51
  79. markback-0.2.1/packages/markbackjs/package.json +0 -33
  80. markback-0.2.1/packages/markbackjs/src/index.ts +0 -24
  81. markback-0.2.1/packages/markbackjs/src/linter.ts +0 -417
  82. markback-0.2.1/packages/markbackjs/src/parser.ts +0 -450
  83. markback-0.2.1/packages/markbackjs/src/types.ts +0 -418
  84. markback-0.2.1/packages/markbackjs/src/writer.ts +0 -174
  85. markback-0.2.1/packages/markbackjs/test/linter.test.js +0 -378
  86. markback-0.2.1/packages/markbackjs/test/multi_segment.test.js +0 -167
  87. markback-0.2.1/tests/__init__.py +0 -1
  88. {markback-0.2.1 → markback-0.3.1}/LICENSE +0 -0
  89. {markback-0.2.1/packages/markbackjs → markback-0.3.1/packages/markback-vscode}/LICENSE +0 -0
  90. {markback-0.2.1 → markback-0.3.1}/scripts/bump-version.sh +0 -0
  91. {markback-0.2.1 → markback-0.3.1}/scripts/publish-npm.sh +0 -0
  92. {markback-0.2.1 → markback-0.3.1}/scripts/publish-pypi.sh +0 -0
  93. {markback-0.2.1 → markback-0.3.1}/scripts/publish.sh +0 -0
  94. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/compact_source.mb +0 -0
  95. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/errors/content_with_source.mb +0 -0
  96. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/errors/empty_feedback.mb +0 -0
  97. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/errors/malformed_uri.mb +0 -0
  98. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/errors/missing_feedback.mb +0 -0
  99. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/errors/multiple_feedback.mb +0 -0
  100. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/essay.label.txt +0 -0
  101. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/essay.txt +0 -0
  102. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/external_source.mb +0 -0
  103. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/freeform_feedback.mb +0 -0
  104. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/json_feedback.mb +0 -0
  105. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/label_list.mb +0 -0
  106. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/minimal.mb +0 -0
  107. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/minimal.mb.mb +0 -0
  108. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/multi_record.mb +0 -0
  109. {markback-0.2.1 → markback-0.3.1}/tests/fixtures/with_uri.mb +0 -0
@@ -208,8 +208,22 @@ cython_debug/
208
208
  node_modules/
209
209
  packages/markback/dist/
210
210
  packages/markback/*.tsbuildinfo
211
+ packages/markback-vscode/.vscode-test/
212
+ packages/markback-vscode/dist/
213
+ packages/markback-vscode/*.vsix
214
+
215
+ # Track the internal markbackjs lib's build output (overrides the blanket
216
+ # `dist/` rule above). The VS Code extension consumes markbackjs as a file:
217
+ # dependency via its dist, so committing it keeps a fresh checkout's type
218
+ # resolution and bundle correct without a separate per-consumer build step.
219
+ !packages/markbackjs/dist/
220
+ !packages/markbackjs/dist/**
221
+ packages/markbackjs/dist/*.map
222
+ packages/markbackjs/dist/**/*.map
211
223
 
212
224
  # Marimo
213
225
  marimo/_static/
214
226
  marimo/_lsp/
215
227
  __marimo__/
228
+ # Local agent/tooling state — never commit
229
+ .claude/
@@ -1,8 +1,9 @@
1
1
  ---
2
- title: "MarkBack"
2
+ title: "Markback"
3
3
  summary: "Human-writable format for pairing content with labels and feedback."
4
4
  shipped: 2026-01-04
5
5
  theme: forest
6
+ icon: markback-icon.png
6
7
  tags: [data-annotation, machine-learning, cli, python, typescript]
7
8
  links:
8
9
  - label: "markback.org"
@@ -16,7 +17,7 @@ links:
16
17
 
17
18
  ## What is it?
18
19
 
19
- MarkBack is a compact file format for storing content alongside feedback and labels. It's built for training data management, prompt engineering, and annotation workflows where you need human-readable files that machines can parse reliably.
20
+ Markback is a compact file format for storing content alongside feedback and labels. It's built for training data management, prompt engineering, and annotation workflows where you need human-readable files that machines can parse reliably.
20
21
 
21
22
  ## Key Features
22
23
 
@@ -0,0 +1,213 @@
1
+ # Writing Markback (.mb) files
2
+
3
+ Markback pairs content with single-line feedback using `<<<` as the delimiter.
4
+
5
+ This is the quickstart. For the full read/write manual — including the traps
6
+ that cost real time — load `skills/markback/SKILL.md`. `SPEC.md` is the
7
+ authority.
8
+
9
+ ## Minimal record
10
+
11
+ ```
12
+ Some content here.
13
+ <<< positive
14
+ ```
15
+
16
+ ## Record with headers
17
+
18
+ ```
19
+ @id item-001
20
+ @by reviewer@example.com
21
+ @file ./file.txt
22
+ @input ./prompt.txt
23
+ @tag review p1
24
+
25
+ Inline content goes here.
26
+ <<< good; quality=high
27
+ ```
28
+
29
+ Headers: `@id`, `@reply-to`, `@by`, `@action`, `@tag`, `@input`, `@file`. All
30
+ optional, and that is also their canonical order.
31
+
32
+ ## Rules
33
+
34
+ - `<<<` must be followed by one space then feedback text
35
+ - a blank line is **required** between headers and inline content — omit it and
36
+ a content line starting with `@` is parsed as a header, and the content is
37
+ silently dropped
38
+ - `@file` + inline content can coexist (file is provenance, content is snapshot)
39
+ - full records are separated by `---`, written directly after the preceding
40
+ `<<<` line with no blank line before it
41
+ - files must be UTF-8 with LF line endings
42
+ - `@id` values are plain strings (no URI validation)
43
+
44
+ ## Compact format (one record per line)
45
+
46
+ ```
47
+ @file ./images/001.jpg <<< approved; scene=beach
48
+ @file ./images/002.jpg <<< rejected; too dark
49
+ ```
50
+
51
+ No `---` separator needed between compact records. `@id` can go on the line above:
52
+
53
+ ```
54
+ @id item-001
55
+ @file ./file.txt <<< good
56
+ ```
57
+
58
+ Do not leave a blank line before those headers — in 0.3.0 that makes the parser
59
+ discard the record's own `@id`, `@by`, and `@tag` and inherit the previous
60
+ record's instead ([#15](https://github.com/dandriscoll/markback/issues/15)).
61
+ Pack compact records together, or separate them with `---`.
62
+
63
+ ## Multi-record file
64
+
65
+ ```
66
+ @id first
67
+
68
+ First content.
69
+ <<< positive
70
+ ---
71
+ @id second
72
+
73
+ Second content.
74
+ <<< negative; needs work
75
+ ```
76
+
77
+ ## Multi-segment section
78
+
79
+ Several comments on one source, without repeating the headers. Write successive
80
+ content + `<<<` pairs with no `---` between them; the first segment's `@file`,
81
+ `@by`, `@tag`, and `@input` carry to the rest.
82
+
83
+ ```
84
+ @file ./essay.txt
85
+ @by dan
86
+
87
+ the lazy fox
88
+ <<< awkward
89
+
90
+ weak ending
91
+ <<< needs punch
92
+ ```
93
+
94
+ That is two records, both on `./essay.txt`. A `---` ends the section. `@id`,
95
+ `@reply-to`, and `@action` are per-record and never inherited.
96
+
97
+ ## File-level headers (% prefix)
98
+
99
+ ```
100
+ %markback 2
101
+ %scope issue-A issue-B
102
+ %covers ./gen/batch3/*.txt
103
+
104
+ @file ./gen/batch3/file2.txt <<< issue-B; tone is off
105
+ ```
106
+
107
+ - `%markback 2` — version declaration
108
+ - `%scope` — what issues are being checked (sweep pattern)
109
+ - `%covers` — glob of all files reviewed (absence = clean for scope)
110
+
111
+ All `%` lines go at the very top, before any record.
112
+
113
+ ## Tags
114
+
115
+ ```
116
+ @id item-001
117
+ @tag training positive-examples batch-2024-03
118
+ @file ./data/example.txt
119
+ <<< approved
120
+ ```
121
+
122
+ Space-separated. Multiple `@tag` lines merge.
123
+
124
+ ## Threading and lifecycle
125
+
126
+ `@reply-to` carries the `@id` of the record being replied to:
127
+
128
+ ```
129
+ @id c1
130
+ @file ./login.py:42 <<< this branch never fires
131
+ ---
132
+ @id c2
133
+ @reply-to c1
134
+ @file ./login.py:42 <<< it does — covered by test_login_edge()
135
+ ```
136
+
137
+ `@action <verb> <timestamp> [actor]` records a lifecycle event. Repeatable and
138
+ order-preserving; the well-known verbs are `created`, `viewed`, `resolved`,
139
+ `reopened`.
140
+
141
+ ```
142
+ @action created 2026-06-17T10:00:00Z dan@example.com
143
+ @action resolved 2026-06-18T14:30:00Z Reviewer Two
144
+ ```
145
+
146
+ A record is resolved when its most recent `resolved`/`reopened` action is
147
+ `resolved`.
148
+
149
+ ## Feedback format
150
+
151
+ Feedback is freeform text. Optional structured convention:
152
+
153
+ | Pattern | Meaning |
154
+ |---------|---------|
155
+ | `<<< positive` | label |
156
+ | `<<< negative; too vague` | label + comment |
157
+ | `<<< good; quality=high` | label + attribute |
158
+ | `<<< quality=high; confidence=0.9` | attributes only |
159
+ | `<<< json:{"key":"value"}` | JSON mode |
160
+
161
+ Segments are separated by `; ` (semicolon + space). Segments with `=` are key-value attributes; without are labels or comments.
162
+
163
+ ## Multi-line feedback
164
+
165
+ When the text right after `<<< ` is exactly `"""`, the feedback runs until a
166
+ line whose only content is `"""`:
167
+
168
+ ```
169
+ @id c1
170
+ @file ./login.py:42
171
+ <<< """
172
+ This branch looks dead, but I want to double-check before
173
+ suggesting removal.
174
+ """
175
+ ```
176
+
177
+ Use it only when the feedback genuinely contains a newline.
178
+
179
+ ## Sidecar files
180
+
181
+ Content in `name.ext`, annotation in `name.ext.mb`:
182
+
183
+ **report.pdf** — the content
184
+ **report.pdf.mb:**
185
+ ```
186
+ @id report-001
187
+ <<< good; grade=B+
188
+ ```
189
+
190
+ ## Line/character ranges
191
+
192
+ `@file` and `@input` support position references:
193
+
194
+ ```
195
+ @file ./code.py:42 ← line 42
196
+ @file ./code.py:42-50 ← lines 42–50
197
+ @file ./code.py:10:5-15:20 ← line 10 col 5 to line 15 col 20
198
+ ```
199
+
200
+ ## V1 backward compatibility
201
+
202
+ V1 headers (`@uri`, `@source`, `@prior`) are automatically mapped to V2 (`@id`, `@file`, `@input`) with a W010 warning.
203
+
204
+ ## Quick checklist
205
+
206
+ - [ ] every record has exactly one `<<<` line
207
+ - [ ] feedback is a single line, or fenced with `"""`
208
+ - [ ] blank line before inline content
209
+ - [ ] `---` between full records, no blank line before it; not needed between compact records
210
+ - [ ] file ends with a newline
211
+
212
+ Validate with `mb --lint file.mb`. Add `--no-canonical-check` if the file has
213
+ `%` headers — W008 always fires on those.
@@ -1,4 +1,4 @@
1
- # Implementation Notes — MarkBack V2
1
+ # Implementation Notes — Markback V2
2
2
 
3
3
  ## V1 → V2 Changes
4
4
 
@@ -15,9 +15,9 @@
15
15
  - Sidecar convention simplified to `name.ext.mb` only
16
16
 
17
17
  ### Removed
18
- - LLM workflow layer (`llm.py`, `workflow.py`) — not core to MarkBack
18
+ - LLM workflow layer (`llm.py`, `workflow.py`) — not core to Markback
19
19
  - `httpx` dependency
20
- - `config.py` / `python-dotenv` dependency / `--init` command — not core to MarkBack
20
+ - `config.py` / `python-dotenv` dependency / `--init` command — not core to Markback
21
21
  - RFC 3986 URI validation on `@id`
22
22
  - E003 (malformed URI) no longer emitted
23
23
  - E005 (content with @source) no longer emitted — coexistence is valid
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markback
3
- Version: 0.2.1
4
- Summary: A compact, human-writable format for storing content paired with feedback/labels
5
- Project-URL: Homepage, https://github.com/dandriscoll/markback
3
+ Version: 0.3.1
4
+ Summary: Markback comments for anything, in plain text, in git.
5
+ Project-URL: Homepage, https://markback.org
6
6
  Project-URL: Repository, https://github.com/dandriscoll/markback
7
- Project-URL: Documentation, https://github.com/dandriscoll/markback#readme
7
+ Project-URL: Documentation, https://markback.org/format/spec
8
8
  Project-URL: Issues, https://github.com/dandriscoll/markback/issues
9
9
  Author: Dan Driscoll
10
10
  License-Expression: MIT
11
11
  License-File: LICENSE
12
- Keywords: annotation,data-labeling,feedback,labeling,llm,markdown
12
+ Keywords: annotation,data-labeling,evaluation,feedback,labeling,linter,llm,markdown,prompt-engineering
13
13
  Classifier: Development Status :: 3 - Alpha
14
14
  Classifier: Environment :: Console
15
15
  Classifier: Intended Audience :: Developers
@@ -31,9 +31,26 @@ Requires-Dist: pytest>=7.0.0; extra == 'dev'
31
31
  Requires-Dist: twine>=5.0.0; extra == 'dev'
32
32
  Description-Content-Type: text/markdown
33
33
 
34
- # MarkBack V2
34
+ # Markback
35
35
 
36
- A compact, human-writable format for storing content paired with feedback/labels.
36
+ > **Comments for anything. In plain text. In git.**
37
+
38
+ [![PyPI](https://img.shields.io/pypi/v/markback.svg)](https://pypi.org/project/markback/)
39
+ [![npm](https://img.shields.io/npm/v/markbackjs.svg)](https://www.npmjs.com/package/markbackjs)
40
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
41
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
42
+
43
+ Markback is a tiny text format for leaving feedback on any file —
44
+ text, code, images, PDFs — that lints, diffs, and lives next to the
45
+ work. CLI, Python, Node, a browser editor, and a VS Code extension.
46
+
47
+ ## Start here
48
+
49
+ - **Try it without installing** — [markback.org/try-it](https://markback.org/try-it)
50
+ - **Install the CLI** — `pip install markback` or `npm install markbackjs`
51
+ - **Read the format** — [Specification](https://markback.org/format/spec)
52
+ - **Comment from your editor** — [VS Code extension](https://marketplace.visualstudio.com/items?itemName=dandriscoll.markback-vscode)
53
+ - **Point your coding agent at it** — [`skills/markback`](skills/markback/SKILL.md)
37
54
 
38
55
  ## Installation
39
56
 
@@ -41,9 +58,9 @@ A compact, human-writable format for storing content paired with feedback/labels
41
58
  pip install -e .
42
59
  ```
43
60
 
44
- ## Quick Start
61
+ ## Quick start
45
62
 
46
- ### Parse a MarkBack file
63
+ ### Parse a Markback file
47
64
 
48
65
  ```python
49
66
  from markback import parse_file, parse_string
@@ -63,7 +80,7 @@ Some content here.
63
80
  result = parse_string(text)
64
81
  ```
65
82
 
66
- ### Write MarkBack files
83
+ ### Write Markback files
67
84
 
68
85
  ```python
69
86
  from markback import Record, FileRef, write, append
@@ -90,7 +107,7 @@ if result.has_errors:
90
107
  print(d)
91
108
  ```
92
109
 
93
- ## CLI Usage
110
+ ## CLI usage
94
111
 
95
112
  The CLI is available via `markback` or `mb` (shorthand).
96
113
 
@@ -162,18 +179,22 @@ mb --upgrade *.mb # preview
162
179
  mb --upgrade --apply --in-place *.mb # apply
163
180
  ```
164
181
 
165
- ## File Format
182
+ ## File format
166
183
 
167
- ### V2 Headers
184
+ ### Headers
168
185
 
169
186
  | Header | Purpose |
170
187
  |--------|---------|
171
188
  | `@id` | Record identifier (plain string) |
189
+ | `@reply-to` | The `@id` this record replies to |
172
190
  | `@by` | Who provided feedback |
191
+ | `@action` | `<verb> <timestamp> [actor]` lifecycle event; repeatable |
173
192
  | `@tag` | Space-separated tags |
174
193
  | `@input` | What produced the content (e.g., a prompt) |
175
194
  | `@file` | Path to the content being annotated |
176
195
 
196
+ Listed in canonical order. All are optional.
197
+
177
198
  ### File-level headers (% prefix)
178
199
 
179
200
  ```
@@ -200,6 +221,49 @@ mb --upgrade --apply --in-place *.mb # apply
200
221
  @file ./images/002.jpg <<< rejected; too dark
201
222
  ```
202
223
 
224
+ ### Multi-segment section
225
+
226
+ Several comments on one source, without repeating the headers — write
227
+ successive content + `<<<` pairs with no `---` between them:
228
+
229
+ ```
230
+ @file ./essay.txt
231
+
232
+ the lazy fox
233
+ <<< awkward
234
+
235
+ weak ending
236
+ <<< needs punch
237
+ ```
238
+
239
+ Two records, both on `./essay.txt`. A `---` ends the section.
240
+
241
+ ### Threading and lifecycle
242
+
243
+ ```
244
+ @id c1
245
+ @action created 2026-06-17T10:00:00Z dan@example.com
246
+ @file ./login.py:42 <<< this branch never fires
247
+ ---
248
+ @id c2
249
+ @reply-to c1
250
+ @file ./login.py:42 <<< it does — covered by test_login_edge()
251
+ ```
252
+
253
+ ### Multi-line feedback
254
+
255
+ When the text right after `<<< ` is exactly `"""`, feedback runs until a line
256
+ whose only content is `"""`:
257
+
258
+ ```
259
+ @id c1
260
+ @file ./login.py:42
261
+ <<< """
262
+ This branch looks dead, but I want to double-check before
263
+ suggesting removal.
264
+ """
265
+ ```
266
+
203
267
  ### Sidecar files
204
268
 
205
269
  Content in `report.pdf`, annotation in `report.pdf.mb`:
@@ -224,7 +288,7 @@ Track issues across batches with meaningful absence:
224
288
 
225
289
  Files matching `%covers` without annotations are implicitly clean for all `%scope` items.
226
290
 
227
- ## V1 Backward Compatibility
291
+ ## V1 backward compatibility
228
292
 
229
293
  V1 headers (`@uri`, `@source`, `@prior`) are automatically mapped to V2 equivalents with a W010 warning. The V2 parser reads V1 files transparently.
230
294
 
@@ -1,6 +1,23 @@
1
- # MarkBack V2
1
+ # Markback
2
2
 
3
- A compact, human-writable format for storing content paired with feedback/labels.
3
+ > **Comments for anything. In plain text. In git.**
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/markback.svg)](https://pypi.org/project/markback/)
6
+ [![npm](https://img.shields.io/npm/v/markbackjs.svg)](https://www.npmjs.com/package/markbackjs)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
9
+
10
+ Markback is a tiny text format for leaving feedback on any file —
11
+ text, code, images, PDFs — that lints, diffs, and lives next to the
12
+ work. CLI, Python, Node, a browser editor, and a VS Code extension.
13
+
14
+ ## Start here
15
+
16
+ - **Try it without installing** — [markback.org/try-it](https://markback.org/try-it)
17
+ - **Install the CLI** — `pip install markback` or `npm install markbackjs`
18
+ - **Read the format** — [Specification](https://markback.org/format/spec)
19
+ - **Comment from your editor** — [VS Code extension](https://marketplace.visualstudio.com/items?itemName=dandriscoll.markback-vscode)
20
+ - **Point your coding agent at it** — [`skills/markback`](skills/markback/SKILL.md)
4
21
 
5
22
  ## Installation
6
23
 
@@ -8,9 +25,9 @@ A compact, human-writable format for storing content paired with feedback/labels
8
25
  pip install -e .
9
26
  ```
10
27
 
11
- ## Quick Start
28
+ ## Quick start
12
29
 
13
- ### Parse a MarkBack file
30
+ ### Parse a Markback file
14
31
 
15
32
  ```python
16
33
  from markback import parse_file, parse_string
@@ -30,7 +47,7 @@ Some content here.
30
47
  result = parse_string(text)
31
48
  ```
32
49
 
33
- ### Write MarkBack files
50
+ ### Write Markback files
34
51
 
35
52
  ```python
36
53
  from markback import Record, FileRef, write, append
@@ -57,7 +74,7 @@ if result.has_errors:
57
74
  print(d)
58
75
  ```
59
76
 
60
- ## CLI Usage
77
+ ## CLI usage
61
78
 
62
79
  The CLI is available via `markback` or `mb` (shorthand).
63
80
 
@@ -129,18 +146,22 @@ mb --upgrade *.mb # preview
129
146
  mb --upgrade --apply --in-place *.mb # apply
130
147
  ```
131
148
 
132
- ## File Format
149
+ ## File format
133
150
 
134
- ### V2 Headers
151
+ ### Headers
135
152
 
136
153
  | Header | Purpose |
137
154
  |--------|---------|
138
155
  | `@id` | Record identifier (plain string) |
156
+ | `@reply-to` | The `@id` this record replies to |
139
157
  | `@by` | Who provided feedback |
158
+ | `@action` | `<verb> <timestamp> [actor]` lifecycle event; repeatable |
140
159
  | `@tag` | Space-separated tags |
141
160
  | `@input` | What produced the content (e.g., a prompt) |
142
161
  | `@file` | Path to the content being annotated |
143
162
 
163
+ Listed in canonical order. All are optional.
164
+
144
165
  ### File-level headers (% prefix)
145
166
 
146
167
  ```
@@ -167,6 +188,49 @@ mb --upgrade --apply --in-place *.mb # apply
167
188
  @file ./images/002.jpg <<< rejected; too dark
168
189
  ```
169
190
 
191
+ ### Multi-segment section
192
+
193
+ Several comments on one source, without repeating the headers — write
194
+ successive content + `<<<` pairs with no `---` between them:
195
+
196
+ ```
197
+ @file ./essay.txt
198
+
199
+ the lazy fox
200
+ <<< awkward
201
+
202
+ weak ending
203
+ <<< needs punch
204
+ ```
205
+
206
+ Two records, both on `./essay.txt`. A `---` ends the section.
207
+
208
+ ### Threading and lifecycle
209
+
210
+ ```
211
+ @id c1
212
+ @action created 2026-06-17T10:00:00Z dan@example.com
213
+ @file ./login.py:42 <<< this branch never fires
214
+ ---
215
+ @id c2
216
+ @reply-to c1
217
+ @file ./login.py:42 <<< it does — covered by test_login_edge()
218
+ ```
219
+
220
+ ### Multi-line feedback
221
+
222
+ When the text right after `<<< ` is exactly `"""`, feedback runs until a line
223
+ whose only content is `"""`:
224
+
225
+ ```
226
+ @id c1
227
+ @file ./login.py:42
228
+ <<< """
229
+ This branch looks dead, but I want to double-check before
230
+ suggesting removal.
231
+ """
232
+ ```
233
+
170
234
  ### Sidecar files
171
235
 
172
236
  Content in `report.pdf`, annotation in `report.pdf.mb`:
@@ -191,7 +255,7 @@ Track issues across batches with meaningful absence:
191
255
 
192
256
  Files matching `%covers` without annotations are implicitly clean for all `%scope` items.
193
257
 
194
- ## V1 Backward Compatibility
258
+ ## V1 backward compatibility
195
259
 
196
260
  V1 headers (`@uri`, `@source`, `@prior`) are automatically mapped to V2 equivalents with a W010 warning. The V2 parser reads V1 files transparently.
197
261