feat(card): a folder shows every bundle under it, as the server does

`okf card <folder>` prints `okf_list` and `okf_describe` with no bundle
named, joined by `mcp_server.overview`, and computes nothing of its own:
one source, two doors. Chosen over a separate `--root` flag because the
skill's first step must be the same command whether it was pointed at a
bundle or at a folder of them; the rule that decides is discovery's own
(a directory carrying an `index.md` is a bundle). A bundle path prints its
card as before.

v1.1 order F, part F1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-21 10:28:32 +02:00
commit df83c65e32
5 changed files with 212 additions and 4 deletions

View file

@ -1003,15 +1003,31 @@ def card_main(argv: list[str] | None = None) -> int:
prog="okf card",
description=(
"Print one bundle's identity, concept count, conditional-field counts "
"and whole-bundle cost as JSON. Derived from the bundle on every run."
"and whole-bundle cost as JSON -- or, for a folder, every bundle under "
"it with its card. Derived from the bundles on every run."
),
)
parser.add_argument(
"bundle",
type=Path,
help=(
"the OKF bundle to describe, or a FOLDER: then every bundle under it "
"is listed with its card, as the server's `okf_list` and "
"`okf_describe` give them"
),
)
parser.add_argument("bundle", type=Path, help="the OKF bundle to describe")
args = parser.parse_args(argv)
from .mcp_server import card as build_card
from . import mcp_server
try:
payload = build_card(args.bundle.resolve(), profile=okf_consume.DEFAULT_PROFILE)
if args.bundle.is_dir() and not mcp_server.is_bundle(args.bundle):
surface = mcp_server.build_surface(bundle=None, roots=[args.bundle])
payload = mcp_server.overview(surface)
else:
payload = mcp_server.card(args.bundle.resolve(), profile=okf_consume.DEFAULT_PROFILE)
except mcp_server.ToolError as exc:
print(f"refused ({exc.code}): {exc}", file=sys.stderr)
return 1
except okf_consume.ConsumeError as exc:
print(f"refused ({exc.code}): {exc}", file=sys.stderr)
return 1