familiar-cli 0.5.2__tar.gz → 0.6.1__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.
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/PKG-INFO +14 -5
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/pyproject.toml +2 -2
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/readme.md +12 -3
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/__init__.py +1 -1
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/_plugins.py +4 -2
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/agents.py +3 -2
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/cli.py +7 -5
- familiar_cli-0.6.1/src/familiar/lint.py +593 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/render.py +57 -24
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar_cli.egg-info/PKG-INFO +14 -5
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar_cli.egg-info/requires.txt +1 -1
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/tests/test_agents.py +5 -4
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/tests/test_cli.py +108 -89
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/tests/test_integration.py +20 -0
- familiar_cli-0.6.1/tests/test_lint.py +1260 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/tests/test_render.py +113 -0
- familiar_cli-0.5.2/src/familiar/lint.py +0 -291
- familiar_cli-0.5.2/tests/test_lint.py +0 -421
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/LICENSE +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/setup.cfg +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/core.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/data.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/docs.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/frontend.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/infra.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/python.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/rust.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/conjurings/sec.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/__noop__.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/add-ci.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/add-tests.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/audit.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/bootstrap-python.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/bootstrap-rust.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/code-review.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/explain.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/implement-feature.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/infra-change.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/performance.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/refactor.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/release.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/invocations/security-review.md +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/node/github-ci.yml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/node/gitlab-ci.yml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/python/github-ci.yml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/python/gitlab-ci.yml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/python/pyproject.toml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/rust/Cargo.toml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/rust/github-ci.yml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/data/snippets/rust/gitlab-ci.yml +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar/py.typed +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar_cli.egg-info/SOURCES.txt +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar_cli.egg-info/dependency_links.txt +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar_cli.egg-info/entry_points.txt +0 -0
- {familiar_cli-0.5.2 → familiar_cli-0.6.1}/src/familiar_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: familiar-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: compose and invoke ai agent prompts from reusable templates
|
|
5
5
|
Author-email: cyberwitchery lab <contact@cyberwitchery.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,7 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
Provides-Extra: dev
|
|
23
|
-
Requires-Dist: ruff; extra == "dev"
|
|
23
|
+
Requires-Dist: ruff==0.16.5; extra == "dev"
|
|
24
24
|
Requires-Dist: mypy; extra == "dev"
|
|
25
25
|
Requires-Dist: pytest; extra == "dev"
|
|
26
26
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -46,18 +46,21 @@ pip install familiar-cli
|
|
|
46
46
|
## usage
|
|
47
47
|
|
|
48
48
|
```
|
|
49
|
-
usage: familiar [-h] {conjure,invoke,list} ...
|
|
49
|
+
usage: familiar [-h] [--version] [--debug] {conjure,invoke,list,lint} ...
|
|
50
50
|
|
|
51
51
|
conjure and invoke familiars
|
|
52
52
|
|
|
53
53
|
positional arguments:
|
|
54
|
-
{conjure,invoke,list}
|
|
54
|
+
{conjure,invoke,list,lint}
|
|
55
55
|
conjure compose system instructions for an agent
|
|
56
56
|
invoke render an invocation and run the agent
|
|
57
|
-
list list available conjurings
|
|
57
|
+
list list available conjurings and invocations
|
|
58
|
+
lint lint conjurings and invocations
|
|
58
59
|
|
|
59
60
|
options:
|
|
60
61
|
-h, --help show this help message and exit
|
|
62
|
+
--version show program's version number and exit
|
|
63
|
+
--debug show full traceback on error
|
|
61
64
|
```
|
|
62
65
|
|
|
63
66
|
conjure conjurings to create system instructions for an agent:
|
|
@@ -98,6 +101,12 @@ list available conjurings and invocations:
|
|
|
98
101
|
familiar list
|
|
99
102
|
```
|
|
100
103
|
|
|
104
|
+
lint conjurings and invocations, including local `.familiar/` overrides:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
familiar lint
|
|
108
|
+
```
|
|
109
|
+
|
|
101
110
|
## customization
|
|
102
111
|
|
|
103
112
|
add your own conjurings and invocations by creating files in `.familiar/` in your repo:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "familiar-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.6.1"
|
|
4
4
|
description = "compose and invoke ai agent prompts from reusable templates"
|
|
5
5
|
readme = "readme.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -36,7 +36,7 @@ claude = "familiar.agents:ClaudeAgent"
|
|
|
36
36
|
package-dir = {"" = "src"}
|
|
37
37
|
|
|
38
38
|
[project.optional-dependencies]
|
|
39
|
-
dev = ["ruff", "mypy", "pytest", "pytest-cov", "bandit"]
|
|
39
|
+
dev = ["ruff==0.16.5", "mypy", "pytest", "pytest-cov", "bandit"]
|
|
40
40
|
|
|
41
41
|
[tool.setuptools.package-data]
|
|
42
42
|
"familiar.data.conjurings" = ["*.md"]
|
|
@@ -17,18 +17,21 @@ pip install familiar-cli
|
|
|
17
17
|
## usage
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
usage: familiar [-h] {conjure,invoke,list} ...
|
|
20
|
+
usage: familiar [-h] [--version] [--debug] {conjure,invoke,list,lint} ...
|
|
21
21
|
|
|
22
22
|
conjure and invoke familiars
|
|
23
23
|
|
|
24
24
|
positional arguments:
|
|
25
|
-
{conjure,invoke,list}
|
|
25
|
+
{conjure,invoke,list,lint}
|
|
26
26
|
conjure compose system instructions for an agent
|
|
27
27
|
invoke render an invocation and run the agent
|
|
28
|
-
list list available conjurings
|
|
28
|
+
list list available conjurings and invocations
|
|
29
|
+
lint lint conjurings and invocations
|
|
29
30
|
|
|
30
31
|
options:
|
|
31
32
|
-h, --help show this help message and exit
|
|
33
|
+
--version show program's version number and exit
|
|
34
|
+
--debug show full traceback on error
|
|
32
35
|
```
|
|
33
36
|
|
|
34
37
|
conjure conjurings to create system instructions for an agent:
|
|
@@ -69,6 +72,12 @@ list available conjurings and invocations:
|
|
|
69
72
|
familiar list
|
|
70
73
|
```
|
|
71
74
|
|
|
75
|
+
lint conjurings and invocations, including local `.familiar/` overrides:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
familiar lint
|
|
79
|
+
```
|
|
80
|
+
|
|
72
81
|
## customization
|
|
73
82
|
|
|
74
83
|
add your own conjurings and invocations by creating files in `.familiar/` in your repo:
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import warnings
|
|
6
|
+
from collections.abc import Callable
|
|
6
7
|
from importlib.metadata import entry_points
|
|
7
|
-
from typing import Any
|
|
8
|
+
from typing import Any
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def load_plugins(
|
|
@@ -36,7 +37,8 @@ def load_plugins(
|
|
|
36
37
|
)
|
|
37
38
|
continue
|
|
38
39
|
results.append(obj)
|
|
39
|
-
|
|
40
|
+
# a broken third-party entry point must not take down the cli
|
|
41
|
+
except Exception as e: # noqa: BLE001
|
|
40
42
|
warnings.warn(
|
|
41
43
|
f"failed to load {label} '{ep.name}': {e}",
|
|
42
44
|
stacklevel=2,
|
|
@@ -61,7 +61,7 @@ class CodexAgent(Agent):
|
|
|
61
61
|
if auto:
|
|
62
62
|
cmd.append("--full-auto")
|
|
63
63
|
cmd.extend(["exec", "--skip-git-repo-check", "-C", str(repo_root), "-"])
|
|
64
|
-
proc = subprocess.run(cmd, input=prompt, text=True)
|
|
64
|
+
proc = subprocess.run(cmd, input=prompt, text=True, check=False)
|
|
65
65
|
return proc.returncode
|
|
66
66
|
else:
|
|
67
67
|
cmd = ["codex"]
|
|
@@ -108,7 +108,8 @@ def load_agents() -> dict[str, Agent]:
|
|
|
108
108
|
try:
|
|
109
109
|
instance = cls()
|
|
110
110
|
agents[instance.name] = instance
|
|
111
|
-
|
|
111
|
+
# a broken agent plugin must not take down the cli
|
|
112
|
+
except Exception as e: # noqa: BLE001
|
|
112
113
|
warnings.warn(
|
|
113
114
|
f"failed to load agent plugin '{cls.__name__}': {e}",
|
|
114
115
|
stacklevel=2,
|
|
@@ -14,7 +14,7 @@ import warnings
|
|
|
14
14
|
from importlib.metadata import version
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
|
|
17
|
-
from .agents import Agent,
|
|
17
|
+
from .agents import Agent, get_agent, get_agents
|
|
18
18
|
from .lint import lint_all
|
|
19
19
|
from .render import (
|
|
20
20
|
NotFoundError,
|
|
@@ -46,7 +46,7 @@ def _agent_hint() -> str:
|
|
|
46
46
|
return f"valid agents: {', '.join(get_agents().keys())}"
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
def _resolve_agent(name: str) ->
|
|
49
|
+
def _resolve_agent(name: str) -> Agent:
|
|
50
50
|
"""look up an agent by name, raising CliError on unknown names."""
|
|
51
51
|
try:
|
|
52
52
|
return get_agent(name)
|
|
@@ -94,6 +94,7 @@ def _remove_worktree(repo_root: Path, worktree_path: Path) -> None:
|
|
|
94
94
|
str(worktree_path),
|
|
95
95
|
],
|
|
96
96
|
capture_output=True,
|
|
97
|
+
check=False,
|
|
97
98
|
)
|
|
98
99
|
if result.returncode != 0:
|
|
99
100
|
stderr = result.stderr.decode(errors="replace").strip()
|
|
@@ -119,8 +120,8 @@ def create_worktree(repo_root: Path) -> Path:
|
|
|
119
120
|
)
|
|
120
121
|
|
|
121
122
|
tmpdir = tempfile.mkdtemp(prefix="familiar-")
|
|
122
|
-
# git worktree add requires the
|
|
123
|
-
# mkdtemp
|
|
123
|
+
# git worktree add requires the target to not exist, so remove the
|
|
124
|
+
# mkdtemp-created directory and let git create it
|
|
124
125
|
os.rmdir(tmpdir)
|
|
125
126
|
|
|
126
127
|
try:
|
|
@@ -509,7 +510,8 @@ def main() -> None:
|
|
|
509
510
|
if e.hint:
|
|
510
511
|
print(f"hint: {e.hint}", file=sys.stderr)
|
|
511
512
|
raise SystemExit(e.exit_code)
|
|
512
|
-
|
|
513
|
+
# top-level handler: any unexpected error becomes an exit code, not a traceback
|
|
514
|
+
except Exception as e: # noqa: BLE001
|
|
513
515
|
if args.debug:
|
|
514
516
|
traceback.print_exc()
|
|
515
517
|
print(f"error: {e}", file=sys.stderr)
|