Skip to content

Commit 0ad1318

Browse files
dreamrecclaude
andcommitted
fix: wrap info textDAT banner in Python docstring (CLI bridge red ❌)
Live diagnosis on a v2.0.0 install showed ``/project1/tdpilot_dpsk4/mcp_server/info`` flagged with a red error indicator inside the COMP — "1 network with errors inside". The content of the info textDAT is a pure metadata banner: TDPilot DPSK4 v2.0.0 installer + MCP server Generated by build_tdpilot_tox.py Generated at (UTC): 2026-05-08T15:38:42.646763+00:00 Source repo: sharp-carson-4c8695 Export file: tdpilot-dpsk4.tox TD compiles every textDAT as Python by default. The ISO-8601 timestamp ``2026-05-08T15:38:42…`` parses as ``2026 - 05 - 08T…`` and ``05`` is rejected as an invalid decimal-with-leading-zero literal: SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers Functionally nothing was broken — every other textDAT in mcp_server/ worked fine, ``callbacks.module.API_VERSION = '2.0.0'`` resolved cleanly. But the red ❌ on the COMP icon is alarming and gets mistaken for a real error every time someone scans the network. Fix at the consumption site (``info.text = ...``) rather than at the generator. Adding ``_python_safe_info()`` that wraps the banner in ``"""…"""`` triple quotes — turning the body into a module-level string literal (a no-op pseudo-docstring), valid Python, compiles cleanly. Idempotent so any future caller passing already-wrapped text won't double-wrap. Two info-text generators feed this site — ``build_export_mcp_tox._build_info_text`` (CLI direct) and ``build_tdpilot_tox._build_info_text_v156`` (panel installer). The user's actual rebuild today went through the v1.5.6 installer path, which is why the bug showed live. Wrapping at the consumer covers both paths and any future ones. Standalone (``tdpilot_API``) is unaffected — it puts info-banner into ``comp.comment`` (a parameter, not a textDAT), which TD doesn't compile. The ``_populate_comp`` in build_tdpilot_api_tox.py at line 533 was already safe. Tests: 1623 pass / 12 deselected, ruff clean, versions in sync at v2.0.0, tox-freshness fresh (build script not in _TOX_SOURCE_FILES). Rebuild required to take effect on installed .tox — the source-hash of the CLI tox doesn't include build script content, so CI freshness will not flag this PR. After merge, rebuild the .tox in TD to bake the wrapped banner. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent f6ea2ae commit 0ad1318

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

td_component/build_export_mcp_tox.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,23 @@ def _build_info_text(repo_root, export_path):
345345
)
346346

347347

348+
def _python_safe_info(text):
349+
"""Wrap info-banner text in a Python triple-quoted string literal so the
350+
textDAT compiles cleanly under TD's default Python parser. Without this,
351+
an ISO-8601 timestamp like ``2026-05-08T15:38:42`` is parsed as
352+
``2026 - 05 - 08T...`` and ``05`` is rejected as an invalid decimal-with-
353+
leading-zero literal — the COMP shows a red error indicator for what is
354+
purely a banner. Wrapping turns the body into a module-level string
355+
literal (a no-op pseudo-docstring) that TD compiles without complaint.
356+
357+
Idempotent: if text is already triple-quote-wrapped, returns it unchanged.
358+
"""
359+
stripped = text.strip()
360+
if stripped.startswith('"""') and stripped.endswith('"""'):
361+
return text
362+
return '"""\n' + text.rstrip("\n") + '\n"""\n'
363+
364+
348365
def _reset_or_create_comp(parent, name):
349366
existing = parent.op(name)
350367
if existing is not None and OVERWRITE_COMPONENT:
@@ -399,7 +416,9 @@ def _populate_component(comp, callbacks_code, event_emitter_code, ws_callbacks_c
399416
callbacks.text = callbacks_code
400417
ws_callbacks.text = ws_callbacks_code
401418
event_emitter.text = event_emitter_code
402-
info.text = info_text
419+
# Wrap banner content so TD's Python compile-on-access doesn't choke on
420+
# the ISO timestamps. See _python_safe_info() for the full rationale.
421+
info.text = _python_safe_info(info_text)
403422
state_cache.text = state_cache_code
404423

405424
_configure_websocket_dat(ws_client)

0 commit comments

Comments
 (0)