Skip to content

Commit df73c9a

Browse files
committed
feat: add output profile support for generate and update commands
1 parent ba811aa commit df73c9a

7 files changed

Lines changed: 242 additions & 1 deletion

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,13 +245,15 @@ agentskill generate <repo>
245245
agentskill generate <repo> --out AGENTS.md
246246
agentskill generate <repo> --reference ../ref-a --reference ../ref-b
247247
agentskill generate <repo> --interactive
248+
agentskill generate <repo> --profile comprehensive
248249

249250
# Update or create AGENTS.md in place
250251
agentskill update <repo>
251252
agentskill update <repo> --section testing
252253
agentskill update <repo> --exclude-section git
253254
agentskill update <repo> --force
254255
agentskill update <repo> --out updated-AGENTS.md
256+
agentskill update <repo> --profile concise
255257

256258
# Retained wrapper entrypoints for operator/skill workflows
257259
python scripts/analyze.py <repo> --pretty

agentskill/lib/generate_runner.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
interactive_section_notes,
1414
)
1515
from agentskill.lib.output import validate_out_path
16+
from agentskill.lib.output_profiles import validate_output_profile
1617
from agentskill.lib.reference_flow import load_reference_documents
1718
from agentskill.lib.reference_initialization import (
1819
initialize_from_references,
@@ -46,7 +47,15 @@ def render_agents_markdown(
4647
references: list[str] | None = None,
4748
interactive: bool = False,
4849
prompt_io: PromptIO | None = None,
50+
profile: str = "concise",
4951
) -> str:
52+
profile = validate_output_profile(profile)
53+
54+
if profile == "split":
55+
raise NotImplementedError(
56+
"generate with profile 'split' is not implemented yet"
57+
)
58+
5059
documents = load_reference_documents(references)
5160
analysis = run_all(str(repo))
5261
feedback = load_feedback(repo)
@@ -83,6 +92,7 @@ def generate_agents(
8392
references: list[str] | None = None,
8493
interactive: bool = False,
8594
prompt_io: PromptIO | None = None,
95+
profile: str = "concise",
8696
) -> int:
8797
try:
8898
repo_path = validate_repo(repo)
@@ -91,6 +101,7 @@ def generate_agents(
91101
references=references,
92102
interactive=interactive,
93103
prompt_io=prompt_io,
104+
profile=profile,
94105
)
95106

96107
if out is not None:

agentskill/lib/output_profiles.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""Shared output profile contract for generate and update flows."""
2+
3+
SUPPORTED_OUTPUT_PROFILES = ("concise", "comprehensive", "split")
4+
DEFAULT_OUTPUT_PROFILE = "concise"
5+
6+
7+
def validate_output_profile(value: str) -> str:
8+
"""Normalize and validate an output profile name.
9+
10+
Returns the normalized profile string on success.
11+
12+
Raises ValueError for unsupported values.
13+
"""
14+
normalized = value.strip().lower()
15+
16+
if normalized not in SUPPORTED_OUTPUT_PROFILES:
17+
allowed = ", ".join(SUPPORTED_OUTPUT_PROFILES)
18+
raise ValueError(f"unsupported output profile: {value!r} (allowed: {allowed})")
19+
20+
return normalized

agentskill/lib/update_runner.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
normalize_section_name,
1818
)
1919
from agentskill.lib.output import validate_out_path
20+
from agentskill.lib.output_profiles import validate_output_profile
2021
from agentskill.lib.runner import run_all
2122
from agentskill.lib.update_feedback import (
2223
SectionFeedback,
@@ -1030,9 +1031,17 @@ def update_agents(
10301031
exclude_sections: list[str] | None = None,
10311032
force: bool = False,
10321033
out: str | None = None,
1034+
profile: str = "concise",
10331035
) -> int:
10341036
"""Update or create AGENTS.md for a repository."""
10351037
try:
1038+
profile = validate_output_profile(profile)
1039+
1040+
if profile == "split":
1041+
raise NotImplementedError(
1042+
"update with profile 'split' is not implemented yet"
1043+
)
1044+
10361045
repo_path = validate_repo(repo)
10371046
analysis = run_all(str(repo_path))
10381047
feedback = load_feedback(repo_path)

agentskill/main.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
from agentskill.lib.generate_runner import generate_agents
77
from agentskill.lib.logging_utils import configure_logging
88
from agentskill.lib.output import run_and_output, write_output
9+
from agentskill.lib.output_profiles import (
10+
DEFAULT_OUTPUT_PROFILE,
11+
validate_output_profile,
12+
)
913
from agentskill.lib.runner import COMMANDS, run_many
1014
from agentskill.lib.update_runner import update_agents
1115

@@ -53,12 +57,21 @@ def cmd_update(args: argparse.Namespace) -> int:
5357
print("update does not support --pretty", file=sys.stderr)
5458
return 1
5559

60+
try:
61+
profile = validate_output_profile(
62+
getattr(args, "profile", DEFAULT_OUTPUT_PROFILE)
63+
)
64+
except ValueError as exc:
65+
print(str(exc), file=sys.stderr)
66+
return 1
67+
5668
return update_agents(
5769
args.repo,
5870
include_sections=getattr(args, "section", None),
5971
exclude_sections=getattr(args, "exclude_section", None),
6072
force=args.force,
6173
out=getattr(args, "out", None),
74+
profile=profile,
6275
)
6376

6477

@@ -67,11 +80,20 @@ def cmd_generate(args: argparse.Namespace) -> int:
6780
print("generate does not support --pretty", file=sys.stderr)
6881
return 1
6982

83+
try:
84+
profile = validate_output_profile(
85+
getattr(args, "profile", DEFAULT_OUTPUT_PROFILE)
86+
)
87+
except ValueError as exc:
88+
print(str(exc), file=sys.stderr)
89+
return 1
90+
7091
return generate_agents(
7192
args.repo,
7293
out=getattr(args, "out", None),
7394
references=getattr(args, "reference", None),
7495
interactive=getattr(args, "interactive", False),
96+
profile=profile,
7597
)
7698

7799

@@ -96,9 +118,11 @@ def main(argv: list[str] | None = None) -> int:
96118
p_analyze.add_argument(
97119
"repos", nargs="+", metavar="repo", help="Path(s) to repository"
98120
)
121+
99122
p_analyze.add_argument(
100123
"--lang", help="Filter to a single language where applicable"
101124
)
125+
102126
p_analyze.add_argument(
103127
"--reference",
104128
action="append",
@@ -126,48 +150,66 @@ def main(argv: list[str] | None = None) -> int:
126150
p_symbols = sub.add_parser(
127151
"symbols", help="Symbol name extraction and pattern clustering"
128152
)
153+
129154
p_symbols.add_argument("repo", help="Path to repository")
130155
p_symbols.add_argument("--lang", help="Filter to a single language")
131156

132157
p_tests = sub.add_parser(
133158
"tests", help="Test-to-source mapping and framework detection"
134159
)
135-
p_tests.add_argument("repo", help="Path to repository")
136160

161+
p_tests.add_argument("repo", help="Path to repository")
137162
p_update = sub.add_parser("update", help="Update or create AGENTS.md")
138163
p_update.add_argument("repo", help="Path to repository")
164+
139165
p_update.add_argument(
140166
"--section",
141167
action="append",
142168
help="Regenerate only the named section; may be repeated",
143169
)
170+
144171
p_update.add_argument(
145172
"--exclude-section",
146173
action="append",
147174
help="Skip regenerating the named section; may be repeated",
148175
)
176+
149177
p_update.add_argument(
150178
"--force",
151179
action="store_true",
152180
help="Rebuild AGENTS.md from regenerated sections only",
153181
)
182+
154183
p_update.add_argument("--out", metavar="FILE", help="Write markdown to file")
184+
p_update.add_argument(
185+
"--profile",
186+
default=DEFAULT_OUTPUT_PROFILE,
187+
help=f"Output profile (default: {DEFAULT_OUTPUT_PROFILE})",
188+
)
155189

156190
p_generate = sub.add_parser(
157191
"generate", help="Generate AGENTS.md markdown from repository analysis"
158192
)
193+
159194
p_generate.add_argument("repo", help="Path to repository")
160195
p_generate.add_argument(
161196
"--reference",
162197
action="append",
163198
help="Reference repository path or URL; may be repeated",
164199
)
200+
165201
p_generate.add_argument(
166202
"--interactive",
167203
action="store_true",
168204
help="Prompt for missing or ambiguous generation inputs",
169205
)
206+
170207
p_generate.add_argument("--out", metavar="FILE", help="Write markdown to file")
208+
p_generate.add_argument(
209+
"--profile",
210+
default=DEFAULT_OUTPUT_PROFILE,
211+
help=f"Output profile (default: {DEFAULT_OUTPUT_PROFILE})",
212+
)
171213

172214
for p in [
173215
p_scan,

docs/reference/cli.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ generation, and update workflows.
3939
- `--out` writes JSON or markdown to a file instead of stdout.
4040
- `--reference` is supported by `analyze` and `generate`.
4141
- `--interactive` is supported by `generate` only.
42+
- `--profile` is supported by `generate` and `update`. Accepted values are `concise` (default), `comprehensive`, and `split`. The `split` profile is accepted at the CLI level but raises a not-implemented error until multi-file emission is ready.
4243
- `--section`, `--exclude-section`, and `--force` are supported by `update`.
4344

4445
Release-grade CLI contract tests live in `tests/test_cli_contract.py`.

0 commit comments

Comments
 (0)