python-hwpx-automation 6.0.3__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.
Files changed (217) hide show
  1. hwpx_automation/__init__.py +61 -0
  2. hwpx_automation/__init__.pyi +27 -0
  3. hwpx_automation/__main__.py +8 -0
  4. hwpx_automation/agent_document.py +392 -0
  5. hwpx_automation/api.py +136 -0
  6. hwpx_automation/blind_eval.py +407 -0
  7. hwpx_automation/capabilities.py +110 -0
  8. hwpx_automation/compat.py +48 -0
  9. hwpx_automation/configuration.py +60 -0
  10. hwpx_automation/core/__init__.py +2 -0
  11. hwpx_automation/core/content.py +762 -0
  12. hwpx_automation/core/context.py +111 -0
  13. hwpx_automation/core/diff.py +53 -0
  14. hwpx_automation/core/document.py +37 -0
  15. hwpx_automation/core/formatting.py +513 -0
  16. hwpx_automation/core/handles.py +24 -0
  17. hwpx_automation/core/locations.py +205 -0
  18. hwpx_automation/core/locator.py +162 -0
  19. hwpx_automation/core/plan.py +680 -0
  20. hwpx_automation/core/resources.py +42 -0
  21. hwpx_automation/core/search.py +296 -0
  22. hwpx_automation/core/transactions.py +434 -0
  23. hwpx_automation/core/txn.py +48 -0
  24. hwpx_automation/document_state.py +95 -0
  25. hwpx_automation/errors.py +174 -0
  26. hwpx_automation/execution_lock.py +15 -0
  27. hwpx_automation/fastmcp_adapter.py +672 -0
  28. hwpx_automation/form_fill.py +1177 -0
  29. hwpx_automation/form_output_models.py +223 -0
  30. hwpx_automation/handlers/__init__.py +2 -0
  31. hwpx_automation/handlers/_shared.py +377 -0
  32. hwpx_automation/handlers/agent_document.py +257 -0
  33. hwpx_automation/handlers/authoring.py +750 -0
  34. hwpx_automation/handlers/content_edit.py +1078 -0
  35. hwpx_automation/handlers/form_fill.py +607 -0
  36. hwpx_automation/handlers/layout_style.py +660 -0
  37. hwpx_automation/handlers/quality_render.py +566 -0
  38. hwpx_automation/handlers/read_export.py +1295 -0
  39. hwpx_automation/handlers/specialized.py +624 -0
  40. hwpx_automation/handlers/tracked_changes.py +589 -0
  41. hwpx_automation/handlers/workflow.py +105 -0
  42. hwpx_automation/hwp_converter.py +227 -0
  43. hwpx_automation/hwp_support.py +94 -0
  44. hwpx_automation/hwpx_ops.py +1439 -0
  45. hwpx_automation/identity.json +263 -0
  46. hwpx_automation/identity.py +18 -0
  47. hwpx_automation/ingest_adapters.py +85 -0
  48. hwpx_automation/markdown_plan.py +216 -0
  49. hwpx_automation/mcp_cli.py +29 -0
  50. hwpx_automation/metadata/tools_meta.py +40 -0
  51. hwpx_automation/mixed_form.py +3007 -0
  52. hwpx_automation/mutation_models.py +401 -0
  53. hwpx_automation/network_policy.py +232 -0
  54. hwpx_automation/office/__init__.py +14 -0
  55. hwpx_automation/office/agent/__init__.py +125 -0
  56. hwpx_automation/office/agent/_batch_verification.py +383 -0
  57. hwpx_automation/office/agent/blueprint/__init__.py +58 -0
  58. hwpx_automation/office/agent/blueprint/bundle.py +282 -0
  59. hwpx_automation/office/agent/blueprint/catalog.py +136 -0
  60. hwpx_automation/office/agent/blueprint/dump.py +520 -0
  61. hwpx_automation/office/agent/blueprint/mapping.py +312 -0
  62. hwpx_automation/office/agent/blueprint/model.py +722 -0
  63. hwpx_automation/office/agent/blueprint/native.py +621 -0
  64. hwpx_automation/office/agent/blueprint/replay.py +622 -0
  65. hwpx_automation/office/agent/catalog.py +252 -0
  66. hwpx_automation/office/agent/cli.py +647 -0
  67. hwpx_automation/office/agent/commands.py +1383 -0
  68. hwpx_automation/office/agent/document.py +801 -0
  69. hwpx_automation/office/agent/form_plan.py +1760 -0
  70. hwpx_automation/office/agent/model.py +808 -0
  71. hwpx_automation/office/agent/path.py +155 -0
  72. hwpx_automation/office/agent/query.py +230 -0
  73. hwpx_automation/office/agent/story.py +207 -0
  74. hwpx_automation/office/authoring/__init__.py +3542 -0
  75. hwpx_automation/office/authoring/advanced_generators.py +154 -0
  76. hwpx_automation/office/authoring/builder/__init__.py +52 -0
  77. hwpx_automation/office/authoring/builder/core.py +996 -0
  78. hwpx_automation/office/authoring/builder/report.py +195 -0
  79. hwpx_automation/office/authoring/design/__init__.py +30 -0
  80. hwpx_automation/office/authoring/design/_support.py +144 -0
  81. hwpx_automation/office/authoring/design/composer.py +282 -0
  82. hwpx_automation/office/authoring/design/harvest.py +305 -0
  83. hwpx_automation/office/authoring/design/plan.py +69 -0
  84. hwpx_automation/office/authoring/design/profile.py +88 -0
  85. hwpx_automation/office/authoring/design/profiles/application_form/fragments/body.xml +1 -0
  86. hwpx_automation/office/authoring/design/profiles/application_form/fragments/heading.xml +1 -0
  87. hwpx_automation/office/authoring/design/profiles/application_form/fragments/info_table.xml +1 -0
  88. hwpx_automation/office/authoring/design/profiles/application_form/fragments/title.xml +1 -0
  89. hwpx_automation/office/authoring/design/profiles/application_form/profile.json +25 -0
  90. hwpx_automation/office/authoring/design/profiles/application_form/template.hwpx +0 -0
  91. hwpx_automation/office/authoring/design/profiles/home_notice/fragments/body.xml +1 -0
  92. hwpx_automation/office/authoring/design/profiles/home_notice/fragments/heading.xml +1 -0
  93. hwpx_automation/office/authoring/design/profiles/home_notice/fragments/title.xml +1 -0
  94. hwpx_automation/office/authoring/design/profiles/home_notice/profile.json +24 -0
  95. hwpx_automation/office/authoring/design/profiles/home_notice/template.hwpx +0 -0
  96. hwpx_automation/office/authoring/design/profiles/official_notice/fragments/body.xml +1 -0
  97. hwpx_automation/office/authoring/design/profiles/official_notice/fragments/heading.xml +1 -0
  98. hwpx_automation/office/authoring/design/profiles/official_notice/fragments/info_table.xml +1 -0
  99. hwpx_automation/office/authoring/design/profiles/official_notice/fragments/title.xml +1 -0
  100. hwpx_automation/office/authoring/design/profiles/official_notice/profile.json +25 -0
  101. hwpx_automation/office/authoring/design/profiles/official_notice/template.hwpx +0 -0
  102. hwpx_automation/office/authoring/design/profiles/report/fragments/body.xml +1 -0
  103. hwpx_automation/office/authoring/design/profiles/report/fragments/heading.xml +1 -0
  104. hwpx_automation/office/authoring/design/profiles/report/fragments/info_table.xml +1 -0
  105. hwpx_automation/office/authoring/design/profiles/report/fragments/title.xml +1 -0
  106. hwpx_automation/office/authoring/design/profiles/report/profile.json +25 -0
  107. hwpx_automation/office/authoring/design/profiles/report/template.hwpx +0 -0
  108. hwpx_automation/office/authoring/design/validator.py +107 -0
  109. hwpx_automation/office/authoring/presets/__init__.py +22 -0
  110. hwpx_automation/office/authoring/presets/proposal.py +538 -0
  111. hwpx_automation/office/authoring/report_parser.py +141 -0
  112. hwpx_automation/office/authoring/style_profile.py +437 -0
  113. hwpx_automation/office/authoring/template_analyzer.py +657 -0
  114. hwpx_automation/office/compliance/__init__.py +38 -0
  115. hwpx_automation/office/compliance/official_lint.py +478 -0
  116. hwpx_automation/office/compliance/pii.py +388 -0
  117. hwpx_automation/office/document_ops/__init__.py +13 -0
  118. hwpx_automation/office/document_ops/comparison.py +62 -0
  119. hwpx_automation/office/document_ops/mail_merge.py +73 -0
  120. hwpx_automation/office/document_ops/redline.py +35 -0
  121. hwpx_automation/office/evalplan/__init__.py +36 -0
  122. hwpx_automation/office/evalplan/runtime.py +2762 -0
  123. hwpx_automation/office/exam/__init__.py +44 -0
  124. hwpx_automation/office/exam/compose.py +282 -0
  125. hwpx_automation/office/exam/ir.py +44 -0
  126. hwpx_automation/office/exam/measure.py +163 -0
  127. hwpx_automation/office/exam/parser.py +150 -0
  128. hwpx_automation/office/exam/profile.py +123 -0
  129. hwpx_automation/office/form_fill/__init__.py +66 -0
  130. hwpx_automation/office/form_fill/classification.py +108 -0
  131. hwpx_automation/office/form_fill/fill_residue.py +242 -0
  132. hwpx_automation/office/form_fill/fit/__init__.py +36 -0
  133. hwpx_automation/office/form_fill/fit/apply.py +24 -0
  134. hwpx_automation/office/form_fill/fit/engine.py +24 -0
  135. hwpx_automation/office/form_fill/fit/measure.py +50 -0
  136. hwpx_automation/office/form_fill/fit/policy.py +28 -0
  137. hwpx_automation/office/form_fill/fit/report.py +28 -0
  138. hwpx_automation/office/form_fill/fit/seal.py +457 -0
  139. hwpx_automation/office/form_fill/fit/wordbox.py +1343 -0
  140. hwpx_automation/office/form_fill/guidance.py +704 -0
  141. hwpx_automation/office/form_fill/quality.py +961 -0
  142. hwpx_automation/office/form_fill/split_run.py +333 -0
  143. hwpx_automation/office/form_fill/template_formfit.py +656 -0
  144. hwpx_automation/office/house_style/__init__.py +196 -0
  145. hwpx_automation/office/house_style/composition.py +68 -0
  146. hwpx_automation/office/house_style/data/bank.json +625 -0
  147. hwpx_automation/office/house_style/data/genres.json +43 -0
  148. hwpx_automation/office/quality/__init__.py +14 -0
  149. hwpx_automation/office/quality/page_guard.py +277 -0
  150. hwpx_automation/office/rendering/__init__.py +145 -0
  151. hwpx_automation/office/rendering/_hancom_open_rate.ps1 +374 -0
  152. hwpx_automation/office/rendering/_refresh_hwpx_mac.applescript +162 -0
  153. hwpx_automation/office/rendering/_render_hwpx.ps1 +72 -0
  154. hwpx_automation/office/rendering/_render_hwpx_mac.applescript +249 -0
  155. hwpx_automation/office/rendering/block_splits.py +76 -0
  156. hwpx_automation/office/rendering/detectors.py +151 -0
  157. hwpx_automation/office/rendering/diff.py +153 -0
  158. hwpx_automation/office/rendering/fixture_corpus.py +215 -0
  159. hwpx_automation/office/rendering/oracle.py +909 -0
  160. hwpx_automation/office/rendering/page_qa.py +245 -0
  161. hwpx_automation/office/rendering/qa_contracts.py +293 -0
  162. hwpx_automation/office/rendering/qa_metrics.py +241 -0
  163. hwpx_automation/office/rendering/worker.py +290 -0
  164. hwpx_automation/office/utilities/__init__.py +12 -0
  165. hwpx_automation/office/utilities/table_compute.py +477 -0
  166. hwpx_automation/ops_services/__init__.py +1 -0
  167. hwpx_automation/ops_services/_border_fill.py +283 -0
  168. hwpx_automation/ops_services/composition.py +55 -0
  169. hwpx_automation/ops_services/content_layout.py +322 -0
  170. hwpx_automation/ops_services/context.py +213 -0
  171. hwpx_automation/ops_services/form_fields.py +557 -0
  172. hwpx_automation/ops_services/media.py +178 -0
  173. hwpx_automation/ops_services/memo_style.py +477 -0
  174. hwpx_automation/ops_services/package_validation.py +166 -0
  175. hwpx_automation/ops_services/planning.py +201 -0
  176. hwpx_automation/ops_services/preview_export.py +585 -0
  177. hwpx_automation/ops_services/read_query.py +601 -0
  178. hwpx_automation/ops_services/save_policy.py +604 -0
  179. hwpx_automation/ops_services/tables.py +539 -0
  180. hwpx_automation/ops_services/transactions.py +616 -0
  181. hwpx_automation/preview_output_models.py +69 -0
  182. hwpx_automation/public-modules.json +206 -0
  183. hwpx_automation/py.typed +1 -0
  184. hwpx_automation/quality.py +351 -0
  185. hwpx_automation/quality_generation.py +725 -0
  186. hwpx_automation/runtime.py +321 -0
  187. hwpx_automation/runtime_services.py +100 -0
  188. hwpx_automation/server.py +259 -0
  189. hwpx_automation/storage.py +747 -0
  190. hwpx_automation/tool_bindings.py +170 -0
  191. hwpx_automation/tool_contract.py +982 -0
  192. hwpx_automation/upstream.py +755 -0
  193. hwpx_automation/utils/__init__.py +2 -0
  194. hwpx_automation/utils/helpers.py +29 -0
  195. hwpx_automation/visual_qa.py +667 -0
  196. hwpx_automation/workflow/__init__.py +55 -0
  197. hwpx_automation/workflow/adapters.py +482 -0
  198. hwpx_automation/workflow/dispatcher.py +213 -0
  199. hwpx_automation/workflow/models.py +243 -0
  200. hwpx_automation/workflow/policy.py +198 -0
  201. hwpx_automation/workflow/render_contracts.py +173 -0
  202. hwpx_automation/workflow/render_metrics.py +196 -0
  203. hwpx_automation/workflow/render_queue.py +482 -0
  204. hwpx_automation/workflow/render_security.py +172 -0
  205. hwpx_automation/workflow/render_transport.py +369 -0
  206. hwpx_automation/workflow/rendering.py +206 -0
  207. hwpx_automation/workflow/service.py +758 -0
  208. hwpx_automation/workflow/state_machine.py +65 -0
  209. hwpx_automation/workflow/store.py +747 -0
  210. hwpx_automation/workspace.py +1694 -0
  211. python_hwpx_automation-6.0.3.dist-info/METADATA +279 -0
  212. python_hwpx_automation-6.0.3.dist-info/RECORD +217 -0
  213. python_hwpx_automation-6.0.3.dist-info/WHEEL +5 -0
  214. python_hwpx_automation-6.0.3.dist-info/entry_points.txt +3 -0
  215. python_hwpx_automation-6.0.3.dist-info/licenses/LICENSE +178 -0
  216. python_hwpx_automation-6.0.3.dist-info/licenses/NOTICE +14 -0
  217. python_hwpx_automation-6.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,196 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """Typed house-style data service owned by the automation application layer."""
3
+ from __future__ import annotations
4
+
5
+ import copy
6
+ import json
7
+ from functools import lru_cache
8
+ from importlib import resources
9
+ from typing import Any
10
+
11
+ from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator
12
+
13
+ from .composition import SectionChipPlan, compose_section_chip
14
+
15
+ BANK_SCHEMA_VERSION = "hwpx.house-style-bank/v0"
16
+ GENRES_SCHEMA_VERSION = "hwpx.house-style-genres/v0"
17
+
18
+
19
+ class HouseStyleDataError(ValueError):
20
+ """The packaged bank or genre grammar violates its frozen schema."""
21
+
22
+
23
+ class _FrozenModel(BaseModel):
24
+ model_config = ConfigDict(
25
+ extra="forbid",
26
+ frozen=True,
27
+ populate_by_name=True,
28
+ )
29
+
30
+
31
+ class HouseStyleBank(_FrozenModel):
32
+ schema_version: str = Field(alias="schemaVersion")
33
+ generated: str
34
+ status: str
35
+ research_doc: str = Field(alias="researchDoc")
36
+ usage: str = Field(alias="_usage")
37
+ font_safety: dict[str, Any] = Field(alias="fontSafety")
38
+ shared_rules: list[str] = Field(alias="sharedRules")
39
+ profiles: dict[str, dict[str, Any]]
40
+
41
+ @field_validator("schema_version")
42
+ @classmethod
43
+ def _schema_is_exact(cls, value: str) -> str:
44
+ if value != BANK_SCHEMA_VERSION:
45
+ raise ValueError(f"expected {BANK_SCHEMA_VERSION!r}, got {value!r}")
46
+ return value
47
+
48
+ @field_validator("profiles")
49
+ @classmethod
50
+ def _profiles_are_named_objects(
51
+ cls,
52
+ value: dict[str, dict[str, Any]],
53
+ ) -> dict[str, dict[str, Any]]:
54
+ if not value or any(not name.strip() or not isinstance(profile, dict) for name, profile in value.items()):
55
+ raise ValueError("profiles must be a non-empty map of named objects")
56
+ return value
57
+
58
+
59
+ class GenreDefinition(_FrozenModel):
60
+ label: str
61
+ when: str
62
+ typography: dict[str, Any]
63
+ grammar: dict[str, Any]
64
+
65
+
66
+ class GenreCatalog(_FrozenModel):
67
+ schema_version: str = Field(alias="schemaVersion")
68
+ generated: str
69
+ usage: str = Field(alias="_usage")
70
+ genres: dict[str, GenreDefinition]
71
+
72
+ @field_validator("schema_version")
73
+ @classmethod
74
+ def _schema_is_exact(cls, value: str) -> str:
75
+ if value != GENRES_SCHEMA_VERSION:
76
+ raise ValueError(f"expected {GENRES_SCHEMA_VERSION!r}, got {value!r}")
77
+ return value
78
+
79
+ @field_validator("genres")
80
+ @classmethod
81
+ def _genres_are_nonempty(
82
+ cls,
83
+ value: dict[str, GenreDefinition],
84
+ ) -> dict[str, GenreDefinition]:
85
+ if not value:
86
+ raise ValueError("genres must be a non-empty map")
87
+ return value
88
+
89
+
90
+ def validate_bank(payload: dict[str, Any]) -> HouseStyleBank:
91
+ """Validate a decoded bank payload or fail closed with one public error."""
92
+
93
+ try:
94
+ return HouseStyleBank.model_validate(payload)
95
+ except ValidationError as exc:
96
+ raise HouseStyleDataError(f"invalid house-style bank: {exc}") from exc
97
+
98
+
99
+ def validate_genres(payload: dict[str, Any]) -> GenreCatalog:
100
+ """Validate a decoded genre payload or fail closed with one public error."""
101
+
102
+ try:
103
+ return GenreCatalog.model_validate(payload)
104
+ except ValidationError as exc:
105
+ raise HouseStyleDataError(f"invalid house-style genres: {exc}") from exc
106
+
107
+
108
+ def _load_payload(filename: str) -> dict[str, Any]:
109
+ try:
110
+ text = (
111
+ resources.files("hwpx_automation.office.house_style")
112
+ .joinpath("data")
113
+ .joinpath(filename)
114
+ .read_text(encoding="utf-8")
115
+ )
116
+ payload = json.loads(text)
117
+ except (OSError, json.JSONDecodeError) as exc:
118
+ raise HouseStyleDataError(f"cannot load packaged house-style data {filename!r}") from exc
119
+ if not isinstance(payload, dict):
120
+ raise HouseStyleDataError(f"house-style data {filename!r} must be a JSON object")
121
+ return payload
122
+
123
+
124
+ @lru_cache(maxsize=1)
125
+ def load_bank() -> HouseStyleBank:
126
+ return validate_bank(_load_payload("bank.json"))
127
+
128
+
129
+ @lru_cache(maxsize=1)
130
+ def load_genres() -> GenreCatalog:
131
+ return validate_genres(_load_payload("genres.json"))
132
+
133
+
134
+ def list_profiles() -> list[str]:
135
+ return sorted(load_bank().profiles)
136
+
137
+
138
+ def get_profile(name: str) -> dict[str, Any]:
139
+ profiles = load_bank().profiles
140
+ if name not in profiles:
141
+ raise KeyError(f"unknown house-style profile: {name!r} (have {sorted(profiles)})")
142
+ return copy.deepcopy(profiles[name])
143
+
144
+
145
+ def list_genres() -> list[str]:
146
+ return sorted(load_genres().genres)
147
+
148
+
149
+ def get_genre(name: str) -> GenreDefinition:
150
+ genres = load_genres().genres
151
+ if name not in genres:
152
+ raise KeyError(f"unknown genre: {name!r} (have {sorted(genres)})")
153
+ return genres[name]
154
+
155
+
156
+ def genre_typography(name: str) -> dict[str, Any]:
157
+ typography = get_genre(name).typography
158
+ base_name = typography.get("inherits")
159
+ roles: dict[str, Any] = {}
160
+ if base_name:
161
+ roles.update(get_profile(str(base_name)).get("roles", {}))
162
+ roles.update(copy.deepcopy(typography.get("roles", {})))
163
+ return {"inherits": base_name, "roles": roles}
164
+
165
+
166
+ def font_policy() -> dict[str, Any]:
167
+ return copy.deepcopy(load_bank().font_safety)
168
+
169
+
170
+ def resolve_font(font: str, *, mode: str = "hancom-native") -> str:
171
+ if mode != "portable":
172
+ return font
173
+ return str(font_policy().get("portableMap", {}).get(font, font))
174
+
175
+
176
+ __all__ = [
177
+ "BANK_SCHEMA_VERSION",
178
+ "GENRES_SCHEMA_VERSION",
179
+ "GenreCatalog",
180
+ "GenreDefinition",
181
+ "HouseStyleBank",
182
+ "HouseStyleDataError",
183
+ "SectionChipPlan",
184
+ "compose_section_chip",
185
+ "font_policy",
186
+ "genre_typography",
187
+ "get_genre",
188
+ "get_profile",
189
+ "list_genres",
190
+ "list_profiles",
191
+ "load_bank",
192
+ "load_genres",
193
+ "resolve_font",
194
+ "validate_bank",
195
+ "validate_genres",
196
+ ]
@@ -0,0 +1,68 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """Typed application composition for an operating-plan section divider."""
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Literal
6
+
7
+ from pydantic import BaseModel, ConfigDict, field_validator
8
+
9
+
10
+ class SectionChipPlan(BaseModel):
11
+ """Application-level section divider lowered to generic plan blocks."""
12
+
13
+ model_config = ConfigDict(extra="forbid", frozen=True)
14
+
15
+ number: str
16
+ title: str
17
+ style: Literal["box", "inline"] = "box"
18
+ accent_color: str | None = None
19
+
20
+ @field_validator("number", "title")
21
+ @classmethod
22
+ def _nonempty(cls, value: str) -> str:
23
+ normalized = str(value).strip()
24
+ if not normalized:
25
+ raise ValueError("section chip number and title must be non-empty")
26
+ return normalized
27
+
28
+ def to_document_plan_block(self) -> dict[str, Any]:
29
+ metadata: dict[str, Any] = {
30
+ "generator": "section_chip",
31
+ "style": self.style,
32
+ "number": self.number,
33
+ }
34
+ if self.accent_color:
35
+ metadata["accentColor"] = self.accent_color
36
+ if self.style == "inline":
37
+ return {
38
+ "type": "heading",
39
+ "level": 1,
40
+ "text": f"{self.number} {self.title}",
41
+ "metadata": metadata,
42
+ }
43
+ return {
44
+ "type": "table",
45
+ "rows": [[self.number, "", self.title]],
46
+ "columnWidths": [1, 0.4, 11],
47
+ "metadata": metadata,
48
+ }
49
+
50
+
51
+ def compose_section_chip(
52
+ number: str,
53
+ title: str,
54
+ *,
55
+ style: Literal["box", "inline"] = "box",
56
+ accent_color: str | None = None,
57
+ ) -> dict[str, Any]:
58
+ """Compose a genre-specific divider using generic document-plan blocks."""
59
+
60
+ return SectionChipPlan(
61
+ number=number,
62
+ title=title,
63
+ style=style,
64
+ accent_color=accent_color,
65
+ ).to_document_plan_block()
66
+
67
+
68
+ __all__ = ["SectionChipPlan", "compose_section_chip"]