agent-style 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. agent_style-0.1.0/PKG-INFO +73 -0
  2. agent_style-0.1.0/README.md +45 -0
  3. agent_style-0.1.0/agent_style/__init__.py +51 -0
  4. agent_style-0.1.0/agent_style/cli.py +173 -0
  5. agent_style-0.1.0/agent_style/data/LICENSES/CC-BY-4.0.txt +396 -0
  6. agent_style-0.1.0/agent_style/data/LICENSES/MIT.txt +21 -0
  7. agent_style-0.1.0/agent_style/data/NOTICE.md +18 -0
  8. agent_style-0.1.0/agent_style/data/RULES.md +803 -0
  9. agent_style-0.1.0/agent_style/data/agents/AGENTS.md +53 -0
  10. agent_style-0.1.0/agent_style/data/agents/aider-conventions.md +67 -0
  11. agent_style-0.1.0/agent_style/data/agents/anthropic-skill/SKILL.md +57 -0
  12. agent_style-0.1.0/agent_style/data/agents/claude-code.md +54 -0
  13. agent_style-0.1.0/agent_style/data/agents/codex.md +53 -0
  14. agent_style-0.1.0/agent_style/data/agents/copilot-instructions.md +53 -0
  15. agent_style-0.1.0/agent_style/data/agents/copilot-path-instructions.md +57 -0
  16. agent_style-0.1.0/agent_style/data/agents/cursor-rule.mdc +58 -0
  17. agent_style-0.1.0/agent_style/data/tools.json +56 -0
  18. agent_style-0.1.0/agent_style/installer.py +462 -0
  19. agent_style-0.1.0/agent_style/markers.py +112 -0
  20. agent_style-0.1.0/agent_style/owned_file.py +101 -0
  21. agent_style-0.1.0/agent_style/registry.py +87 -0
  22. agent_style-0.1.0/agent_style.egg-info/PKG-INFO +73 -0
  23. agent_style-0.1.0/agent_style.egg-info/SOURCES.txt +26 -0
  24. agent_style-0.1.0/agent_style.egg-info/dependency_links.txt +1 -0
  25. agent_style-0.1.0/agent_style.egg-info/entry_points.txt +2 -0
  26. agent_style-0.1.0/agent_style.egg-info/top_level.txt +1 -0
  27. agent_style-0.1.0/pyproject.toml +58 -0
  28. agent_style-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-style
3
+ Version: 0.1.0
4
+ Summary: The Elements of Agent Style: a literature-backed English technical-prose writing ruleset for AI agents, with CLI install/enable/disable for 8 primary agent surfaces.
5
+ Author-email: Yue Zhao <fortis@usc.edu>
6
+ License: MIT AND CC-BY-4.0
7
+ Project-URL: Homepage, https://github.com/yzhao062/agent-style
8
+ Project-URL: Repository, https://github.com/yzhao062/agent-style
9
+ Project-URL: Issues, https://github.com/yzhao062/agent-style/issues
10
+ Project-URL: Changelog, https://github.com/yzhao062/agent-style/blob/main/CHANGELOG.md
11
+ Keywords: writing,style,agent,llm,ai,instructions,prompt
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Documentation
24
+ Classifier: Topic :: Software Development :: Documentation
25
+ Classifier: Topic :: Text Processing :: Markup
26
+ Requires-Python: >=3.8
27
+ Description-Content-Type: text/markdown
28
+
29
+ <!-- SPDX-License-Identifier: MIT -->
30
+
31
+ # agent-style (PyPI)
32
+
33
+ CLI for *The Elements of Agent Style*: a literature-backed English technical-prose writing ruleset for AI agents.
34
+
35
+ Install:
36
+
37
+ ```bash
38
+ pip install agent-style
39
+ ```
40
+
41
+ Basic use:
42
+
43
+ ```bash
44
+ agent-style list-tools # show supported tools
45
+ agent-style enable claude-code # wire up Claude Code
46
+ agent-style enable claude-code --dry-run --json # preview in canonical JSON
47
+ agent-style disable claude-code # reverse
48
+ agent-style rules # print bundled RULES.md
49
+ ```
50
+
51
+ The CLI writes to `.agent-style/` in your project and safely adds a marker-wrapped reference to your existing instruction file (CLAUDE.md, AGENTS.md, .github/copilot-instructions.md, etc.). Existing content is preserved; writes are idempotent; `--dry-run` previews without changing any file.
52
+
53
+ Supported tools and install modes in v0.1.0:
54
+
55
+ | Tool | Install mode |
56
+ | --- | --- |
57
+ | claude-code | import-marker (writes `@.agent-style/claude-code.md` to your CLAUDE.md) |
58
+ | agents-md | append-block (writes a marker block to your AGENTS.md) |
59
+ | copilot | append-block (writes a marker block to `.github/copilot-instructions.md`) |
60
+ | copilot-path | owned-file (writes `.github/instructions/agent-style.instructions.md`) |
61
+ | cursor | owned-file (writes `.cursor/rules/agent-style.mdc`) |
62
+ | anthropic-skill | owned-file (writes `.claude/skills/agent-style/SKILL.md`) |
63
+ | codex | print-only (writes `.agent-style/codex-system-prompt.md`; stdout = prompt) |
64
+ | aider | multi-file-required (writes `.agent-style/aider-conventions.md`; stderr = `.aider.conf.yml` snippet) |
65
+
66
+ The full rule set lives in the canonical repository at https://github.com/yzhao062/agent-style. This PyPI package bundles `RULES.md`, `NOTICE.md`, the 8 primary adapters, and the `tools.json` registry; running `agent-style rules` prints the bundled `RULES.md` for quick review.
67
+
68
+ ## License
69
+
70
+ - Code: MIT (`LICENSES/MIT.txt`).
71
+ - Bundled prose (`RULES.md`, `NOTICE.md`, adapters): CC BY 4.0 (`LICENSES/CC-BY-4.0.txt`).
72
+
73
+ Roadmap (v0.2.0+): `agent-style update` (pull refreshed adapters), `agent-style override <RULE> disable` (per-rule opt-out), `agent-style clean` (single-command uninstall), `.agent-style/config.toml` (project-level config).
@@ -0,0 +1,45 @@
1
+ <!-- SPDX-License-Identifier: MIT -->
2
+
3
+ # agent-style (PyPI)
4
+
5
+ CLI for *The Elements of Agent Style*: a literature-backed English technical-prose writing ruleset for AI agents.
6
+
7
+ Install:
8
+
9
+ ```bash
10
+ pip install agent-style
11
+ ```
12
+
13
+ Basic use:
14
+
15
+ ```bash
16
+ agent-style list-tools # show supported tools
17
+ agent-style enable claude-code # wire up Claude Code
18
+ agent-style enable claude-code --dry-run --json # preview in canonical JSON
19
+ agent-style disable claude-code # reverse
20
+ agent-style rules # print bundled RULES.md
21
+ ```
22
+
23
+ The CLI writes to `.agent-style/` in your project and safely adds a marker-wrapped reference to your existing instruction file (CLAUDE.md, AGENTS.md, .github/copilot-instructions.md, etc.). Existing content is preserved; writes are idempotent; `--dry-run` previews without changing any file.
24
+
25
+ Supported tools and install modes in v0.1.0:
26
+
27
+ | Tool | Install mode |
28
+ | --- | --- |
29
+ | claude-code | import-marker (writes `@.agent-style/claude-code.md` to your CLAUDE.md) |
30
+ | agents-md | append-block (writes a marker block to your AGENTS.md) |
31
+ | copilot | append-block (writes a marker block to `.github/copilot-instructions.md`) |
32
+ | copilot-path | owned-file (writes `.github/instructions/agent-style.instructions.md`) |
33
+ | cursor | owned-file (writes `.cursor/rules/agent-style.mdc`) |
34
+ | anthropic-skill | owned-file (writes `.claude/skills/agent-style/SKILL.md`) |
35
+ | codex | print-only (writes `.agent-style/codex-system-prompt.md`; stdout = prompt) |
36
+ | aider | multi-file-required (writes `.agent-style/aider-conventions.md`; stderr = `.aider.conf.yml` snippet) |
37
+
38
+ The full rule set lives in the canonical repository at https://github.com/yzhao062/agent-style. This PyPI package bundles `RULES.md`, `NOTICE.md`, the 8 primary adapters, and the `tools.json` registry; running `agent-style rules` prints the bundled `RULES.md` for quick review.
39
+
40
+ ## License
41
+
42
+ - Code: MIT (`LICENSES/MIT.txt`).
43
+ - Bundled prose (`RULES.md`, `NOTICE.md`, adapters): CC BY 4.0 (`LICENSES/CC-BY-4.0.txt`).
44
+
45
+ Roadmap (v0.2.0+): `agent-style update` (pull refreshed adapters), `agent-style override <RULE> disable` (per-rule opt-out), `agent-style clean` (single-command uninstall), `.agent-style/config.toml` (project-level config).
@@ -0,0 +1,51 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """agent-style: literature-backed English technical-prose writing ruleset for AI agents.
3
+
4
+ Programmatic entry points:
5
+
6
+ from agent_style import __version__, rules, path, list_tools, enable, disable
7
+
8
+ See `agent-style --help` for the CLI.
9
+ """
10
+
11
+ __version__ = "0.1.0"
12
+
13
+
14
+ def rules() -> str:
15
+ """Return the bundled RULES.md content as a string."""
16
+ from agent_style.registry import Registry
17
+ return Registry().read_bundled_rules()
18
+
19
+
20
+ def path() -> str:
21
+ """Return the absolute path of the bundled data directory."""
22
+ from agent_style.registry import Registry
23
+ return Registry().data_dir
24
+
25
+
26
+ def list_tools() -> list:
27
+ """Return a list of (tool_name, install_mode, target_path) tuples."""
28
+ from agent_style.registry import Registry
29
+ r = Registry()
30
+ return [
31
+ (name, spec["install_mode"], spec["target_path"])
32
+ for name, spec in r.tools.items()
33
+ ]
34
+
35
+
36
+ def enable(tool: str, project_root: str = ".", dry_run: bool = False) -> dict:
37
+ """Enable agent-style for the given tool in the given project root.
38
+
39
+ Returns a canonical JSON-shaped dict with fields: tool, install_mode, enabled,
40
+ manual_step_required, actions.
41
+ """
42
+ from agent_style.installer import enable as _enable
43
+ from agent_style.registry import Registry
44
+ return _enable(tool, Registry(), project_root=project_root, dry_run=dry_run)
45
+
46
+
47
+ def disable(tool: str, project_root: str = ".", dry_run: bool = False) -> dict:
48
+ """Disable agent-style for the given tool in the given project root."""
49
+ from agent_style.installer import disable as _disable
50
+ from agent_style.registry import Registry
51
+ return _disable(tool, Registry(), project_root=project_root, dry_run=dry_run)
@@ -0,0 +1,173 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """agent-style CLI entry point.
3
+
4
+ Subcommands:
5
+ rules Print bundled RULES.md to stdout
6
+ path Print bundled data directory
7
+ list-tools Print supported tools
8
+ enable <tool> Install agent-style for a given tool (safe, idempotent)
9
+ disable <tool> Remove agent-style from a given tool's instruction file
10
+
11
+ Global:
12
+ --version Print version and exit
13
+ --help Print help
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import argparse
19
+ import sys
20
+ from typing import Any
21
+
22
+ from agent_style import __version__
23
+ from agent_style.installer import enable, disable, canonical_json
24
+ from agent_style.registry import Registry, RegistryError
25
+
26
+
27
+ def _print_json_result(result: dict[str, Any]) -> None:
28
+ sys.stdout.write(canonical_json(result))
29
+ sys.stdout.write("\n")
30
+
31
+
32
+ def _print_human_result(result: dict[str, Any], subcommand: str) -> None:
33
+ tool = result.get("tool", "?")
34
+ mode = result.get("install_mode", "?")
35
+ manual = result.get("manual_step_required", False)
36
+ actions = result.get("actions", [])
37
+ if manual:
38
+ # FIRST LINE must be "manual step required:" per Rev 8 acceptance criterion.
39
+ sys.stdout.write(f"manual step required: {tool} ({mode}) prepared, but needs a user action\n")
40
+ else:
41
+ sys.stdout.write(f"agent-style {subcommand} {tool} ({mode}): ")
42
+ sys.stdout.write("ok\n" if actions else "no changes\n")
43
+ for action in actions:
44
+ op = action.get("op", "?")
45
+ path = action.get("path", "?")
46
+ if op == "print-prompt":
47
+ # For print-only tools, the prompt body goes to stdout (clean).
48
+ # The human-step message is already above; the prompt content is whatever
49
+ # the adapter contains. The CLI loads it via print-prompt here.
50
+ # (Installer already wrote the file; we just echo the bundled body.)
51
+ sys.stderr.write(f" action: {op} {path} (prompt body printed to stdout below)\n")
52
+ elif op == "print-snippet":
53
+ # For multi-file-required, the snippet goes to stderr so stdout stays clean.
54
+ snippet = action.get("snippet", "")
55
+ sys.stderr.write(f" action: {op} {path}\n")
56
+ sys.stderr.write(" add this to your config:\n")
57
+ for line in snippet.splitlines():
58
+ sys.stderr.write(f" {line}\n")
59
+ else:
60
+ sys.stderr.write(f" action: {op} {path}\n")
61
+
62
+
63
+ def _cmd_rules(args: argparse.Namespace, registry: Registry) -> int:
64
+ sys.stdout.write(registry.read_bundled_rules())
65
+ return 0
66
+
67
+
68
+ def _cmd_path(args: argparse.Namespace, registry: Registry) -> int:
69
+ print(registry.data_dir)
70
+ return 0
71
+
72
+
73
+ def _cmd_list_tools(args: argparse.Namespace, registry: Registry) -> int:
74
+ for name, spec in registry.tools.items():
75
+ print(f"{name:18} {spec['install_mode']:22} {spec['target_path']}")
76
+ return 0
77
+
78
+
79
+ def _cmd_enable(args: argparse.Namespace, registry: Registry) -> int:
80
+ try:
81
+ result = enable(args.tool, registry, project_root=".", dry_run=args.dry_run)
82
+ except (RegistryError, RuntimeError) as exc:
83
+ sys.stderr.write(f"error: {exc}\n")
84
+ return 2
85
+ if args.json:
86
+ _print_json_result(result)
87
+ else:
88
+ _print_human_result(result, "enable")
89
+ if result.get("install_mode") == "print-only":
90
+ # Clean stdout with prompt body (for users who redirect `> prompt.md`).
91
+ target = result["actions"][0].get("path") if result["actions"] else None
92
+ if target:
93
+ body = registry.read_adapter(registry.get(args.tool)["adapter_source"])
94
+ sys.stdout.write(body)
95
+ return 0
96
+
97
+
98
+ def _cmd_disable(args: argparse.Namespace, registry: Registry) -> int:
99
+ try:
100
+ result = disable(args.tool, registry, project_root=".", dry_run=args.dry_run)
101
+ except (RegistryError, RuntimeError) as exc:
102
+ sys.stderr.write(f"error: {exc}\n")
103
+ return 2
104
+ if args.json:
105
+ _print_json_result(result)
106
+ else:
107
+ _print_human_result(result, "disable")
108
+ return 0
109
+
110
+
111
+ def build_parser() -> argparse.ArgumentParser:
112
+ parser = argparse.ArgumentParser(
113
+ prog="agent-style",
114
+ description=(
115
+ "agent-style: install and manage The Elements of Agent Style writing "
116
+ "ruleset for AI agents (Claude Code, GitHub Copilot, Cursor, AGENTS.md-aware "
117
+ "tools, Aider, Anthropic Skills, Codex API, and more)."
118
+ ),
119
+ )
120
+ parser.add_argument(
121
+ "--version",
122
+ action="version",
123
+ version=f"agent-style {__version__}",
124
+ )
125
+ sub = parser.add_subparsers(dest="command", required=True, metavar="<command>")
126
+
127
+ sub.add_parser("rules", help="Print bundled RULES.md to stdout.")
128
+ sub.add_parser("path", help="Print bundled data directory path.")
129
+ sub.add_parser("list-tools", help="List supported tools and their install modes.")
130
+
131
+ for subcmd in ("enable", "disable"):
132
+ p = sub.add_parser(
133
+ subcmd,
134
+ help=(
135
+ "Enable agent-style for a given tool (safe-append to your existing file)."
136
+ if subcmd == "enable"
137
+ else "Remove agent-style for a given tool from your instruction file."
138
+ ),
139
+ )
140
+ p.add_argument("tool", help="Tool name (see `agent-style list-tools`).")
141
+ p.add_argument(
142
+ "--dry-run",
143
+ action="store_true",
144
+ help="Print planned actions without writing any file.",
145
+ )
146
+ p.add_argument(
147
+ "--json",
148
+ action="store_true",
149
+ help="Emit canonical JSON output (sorted keys, LF, POSIX paths).",
150
+ )
151
+ return parser
152
+
153
+
154
+ def main(argv: list[str] | None = None) -> int:
155
+ parser = build_parser()
156
+ args = parser.parse_args(argv)
157
+ try:
158
+ registry = Registry()
159
+ except RegistryError as exc:
160
+ sys.stderr.write(f"registry error: {exc}\n")
161
+ return 2
162
+ dispatch = {
163
+ "rules": _cmd_rules,
164
+ "path": _cmd_path,
165
+ "list-tools": _cmd_list_tools,
166
+ "enable": _cmd_enable,
167
+ "disable": _cmd_disable,
168
+ }
169
+ return dispatch[args.command](args, registry)
170
+
171
+
172
+ if __name__ == "__main__":
173
+ sys.exit(main())