bookwright-cli 0.2.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.
- bookwright/__init__.py +3 -0
- bookwright/__main__.py +6 -0
- bookwright/cli.py +19 -0
- bookwright/commands/__init__.py +0 -0
- bookwright/commands/_envelope.py +36 -0
- bookwright/commands/check.py +75 -0
- bookwright/commands/graph/__init__.py +23 -0
- bookwright/commands/graph/build.py +157 -0
- bookwright/commands/graph/envelope.py +26 -0
- bookwright/commands/graph/query.py +98 -0
- bookwright/commands/init/__init__.py +5 -0
- bookwright/commands/init/conflict.py +107 -0
- bookwright/commands/init/envelope.py +322 -0
- bookwright/commands/init/git.py +96 -0
- bookwright/commands/init/main.py +263 -0
- bookwright/commands/init/resolve.py +193 -0
- bookwright/commands/init/scaffold.py +242 -0
- bookwright/commands/init/validate.py +172 -0
- bookwright/commands/integration/__init__.py +22 -0
- bookwright/commands/integration/use.py +120 -0
- bookwright/commands/validate.py +160 -0
- bookwright/commands/version.py +35 -0
- bookwright/core/__init__.py +35 -0
- bookwright/core/_blocks.py +239 -0
- bookwright/core/_build.py +154 -0
- bookwright/core/_research_block.py +56 -0
- bookwright/core/_translate.py +90 -0
- bookwright/core/errors.py +127 -0
- bookwright/core/iso639_1.py +200 -0
- bookwright/core/manifest.py +343 -0
- bookwright/errors.py +47 -0
- bookwright/golem/__init__.py +71 -0
- bookwright/golem/base.py +200 -0
- bookwright/golem/errors.py +29 -0
- bookwright/golem/modules/__init__.py +1 -0
- bookwright/golem/modules/character.py +109 -0
- bookwright/golem/modules/event.py +91 -0
- bookwright/golem/modules/feature.py +161 -0
- bookwright/golem/modules/inference.py +41 -0
- bookwright/golem/modules/narrative.py +55 -0
- bookwright/golem/modules/provenance.py +197 -0
- bookwright/golem/modules/relationship.py +38 -0
- bookwright/golem/modules/setting.py +30 -0
- bookwright/golem/namespaces.py +332 -0
- bookwright/golem/serialize.py +25 -0
- bookwright/golem/slug.py +22 -0
- bookwright/indexers/__init__.py +47 -0
- bookwright/indexers/base.py +55 -0
- bookwright/indexers/errors.py +80 -0
- bookwright/indexers/rdflib_indexer.py +89 -0
- bookwright/integrations/__init__.py +155 -0
- bookwright/integrations/base.py +117 -0
- bookwright/integrations/claude/__init__.py +29 -0
- bookwright/integrations/constants.py +38 -0
- bookwright/integrations/descriptions.py +48 -0
- bookwright/integrations/errors.py +170 -0
- bookwright/integrations/generic/__init__.py +56 -0
- bookwright/integrations/lint.py +160 -0
- bookwright/integrations/materialize.py +202 -0
- bookwright/integrations/options.py +203 -0
- bookwright/io/__init__.py +1 -0
- bookwright/io/bible.py +500 -0
- bookwright/io/errors.py +98 -0
- bookwright/io/frontmatter.py +61 -0
- bookwright/io/fs.py +226 -0
- bookwright/io/manuscript.py +15 -0
- bookwright/io/project.py +21 -0
- bookwright/io/report.py +107 -0
- bookwright/io/research.py +427 -0
- bookwright/resources/__init__.py +1 -0
- bookwright/resources/commands/bookwright-analyze.md +66 -0
- bookwright/resources/commands/bookwright-bible.md +96 -0
- bookwright/resources/commands/bookwright-checklist.md +67 -0
- bookwright/resources/commands/bookwright-clarify.md +65 -0
- bookwright/resources/commands/bookwright-constitution.md +79 -0
- bookwright/resources/commands/bookwright-continuity.md +70 -0
- bookwright/resources/commands/bookwright-draft.md +74 -0
- bookwright/resources/commands/bookwright-outline.md +71 -0
- bookwright/resources/commands/bookwright-research.md +107 -0
- bookwright/resources/commands/bookwright-scenes.md +66 -0
- bookwright/resources/commands/bookwright-synopsis.md +67 -0
- bookwright/resources/commands/bookwright-verify.md +136 -0
- bookwright/resources/commands/references/golem-character.md +65 -0
- bookwright/resources/commands/references/golem-events-timeline.md +56 -0
- bookwright/resources/commands/references/golem-relationships.md +53 -0
- bookwright/resources/commands/references/greimas-actants.md +57 -0
- bookwright/resources/commands/references/pending-protocol.md +72 -0
- bookwright/resources/commands/references/propp-functions.md +54 -0
- bookwright/resources/commands/references/research-format.md +136 -0
- bookwright/resources/project/.bookwright/cache/.gitkeep +0 -0
- bookwright/resources/project/.bookwright/schema/.gitkeep +0 -0
- bookwright/resources/project/.bookwright/templates/.gitkeep +0 -0
- bookwright/resources/project/.gitignore +23 -0
- bookwright/resources/project/README.md.j2 +40 -0
- bookwright/resources/project/__init__.py +6 -0
- bookwright/resources/project/bible/characters/.gitkeep +0 -0
- bookwright/resources/project/bible/constitution.md.j2 +74 -0
- bookwright/resources/project/bible/glossary.md +36 -0
- bookwright/resources/project/bible/locations/.gitkeep +0 -0
- bookwright/resources/project/bible/pov-structure.md +43 -0
- bookwright/resources/project/bible/relationships.md +36 -0
- bookwright/resources/project/bible/research/_index.md +28 -0
- bookwright/resources/project/bible/research/sources.md +23 -0
- bookwright/resources/project/bible/settings/.gitkeep +0 -0
- bookwright/resources/project/bible/subplots.md +35 -0
- bookwright/resources/project/bible/themes.md +36 -0
- bookwright/resources/project/bible/timeline.md +38 -0
- bookwright/resources/project/manuscript/.gitkeep +0 -0
- bookwright/resources/project/outline/arcs.md +34 -0
- bookwright/resources/project/outline/scenes.md +31 -0
- bookwright/resources/project/outline/structure.md +35 -0
- bookwright/resources/project/outline/synopsis.md +25 -0
- bookwright/resources/schemas/__init__.py +19 -0
- bookwright/resources/schemas/golem-1.1/VERSION +1 -0
- bookwright/resources/schemas/golem-1.1/golem.ttl +1947 -0
- bookwright/resources/schemas/golem-1.1/version.json +8 -0
- bookwright/resources/templates/__init__.py +1 -0
- bookwright/resources/templates/bible/character.md.tmpl +63 -0
- bookwright/resources/templates/bible/location.md.tmpl +37 -0
- bookwright/resources/templates/bible/research/_index.md.tmpl +25 -0
- bookwright/resources/templates/bible/research/sources.md.tmpl +21 -0
- bookwright/resources/templates/bible/research/tema.md.tmpl +37 -0
- bookwright/resources/templates/bible/setting.md.tmpl +38 -0
- bookwright/resources/templates/manifest.template.toml +79 -0
- bookwright/resources/templates/manuscript/chapter.md.tmpl +36 -0
- bookwright/resources/templates/scenes/scene.md.tmpl +37 -0
- bookwright/resources/vocabularies/__init__.py +6 -0
- bookwright/resources/vocabularies/greimas.ttl +4 -0
- bookwright/resources/vocabularies/propp.ttl +4 -0
- bookwright/resources/vocabularies/sources.ttl +82 -0
- bookwright/validation/__init__.py +33 -0
- bookwright/validation/anchor_queries.py +223 -0
- bookwright/validation/base.py +233 -0
- bookwright/validation/queries.py +197 -0
- bookwright/validation/registry.py +185 -0
- bookwright/validation/report.py +106 -0
- bookwright/validation/runner.py +65 -0
- bookwright/validation/validators/__init__.py +9 -0
- bookwright/validation/validators/character_presence.py +202 -0
- bookwright/validation/validators/factual_anchor.py +291 -0
- bookwright/validation/validators/focalization.py +152 -0
- bookwright/validation/validators/setting_continuity.py +100 -0
- bookwright/validation/validators/temporal.py +277 -0
- bookwright_cli-0.2.0.dist-info/METADATA +218 -0
- bookwright_cli-0.2.0.dist-info/RECORD +149 -0
- bookwright_cli-0.2.0.dist-info/WHEEL +4 -0
- bookwright_cli-0.2.0.dist-info/entry_points.txt +2 -0
- bookwright_cli-0.2.0.dist-info/licenses/LICENSE +202 -0
- bookwright_cli-0.2.0.dist-info/licenses/NOTICE +14 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"""``temporal`` — timeline contradictions over the interval + relation graph (FR-015).
|
|
2
|
+
|
|
3
|
+
A pure graph consumer (research D12): it reads each event's begin/end years and the
|
|
4
|
+
five qualitative ``TR:*`` relations through :mod:`bookwright.validation.queries` and
|
|
5
|
+
emits one ``error`` ``Violation`` per contradiction — never consulting document order,
|
|
6
|
+
insensitive to the interval carrier-node shape. The four rules:
|
|
7
|
+
|
|
8
|
+
* **(a)** a ``follows`` / ``precedes`` cycle (mutually-before events),
|
|
9
|
+
* **(b)** a pair both strictly ordered *and* ``temporally-overlaps``,
|
|
10
|
+
* **(c)** containment conflicting with a strict order,
|
|
11
|
+
* **(d)** numeric begin/end contradicting a declared relation.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import ClassVar
|
|
17
|
+
|
|
18
|
+
from bookwright.golem.namespaces import TEMPORAL_RELATIONS
|
|
19
|
+
from bookwright.indexers import Indexer
|
|
20
|
+
from bookwright.validation.base import Severity, ValidationContext, Violation
|
|
21
|
+
from bookwright.validation.queries import (
|
|
22
|
+
EventInterval,
|
|
23
|
+
intervals_disjoint,
|
|
24
|
+
load_intervals,
|
|
25
|
+
load_relations,
|
|
26
|
+
resolve_source,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
_MIN_CYCLE = 2 # an SCC of ≥2 events is a follows/precedes cycle (rule a).
|
|
30
|
+
|
|
31
|
+
# Canonical relation name → its predicate string, derived from the single source
|
|
32
|
+
# of truth so this validator and the loader can never disagree on the key spelling.
|
|
33
|
+
_PRED: dict[str, str] = {rel.name: str(rel.predicate) for rel in TEMPORAL_RELATIONS}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _label(uri: str) -> str:
|
|
37
|
+
"""A short, readable event name from its URI (the final path segment)."""
|
|
38
|
+
return uri.rstrip("/").rsplit("/", 1)[-1]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Temporal:
|
|
42
|
+
"""Detects the four FR-015 timeline contradictions in the graph."""
|
|
43
|
+
|
|
44
|
+
name: ClassVar[str] = "temporal"
|
|
45
|
+
severity_default: ClassVar[Severity] = Severity.error
|
|
46
|
+
|
|
47
|
+
def validate(self, project: ValidationContext, indexer: Indexer) -> list[Violation]:
|
|
48
|
+
intervals = load_intervals(indexer)
|
|
49
|
+
relations = load_relations(indexer)
|
|
50
|
+
|
|
51
|
+
# Normalize follows/precedes into a strict "x strictly before y" relation,
|
|
52
|
+
# remembering which declared edge each came from for the implicated triples.
|
|
53
|
+
before: set[tuple[str, str]] = set()
|
|
54
|
+
before_triple: dict[tuple[str, str], tuple[str, str, str]] = {}
|
|
55
|
+
for a, b in relations["precedes"]: # a before b
|
|
56
|
+
before.add((a, b))
|
|
57
|
+
before_triple[(a, b)] = (a, _PRED["precedes"], b)
|
|
58
|
+
for a, b in relations["follows"]: # a after b → b before a
|
|
59
|
+
before.add((b, a))
|
|
60
|
+
before_triple[(b, a)] = (a, _PRED["follows"], b)
|
|
61
|
+
|
|
62
|
+
out: list[Violation] = []
|
|
63
|
+
out.extend(self._cycles(before, before_triple))
|
|
64
|
+
out.extend(self._order_vs_overlap(before, relations))
|
|
65
|
+
out.extend(self._containment_vs_order(before, relations))
|
|
66
|
+
out.extend(self._numeric(relations, intervals, indexer))
|
|
67
|
+
return out
|
|
68
|
+
|
|
69
|
+
# --- rule (a): cycle in the strict-order graph --------------------------
|
|
70
|
+
|
|
71
|
+
def _cycles(
|
|
72
|
+
self,
|
|
73
|
+
before: set[tuple[str, str]],
|
|
74
|
+
before_triple: dict[tuple[str, str], tuple[str, str, str]],
|
|
75
|
+
) -> list[Violation]:
|
|
76
|
+
adjacency: dict[str, list[str]] = {}
|
|
77
|
+
for x, y in before:
|
|
78
|
+
adjacency.setdefault(x, []).append(y)
|
|
79
|
+
adjacency.setdefault(y, [])
|
|
80
|
+
out: list[Violation] = []
|
|
81
|
+
for component in _strongly_connected(adjacency):
|
|
82
|
+
if len(component) < _MIN_CYCLE:
|
|
83
|
+
continue
|
|
84
|
+
members = set(component)
|
|
85
|
+
triples = tuple(
|
|
86
|
+
sorted(before_triple[(x, y)] for (x, y) in before if x in members and y in members)
|
|
87
|
+
)
|
|
88
|
+
names = ", ".join(sorted(_label(uri) for uri in component))
|
|
89
|
+
out.append(
|
|
90
|
+
Violation(
|
|
91
|
+
validator=self.name,
|
|
92
|
+
severity=Severity.error,
|
|
93
|
+
message=(
|
|
94
|
+
f"temporal cycle: events {{{names}}} are each asserted to come "
|
|
95
|
+
"before another in the group (follows/precedes form a loop)"
|
|
96
|
+
),
|
|
97
|
+
source=None,
|
|
98
|
+
triples=triples,
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
return out
|
|
102
|
+
|
|
103
|
+
# --- rule (b): a strictly ordered pair that also overlaps ---------------
|
|
104
|
+
|
|
105
|
+
def _order_vs_overlap(
|
|
106
|
+
self,
|
|
107
|
+
before: set[tuple[str, str]],
|
|
108
|
+
relations: dict[str, set[tuple[str, str]]],
|
|
109
|
+
) -> list[Violation]:
|
|
110
|
+
out: list[Violation] = []
|
|
111
|
+
for a, b in _unordered_pairs(relations["overlaps"]):
|
|
112
|
+
if (a, b) in before or (b, a) in before:
|
|
113
|
+
out.append(
|
|
114
|
+
Violation(
|
|
115
|
+
validator=self.name,
|
|
116
|
+
severity=Severity.error,
|
|
117
|
+
message=(
|
|
118
|
+
f"'{_label(a)}' and '{_label(b)}' are asserted to overlap, "
|
|
119
|
+
"yet one is also strictly ordered before the other"
|
|
120
|
+
),
|
|
121
|
+
source=None,
|
|
122
|
+
triples=((a, _PRED["overlaps"], b),),
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
return out
|
|
126
|
+
|
|
127
|
+
# --- rule (c): containment conflicting with a strict order --------------
|
|
128
|
+
|
|
129
|
+
def _containment_vs_order(
|
|
130
|
+
self,
|
|
131
|
+
before: set[tuple[str, str]],
|
|
132
|
+
relations: dict[str, set[tuple[str, str]]],
|
|
133
|
+
) -> list[Violation]:
|
|
134
|
+
out: list[Violation] = []
|
|
135
|
+
containments = [("includes", a, b) for a, b in relations["includes"]]
|
|
136
|
+
containments += [("included_in", a, b) for a, b in relations["included_in"]]
|
|
137
|
+
for key, a, b in sorted(containments):
|
|
138
|
+
if (a, b) in before or (b, a) in before:
|
|
139
|
+
out.append(
|
|
140
|
+
Violation(
|
|
141
|
+
validator=self.name,
|
|
142
|
+
severity=Severity.error,
|
|
143
|
+
message=(
|
|
144
|
+
f"'{_label(a)}' and '{_label(b)}' are in a containment relation "
|
|
145
|
+
f"({key}), which is incompatible with a strict before/after order"
|
|
146
|
+
),
|
|
147
|
+
source=None,
|
|
148
|
+
triples=((a, _PRED[key], b),),
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
return out
|
|
152
|
+
|
|
153
|
+
# --- rule (d): numeric begin/end contradicting a relation ---------------
|
|
154
|
+
|
|
155
|
+
def _numeric(
|
|
156
|
+
self,
|
|
157
|
+
relations: dict[str, set[tuple[str, str]]],
|
|
158
|
+
intervals: dict[str, EventInterval],
|
|
159
|
+
indexer: Indexer,
|
|
160
|
+
) -> list[Violation]:
|
|
161
|
+
out: list[Violation] = []
|
|
162
|
+
|
|
163
|
+
def interval(uri: str) -> EventInterval:
|
|
164
|
+
return intervals.get(uri, EventInterval(uri, None, None))
|
|
165
|
+
|
|
166
|
+
def emit(a: str, key: str, b: str, why: str) -> None:
|
|
167
|
+
out.append(
|
|
168
|
+
Violation(
|
|
169
|
+
validator=self.name,
|
|
170
|
+
severity=Severity.error,
|
|
171
|
+
message=why,
|
|
172
|
+
source=resolve_source(indexer, a),
|
|
173
|
+
triples=((a, _PRED[key], b),),
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
for a, b in sorted(relations["follows"]): # a after b: a.begin must be >= b.end
|
|
178
|
+
ia, ib = interval(a), interval(b)
|
|
179
|
+
if ia.begin is not None and ib.end is not None and ia.begin < ib.end:
|
|
180
|
+
emit(
|
|
181
|
+
a,
|
|
182
|
+
"follows",
|
|
183
|
+
b,
|
|
184
|
+
f"'{_label(a)}' (begins {ia.begin}) is asserted to follow "
|
|
185
|
+
f"'{_label(b)}' (ends {ib.end}), but starts before it ends",
|
|
186
|
+
)
|
|
187
|
+
for a, b in sorted(relations["precedes"]): # a before b: a.end must be <= b.begin
|
|
188
|
+
ia, ib = interval(a), interval(b)
|
|
189
|
+
if ia.end is not None and ib.begin is not None and ia.end > ib.begin:
|
|
190
|
+
emit(
|
|
191
|
+
a,
|
|
192
|
+
"precedes",
|
|
193
|
+
b,
|
|
194
|
+
f"'{_label(a)}' (ends {ia.end}) is asserted to precede "
|
|
195
|
+
f"'{_label(b)}' (begins {ib.begin}), but ends after it begins",
|
|
196
|
+
)
|
|
197
|
+
for a, b in _unordered_pairs(relations["overlaps"]):
|
|
198
|
+
ia, ib = interval(a), interval(b)
|
|
199
|
+
# The disjointness DECISION is the shared single source of truth (FR-011);
|
|
200
|
+
# the two directional comparisons below only choose which message to emit
|
|
201
|
+
# (formatting), never re-decide the contradiction.
|
|
202
|
+
if not intervals_disjoint(ia, ib):
|
|
203
|
+
continue
|
|
204
|
+
if ia.end is not None and ib.begin is not None and ia.end < ib.begin:
|
|
205
|
+
emit(
|
|
206
|
+
a,
|
|
207
|
+
"overlaps",
|
|
208
|
+
b,
|
|
209
|
+
f"'{_label(a)}' (ends {ia.end}) and '{_label(b)}' (begins {ib.begin}) "
|
|
210
|
+
"are asserted to overlap, but their year ranges are disjoint",
|
|
211
|
+
)
|
|
212
|
+
else:
|
|
213
|
+
emit(
|
|
214
|
+
a,
|
|
215
|
+
"overlaps",
|
|
216
|
+
b,
|
|
217
|
+
f"'{_label(a)}' (begins {ia.begin}) and '{_label(b)}' (ends {ib.end}) "
|
|
218
|
+
"are asserted to overlap, but their year ranges are disjoint",
|
|
219
|
+
)
|
|
220
|
+
for key in ("includes", "included_in"):
|
|
221
|
+
for a, b in sorted(relations[key]):
|
|
222
|
+
container, contained = (a, b) if key == "includes" else (b, a)
|
|
223
|
+
ic, ict = interval(container), interval(contained)
|
|
224
|
+
if (ic.begin is not None and ict.begin is not None and ic.begin > ict.begin) or (
|
|
225
|
+
ic.end is not None and ict.end is not None and ic.end < ict.end
|
|
226
|
+
):
|
|
227
|
+
emit(
|
|
228
|
+
a,
|
|
229
|
+
key,
|
|
230
|
+
b,
|
|
231
|
+
f"'{_label(container)}' is asserted to contain "
|
|
232
|
+
f"'{_label(contained)}', but its year range does not enclose it",
|
|
233
|
+
)
|
|
234
|
+
return out
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _unordered_pairs(pairs: set[tuple[str, str]]) -> list[tuple[str, str]]:
|
|
238
|
+
"""Collapse a symmetric relation to one canonical ``(min, max)`` pair each."""
|
|
239
|
+
canonical = {tuple(sorted(pair)) for pair in pairs}
|
|
240
|
+
return sorted(canonical) # type: ignore[arg-type]
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def _strongly_connected(adjacency: dict[str, list[str]]) -> list[list[str]]:
|
|
244
|
+
"""Tarjan's SCC over the directed ``adjacency`` graph (deterministic order)."""
|
|
245
|
+
index_of: dict[str, int] = {}
|
|
246
|
+
low: dict[str, int] = {}
|
|
247
|
+
on_stack: set[str] = set()
|
|
248
|
+
stack: list[str] = []
|
|
249
|
+
counter = 0
|
|
250
|
+
result: list[list[str]] = []
|
|
251
|
+
|
|
252
|
+
def strong(node: str) -> None:
|
|
253
|
+
nonlocal counter
|
|
254
|
+
index_of[node] = low[node] = counter
|
|
255
|
+
counter += 1
|
|
256
|
+
stack.append(node)
|
|
257
|
+
on_stack.add(node)
|
|
258
|
+
for nbr in sorted(adjacency.get(node, ())):
|
|
259
|
+
if nbr not in index_of:
|
|
260
|
+
strong(nbr)
|
|
261
|
+
low[node] = min(low[node], low[nbr])
|
|
262
|
+
elif nbr in on_stack:
|
|
263
|
+
low[node] = min(low[node], index_of[nbr])
|
|
264
|
+
if low[node] == index_of[node]:
|
|
265
|
+
component: list[str] = []
|
|
266
|
+
while True:
|
|
267
|
+
w = stack.pop()
|
|
268
|
+
on_stack.discard(w)
|
|
269
|
+
component.append(w)
|
|
270
|
+
if w == node:
|
|
271
|
+
break
|
|
272
|
+
result.append(sorted(component))
|
|
273
|
+
|
|
274
|
+
for vertex in sorted(adjacency):
|
|
275
|
+
if vertex not in index_of:
|
|
276
|
+
strong(vertex)
|
|
277
|
+
return result
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bookwright-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Spec-driven authoring toolkit for novels, essays, and memoirs.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jmorenobl/bookwright
|
|
6
|
+
Project-URL: Repository, https://github.com/jmorenobl/bookwright
|
|
7
|
+
Project-URL: Issues, https://github.com/jmorenobl/bookwright/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/jmorenobl/bookwright/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: Jorge MB <jmorenobl@gmail.com>
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: NOTICE
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: POSIX
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: jinja2>=3.1
|
|
22
|
+
Requires-Dist: packaging>=23.0
|
|
23
|
+
Requires-Dist: platformdirs>=4.2
|
|
24
|
+
Requires-Dist: pydantic>=2.5
|
|
25
|
+
Requires-Dist: python-slugify>=8.0
|
|
26
|
+
Requires-Dist: pyyaml>=6.0
|
|
27
|
+
Requires-Dist: rdflib>=7.0
|
|
28
|
+
Requires-Dist: rich>=13.7
|
|
29
|
+
Requires-Dist: tomlkit>=0.12
|
|
30
|
+
Requires-Dist: typer>=0.12
|
|
31
|
+
Requires-Dist: uuid-utils>=0.16
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<picture>
|
|
36
|
+
<source srcset="https://raw.githubusercontent.com/jmorenobl/bookwright/main/assets/banner.svg" type="image/svg+xml">
|
|
37
|
+
<img src="https://raw.githubusercontent.com/jmorenobl/bookwright/main/assets/banner.png" alt="Bookwright — toolkit de autoría spec-driven para novelas, ensayos y memorias" width="100%">
|
|
38
|
+
</picture>
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<a href="https://github.com/jmorenobl/bookwright/actions/workflows/tests.yml"><img src="https://github.com/jmorenobl/bookwright/actions/workflows/tests.yml/badge.svg" alt="CI"></a>
|
|
43
|
+
<a href="https://github.com/jmorenobl/bookwright/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/version-0.2.0-6f42c1" alt="Versión 0.2.0"></a>
|
|
44
|
+
<a href="https://github.com/jmorenobl/bookwright/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue" alt="Licencia: Apache-2.0"></a>
|
|
45
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-3776ab?logo=python&logoColor=white" alt="Python 3.11+">
|
|
46
|
+
<img src="https://img.shields.io/badge/coverage-%E2%89%A580%25-2ea44f" alt="Cobertura ≥80%">
|
|
47
|
+
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/badge/lint-ruff-261230?logo=ruff&logoColor=white" alt="Lint con Ruff"></a>
|
|
48
|
+
<img src="https://img.shields.io/badge/types-mypy%20strict-2a6db2" alt="Tipado con mypy --strict">
|
|
49
|
+
<a href="https://github.com/github/spec-kit"><img src="https://img.shields.io/badge/built%20with-Spec%20Kit-0b7285" alt="Hecho con Spec Kit"></a>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<b>Toolkit de autoría spec-driven para novelas, ensayos y memorias.</b><br>
|
|
54
|
+
<i><a href="https://github.com/jmorenobl/bookwright/blob/main/README.en.md">Read in English</a></i>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
Bookwright aplica el patrón Spec-Driven Development a la escritura de
|
|
58
|
+
formato largo: destilas tus ideas en un conjunto reducido de documentos
|
|
59
|
+
canónicos (constitución, biblia, outline, escenas) y dejas que un agente
|
|
60
|
+
IA escriba a partir de *ellos*, no de un chat libre. Tu libro vive en
|
|
61
|
+
texto plano, versionado en git, completamente auditable, y sobrevive al
|
|
62
|
+
toolkit.
|
|
63
|
+
|
|
64
|
+
> ### Estado: v0.2.0
|
|
65
|
+
>
|
|
66
|
+
> Dos hitos están en `main`. **v0.1.0** (el toolkit base, iteraciones
|
|
67
|
+
> 1–11): scaffolding del proyecto (`bookwright init`), el modelo de
|
|
68
|
+
> dominio GOLEM, el indexer y los comandos `bookwright graph`, las skills
|
|
69
|
+
> de autoría materializadas como Agent Skills, y el sistema de validación
|
|
70
|
+
> de continuidad. **v0.2.0 / M4** (investigación y verificación,
|
|
71
|
+
> iteraciones 12–18): el modelo de procedencia `Source` / `Finding` /
|
|
72
|
+
> `Anchor`, las skills `/bookwright-research` y `/bookwright-verify`, el
|
|
73
|
+
> validador `factual_anchor` y la envoltura `--json` unificada. La
|
|
74
|
+
> documentación de usuario completa vive en el
|
|
75
|
+
> [sitio de documentación](https://github.com/jmorenobl/bookwright/blob/main/docs/index.md).
|
|
76
|
+
|
|
77
|
+
## El loop del escritor
|
|
78
|
+
|
|
79
|
+
1. **Idea libremente** — conversa con tu agente o tu libreta y vuelca un
|
|
80
|
+
brief a Markdown.
|
|
81
|
+
2. **Scaffolding del proyecto** —
|
|
82
|
+
`bookwright init mi-novela --integration claude` genera la estructura
|
|
83
|
+
de directorios, los templates de los documentos canónicos e instala
|
|
84
|
+
los *Agent Skills* de Bookwright en `.claude/skills/`.
|
|
85
|
+
3. **Destila, en orden** — abre el proyecto con Claude Code (o cualquier
|
|
86
|
+
agente compatible con [agentskills.io](https://agentskills.io)) y
|
|
87
|
+
ejecuta:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
/bookwright-constitution ← reglas no negociables de la obra
|
|
91
|
+
/bookwright-bible ← personajes, settings, lore
|
|
92
|
+
/bookwright-outline ← estructura de actos/capítulos
|
|
93
|
+
/bookwright-scenes ← desglose beat por beat
|
|
94
|
+
/bookwright-draft ← generación de prosa por escena
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Cada comando toma input no estructurado y produce un artefacto
|
|
98
|
+
Markdown / Turtle versionable. Iteras los *documentos*, no el
|
|
99
|
+
borrador.
|
|
100
|
+
|
|
101
|
+
4. **Construye y valida** — `bookwright graph build` deriva el grafo
|
|
102
|
+
narrativo GOLEM y `bookwright validate` corre los chequeos de
|
|
103
|
+
continuidad (continuidad temporal, presencia de personajes,
|
|
104
|
+
focalización, continuidad de settings).
|
|
105
|
+
|
|
106
|
+
5. **Edita en tu editor favorito** — Bookwright no es un editor de
|
|
107
|
+
texto. Abre los `.md` en Obsidian, Scrivener, VS Code o vim.
|
|
108
|
+
|
|
109
|
+
## Instalación
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
uv build
|
|
113
|
+
pipx install ./dist/bookwright_cli-*.whl # o: uv tool install ./dist/*.whl
|
|
114
|
+
bookwright version
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Para desarrollar sobre el toolkit, sincroniza el entorno del proyecto:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uv sync
|
|
121
|
+
uv run bookwright --help
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Quickstart en 5 minutos
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
bookwright init mi-novela --integration claude # scaffolding + Agent Skills
|
|
128
|
+
cd mi-novela
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Abre el proyecto en tu agente y destila tu idea con las skills (no editas los
|
|
132
|
+
documentos a mano; las skills leen tu brief y te preguntan lo que falte):
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
/bookwright-constitution lee idea.md y destila la constitución
|
|
136
|
+
/bookwright-bible ← personajes, settings, cronología
|
|
137
|
+
/bookwright-outline ← arcos y estructura
|
|
138
|
+
/bookwright-scenes ← desglose en escenas
|
|
139
|
+
/bookwright-draft ← redacta la prosa de una escena
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Para obra basada en hechos (p. ej. novela histórica), el loop opcional de
|
|
143
|
+
investigación documenta fuentes, hallazgos y anclas, y contrasta la prosa
|
|
144
|
+
contra ellas:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
/bookwright-research <tema> ← documenta hallazgos con procedencia completa
|
|
148
|
+
/bookwright-verify ← contrasta la prosa redactada con las anclas
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Y construye/valida desde el CLI:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
bookwright graph build # → bible/graph.ttl
|
|
155
|
+
bookwright graph query "SELECT ?c WHERE { ?c a golem:G1_Character }" --json
|
|
156
|
+
bookwright validate # exit 0 si no hay errores
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
¿Quieres cambiar de integración (p. ej. de `claude` a `generic`)?
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
bookwright integration use generic # re-materializa en .agents/skills/
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
El recorrido completo está en
|
|
166
|
+
[docs/getting-started.md](https://github.com/jmorenobl/bookwright/blob/main/docs/getting-started.md).
|
|
167
|
+
|
|
168
|
+
## Principios de diseño
|
|
169
|
+
|
|
170
|
+
- **El texto plano es la fuente de verdad.** Manuscrito, biblia,
|
|
171
|
+
constitución y grafo narrativo son Markdown, TOML o Turtle (RDF).
|
|
172
|
+
Auditables por humanos, diffables en git, portables.
|
|
173
|
+
- **Agnóstico de agente.** La capa de comandos se materializa como
|
|
174
|
+
[Agent Skills](https://agentskills.io) portables. Bookwright entrega dos
|
|
175
|
+
integraciones (`claude`, `generic`); agentes como Codex, Cursor o Copilot
|
|
176
|
+
consumen la salida `generic` directamente, sin integración nativa dedicada.
|
|
177
|
+
- **Batch, no conversacional.** Tú consolidas el input; el comando lo
|
|
178
|
+
destila. El agente no es un co-escritor frase a frase.
|
|
179
|
+
- **GOLEM por debajo.** El grafo narrativo usa la
|
|
180
|
+
[ontología GOLEM](https://github.com/GOLEM-lab/golem-ontology)
|
|
181
|
+
publicada (personajes, eventos, settings, relaciones, estructura
|
|
182
|
+
narrativa, procedencia de inferencias) serializada en Turtle.
|
|
183
|
+
|
|
184
|
+
## Roadmap y fuera de scope
|
|
185
|
+
|
|
186
|
+
Hecho: **v0.2 / M4** — investigación y verificación (modelo de procedencia,
|
|
187
|
+
skills `research`/`verify`, validador `factual_anchor`). Planificado:
|
|
188
|
+
**v0.3** — búsqueda vectorial (ChromaDB sobre rdflib, desacoplada); **v1.0** —
|
|
189
|
+
export a EPUB / PDF / impresión vía pandoc.
|
|
190
|
+
|
|
191
|
+
**Cancelado (decisión del owner), no lo pidas:** presets de género / paquetes
|
|
192
|
+
de plantilla (la resolución es de 2 capas, overrides → core); el motor
|
|
193
|
+
`Grafeo` / `GrafeoIndexer`; integraciones más allá de `claude` y `generic`;
|
|
194
|
+
el sistema de extensiones. Agentes como Codex, Cursor o Copilot ya se soportan
|
|
195
|
+
hoy vía la integración `generic` con `--integration-options="--skills-dir …"`,
|
|
196
|
+
sin integración nativa dedicada.
|
|
197
|
+
|
|
198
|
+
## Documentos del proyecto
|
|
199
|
+
|
|
200
|
+
- **[Sitio de documentación](https://github.com/jmorenobl/bookwright/blob/main/docs/index.md)** — guía de usuario completa
|
|
201
|
+
(primeros pasos, comandos, validación, extender, FAQ).
|
|
202
|
+
- **[bookwright-design.md](https://github.com/jmorenobl/bookwright/blob/main/bookwright-design.md)** — la especificación
|
|
203
|
+
de diseño completa. La numeración de secciones es load-bearing.
|
|
204
|
+
- **[bookwright-implementation-plan.md](https://github.com/jmorenobl/bookwright/blob/main/bookwright-implementation-plan.md)**
|
|
205
|
+
— el plan de iteraciones ordenado.
|
|
206
|
+
- **[.specify/memory/constitution.md](https://github.com/jmorenobl/bookwright/blob/main/.specify/memory/constitution.md)** —
|
|
207
|
+
los principios ratificados y vinculantes para cada PR.
|
|
208
|
+
- **[CONTRIBUTING.md](https://github.com/jmorenobl/bookwright/blob/main/CONTRIBUTING.md)** — instalación, quality gates y
|
|
209
|
+
cómo extender el toolkit (nueva integración, validador, vocabulario).
|
|
210
|
+
- **[CHANGELOG.md](https://github.com/jmorenobl/bookwright/blob/main/CHANGELOG.md)** — historial de cambios.
|
|
211
|
+
|
|
212
|
+
## Licencia
|
|
213
|
+
|
|
214
|
+
[Apache-2.0](https://github.com/jmorenobl/bookwright/blob/main/LICENSE). Consulta [NOTICE](https://github.com/jmorenobl/bookwright/blob/main/NOTICE) para la atribución.
|
|
215
|
+
|
|
216
|
+
Esta licencia cubre **solo el software bookwright**. El contenido que crees
|
|
217
|
+
con la herramienta —*bibles*, escaletas, manuscritos y los grafos de
|
|
218
|
+
conocimiento derivados— sigue siendo enteramente tuyo.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
bookwright/__init__.py,sha256=23ymNkiVBlZ46IWynllTjjwuZJUiEjt2fqv3viHPGbk,75
|
|
2
|
+
bookwright/__main__.py,sha256=cBSZ5tESgL2KDMDtYlJGSQKDdOpDLZNgJowdOIJ0IeI,124
|
|
3
|
+
bookwright/cli.py,sha256=JxvKKH_e-awLtBcLjijqZb6eThjNmEblDtm0j7wFHI8,554
|
|
4
|
+
bookwright/errors.py,sha256=neja3k4RI_ce63UjOtVj07zSbX86q6TEkyMOB96TA44,1906
|
|
5
|
+
bookwright/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
bookwright/commands/_envelope.py,sha256=cW_IzjC780Mzkp2FVB4silNlyp9Jr7T5lH6VQqbi1n4,1457
|
|
7
|
+
bookwright/commands/check.py,sha256=j1Q06hBqopT23NpzJklMyZ1QxJd203-btY-3B4RJQbk,2138
|
|
8
|
+
bookwright/commands/validate.py,sha256=3j_vhrTe3r9kw_4rFmHOR48WJ51aGFiLNXldEodIGCk,5738
|
|
9
|
+
bookwright/commands/version.py,sha256=WcnAiNR6nNXBPx5ePEH_iAR3P0EPlSZcdWD1m1nmWaM,1003
|
|
10
|
+
bookwright/commands/graph/__init__.py,sha256=PN6tEi0gcUl-Sj-k-JimTtQagar56GDp9g1I9jGFlB0,760
|
|
11
|
+
bookwright/commands/graph/build.py,sha256=zj8FcMA_SpDFvo_W-85NS524RtK3pvzgVYVLZIXICmw,5984
|
|
12
|
+
bookwright/commands/graph/envelope.py,sha256=wbTysVTjnO49fo4Mm-yhoTImMX1JgO8HzuyiDEfaKGo,958
|
|
13
|
+
bookwright/commands/graph/query.py,sha256=_14nxX1SkTiS-95BhAcSdUaJLo1RHv2GDCCsYBZTtTM,3088
|
|
14
|
+
bookwright/commands/init/__init__.py,sha256=Sdgz4eUhmbJqLgknw6X66sA_fR39vZFbAZDxOayWxq0,147
|
|
15
|
+
bookwright/commands/init/conflict.py,sha256=puN6on6orfwH1LE5zyOgnxk7dlkMo1J5HS0Ac3NMMmI,3239
|
|
16
|
+
bookwright/commands/init/envelope.py,sha256=CgMwGmgNRXMGwQq9UjpcqACoq8zYFcnSibXGszxo--g,11154
|
|
17
|
+
bookwright/commands/init/git.py,sha256=pJ5J9oOH-gO7U5UTfhtN_ICH1b4esMwZ0d8zSi8Ek8A,2733
|
|
18
|
+
bookwright/commands/init/main.py,sha256=ZMCPSQeqH7gmMABmq52RbsG2jPv4wm3nk3LNROwFRiA,9827
|
|
19
|
+
bookwright/commands/init/resolve.py,sha256=uaA_jf4Al45-u8rQ2DEewQDxUD81cbOmY3cS_uEYDCI,5462
|
|
20
|
+
bookwright/commands/init/scaffold.py,sha256=05v2vEpVnsk8MfsYHY-8HRhLeqI5sFzVwoNuUuK5ie8,8439
|
|
21
|
+
bookwright/commands/init/validate.py,sha256=b51Hj3hRYnBHvQoQa2e5EjlXmYYUF7yW9qUrwDeTZ2I,5275
|
|
22
|
+
bookwright/commands/integration/__init__.py,sha256=4j8a0_5oPZACeK2r3iexnjyEnFCpWfNan8Lf2Ep-dOo,756
|
|
23
|
+
bookwright/commands/integration/use.py,sha256=x3jL6gaXMN700FlFTZM1PT9Zodd1Gt8ItBVl9rLXSO4,4588
|
|
24
|
+
bookwright/core/__init__.py,sha256=lbt96r7Utdm0rMhkzih5nG5EajQ402I1rxGTqiMeIPM,869
|
|
25
|
+
bookwright/core/_blocks.py,sha256=Kb4mByy48Vs6O37XWRXCCuUYnPntE27cSNVPF2Ujiys,7609
|
|
26
|
+
bookwright/core/_build.py,sha256=wyqd1Y_wb8YRMJzbgGIzNhUkUuK3Xqzff0d1A8MzzoQ,6176
|
|
27
|
+
bookwright/core/_research_block.py,sha256=dARIg-uEGcqgFyvTt8CQd6swWOYeMf_UFYp_6bCOrDg,2328
|
|
28
|
+
bookwright/core/_translate.py,sha256=sqhGox_C4rW3-ksg6RG9f_9fSlE5mG-ToOUNiYb28W4,3264
|
|
29
|
+
bookwright/core/errors.py,sha256=L1WJG2JaiaxXUuOzz6bBJkykx01TGiomSYHTCkdngoI,3542
|
|
30
|
+
bookwright/core/iso639_1.py,sha256=RblKhCrAg6EUAxqa2Rq_chXDMaowueEqVQC4mpPwTRo,3113
|
|
31
|
+
bookwright/core/manifest.py,sha256=z5P0F2sCYvpzAvK1caCH5dKZvZmdvq0mffwIANIa0Ys,13121
|
|
32
|
+
bookwright/golem/__init__.py,sha256=w8zFvSplB3gIZiD3t0uctwvbInAh3OMxodbMJKSXzx8,2438
|
|
33
|
+
bookwright/golem/base.py,sha256=oLkRpeUuyR3Ax_Yb75p2p2_W6u__IF-4f2VyqDLtMvo,8137
|
|
34
|
+
bookwright/golem/errors.py,sha256=-_2m0FRLkHVXDl2xQn1sIOrEaJPW7MpqRQO5gSXOvZA,857
|
|
35
|
+
bookwright/golem/namespaces.py,sha256=9cSaREMNGxxWy7_LPEmOdx0XjwDAv9qxgcqG_2K2qqI,13708
|
|
36
|
+
bookwright/golem/serialize.py,sha256=VUSaygvac2GNze3_yetal_FPxzUOuoHdyAsUjuRD17o,794
|
|
37
|
+
bookwright/golem/slug.py,sha256=yBVz5jXE2EVPsReijKzyIqgfuv53Jzmo6uNkoDg1fTk,749
|
|
38
|
+
bookwright/golem/modules/__init__.py,sha256=3D0p5QFDOUHdjb_hkg8AtAGeNzfZt3cnfJCQS3xIOP0,65
|
|
39
|
+
bookwright/golem/modules/character.py,sha256=H0KXm3p6E3aIzwAiecDn1ScZyJSocF3vE4YF9v4fDKU,4773
|
|
40
|
+
bookwright/golem/modules/event.py,sha256=u3OUxkz3yS6Hk4Kdv5g-0gbkT4xOBlrQKh5dLz5KE9Q,3814
|
|
41
|
+
bookwright/golem/modules/feature.py,sha256=xr0HmCoHWdM4innRw1uwAdHjCFTwP1DaNltSnP6aJ5c,7316
|
|
42
|
+
bookwright/golem/modules/inference.py,sha256=0WU-8A17E3QoQFoh59JL9CUaAJ7rLWpS9zAhZw6IivU,1407
|
|
43
|
+
bookwright/golem/modules/narrative.py,sha256=z2kp2dwcnOwCDIjnjPqKbvHJ8BvyxIx6CgI9fQDmM8Y,1888
|
|
44
|
+
bookwright/golem/modules/provenance.py,sha256=niaZmu3IFNzvRHtAxWxarsdcchhtf5at7COMo5ZKmew,8163
|
|
45
|
+
bookwright/golem/modules/relationship.py,sha256=8za7fY2tTGdnWSAH6tKzcqYrTnwV9dXtQTZg9iTNIf4,1257
|
|
46
|
+
bookwright/golem/modules/setting.py,sha256=GLOLJkz5dVg5WhjjIQJOl0hD4R5AxdP6WUjAy4fWwGw,963
|
|
47
|
+
bookwright/indexers/__init__.py,sha256=CK5H1en7cerOJ46_s2oSV-3xlAZCGN5zxR7x8l169Ts,1371
|
|
48
|
+
bookwright/indexers/base.py,sha256=09CQW8Ct6rzf1zJiMESQ_sUtQXD7yCPvnrhc6YLj63A,1792
|
|
49
|
+
bookwright/indexers/errors.py,sha256=9gVa-BSz1YAVc4z51R_o6PuKYozaqrfN8yTe-YryCzA,2466
|
|
50
|
+
bookwright/indexers/rdflib_indexer.py,sha256=RwAxoTntuHSvvAzaxzlqjkThhCYcJhgpzrXHPcgo1Xw,3439
|
|
51
|
+
bookwright/integrations/__init__.py,sha256=bF6FHU38cD4jIlMhDujQxAWm8125IWYNUFIuyUC3S4I,5872
|
|
52
|
+
bookwright/integrations/base.py,sha256=6K4cjE1sM3iMn0-7czKSATjaIoJJWOGwhOLgcTxkBy4,5032
|
|
53
|
+
bookwright/integrations/constants.py,sha256=HQLJlh9JRV40jNCu424xQcjffXn8TgZGRaia7UnfbaA,1915
|
|
54
|
+
bookwright/integrations/descriptions.py,sha256=UcDgvkFNliJ43BSEq8xyXLs13yfW7mC8N2aFK5lLt4g,8872
|
|
55
|
+
bookwright/integrations/errors.py,sha256=jUOffDrmxZUCR3ehcutwRMEAVZ4VO6SXHzEHOOVVAl8,6667
|
|
56
|
+
bookwright/integrations/lint.py,sha256=3ykg20_yaEEhDRJEzYrXyAYUSJfGsMnlR4gQiTa66n4,6325
|
|
57
|
+
bookwright/integrations/materialize.py,sha256=JSSPAnBhP-4aLxluFEuu80lm11i2T42Agkl0nNGVSMs,7883
|
|
58
|
+
bookwright/integrations/options.py,sha256=1nsHN_J3sXUqlvQJOqS6mbwENCQqRUft9siDAs3OeEA,8288
|
|
59
|
+
bookwright/integrations/claude/__init__.py,sha256=zZge3UC1os8t4zYA9JNazMB9PXfwYkHmdA6PleDTmrU,962
|
|
60
|
+
bookwright/integrations/generic/__init__.py,sha256=7_jlMdVZrDyVEsGYdZP9B6bqd3zSsu12hllkKi6jw1k,1989
|
|
61
|
+
bookwright/io/__init__.py,sha256=15BdoOgQzkpKaflQQfnUVPJtHkdboWxANN8T6sFa8z8,84
|
|
62
|
+
bookwright/io/bible.py,sha256=9lRnhfqkojTUrRVY4bBlGG0f0PQBI1nxNMBTrQP_e6s,18353
|
|
63
|
+
bookwright/io/errors.py,sha256=FcrckBsDJ20ubnqzIlGQrJIXD_a3i4yeWLsPoyT4Iak,3388
|
|
64
|
+
bookwright/io/frontmatter.py,sha256=SiXqfHckgWo91TVlmSUroBun3iUvR1hrCMfOXLoXFqc,2146
|
|
65
|
+
bookwright/io/fs.py,sha256=TVdaEXO_zx_mfYBX3qHoKDink7yhHn_z0ZWp6KU-ndE,8237
|
|
66
|
+
bookwright/io/manuscript.py,sha256=tFehtR4dQ9owNuG7xCCTheUwLEQ7X5fZExubWjsUEGA,449
|
|
67
|
+
bookwright/io/project.py,sha256=hKwoCUGq-z3SZ1xY7O1gI1Gs6T-dJnQa1ZVI9tif88s,660
|
|
68
|
+
bookwright/io/report.py,sha256=ELJgaw0HsxsDftnV6JUk_tIl4n2vTbY-GhGQhiD8EwQ,3351
|
|
69
|
+
bookwright/io/research.py,sha256=tMHWDwHWQJIvMiTXnt2JAaFOF213i5yR69GUQu-OsWw,16051
|
|
70
|
+
bookwright/resources/__init__.py,sha256=tGBRWRfSqEJx5YjWHHpOn-TCSpdYjJr2Sk1f84kapWU,59
|
|
71
|
+
bookwright/resources/commands/bookwright-analyze.md,sha256=PffZ-O7Wdca4j_vr7A-B9N4UvwEEXdCo03fgZBSbcEU,2606
|
|
72
|
+
bookwright/resources/commands/bookwright-bible.md,sha256=inO8kbt4Q3ZQZ7q0KWj9bLk7-6HLFl2AlGypzixLIVE,4766
|
|
73
|
+
bookwright/resources/commands/bookwright-checklist.md,sha256=-Ct5P72vxmPFrKHlH1NYdYInVVaSfrQcB78TYtTbMzc,2684
|
|
74
|
+
bookwright/resources/commands/bookwright-clarify.md,sha256=XWB8NVnYwjjc_YzbvoEZd2DZHZI3twTpjAAAANR-mNs,2562
|
|
75
|
+
bookwright/resources/commands/bookwright-constitution.md,sha256=qSLTGWPHHrNdkF-7AtEHy86P3hM3NziU3GCVs5hqqnM,3507
|
|
76
|
+
bookwright/resources/commands/bookwright-continuity.md,sha256=ANALjUtrL3PC3JGIf72nN9jol89WQ-Oq5YFLc6Bfb8M,3003
|
|
77
|
+
bookwright/resources/commands/bookwright-draft.md,sha256=Q3tJr2BHebYvqBGCfqaMZrPnU85QXn3_qdOS3mzM5no,3199
|
|
78
|
+
bookwright/resources/commands/bookwright-outline.md,sha256=1JS6zmopNeTcnJ5wV9G-TannMYResQ3t8EB86Tsgwok,3051
|
|
79
|
+
bookwright/resources/commands/bookwright-research.md,sha256=RDkRIMLpXLZDp7EC4q5PHeTmsiFmygzu_ko1Yip-nUE,5409
|
|
80
|
+
bookwright/resources/commands/bookwright-scenes.md,sha256=lw8zfkf8ppAH7ig88o8XjTdWV3fNIj41BT2mQsFzYQA,2647
|
|
81
|
+
bookwright/resources/commands/bookwright-synopsis.md,sha256=u1gnYpvL44BdkljLdHP5GK2dAnl_CTXBk-V1m8biIeI,2764
|
|
82
|
+
bookwright/resources/commands/bookwright-verify.md,sha256=3fvScVdixMUwd4x707kMs5ju6v1FlVTHz1V25wyteCU,6839
|
|
83
|
+
bookwright/resources/commands/references/golem-character.md,sha256=T7RWgSE5s196PMotOdMVNJ30wGra2K6bKvzKH0CD8i4,3208
|
|
84
|
+
bookwright/resources/commands/references/golem-events-timeline.md,sha256=Qn9b0b2Amgvg41T1mDyOkZgc8Q4UKHTtVoPNF-Piv1U,2595
|
|
85
|
+
bookwright/resources/commands/references/golem-relationships.md,sha256=VnnR34rPqQg_09JXnyCL7OVb5t9lmsd-kgZptqEfgEA,2547
|
|
86
|
+
bookwright/resources/commands/references/greimas-actants.md,sha256=4Dr00cYiKfpU13yupCPLkXh-6sMQdRb31nKicBz3Tfc,2715
|
|
87
|
+
bookwright/resources/commands/references/pending-protocol.md,sha256=JiRG1mwIxZHiMM5nLyV0rbLjIIIGfCawDuUaxoDM-l4,3336
|
|
88
|
+
bookwright/resources/commands/references/propp-functions.md,sha256=kQfUf_pGz2nxruewkd90SPNmNNw2ftHiw0x9fFdtiuY,2858
|
|
89
|
+
bookwright/resources/commands/references/research-format.md,sha256=wB_zBCUpcqvtdMVa1iD4wE0HmGZgELNP8RjCk6Khfmo,5599
|
|
90
|
+
bookwright/resources/project/.gitignore,sha256=db-DW5tJ512haAhQp5m_KCCGGkVMa0GWNnkDxqOr4rs,274
|
|
91
|
+
bookwright/resources/project/README.md.j2,sha256=PnTAu_FdHTHB42DmW7AJ3E_hp7O7kAoQVenRYnuf8rI,1657
|
|
92
|
+
bookwright/resources/project/__init__.py,sha256=99rfdXfZwlvnOabKYlovV2M-HBAje2UuZQbjjsAtMVc,234
|
|
93
|
+
bookwright/resources/project/.bookwright/cache/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
94
|
+
bookwright/resources/project/.bookwright/schema/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
|
+
bookwright/resources/project/.bookwright/templates/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
96
|
+
bookwright/resources/project/bible/constitution.md.j2,sha256=34SvFkGhM5noc3r2gXaConLqyQzuLRxasxfTVpx6KrM,3523
|
|
97
|
+
bookwright/resources/project/bible/glossary.md,sha256=egIHFLZLU4vH42wnc8pixRUHv2bHCMJT6KVUhh5RSkc,1422
|
|
98
|
+
bookwright/resources/project/bible/pov-structure.md,sha256=Crc_UaOXBadkZqURv9MlWfaheUh93nJ06nFny22ZMTU,1651
|
|
99
|
+
bookwright/resources/project/bible/relationships.md,sha256=Abce1dTEMV0K_kLpYEvpf-07HR8tmDqVQhqWkCe20UU,1383
|
|
100
|
+
bookwright/resources/project/bible/subplots.md,sha256=CwGWhnNE88RLfyiLECP_5jo9bsK1b1S-shoLdY3nDkU,1332
|
|
101
|
+
bookwright/resources/project/bible/themes.md,sha256=0eaj689-1CmuqGQqAm8wvDmP82Fg6WSgJfGSxVrtF5o,1397
|
|
102
|
+
bookwright/resources/project/bible/timeline.md,sha256=S_axsGSVcT5rgB2nwnIpPKBub-tg5XKBdNecZIM0P98,1507
|
|
103
|
+
bookwright/resources/project/bible/characters/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
104
|
+
bookwright/resources/project/bible/locations/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
105
|
+
bookwright/resources/project/bible/research/_index.md,sha256=bm0kifgv9NFXKrr84XrowXa8Vewfup96F8CmBUIWjkI,1006
|
|
106
|
+
bookwright/resources/project/bible/research/sources.md,sha256=7KEicPHtTZfBfoDH0Kd8mVeI7S-l7sj1uYeoCE9ZL8w,817
|
|
107
|
+
bookwright/resources/project/bible/settings/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
|
+
bookwright/resources/project/manuscript/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
109
|
+
bookwright/resources/project/outline/arcs.md,sha256=AL4Ss9Ox6FORHoXfXluOUbG_gUqrSWSBNhng2kueZb4,1275
|
|
110
|
+
bookwright/resources/project/outline/scenes.md,sha256=XlbVyjTG4lNFSOJyAB_JPgL2XucvW-H3fzNwXfsEek8,1240
|
|
111
|
+
bookwright/resources/project/outline/structure.md,sha256=-6ry9YeA1KVIyWgWtXfSnm5Sg-or5rvG3LxvrMffPcw,1264
|
|
112
|
+
bookwright/resources/project/outline/synopsis.md,sha256=m3C55mP-afuzlqCqwmkahwoOp8jbow448HlLzHUmEx0,1128
|
|
113
|
+
bookwright/resources/schemas/__init__.py,sha256=RJ9qMTZqMBTHzSbvzaNEkXq38TelVVySW2NrI1Bvb3Y,732
|
|
114
|
+
bookwright/resources/schemas/golem-1.1/VERSION,sha256=CrlOqWYP09Yswd3holmbL2lRw5_IeoBF59jewxWWg7c,10
|
|
115
|
+
bookwright/resources/schemas/golem-1.1/golem.ttl,sha256=w3ax58-qqDmCX57yMCI8QgggheIr-KyMm4qsl5KUM9k,222490
|
|
116
|
+
bookwright/resources/schemas/golem-1.1/version.json,sha256=1HjT_0LNBAk7ppQFrKb4c72wG5wKoIiuOK0aITdDcx8,267
|
|
117
|
+
bookwright/resources/templates/__init__.py,sha256=bvtILwtia3_RcgWtm4XjsFzrBqHR89HxyhLEEKKP3Ho,70
|
|
118
|
+
bookwright/resources/templates/manifest.template.toml,sha256=OGocDgXsX8FKqn-1tp8hr9CxBlEk1xRO_JY9nFv5Pm4,2715
|
|
119
|
+
bookwright/resources/templates/bible/character.md.tmpl,sha256=Yibfvvqrm2AbyfLDq8NYniOey_SBlPfA2JsZw986mvk,2126
|
|
120
|
+
bookwright/resources/templates/bible/location.md.tmpl,sha256=iMW8xQs7-q1vGHxa8R9nHy1U4lXU3KnM-WHDq7vHyE4,1173
|
|
121
|
+
bookwright/resources/templates/bible/setting.md.tmpl,sha256=qXVfUBBXNRTTAnjp7eRKM-i_PgC-5zeDi2TQzdYhJ2Q,1298
|
|
122
|
+
bookwright/resources/templates/bible/research/_index.md.tmpl,sha256=93bI4cnYMNr7q9XbX0L8Q6Im6Npce73RfVSiZe-AO0Q,761
|
|
123
|
+
bookwright/resources/templates/bible/research/sources.md.tmpl,sha256=NeILFKO0-ZsbSLM_R-_3dTClgQE2uZIQbnss5vhgFV8,770
|
|
124
|
+
bookwright/resources/templates/bible/research/tema.md.tmpl,sha256=U74ZbT0hc9XYG_H8ZFGp0LoGUtlKLFlGzbyFdH-wOpM,1292
|
|
125
|
+
bookwright/resources/templates/manuscript/chapter.md.tmpl,sha256=LBD7T2UNNlcvhBLtqGCa8oapmYULX95g0rmzduQVHkE,1335
|
|
126
|
+
bookwright/resources/templates/scenes/scene.md.tmpl,sha256=ZSFItr-jMcf7Zh4eHxM6lsRehD_nmD_rW1WsOEU2jDg,1120
|
|
127
|
+
bookwright/resources/vocabularies/__init__.py,sha256=d8ccqka8_NnEzx70p9FiUuYadrCOvo99lnTC2LCNAlA,252
|
|
128
|
+
bookwright/resources/vocabularies/greimas.ttl,sha256=bUcYyWU6f-rONc-sToJozNb9sui0_WBEZp-Oe4NBuvE,137
|
|
129
|
+
bookwright/resources/vocabularies/propp.ttl,sha256=EOkdkhy7a1IY9szlJH-auMlKtOEd1LQlIh5hCLVJioE,133
|
|
130
|
+
bookwright/resources/vocabularies/sources.ttl,sha256=nW32SiTz7pE8KwzHMaVkmQe0doL-HKfS_uSHs-cMRSM,3974
|
|
131
|
+
bookwright/validation/__init__.py,sha256=ZJtYZJcPHNAje3LnxsfROZqIQshjVLHjKpJf_WUx28s,904
|
|
132
|
+
bookwright/validation/anchor_queries.py,sha256=1yyzdP6pPcpR2snh1EB75KgFxlkJLBPAirFqcoLuUI0,8049
|
|
133
|
+
bookwright/validation/base.py,sha256=ySLN5wOj8q9skc4A1voRH7WbhA5zMv0iM-iC4LYACkI,8872
|
|
134
|
+
bookwright/validation/queries.py,sha256=xTvvysueg_1WpfhMyBMTjDAu3xh89KL1UjvwDWATRhw,7243
|
|
135
|
+
bookwright/validation/registry.py,sha256=9xxzx0aXFboYDaSzoaxXaJhXTMjIP86DhLhFYQeMarE,7605
|
|
136
|
+
bookwright/validation/report.py,sha256=i6hbhaUW2DiGDzChmNA4OA6eT44P3iQFtGYqvQNhtyY,4374
|
|
137
|
+
bookwright/validation/runner.py,sha256=YDVUC6-8XlkOshT1EfT9wXHB4xtyh_tJoEbRpToFMN4,2401
|
|
138
|
+
bookwright/validation/validators/__init__.py,sha256=gUrYmSkeZk0XWLkGPr6hZji3G5vl0EZpMBTqDDvi64E,385
|
|
139
|
+
bookwright/validation/validators/character_presence.py,sha256=zM95aH-KfWCFhu_tow0_cLIqBTsG6Ky6RXAWMVK4BnY,6698
|
|
140
|
+
bookwright/validation/validators/factual_anchor.py,sha256=28Y-5j8szwleo4YaFVRWQCYiiHrvCMN2Vwv-uUuZEQg,12382
|
|
141
|
+
bookwright/validation/validators/focalization.py,sha256=MFnR-MZW7_n7bzQI3e9lXkp3qJJzKQGzIZSZFJjg28Q,6163
|
|
142
|
+
bookwright/validation/validators/setting_continuity.py,sha256=bAA1HC6lFsDh9W5Y8QzF2_WqEhEvbs9RmGT6zjtp3eg,3983
|
|
143
|
+
bookwright/validation/validators/temporal.py,sha256=JOglQKlQ9r9Q154untsRIlmz0BeY6EbGfITtxtuUchY,11253
|
|
144
|
+
bookwright_cli-0.2.0.dist-info/METADATA,sha256=bp39INxbrKkgz3Mgju5MMS87qDXHDAOugiLqNemwCqg,10248
|
|
145
|
+
bookwright_cli-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
146
|
+
bookwright_cli-0.2.0.dist-info/entry_points.txt,sha256=9vmba2QukWicX2nMCJBLNfqn7tUp292Ag4az5QwOCGA,50
|
|
147
|
+
bookwright_cli-0.2.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
148
|
+
bookwright_cli-0.2.0.dist-info/licenses/NOTICE,sha256=iUzpGacN_8pxMjGZLgve2qUOT58FJzH_j5UpAWApB3Y,543
|
|
149
|
+
bookwright_cli-0.2.0.dist-info/RECORD,,
|