kd-cli 2.5.2__tar.gz → 2.6.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.
- {kd_cli-2.5.2/kd_cli.egg-info → kd_cli-2.6.1}/PKG-INFO +1 -1
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/article_marker.py +29 -9
- kd_cli-2.6.1/kd/cache.py +3359 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/main.py +12 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/__init__.py +2 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/article/__init__.py +90 -15
- kd_cli-2.6.1/kd/cli/namespaces/cache/__init__.py +641 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/issue/__init__.py +181 -1
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/tag/__init__.py +2 -4
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/client.py +411 -68
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/connection.py +36 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/tag_entities.py +16 -1
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/CHANGELOG.md +78 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/operating-guide.md +31 -2
- kd_cli-2.6.1/kd/resources/sdlc-doctrine.md +602 -0
- kd_cli-2.6.1/kd/sdlc.py +21 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1/kd_cli.egg-info}/PKG-INFO +1 -1
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd_cli.egg-info/SOURCES.txt +4 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/pyproject.toml +1 -1
- {kd_cli-2.5.2 → kd_cli-2.6.1}/LICENSE +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/MANIFEST.in +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/README.md +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/articles.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/http.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/hub.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/saved_queries.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/tags.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/api/youtrack.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/auth.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/core/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/core/command_base.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/core/command_parser.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/core/confirm.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/core/namespaces.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/core/option_registry.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/input.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/alias/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/init.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/primer/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/project/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/query/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/release_notes.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/search/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/system/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/time/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/namespaces/user/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/output.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/cli/tree.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/config.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/config_read.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/config_schema.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/debug.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/exceptions.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/history.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/locking.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/article.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/assist.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/attachment.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/comment.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/common.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/issue.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/project.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/saved_query.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/search.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/tag.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/user.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/models/work_item.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/operating_guide.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/primer.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/query_parser.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/release_notes.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/command-synonyms.yaml +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/config-template.yaml +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/error-messages.yaml +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/primers/__init__.py +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd/resources/primers/hitl.yaml +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd_cli.egg-info/dependency_links.txt +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd_cli.egg-info/entry_points.txt +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd_cli.egg-info/requires.txt +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/kd_cli.egg-info/top_level.txt +0 -0
- {kd_cli-2.5.2 → kd_cli-2.6.1}/setup.cfg +0 -0
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
The marker block is the upsert key for ``/article push``. It lives as
|
|
4
4
|
an HTML comment at the top of an article's content and in the local
|
|
5
5
|
source file. See ``docs/proposals/19-article-push-proposal.md`` for
|
|
6
|
-
the
|
|
6
|
+
the original design and ``docs/proposals/41-minimal-article-marker-proposal.md``
|
|
7
|
+
for the identity-only shrink.
|
|
7
8
|
|
|
8
9
|
Grammar (informal):
|
|
9
10
|
|
|
@@ -23,11 +24,20 @@ Rules (pinned down by ``tests/test_article_marker.py``):
|
|
|
23
24
|
property that lets future kd versions add keys without breaking
|
|
24
25
|
older versions' round-trips.
|
|
25
26
|
- Known keys are emitted first in the canonical order ``slug``,
|
|
26
|
-
``upstream-id
|
|
27
|
+
``upstream-id``. Unknown keys (including the legacy
|
|
28
|
+
``upstream-updated`` produced by pre-S1 pushes) follow in their
|
|
27
29
|
original insertion order.
|
|
28
30
|
- Line endings and trailing newlines are preserved so that a
|
|
29
31
|
``parse → render`` cycle is a fixed point.
|
|
30
32
|
|
|
33
|
+
Write-back semantics (proposal 41): push writes the local marker only
|
|
34
|
+
when identity must be established or repaired (no marker, missing
|
|
35
|
+
``upstream-id``, or resolved article id differs). It never rewrites the
|
|
36
|
+
file just to refresh tool-generated state. ``upstream-updated`` is
|
|
37
|
+
parsed and preserved when present (forward-compat for the existing
|
|
38
|
+
passive-timestamp conflict path) but is no longer emitted by new
|
|
39
|
+
pushes.
|
|
40
|
+
|
|
31
41
|
Legacy marker synonym (transitional, proposal 28 / M003 §S4):
|
|
32
42
|
|
|
33
43
|
The parser accepts any ``<!-- kd-meta`` or ``<!-- ytctl-meta``
|
|
@@ -95,8 +105,9 @@ _LINE_RE = re.compile(r"^([a-z][a-z0-9-]*)\s*:\s*(.*)$")
|
|
|
95
105
|
_SLUG_RE = re.compile(r"^[A-Za-z0-9._][A-Za-z0-9._/\-]*$")
|
|
96
106
|
|
|
97
107
|
# Canonical emission order for keys kd itself writes. Anything else
|
|
98
|
-
#
|
|
99
|
-
|
|
108
|
+
# (including the legacy ``upstream-updated`` from pre-S1 pushes) is an
|
|
109
|
+
# "unknown key" and appended in original order.
|
|
110
|
+
_KNOWN_KEYS: tuple[str, ...] = ("slug", "upstream-id")
|
|
100
111
|
|
|
101
112
|
|
|
102
113
|
class MarkerError(ValidationError):
|
|
@@ -108,9 +119,10 @@ class ArticleMarker:
|
|
|
108
119
|
"""Parsed kd-meta marker block.
|
|
109
120
|
|
|
110
121
|
``data`` is an insertion-ordered dict of every key/value pair found
|
|
111
|
-
in the block, including unknown keys. The
|
|
112
|
-
|
|
113
|
-
``
|
|
122
|
+
in the block, including unknown keys. The two canonical known keys
|
|
123
|
+
(``slug``, ``upstream-id``) and the tolerated legacy key
|
|
124
|
+
``upstream-updated`` expose typed properties for convenience;
|
|
125
|
+
everything else is accessed via ``data``.
|
|
114
126
|
"""
|
|
115
127
|
|
|
116
128
|
data: "OrderedDict[str, str]" = field(default_factory=OrderedDict)
|
|
@@ -134,6 +146,13 @@ class ArticleMarker:
|
|
|
134
146
|
|
|
135
147
|
@property
|
|
136
148
|
def upstream_updated(self) -> str | None:
|
|
149
|
+
"""Legacy ``upstream-updated`` value if present.
|
|
150
|
+
|
|
151
|
+
Forward-compat accessor: pre-S1 pushes emitted this in the
|
|
152
|
+
canonical set; new pushes never emit it. The existing passive-
|
|
153
|
+
timestamp conflict path in ``ArticleOperations.push`` still
|
|
154
|
+
reads it when present.
|
|
155
|
+
"""
|
|
137
156
|
return self.data.get("upstream-updated")
|
|
138
157
|
|
|
139
158
|
|
|
@@ -290,8 +309,9 @@ def _join_body(lines: list[str], trailing_newline: bool) -> str:
|
|
|
290
309
|
def render_content(parsed: ParsedFile) -> str:
|
|
291
310
|
"""Render a ``ParsedFile`` back to text, preserving byte-identity.
|
|
292
311
|
|
|
293
|
-
-
|
|
294
|
-
|
|
312
|
+
- Canonical known keys first (``slug``, ``upstream-id``), then any
|
|
313
|
+
remaining keys (including the tolerated legacy ``upstream-updated``)
|
|
314
|
+
in their original insertion order.
|
|
295
315
|
- Blank line separator between ``-->`` and the first body line
|
|
296
316
|
(canonical form; also the shape the YouTrack web UI normalizes
|
|
297
317
|
into).
|