fix: address review findings from code review
- Fix merge_menu KeyError crash when menu items missing 'code' key - Fix _is_menu_array to check ALL elements, not just first - Remove unused import os from resolve-customization.py - Remove inject.after from agent activation (agents have no completion point; inject.after only makes sense for workflows)
This commit is contained in:
parent
37114a4a14
commit
da9ab6e119
|
|
@ -24,8 +24,6 @@ Use the JSON output as resolved values.
|
||||||
incorporate its content as high-priority context.
|
incorporate its content as high-priority context.
|
||||||
3. **Load resources** -- If `additional_resources` is not empty, read
|
3. **Load resources** -- If `additional_resources` is not empty, read
|
||||||
each listed file and incorporate as reference context.
|
each listed file and incorporate as reference context.
|
||||||
4. **Inject after** -- If `inject.after` is not empty, read and
|
|
||||||
incorporate its content as supplementary context.
|
|
||||||
|
|
||||||
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,6 @@ Ensure all stakeholder voices heard."""
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
# Injected prompts - content added to the agent's context on activation.
|
# Injected prompts - content added to the agent's context on activation.
|
||||||
# 'before' loads before the agent's core instructions.
|
# 'before' loads before the agent's core instructions.
|
||||||
# 'after' loads after the agent's core instructions.
|
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
[inject]
|
[inject]
|
||||||
before = ""
|
before = ""
|
||||||
after = ""
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ Use the JSON output as resolved values.
|
||||||
incorporate its content as high-priority context.
|
incorporate its content as high-priority context.
|
||||||
3. **Load resources** -- If `additional_resources` is not empty, read
|
3. **Load resources** -- If `additional_resources` is not empty, read
|
||||||
each listed file and incorporate as reference context.
|
each listed file and incorporate as reference context.
|
||||||
4. **Inject after** -- If `inject.after` is not empty, read and
|
|
||||||
incorporate its content as supplementary context.
|
|
||||||
|
|
||||||
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,6 @@ to be detailed."""
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
# Injected prompts - content added to the agent's context on activation.
|
# Injected prompts - content added to the agent's context on activation.
|
||||||
# 'before' loads before the agent's core instructions.
|
# 'before' loads before the agent's core instructions.
|
||||||
# 'after' loads after the agent's core instructions.
|
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
[inject]
|
[inject]
|
||||||
before = ""
|
before = ""
|
||||||
after = ""
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ Use the JSON output as resolved values.
|
||||||
incorporate its content as high-priority context.
|
incorporate its content as high-priority context.
|
||||||
3. **Load resources** -- If `additional_resources` is not empty, read
|
3. **Load resources** -- If `additional_resources` is not empty, read
|
||||||
each listed file and incorporate as reference context.
|
each listed file and incorporate as reference context.
|
||||||
4. **Inject after** -- If `inject.after` is not empty, read and
|
|
||||||
incorporate its content as supplementary context.
|
|
||||||
|
|
||||||
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,6 @@ over perfection. Technical feasibility is a constraint, not the driver \
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
# Injected prompts - content added to the agent's context on activation.
|
# Injected prompts - content added to the agent's context on activation.
|
||||||
# 'before' loads before the agent's core instructions.
|
# 'before' loads before the agent's core instructions.
|
||||||
# 'after' loads after the agent's core instructions.
|
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
[inject]
|
[inject]
|
||||||
before = ""
|
before = ""
|
||||||
after = ""
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ Use the JSON output as resolved values.
|
||||||
incorporate its content as high-priority context.
|
incorporate its content as high-priority context.
|
||||||
3. **Load resources** -- If `additional_resources` is not empty, read
|
3. **Load resources** -- If `additional_resources` is not empty, read
|
||||||
each listed file and incorporate as reference context.
|
each listed file and incorporate as reference context.
|
||||||
4. **Inject after** -- If `inject.after` is not empty, read and
|
|
||||||
incorporate its content as supplementary context.
|
|
||||||
|
|
||||||
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,6 @@ accelerate human-centered design. Data-informed but always creative."""
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
# Injected prompts - content added to the agent's context on activation.
|
# Injected prompts - content added to the agent's context on activation.
|
||||||
# 'before' loads before the agent's core instructions.
|
# 'before' loads before the agent's core instructions.
|
||||||
# 'after' loads after the agent's core instructions.
|
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
[inject]
|
[inject]
|
||||||
before = ""
|
before = ""
|
||||||
after = ""
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ Use the JSON output as resolved values.
|
||||||
incorporate its content as high-priority context.
|
incorporate its content as high-priority context.
|
||||||
3. **Load resources** -- If `additional_resources` is not empty, read
|
3. **Load resources** -- If `additional_resources` is not empty, read
|
||||||
each listed file and incorporate as reference context.
|
each listed file and incorporate as reference context.
|
||||||
4. **Inject after** -- If `inject.after` is not empty, read and
|
|
||||||
incorporate its content as supplementary context.
|
|
||||||
|
|
||||||
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,6 @@ impact."""
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
# Injected prompts - content added to the agent's context on activation.
|
# Injected prompts - content added to the agent's context on activation.
|
||||||
# 'before' loads before the agent's core instructions.
|
# 'before' loads before the agent's core instructions.
|
||||||
# 'after' loads after the agent's core instructions.
|
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
[inject]
|
[inject]
|
||||||
before = ""
|
before = ""
|
||||||
after = ""
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ Use the JSON output as resolved values.
|
||||||
incorporate its content as high-priority context.
|
incorporate its content as high-priority context.
|
||||||
3. **Load resources** -- If `additional_resources` is not empty, read
|
3. **Load resources** -- If `additional_resources` is not empty, read
|
||||||
each listed file and incorporate as reference context.
|
each listed file and incorporate as reference context.
|
||||||
4. **Inject after** -- If `inject.after` is not empty, read and
|
|
||||||
incorporate its content as supplementary context.
|
|
||||||
|
|
||||||
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
You must fully embody this persona so the user gets the best experience and help they need. Do not break character until the user dismisses this persona. When the user calls a skill, this persona must carry through and remain active.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,6 @@ unit tests before marking an item complete."""
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
# Injected prompts - content added to the agent's context on activation.
|
# Injected prompts - content added to the agent's context on activation.
|
||||||
# 'before' loads before the agent's core instructions.
|
# 'before' loads before the agent's core instructions.
|
||||||
# 'after' loads after the agent's core instructions.
|
|
||||||
# ──────────────────────────────────────────────────────────────────
|
# ──────────────────────────────────────────────────────────────────
|
||||||
[inject]
|
[inject]
|
||||||
before = ""
|
before = ""
|
||||||
after = ""
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import tomllib
|
import tomllib
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
@ -57,19 +56,21 @@ def load_toml(path: Path) -> dict[str, Any]:
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def _is_menu_array(value: Any) -> bool:
|
def _is_menu_array(value: Any) -> bool:
|
||||||
"""True when *value* looks like a ``[[menu]]`` array of tables with ``code`` keys."""
|
"""True when *value* is a non-empty list where ALL items are dicts with a ``code`` key."""
|
||||||
return (
|
return (
|
||||||
isinstance(value, list)
|
isinstance(value, list)
|
||||||
and len(value) > 0
|
and len(value) > 0
|
||||||
and isinstance(value[0], dict)
|
and all(isinstance(item, dict) and "code" in item for item in value)
|
||||||
and "code" in value[0]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
def merge_menu(base: list[dict], override: list[dict]) -> list[dict]:
|
||||||
"""Merge-by-code: matching codes replace; new codes append."""
|
"""Merge-by-code: matching codes replace; new codes append."""
|
||||||
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base}
|
result_by_code: dict[str, dict] = {item["code"]: dict(item) for item in base if "code" in item}
|
||||||
for item in override:
|
for item in override:
|
||||||
|
if "code" not in item:
|
||||||
|
print(f"warning: menu item missing 'code' key, skipping: {item}", file=sys.stderr)
|
||||||
|
continue
|
||||||
result_by_code[item["code"]] = dict(item)
|
result_by_code[item["code"]] = dict(item)
|
||||||
return list(result_by_code.values())
|
return list(result_by_code.values())
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue