kd-cli 2.5.1__tar.gz → 2.6.0__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 (86) hide show
  1. {kd_cli-2.5.1/kd_cli.egg-info → kd_cli-2.6.0}/PKG-INFO +1 -1
  2. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/article_marker.py +29 -9
  3. kd_cli-2.6.0/kd/cache.py +3359 -0
  4. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/main.py +12 -0
  5. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/__init__.py +2 -0
  6. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/article/__init__.py +116 -17
  7. kd_cli-2.6.0/kd/cli/namespaces/cache/__init__.py +641 -0
  8. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/issue/__init__.py +181 -1
  9. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/tag/__init__.py +2 -4
  10. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/client.py +434 -63
  11. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/connection.py +36 -0
  12. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/tag_entities.py +16 -1
  13. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/CHANGELOG.md +75 -0
  14. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/operating-guide.md +33 -2
  15. kd_cli-2.6.0/kd/resources/sdlc-doctrine.md +479 -0
  16. kd_cli-2.6.0/kd/sdlc.py +21 -0
  17. {kd_cli-2.5.1 → kd_cli-2.6.0/kd_cli.egg-info}/PKG-INFO +1 -1
  18. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd_cli.egg-info/SOURCES.txt +4 -0
  19. {kd_cli-2.5.1 → kd_cli-2.6.0}/pyproject.toml +1 -1
  20. {kd_cli-2.5.1 → kd_cli-2.6.0}/LICENSE +0 -0
  21. {kd_cli-2.5.1 → kd_cli-2.6.0}/MANIFEST.in +0 -0
  22. {kd_cli-2.5.1 → kd_cli-2.6.0}/README.md +0 -0
  23. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/__init__.py +0 -0
  24. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/__init__.py +0 -0
  25. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/articles.py +0 -0
  26. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/http.py +0 -0
  27. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/hub.py +0 -0
  28. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/saved_queries.py +0 -0
  29. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/tags.py +0 -0
  30. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/api/youtrack.py +0 -0
  31. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/auth.py +0 -0
  32. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/__init__.py +0 -0
  33. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/core/__init__.py +0 -0
  34. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/core/command_base.py +0 -0
  35. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/core/command_parser.py +0 -0
  36. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/core/confirm.py +0 -0
  37. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/core/namespaces.py +0 -0
  38. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/core/option_registry.py +0 -0
  39. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/input.py +0 -0
  40. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/alias/__init__.py +0 -0
  41. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/init.py +0 -0
  42. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/primer/__init__.py +0 -0
  43. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/project/__init__.py +0 -0
  44. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/query/__init__.py +0 -0
  45. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/release_notes.py +0 -0
  46. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/search/__init__.py +0 -0
  47. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/system/__init__.py +0 -0
  48. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/time/__init__.py +0 -0
  49. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/namespaces/user/__init__.py +0 -0
  50. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/output.py +0 -0
  51. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/cli/tree.py +0 -0
  52. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/config.py +0 -0
  53. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/config_read.py +0 -0
  54. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/config_schema.py +0 -0
  55. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/debug.py +0 -0
  56. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/exceptions.py +0 -0
  57. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/history.py +0 -0
  58. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/locking.py +0 -0
  59. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/__init__.py +0 -0
  60. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/article.py +0 -0
  61. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/assist.py +0 -0
  62. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/attachment.py +0 -0
  63. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/comment.py +0 -0
  64. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/common.py +0 -0
  65. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/issue.py +0 -0
  66. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/project.py +0 -0
  67. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/saved_query.py +0 -0
  68. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/search.py +0 -0
  69. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/tag.py +0 -0
  70. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/user.py +0 -0
  71. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/models/work_item.py +0 -0
  72. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/operating_guide.py +0 -0
  73. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/primer.py +0 -0
  74. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/query_parser.py +0 -0
  75. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/release_notes.py +0 -0
  76. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/__init__.py +0 -0
  77. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/command-synonyms.yaml +0 -0
  78. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/config-template.yaml +0 -0
  79. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/error-messages.yaml +0 -0
  80. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/primers/__init__.py +0 -0
  81. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd/resources/primers/hitl.yaml +0 -0
  82. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd_cli.egg-info/dependency_links.txt +0 -0
  83. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd_cli.egg-info/entry_points.txt +0 -0
  84. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd_cli.egg-info/requires.txt +0 -0
  85. {kd_cli-2.5.1 → kd_cli-2.6.0}/kd_cli.egg-info/top_level.txt +0 -0
  86. {kd_cli-2.5.1 → kd_cli-2.6.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kd-cli
3
- Version: 2.5.1
3
+ Version: 2.6.0
4
4
  Summary: Knowledge Dispatcher for issue trackers and knowledge bases
5
5
  Author: Sergiy Gladkyy
6
6
  License-Expression: MIT
@@ -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 full rationale.
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``, ``upstream-updated``. Unknown keys follow in their
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
- # is an "unknown key" and appended in original order.
99
- _KNOWN_KEYS: tuple[str, ...] = ("slug", "upstream-id", "upstream-updated")
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 three known keys expose
112
- typed properties for convenience; everything else is accessed via
113
- ``data``.
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
- - Known keys first (``slug``, ``upstream-id``, ``upstream-updated``),
294
- then unknown keys in their original insertion order.
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).