markback 0.1.0__tar.gz → 0.1.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.
- markback-0.1.1/.claude/settings.local.json +9 -0
- {markback-0.1.0 → markback-0.1.1}/.gitignore +5 -0
- markback-0.1.1/.ishipped/card.md +26 -0
- {markback-0.1.0 → markback-0.1.1}/PKG-INFO +11 -1
- {markback-0.1.0 → markback-0.1.1}/README.md +10 -0
- {markback-0.1.0 → markback-0.1.1}/SPEC.md +47 -8
- {markback-0.1.0 → markback-0.1.1}/markback/linter.py +29 -1
- {markback-0.1.0 → markback-0.1.1}/markback/parser.py +8 -2
- {markback-0.1.0 → markback-0.1.1}/markback/types.py +3 -0
- {markback-0.1.0 → markback-0.1.1}/markback/writer.py +9 -2
- markback-0.1.1/packages/markbackjs/LICENSE +21 -0
- markback-0.1.1/packages/markbackjs/README.md +47 -0
- markback-0.1.1/packages/markbackjs/package-lock.json +51 -0
- markback-0.1.1/packages/markbackjs/package.json +33 -0
- markback-0.1.1/packages/markbackjs/src/index.ts +23 -0
- markback-0.1.1/packages/markbackjs/src/linter.ts +325 -0
- markback-0.1.1/packages/markbackjs/src/parser.ts +357 -0
- markback-0.1.1/packages/markbackjs/src/types.ts +314 -0
- markback-0.1.1/packages/markbackjs/src/writer.ts +73 -0
- markback-0.1.1/packages/markbackjs/test/linter.test.js +107 -0
- markback-0.1.1/packages/markbackjs/tsconfig.json +17 -0
- {markback-0.1.0 → markback-0.1.1}/pyproject.toml +1 -1
- {markback-0.1.0 → markback-0.1.1}/tests/test_linter.py +19 -0
- {markback-0.1.0 → markback-0.1.1}/tests/test_parser.py +52 -0
- {markback-0.1.0 → markback-0.1.1}/tests/test_writer.py +58 -0
- {markback-0.1.0 → markback-0.1.1}/IMPLEMENTATION_NOTES.md +0 -0
- {markback-0.1.0 → markback-0.1.1}/LICENSE +0 -0
- {markback-0.1.0 → markback-0.1.1}/markback/__init__.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/markback/cli.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/markback/config.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/markback/llm.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/markback/workflow.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/__init__.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/compact_source.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/content_with_source.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/empty_feedback.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/malformed_uri.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/missing_feedback.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/multiple_feedback.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/essay.label.txt +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/essay.txt +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/external_source.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/freeform_feedback.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/json_feedback.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/label_list.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/minimal.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/multi_record.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/fixtures/with_uri.mb +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/test_cli.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/test_config.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/test_types.py +0 -0
- {markback-0.1.0 → markback-0.1.1}/tests/test_workflow.py +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "MarkBack"
|
|
3
|
+
summary: "Human-writable format for pairing content with labels and feedback."
|
|
4
|
+
shipped: 2026-01-04
|
|
5
|
+
tags: [data-annotation, machine-learning, cli, python, typescript]
|
|
6
|
+
links:
|
|
7
|
+
- label: "markback.org"
|
|
8
|
+
url: "https://markback.org"
|
|
9
|
+
- label: "GitHub"
|
|
10
|
+
url: "https://github.com/dandriscoll/markback"
|
|
11
|
+
primary: true
|
|
12
|
+
- label: "NPM"
|
|
13
|
+
url: "https://www.npmjs.com/package/markbackjs"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## What is it?
|
|
17
|
+
|
|
18
|
+
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.
|
|
19
|
+
|
|
20
|
+
## Key Features
|
|
21
|
+
|
|
22
|
+
- **Multiple storage modes** — Single-file, multi-record, compact one-liner, or paired files. Pick what fits your workflow.
|
|
23
|
+
- **Structured feedback parsing** — Labels, key-value attributes, JSON, and freeform comments in one line.
|
|
24
|
+
- **Comprehensive linting** — 18 diagnostic rules catch errors and style issues with precise line numbers.
|
|
25
|
+
- **External content references** — Point to files, URIs, or embed content inline. Works with text, images, and binary files.
|
|
26
|
+
- **Dual-language support** — Full implementations in Python (CLI + library) and TypeScript.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: markback
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: A compact, human-writable format for storing content paired with feedback/labels
|
|
5
5
|
Project-URL: Homepage, https://github.com/dandriscoll/markback
|
|
6
6
|
Project-URL: Repository, https://github.com/dandriscoll/markback
|
|
@@ -196,6 +196,16 @@ Second content.
|
|
|
196
196
|
@source ./images/003.jpg <<< approved; scene=mountain
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
+
### With Prior Reference
|
|
200
|
+
|
|
201
|
+
Use `@prior` to reference an item that precedes the source (e.g., a prompt that generated an image):
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
@uri local:generated-001
|
|
205
|
+
@prior ./prompts/sunset-prompt.txt
|
|
206
|
+
@source ./images/generated-sunset.jpg <<< accurate; matches prompt well
|
|
207
|
+
```
|
|
208
|
+
|
|
199
209
|
### Paired Files
|
|
200
210
|
|
|
201
211
|
**content.txt:**
|
|
@@ -161,6 +161,16 @@ Second content.
|
|
|
161
161
|
@source ./images/003.jpg <<< approved; scene=mountain
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
+
### With Prior Reference
|
|
165
|
+
|
|
166
|
+
Use `@prior` to reference an item that precedes the source (e.g., a prompt that generated an image):
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
@uri local:generated-001
|
|
170
|
+
@prior ./prompts/sunset-prompt.txt
|
|
171
|
+
@source ./images/generated-sunset.jpg <<< accurate; matches prompt well
|
|
172
|
+
```
|
|
173
|
+
|
|
164
174
|
### Paired Files
|
|
165
175
|
|
|
166
176
|
**content.txt:**
|
|
@@ -28,6 +28,7 @@ A MarkBack **record** is the fundamental unit. Every record has:
|
|
|
28
28
|
| `feedback` | Yes | Text after the `<<<` delimiter (always one line) |
|
|
29
29
|
| `uri` | No | Unique identifier for the item |
|
|
30
30
|
| `source` | No | Reference to external content (when content is not inline) |
|
|
31
|
+
| `prior` | No | Reference to an item that precedes the source (e.g., a prompt that generated the content) |
|
|
31
32
|
|
|
32
33
|
*Content is required but may be external (via `source` field).
|
|
33
34
|
|
|
@@ -66,6 +67,7 @@ Header lines appear at the start of a record and begin with `@`. They define met
|
|
|
66
67
|
```
|
|
67
68
|
@uri <uri-value>
|
|
68
69
|
@source <path-or-uri>
|
|
70
|
+
@prior <path-or-uri>
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
**Rules:**
|
|
@@ -109,6 +111,22 @@ References external content instead of inline content.
|
|
|
109
111
|
- When `@source` is present, inline content MUST be empty (or contain only whitespace)
|
|
110
112
|
- Parsers MUST verify referenced files exist (warning if missing)
|
|
111
113
|
|
|
114
|
+
#### 3.1.3 `@prior` Header
|
|
115
|
+
|
|
116
|
+
References an item that precedes the source material. For example, if the source is an image generated by an LLM, the prior could be the prompt that was used to create it.
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
@prior ./prompts/image-gen-prompt.txt
|
|
120
|
+
@prior https://example.com/prompts/123
|
|
121
|
+
@prior file:///path/to/prompt.txt
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Rules:**
|
|
125
|
+
- Relative paths are resolved relative to the MarkBack file location
|
|
126
|
+
- `@prior` can be used with or without `@source`
|
|
127
|
+
- `@prior` does not affect content handling (inline content or `@source` rules still apply)
|
|
128
|
+
- Parsers SHOULD verify referenced files exist (warning if missing)
|
|
129
|
+
|
|
112
130
|
### 3.2 Content Block
|
|
113
131
|
|
|
114
132
|
Content is everything between headers and the `<<<` feedback delimiter.
|
|
@@ -442,7 +460,7 @@ Canonical form ensures consistent output for comparison and version control.
|
|
|
442
460
|
### 5.2 Canonicalization Rules
|
|
443
461
|
|
|
444
462
|
1. **Line endings:** Normalize to `\n` (LF)
|
|
445
|
-
2. **Header order:** `@uri` before `@source` before unknown headers (alphabetical)
|
|
463
|
+
2. **Header order:** `@uri` before `@prior` before `@source` before unknown headers (alphabetical)
|
|
446
464
|
3. **Header spacing:** Exactly one space after keyword
|
|
447
465
|
4. **Trailing whitespace:** Remove from all lines
|
|
448
466
|
5. **Content whitespace:** Preserve internal whitespace; trim leading/trailing blank lines
|
|
@@ -570,6 +588,7 @@ Each line is classified as one of:
|
|
|
570
588
|
| W006 | Missing `@uri` (record has no identifier) |
|
|
571
589
|
| W007 | Paired feedback file not found for content file |
|
|
572
590
|
| W008 | Non-canonical formatting detected |
|
|
591
|
+
| W009 | `@prior` file not found |
|
|
573
592
|
|
|
574
593
|
### 7.3 Lint Output Format
|
|
575
594
|
|
|
@@ -617,7 +636,27 @@ Or in compact form:
|
|
|
617
636
|
@source ./images/beach.jpg <<< appropriate; tags=landscape,beach,sunset; quality=high
|
|
618
637
|
```
|
|
619
638
|
|
|
620
|
-
### 8.4
|
|
639
|
+
### 8.4 Record with Prior Reference (e.g., LLM-generated content)
|
|
640
|
+
|
|
641
|
+
```
|
|
642
|
+
@uri local:generated-image-001
|
|
643
|
+
@prior ./prompts/beach-sunset.txt
|
|
644
|
+
@source ./images/generated-beach.jpg
|
|
645
|
+
<<< accurate; matches prompt well; quality=high
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Or with inline content:
|
|
649
|
+
```
|
|
650
|
+
@uri local:generated-text-001
|
|
651
|
+
@prior ./prompts/haiku-prompt.txt
|
|
652
|
+
|
|
653
|
+
Cherry blossoms fall,
|
|
654
|
+
Petals dance on gentle breeze,
|
|
655
|
+
Spring whispers goodbye.
|
|
656
|
+
<<< creative; follows haiku structure; quality=excellent
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
### 8.5 Single-File Example
|
|
621
660
|
|
|
622
661
|
**File:** `question.mb`
|
|
623
662
|
```
|
|
@@ -627,7 +666,7 @@ Explain quantum entanglement in simple terms.
|
|
|
627
666
|
<<< quality=excellent; accuracy=high; clarity=good
|
|
628
667
|
```
|
|
629
668
|
|
|
630
|
-
### 8.
|
|
669
|
+
### 8.6 Label List Example (Compact Format)
|
|
631
670
|
|
|
632
671
|
**File:** `image-annotations.mb`
|
|
633
672
|
```
|
|
@@ -659,7 +698,7 @@ Explain quantum entanglement in simple terms.
|
|
|
659
698
|
@source ./batch1/item3.txt <<< positive; excellent clarity
|
|
660
699
|
```
|
|
661
700
|
|
|
662
|
-
### 8.
|
|
701
|
+
### 8.7 Multi-Record Example (Mixed Freeform and Structured)
|
|
663
702
|
|
|
664
703
|
**File:** `training-data.mb`
|
|
665
704
|
```
|
|
@@ -690,7 +729,7 @@ Please write a formal letter requesting a meeting.
|
|
|
690
729
|
@source ./audio/sample-005.wav <<< transcription="Hello world"; quality=clear; language=en
|
|
691
730
|
```
|
|
692
731
|
|
|
693
|
-
### 8.
|
|
732
|
+
### 8.8 Paired-File Example
|
|
694
733
|
|
|
695
734
|
**Content file:** `essay.txt`
|
|
696
735
|
```
|
|
@@ -706,7 +745,7 @@ agriculture, manufacturing, mining, and transport.
|
|
|
706
745
|
<<< good; grade=B+; well structured but needs more specific examples
|
|
707
746
|
```
|
|
708
747
|
|
|
709
|
-
### 8.
|
|
748
|
+
### 8.9 Freeform Feedback Examples
|
|
710
749
|
|
|
711
750
|
Various styles of freeform feedback:
|
|
712
751
|
|
|
@@ -729,7 +768,7 @@ Explain machine learning to a child.
|
|
|
729
768
|
<<< needs work; the explanation assumes too much prior knowledge
|
|
730
769
|
```
|
|
731
770
|
|
|
732
|
-
### 8.
|
|
771
|
+
### 8.10 Complex Structured Feedback (JSON)
|
|
733
772
|
|
|
734
773
|
```
|
|
735
774
|
@uri local:complex-example
|
|
@@ -738,7 +777,7 @@ Multi-attribute content with special characters.
|
|
|
738
777
|
<<< json:{"rating":4.5,"tags":["important","review"],"notes":"Contains \"quoted\" text and; semicolons","scores":{"accuracy":0.9,"relevance":0.85}}
|
|
739
778
|
```
|
|
740
779
|
|
|
741
|
-
### 8.
|
|
780
|
+
### 8.11 Image with MarkBack Sidecar
|
|
742
781
|
|
|
743
782
|
**Content file:** `diagram.png` (binary)
|
|
744
783
|
|
|
@@ -110,6 +110,33 @@ def lint_source_exists(
|
|
|
110
110
|
return diagnostics
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
def lint_prior_exists(
|
|
114
|
+
record: Record,
|
|
115
|
+
base_path: Optional[Path],
|
|
116
|
+
record_idx: int,
|
|
117
|
+
) -> list[Diagnostic]:
|
|
118
|
+
"""Check if @prior file exists."""
|
|
119
|
+
diagnostics: list[Diagnostic] = []
|
|
120
|
+
|
|
121
|
+
if record.prior and not record.prior.is_uri:
|
|
122
|
+
try:
|
|
123
|
+
resolved = record.prior.resolve(base_path)
|
|
124
|
+
if not resolved.exists():
|
|
125
|
+
diagnostics.append(Diagnostic(
|
|
126
|
+
file=record._source_file,
|
|
127
|
+
line=record._start_line,
|
|
128
|
+
column=None,
|
|
129
|
+
severity=Severity.WARNING,
|
|
130
|
+
code=WarningCode.W009,
|
|
131
|
+
message=f"@prior file not found: {record.prior}",
|
|
132
|
+
record_index=record_idx,
|
|
133
|
+
))
|
|
134
|
+
except ValueError:
|
|
135
|
+
pass # URI that can't be resolved to path
|
|
136
|
+
|
|
137
|
+
return diagnostics
|
|
138
|
+
|
|
139
|
+
|
|
113
140
|
def lint_canonical_format(
|
|
114
141
|
records: list[Record],
|
|
115
142
|
original_text: str,
|
|
@@ -173,10 +200,11 @@ def lint_string(
|
|
|
173
200
|
idx,
|
|
174
201
|
))
|
|
175
202
|
|
|
176
|
-
# Check source file existence
|
|
203
|
+
# Check source and prior file existence
|
|
177
204
|
if check_sources:
|
|
178
205
|
base_path = source_file.parent if source_file else None
|
|
179
206
|
result.diagnostics.extend(lint_source_exists(record, base_path, idx))
|
|
207
|
+
result.diagnostics.extend(lint_prior_exists(record, base_path, idx))
|
|
180
208
|
|
|
181
209
|
# Check canonical format
|
|
182
210
|
if check_canonical and result.records and not result.has_errors:
|
|
@@ -17,7 +17,7 @@ from .types import (
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
# Known header keywords
|
|
20
|
-
KNOWN_HEADERS = {"uri", "source"}
|
|
20
|
+
KNOWN_HEADERS = {"uri", "source", "prior"}
|
|
21
21
|
|
|
22
22
|
# Patterns
|
|
23
23
|
HEADER_PATTERN = re.compile(r"^@([a-z]+)\s+(.+)$")
|
|
@@ -147,6 +147,8 @@ def parse_string(
|
|
|
147
147
|
uri = current_headers.get("uri") or pending_uri
|
|
148
148
|
source_str = current_headers.get("source")
|
|
149
149
|
source = SourceRef(source_str) if source_str else None
|
|
150
|
+
prior_str = current_headers.get("prior")
|
|
151
|
+
prior = SourceRef(prior_str) if prior_str else None
|
|
150
152
|
|
|
151
153
|
content = None
|
|
152
154
|
if current_content_lines:
|
|
@@ -163,6 +165,7 @@ def parse_string(
|
|
|
163
165
|
feedback=feedback,
|
|
164
166
|
uri=uri,
|
|
165
167
|
source=source,
|
|
168
|
+
prior=prior,
|
|
166
169
|
content=content,
|
|
167
170
|
_source_file=source_file,
|
|
168
171
|
_start_line=current_start_line,
|
|
@@ -239,13 +242,16 @@ def parse_string(
|
|
|
239
242
|
line_num,
|
|
240
243
|
)
|
|
241
244
|
|
|
242
|
-
# Use any pending @uri from previous line
|
|
245
|
+
# Use any pending @uri from previous line and @prior if present
|
|
243
246
|
uri = pending_uri or current_headers.get("uri")
|
|
247
|
+
prior_str = current_headers.get("prior")
|
|
248
|
+
prior = SourceRef(prior_str) if prior_str else None
|
|
244
249
|
|
|
245
250
|
record = Record(
|
|
246
251
|
feedback=feedback or "",
|
|
247
252
|
uri=uri,
|
|
248
253
|
source=source,
|
|
254
|
+
prior=prior,
|
|
249
255
|
content=None,
|
|
250
256
|
_source_file=source_file,
|
|
251
257
|
_start_line=current_start_line,
|
|
@@ -37,6 +37,7 @@ class WarningCode(Enum):
|
|
|
37
37
|
W006 = "W006" # Missing @uri (record has no identifier)
|
|
38
38
|
W007 = "W007" # Paired feedback file not found
|
|
39
39
|
W008 = "W008" # Non-canonical formatting detected
|
|
40
|
+
W009 = "W009" # @prior file not found
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
@dataclass
|
|
@@ -122,6 +123,7 @@ class Record:
|
|
|
122
123
|
feedback: str
|
|
123
124
|
uri: Optional[str] = None
|
|
124
125
|
source: Optional[SourceRef] = None
|
|
126
|
+
prior: Optional[SourceRef] = None
|
|
125
127
|
content: Optional[str] = None
|
|
126
128
|
metadata: dict = field(default_factory=dict)
|
|
127
129
|
|
|
@@ -154,6 +156,7 @@ class Record:
|
|
|
154
156
|
return {
|
|
155
157
|
"uri": self.uri,
|
|
156
158
|
"source": str(self.source) if self.source else None,
|
|
159
|
+
"prior": str(self.prior) if self.prior else None,
|
|
157
160
|
"content": self.content,
|
|
158
161
|
"feedback": self.feedback,
|
|
159
162
|
"metadata": self.metadata,
|
|
@@ -38,15 +38,19 @@ def write_record_canonical(
|
|
|
38
38
|
)
|
|
39
39
|
|
|
40
40
|
if use_compact:
|
|
41
|
-
# Compact format: @uri on its own line (if present), then @source ... <<<
|
|
41
|
+
# Compact format: @uri on its own line (if present), then @prior, then @source ... <<<
|
|
42
42
|
if record.uri:
|
|
43
43
|
lines.append(f"@uri {record.uri}")
|
|
44
|
+
if record.prior:
|
|
45
|
+
lines.append(f"@prior {record.prior}")
|
|
44
46
|
lines.append(f"@source {record.source} <<< {record.feedback}")
|
|
45
47
|
else:
|
|
46
48
|
# Full format
|
|
47
|
-
# Headers: @uri first, then @source
|
|
49
|
+
# Headers: @uri first, then @prior, then @source
|
|
48
50
|
if record.uri:
|
|
49
51
|
lines.append(f"@uri {record.uri}")
|
|
52
|
+
if record.prior:
|
|
53
|
+
lines.append(f"@prior {record.prior}")
|
|
50
54
|
if record.source:
|
|
51
55
|
lines.append(f"@source {record.source}")
|
|
52
56
|
|
|
@@ -147,6 +151,9 @@ def write_label_file(record: Record) -> str:
|
|
|
147
151
|
|
|
148
152
|
if record.uri:
|
|
149
153
|
lines.append(f"@uri {record.uri}")
|
|
154
|
+
|
|
155
|
+
if record.prior:
|
|
156
|
+
lines.append(f"@prior {record.prior}")
|
|
150
157
|
|
|
151
158
|
lines.append(f"<<< {record.feedback}")
|
|
152
159
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dandriscoll
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# markbackjs
|
|
2
|
+
|
|
3
|
+
JavaScript/TypeScript linter for the MarkBack format.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install markbackjs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const { lintString, formatDiagnostics } = require("markbackjs");
|
|
15
|
+
|
|
16
|
+
const text = "Content here.\n<<< positive\n";
|
|
17
|
+
const result = lintString(text, { checkSources: false, checkCanonical: false });
|
|
18
|
+
|
|
19
|
+
if (result.hasErrors) {
|
|
20
|
+
console.log(formatDiagnostics(result.diagnostics));
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Supported Headers
|
|
25
|
+
|
|
26
|
+
- `@uri` - Unique identifier for the record
|
|
27
|
+
- `@source` - Reference to external content file
|
|
28
|
+
- `@prior` - Reference to a file that precedes the source (e.g., a prompt that generated it)
|
|
29
|
+
|
|
30
|
+
## API
|
|
31
|
+
|
|
32
|
+
- `lintString(text, options)`
|
|
33
|
+
- `lintFile(path, options)`
|
|
34
|
+
- `lintFiles(paths, options)`
|
|
35
|
+
- `formatDiagnostics(diagnostics, format)`
|
|
36
|
+
- `summarizeResults(results)`
|
|
37
|
+
|
|
38
|
+
Options:
|
|
39
|
+
- `sourceFile`: string
|
|
40
|
+
- `checkSources`: boolean (default true)
|
|
41
|
+
- `checkCanonical`: boolean (default true)
|
|
42
|
+
|
|
43
|
+
## Build
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm run build
|
|
47
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "markbackjs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "markbackjs",
|
|
9
|
+
"version": "0.1.0",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@types/node": "^20.11.0",
|
|
13
|
+
"typescript": "^5.4.0"
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"node_modules/@types/node": {
|
|
20
|
+
"version": "20.19.27",
|
|
21
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz",
|
|
22
|
+
"integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==",
|
|
23
|
+
"dev": true,
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"undici-types": "~6.21.0"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"node_modules/typescript": {
|
|
30
|
+
"version": "5.9.3",
|
|
31
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
32
|
+
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
33
|
+
"dev": true,
|
|
34
|
+
"license": "Apache-2.0",
|
|
35
|
+
"bin": {
|
|
36
|
+
"tsc": "bin/tsc",
|
|
37
|
+
"tsserver": "bin/tsserver"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=14.17"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"node_modules/undici-types": {
|
|
44
|
+
"version": "6.21.0",
|
|
45
|
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
|
46
|
+
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
|
47
|
+
"dev": true,
|
|
48
|
+
"license": "MIT"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "markbackjs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MarkBack tooling for JavaScript and TypeScript",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc -p tsconfig.json",
|
|
15
|
+
"clean": "rm -rf dist",
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"test": "npm run build && node --test test/*.test.js"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"markback",
|
|
21
|
+
"linter",
|
|
22
|
+
"lint",
|
|
23
|
+
"labels",
|
|
24
|
+
"feedback"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.11.0",
|
|
31
|
+
"typescript": "^5.4.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Diagnostic,
|
|
3
|
+
ErrorCode,
|
|
4
|
+
WarningCode,
|
|
5
|
+
Severity,
|
|
6
|
+
SourceRef,
|
|
7
|
+
Record,
|
|
8
|
+
ParseResult,
|
|
9
|
+
FeedbackParsed,
|
|
10
|
+
parseFeedback,
|
|
11
|
+
} from "./types";
|
|
12
|
+
|
|
13
|
+
export { parseString } from "./parser";
|
|
14
|
+
export { writeRecordCanonical, writeRecordsMulti } from "./writer";
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
lintString,
|
|
18
|
+
lintFile,
|
|
19
|
+
lintFiles,
|
|
20
|
+
formatDiagnostics,
|
|
21
|
+
summarizeResults,
|
|
22
|
+
LintOptions,
|
|
23
|
+
} from "./linter";
|