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.
Files changed (52) hide show
  1. markback-0.1.1/.claude/settings.local.json +9 -0
  2. {markback-0.1.0 → markback-0.1.1}/.gitignore +5 -0
  3. markback-0.1.1/.ishipped/card.md +26 -0
  4. {markback-0.1.0 → markback-0.1.1}/PKG-INFO +11 -1
  5. {markback-0.1.0 → markback-0.1.1}/README.md +10 -0
  6. {markback-0.1.0 → markback-0.1.1}/SPEC.md +47 -8
  7. {markback-0.1.0 → markback-0.1.1}/markback/linter.py +29 -1
  8. {markback-0.1.0 → markback-0.1.1}/markback/parser.py +8 -2
  9. {markback-0.1.0 → markback-0.1.1}/markback/types.py +3 -0
  10. {markback-0.1.0 → markback-0.1.1}/markback/writer.py +9 -2
  11. markback-0.1.1/packages/markbackjs/LICENSE +21 -0
  12. markback-0.1.1/packages/markbackjs/README.md +47 -0
  13. markback-0.1.1/packages/markbackjs/package-lock.json +51 -0
  14. markback-0.1.1/packages/markbackjs/package.json +33 -0
  15. markback-0.1.1/packages/markbackjs/src/index.ts +23 -0
  16. markback-0.1.1/packages/markbackjs/src/linter.ts +325 -0
  17. markback-0.1.1/packages/markbackjs/src/parser.ts +357 -0
  18. markback-0.1.1/packages/markbackjs/src/types.ts +314 -0
  19. markback-0.1.1/packages/markbackjs/src/writer.ts +73 -0
  20. markback-0.1.1/packages/markbackjs/test/linter.test.js +107 -0
  21. markback-0.1.1/packages/markbackjs/tsconfig.json +17 -0
  22. {markback-0.1.0 → markback-0.1.1}/pyproject.toml +1 -1
  23. {markback-0.1.0 → markback-0.1.1}/tests/test_linter.py +19 -0
  24. {markback-0.1.0 → markback-0.1.1}/tests/test_parser.py +52 -0
  25. {markback-0.1.0 → markback-0.1.1}/tests/test_writer.py +58 -0
  26. {markback-0.1.0 → markback-0.1.1}/IMPLEMENTATION_NOTES.md +0 -0
  27. {markback-0.1.0 → markback-0.1.1}/LICENSE +0 -0
  28. {markback-0.1.0 → markback-0.1.1}/markback/__init__.py +0 -0
  29. {markback-0.1.0 → markback-0.1.1}/markback/cli.py +0 -0
  30. {markback-0.1.0 → markback-0.1.1}/markback/config.py +0 -0
  31. {markback-0.1.0 → markback-0.1.1}/markback/llm.py +0 -0
  32. {markback-0.1.0 → markback-0.1.1}/markback/workflow.py +0 -0
  33. {markback-0.1.0 → markback-0.1.1}/tests/__init__.py +0 -0
  34. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/compact_source.mb +0 -0
  35. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/content_with_source.mb +0 -0
  36. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/empty_feedback.mb +0 -0
  37. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/malformed_uri.mb +0 -0
  38. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/missing_feedback.mb +0 -0
  39. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/errors/multiple_feedback.mb +0 -0
  40. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/essay.label.txt +0 -0
  41. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/essay.txt +0 -0
  42. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/external_source.mb +0 -0
  43. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/freeform_feedback.mb +0 -0
  44. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/json_feedback.mb +0 -0
  45. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/label_list.mb +0 -0
  46. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/minimal.mb +0 -0
  47. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/multi_record.mb +0 -0
  48. {markback-0.1.0 → markback-0.1.1}/tests/fixtures/with_uri.mb +0 -0
  49. {markback-0.1.0 → markback-0.1.1}/tests/test_cli.py +0 -0
  50. {markback-0.1.0 → markback-0.1.1}/tests/test_config.py +0 -0
  51. {markback-0.1.0 → markback-0.1.1}/tests/test_types.py +0 -0
  52. {markback-0.1.0 → markback-0.1.1}/tests/test_workflow.py +0 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python -m pytest:*)",
5
+ "Bash(npm test:*)",
6
+ "Bash(npm install)"
7
+ ]
8
+ }
9
+ }
@@ -201,6 +201,11 @@ cython_debug/
201
201
  .cursorignore
202
202
  .cursorindexingignore
203
203
 
204
+ # Node
205
+ node_modules/
206
+ packages/markback/dist/
207
+ packages/markback/*.tsbuildinfo
208
+
204
209
  # Marimo
205
210
  marimo/_static/
206
211
  marimo/_lsp/
@@ -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.0
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 Single-File Example
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.5 Label List Example (Compact Format)
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.6 Multi-Record Example (Mixed Freeform and Structured)
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.7 Paired-File Example
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.8 Freeform Feedback Examples
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.9 Complex Structured Feedback (JSON)
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.10 Image with MarkBack Sidecar
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";