face-cli 0.7.0__tar.gz → 0.7.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.
- {face_cli-0.7.0 → face_cli-0.7.1}/CHANGELOG.md +57 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/CLAUDE.md +6 -3
- {face_cli-0.7.0 → face_cli-0.7.1}/PKG-INFO +2 -2
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/__init__.py +26 -2
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/learn.py +17 -8
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/overview.py +9 -1
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/whoami.py +2 -2
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/explain/catalog.py +9 -6
- {face_cli-0.7.0 → face_cli-0.7.1}/pyproject.toml +2 -2
- {face_cli-0.7.0 → face_cli-0.7.1}/tests/test_cli.py +24 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/uv.lock +1 -1
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/agent-config/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/ask-colleague/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/ask-colleague/prompts/review.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/ask-colleague/prompts/write.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/challenge/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/cicd/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/deviate/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/recall/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/recall/scripts/recall.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/remember/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/remember/scripts/remember.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/run-tests/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/scope/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/summarize-delivery/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/think/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/think/scripts/think.sh +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/version-bump/SKILL.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills.local.yaml.example +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.flake8 +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.github/workflows/publish.yml +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.github/workflows/tests.yml +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.gitignore +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/.markdownlint-cli2.yaml +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/AGENTS.colleague.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/LICENSE +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/README.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/culture.yaml +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/docs/skill-sources.md +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/__init__.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/__main__.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/__init__.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/cli.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/doctor.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_commands/explain.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_errors.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/cli/_output.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/face_cli/explain/__init__.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/sonar-project.properties +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/tests/__init__.py +0 -0
- {face_cli-0.7.0 → face_cli-0.7.1}/tests/test_cli_introspection.py +0 -0
|
@@ -5,6 +5,63 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/). This project
|
|
6
6
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.7.1] - 2026-07-24
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`--json` is accepted before the verb, not only after it** — `face --json
|
|
13
|
+
whoami` used to fail with `unrecognized arguments: --json` while `face whoami
|
|
14
|
+
--json` worked. Flag-before-verb is a common idiom, and an agent-first CLI
|
|
15
|
+
that rejects it is a trap. The root parser now declares `--json`, and
|
|
16
|
+
`main()` re-asserts it after `parse_args` from the existing raw-argv scan:
|
|
17
|
+
each subparser re-declares `--json` with its own `False` default, which
|
|
18
|
+
silently overwrites a leading flag during sub-parsing. Both orders now
|
|
19
|
+
produce identical output, pinned by a parametrized test.
|
|
20
|
+
- **`face --json` with no verb emits the machine-readable command map** rather
|
|
21
|
+
than an error — the JSON analogue of printing help. It reuses `learn`'s
|
|
22
|
+
payload builder (promoted from `_as_json_payload` to `as_json_payload`), so
|
|
23
|
+
there is one command map, not two.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **The CLI's own introspection text now describes this agent** — `face --help`,
|
|
28
|
+
`face learn`, `face explain`, and `face overview` still called the repo "a
|
|
29
|
+
clonable template for AgentCulture mesh agents" and gave clone/rename
|
|
30
|
+
instructions, contradicting the docs 0.7.0 rewrote. Because `learn` and
|
|
31
|
+
`explain` are explicitly the machine-readable teaching surface, that mismatch
|
|
32
|
+
misinformed every agent consuming them, not just human readers. All four now
|
|
33
|
+
state the domain (the expressive output side of a face; recognition belongs to
|
|
34
|
+
the sibling) and the honest status (scaffold — no renderer, no gaze primitive,
|
|
35
|
+
no render verbs yet), and `overview` gained a `Status` section carrying the
|
|
36
|
+
same. The leftover clone/rename framing is also gone from the `whoami` and
|
|
37
|
+
`overview` module docstrings. The `face` / `face-cli` naming split is
|
|
38
|
+
untouched: the console script stays `face` and every help / `learn` /
|
|
39
|
+
`explain` string stays `face-cli`, matching argparse's `prog`.
|
|
40
|
+
- **Package metadata no longer advertises capability that was never requested**
|
|
41
|
+
— `pyproject.toml`'s description promised a "gaze **and expression** surface"
|
|
42
|
+
while `README.md` says "gaze surface" and the build brief records that
|
|
43
|
+
expression was *not* asked for. Published metadata is public-facing (it is
|
|
44
|
+
what PyPI shows), so the conflicting claim was narrowed to match the README.
|
|
45
|
+
This removes the claim rather than settling the scope question, which stays
|
|
46
|
+
open in `CLAUDE.md`; the GitHub repo description, set at provisioning, still
|
|
47
|
+
carries the old wording and should follow whichever way the decision lands.
|
|
48
|
+
|
|
49
|
+
- **Public-facing descriptions no longer read as if the renderer exists** —
|
|
50
|
+
`pyproject.toml`'s description (what PyPI renders, and `publish.yml` pushes a
|
|
51
|
+
release on every merge to `main`) and the root `argparse` description both
|
|
52
|
+
described a working browser-rendered face in the present tense, while
|
|
53
|
+
`learn` / `explain` / `overview` said "scaffold, no renderer". Both now carry
|
|
54
|
+
the same qualifier. This also makes 0.7.1's own claim about `face --help`
|
|
55
|
+
true — it stated the honest status was there before the root description
|
|
56
|
+
actually carried it.
|
|
57
|
+
|
|
58
|
+
The first two items were raised by Qodo's review of
|
|
59
|
+
[#2](https://github.com/agentculture/face-cli/pull/2) (review comments
|
|
60
|
+
`3646920415`, `3646920422`), which merged before the fixes landed — hence a
|
|
61
|
+
follow-up release rather than an amendment. The remaining items came from
|
|
62
|
+
Qodo's review of [#3](https://github.com/agentculture/face-cli/pull/3) (review
|
|
63
|
+
comments `3647009663`, `3647009668`).
|
|
64
|
+
|
|
8
65
|
## [0.7.0] - 2026-07-24
|
|
9
66
|
|
|
10
67
|
### Added
|
|
@@ -205,9 +205,12 @@ CHANGELOG entry); do not let them get settled by accident in a commit:
|
|
|
205
205
|
to compute it with no human in the loop.
|
|
206
206
|
- **Whether expression is in scope at all.** The operator asked for direction.
|
|
207
207
|
Expression is the obvious neighbour and was *not* requested — decide
|
|
208
|
-
explicitly rather than drifting into it.
|
|
209
|
-
`pyproject.toml`
|
|
210
|
-
|
|
208
|
+
explicitly rather than drifting into it. Published metadata no longer
|
|
209
|
+
pre-answers it: `pyproject.toml` used to advertise a "gaze **and expression**
|
|
210
|
+
surface" while nothing of the sort exists, so its description was narrowed to
|
|
211
|
+
match the README. That removes the claim, it does not settle the question —
|
|
212
|
+
the GitHub repo description (set at provisioning) still carries the old
|
|
213
|
+
wording and should follow whichever way the decision lands.
|
|
211
214
|
- **What `--json` returns for a verb whose real output is pixels.** A
|
|
212
215
|
screenshot path is one honest answer; the resolved gaze state is another.
|
|
213
216
|
- **Who runs the render loop** — browser-side animation with the CLI setting
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: face-cli
|
|
3
|
-
Version: 0.7.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Summary: Scaffold for a browser-rendered face that reads three-dimensional on a flat 2D screen and looks in any direction — an agent-drivable gaze surface for robots, kiosks, and screens. The renderer is not implemented yet; the CLI ships introspection verbs only.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/face-cli
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/face-cli/issues
|
|
7
7
|
Author: AgentCulture
|
|
@@ -26,7 +26,7 @@ import sys
|
|
|
26
26
|
|
|
27
27
|
from face_cli import __version__
|
|
28
28
|
from face_cli.cli._errors import EXIT_USER_ERROR, CliError
|
|
29
|
-
from face_cli.cli._output import emit_error
|
|
29
|
+
from face_cli.cli._output import emit_error, emit_result
|
|
30
30
|
|
|
31
31
|
_ISSUES_URL = "https://github.com/agentculture/face-cli/issues"
|
|
32
32
|
|
|
@@ -71,13 +71,23 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
71
71
|
|
|
72
72
|
parser = _CliArgumentParser(
|
|
73
73
|
prog="face-cli",
|
|
74
|
-
description="face-cli — a
|
|
74
|
+
description="face-cli — a browser-rendered face that reads 3D on a 2D screen "
|
|
75
|
+
"and looks in any direction. Scaffold: no renderer or gaze verbs yet; the "
|
|
76
|
+
"verbs below are the introspection surface.",
|
|
75
77
|
)
|
|
76
78
|
parser.add_argument(
|
|
77
79
|
"--version",
|
|
78
80
|
action="version",
|
|
79
81
|
version=f"%(prog)s {__version__}",
|
|
80
82
|
)
|
|
83
|
+
# Accepted before the verb too (`face --json whoami`), not just after it.
|
|
84
|
+
# argparse gives each subparser its own `json` default, so a leading flag is
|
|
85
|
+
# clobbered on the way down; main() re-asserts it from the raw-argv scan.
|
|
86
|
+
parser.add_argument(
|
|
87
|
+
"--json",
|
|
88
|
+
action="store_true",
|
|
89
|
+
help="Emit structured JSON. Accepted before or after the verb.",
|
|
90
|
+
)
|
|
81
91
|
# parser_class propagates to every subparser so their .error() routes
|
|
82
92
|
# through _CliArgumentParser too.
|
|
83
93
|
sub = parser.add_subparsers(dest="command", parser_class=_CliArgumentParser)
|
|
@@ -125,7 +135,21 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
125
135
|
parser = _build_parser()
|
|
126
136
|
args = parser.parse_args(argv)
|
|
127
137
|
|
|
138
|
+
# Position must not change meaning: each subparser re-declares `--json` with
|
|
139
|
+
# its own `False` default, which overwrites a leading `--json` during
|
|
140
|
+
# sub-parsing. Re-assert from the raw-argv scan so `face --json whoami` and
|
|
141
|
+
# `face whoami --json` behave identically.
|
|
142
|
+
if _CliArgumentParser._json_hint:
|
|
143
|
+
args.json = True
|
|
144
|
+
|
|
128
145
|
if args.command is None:
|
|
146
|
+
# No verb: the JSON analogue of printing help is the machine-readable
|
|
147
|
+
# command map, which `learn` already owns.
|
|
148
|
+
if getattr(args, "json", False):
|
|
149
|
+
from face_cli.cli._commands.learn import as_json_payload
|
|
150
|
+
|
|
151
|
+
emit_result(as_json_payload(), json_mode=True)
|
|
152
|
+
return 0
|
|
129
153
|
parser.print_help()
|
|
130
154
|
return 0
|
|
131
155
|
|
|
@@ -12,14 +12,19 @@ from face_cli import __version__
|
|
|
12
12
|
from face_cli.cli._output import emit_result
|
|
13
13
|
|
|
14
14
|
_TEXT = """\
|
|
15
|
-
face-cli — a
|
|
15
|
+
face-cli — a browser-rendered face that reads 3D on a 2D screen and looks
|
|
16
|
+
anywhere.
|
|
16
17
|
|
|
17
18
|
Purpose
|
|
18
19
|
-------
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
The expressive *output* side of a face: a simulated face rendered in a browser
|
|
21
|
+
that appears three-dimensional on a flat screen and can point its gaze in any
|
|
22
|
+
direction, drivable by an agent. Its sibling face-recognition-cli is the
|
|
23
|
+
perceptual *input* side; this tool does no recognition.
|
|
24
|
+
|
|
25
|
+
Status: scaffold. No renderer, no gaze primitive, and no render verbs exist
|
|
26
|
+
yet — the commands below are the introspection surface only. See the build
|
|
27
|
+
brief at https://github.com/agentculture/face-cli/issues/1.
|
|
23
28
|
|
|
24
29
|
Commands
|
|
25
30
|
--------
|
|
@@ -48,11 +53,15 @@ More detail
|
|
|
48
53
|
"""
|
|
49
54
|
|
|
50
55
|
|
|
51
|
-
def
|
|
56
|
+
def as_json_payload() -> dict[str, object]:
|
|
57
|
+
"""Machine-readable command map. Shared with the root `--json` (no verb) path."""
|
|
52
58
|
return {
|
|
53
59
|
"tool": "face-cli",
|
|
54
60
|
"version": __version__,
|
|
55
|
-
"purpose":
|
|
61
|
+
"purpose": (
|
|
62
|
+
"Browser-rendered face that reads 3D on a 2D screen and looks in any "
|
|
63
|
+
"direction. Scaffold: no render verbs yet."
|
|
64
|
+
),
|
|
56
65
|
"commands": [
|
|
57
66
|
{"path": ["whoami"], "summary": "Identity probe from culture.yaml."},
|
|
58
67
|
{"path": ["learn"], "summary": "Self-teaching prompt."},
|
|
@@ -73,7 +82,7 @@ def _as_json_payload() -> dict[str, object]:
|
|
|
73
82
|
|
|
74
83
|
def cmd_learn(args: argparse.Namespace) -> int:
|
|
75
84
|
if getattr(args, "json", False):
|
|
76
|
-
emit_result(
|
|
85
|
+
emit_result(as_json_payload(), json_mode=True)
|
|
77
86
|
else:
|
|
78
87
|
emit_result(_TEXT, json_mode=False)
|
|
79
88
|
return 0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""``face-cli overview`` — read-only descriptive snapshot of the agent.
|
|
2
2
|
|
|
3
3
|
Describes the agent to an agent reader: identity (from culture.yaml), the verb
|
|
4
|
-
surface, and the sibling-pattern artifacts this
|
|
4
|
+
surface, and the sibling-pattern artifacts this repo carries. The shared
|
|
5
5
|
section/render helpers here are reused by the ``cli`` noun's ``overview`` (see
|
|
6
6
|
:mod:`face_cli.cli._commands.cli`).
|
|
7
7
|
|
|
@@ -24,6 +24,13 @@ _ARTIFACTS = [
|
|
|
24
24
|
"pyproject.toml + .github/workflows/ — buildable, deployable package baseline",
|
|
25
25
|
]
|
|
26
26
|
|
|
27
|
+
_STATUS = [
|
|
28
|
+
"domain: the expressive output side of a face — browser-rendered, reads 3D "
|
|
29
|
+
"on a flat 2D screen, gaze pointable in any direction",
|
|
30
|
+
"scaffold: no renderer, no gaze primitive, no render verbs on disk yet",
|
|
31
|
+
"build brief: https://github.com/agentculture/face-cli/issues/1",
|
|
32
|
+
]
|
|
33
|
+
|
|
27
34
|
_VERBS = [
|
|
28
35
|
"whoami — identity probe (nick, version, backend, model)",
|
|
29
36
|
"learn — structured self-teaching prompt",
|
|
@@ -46,6 +53,7 @@ def agent_sections() -> list[dict[str, object]]:
|
|
|
46
53
|
f"model: {ident['model']}",
|
|
47
54
|
],
|
|
48
55
|
},
|
|
56
|
+
{"title": "Status", "items": list(_STATUS)},
|
|
49
57
|
{"title": "Verbs", "items": list(_VERBS)},
|
|
50
58
|
{"title": "Sibling-pattern artifacts", "items": list(_ARTIFACTS)},
|
|
51
59
|
]
|
|
@@ -4,8 +4,8 @@ Reports the agent's identity as declared in ``culture.yaml``: its nick
|
|
|
4
4
|
(``suffix``), the backend it runs on, and the served model (if any) — plus the
|
|
5
5
|
package version. Read-only; touches nothing but its own ``culture.yaml``.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
The identity is data, not code: editing ``culture.yaml`` changes what ``whoami``
|
|
8
|
+
reports with no code change.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
@@ -12,11 +12,14 @@ from __future__ import annotations
|
|
|
12
12
|
_ROOT = """\
|
|
13
13
|
# face-cli
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
The expressive *output* side of a face: a simulated face rendered in a browser
|
|
16
|
+
that appears three-dimensional on a flat 2D screen and can look in any
|
|
17
|
+
direction, drivable by an agent. The sibling `face-recognition-cli` is the
|
|
18
|
+
perceptual *input* side — this tool does no recognition.
|
|
19
|
+
|
|
20
|
+
**Status: scaffold.** There is no renderer, no gaze primitive, and no render
|
|
21
|
+
verbs on disk yet; what follows is the introspection surface. The build brief
|
|
22
|
+
is <https://github.com/agentculture/face-cli/issues/1>.
|
|
20
23
|
|
|
21
24
|
## Verbs
|
|
22
25
|
|
|
@@ -81,7 +84,7 @@ _OVERVIEW = """\
|
|
|
81
84
|
# face-cli overview
|
|
82
85
|
|
|
83
86
|
Read-only descriptive snapshot of the agent: identity (from `culture.yaml`), the
|
|
84
|
-
verb surface, and the sibling-pattern artifacts
|
|
87
|
+
verb surface, and the sibling-pattern artifacts this repo carries. Accepts an
|
|
85
88
|
ignored `target` so a stray path never hard-fails.
|
|
86
89
|
|
|
87
90
|
## Usage
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "face-cli"
|
|
3
|
-
version = "0.7.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.7.1"
|
|
4
|
+
description = "Scaffold for a browser-rendered face that reads three-dimensional on a flat 2D screen and looks in any direction — an agent-drivable gaze surface for robots, kiosks, and screens. The renderer is not implemented yet; the CLI ships introspection verbs only."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "Apache-2.0"
|
|
7
7
|
requires-python = ">=3.12"
|
|
@@ -24,6 +24,30 @@ def test_no_args_prints_help(capsys: pytest.CaptureFixture[str]) -> None:
|
|
|
24
24
|
assert "usage: face-cli" in capsys.readouterr().out
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def test_root_json_without_verb_emits_command_map(capsys: pytest.CaptureFixture[str]) -> None:
|
|
28
|
+
"""`face --json` (no verb) is the machine-readable analogue of printing help."""
|
|
29
|
+
rc = main(["--json"])
|
|
30
|
+
assert rc == 0
|
|
31
|
+
payload = json.loads(capsys.readouterr().out)
|
|
32
|
+
assert payload["tool"] == "face-cli"
|
|
33
|
+
assert payload["commands"]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.mark.parametrize(
|
|
37
|
+
"argv",
|
|
38
|
+
[["--json", "whoami"], ["whoami", "--json"]],
|
|
39
|
+
ids=["flag-before-verb", "flag-after-verb"],
|
|
40
|
+
)
|
|
41
|
+
def test_json_flag_position_does_not_change_meaning(
|
|
42
|
+
argv: list[str], capsys: pytest.CaptureFixture[str]
|
|
43
|
+
) -> None:
|
|
44
|
+
"""A leading `--json` must survive sub-parsing (each subparser re-defaults it)."""
|
|
45
|
+
rc = main(argv)
|
|
46
|
+
assert rc == 0
|
|
47
|
+
payload = json.loads(capsys.readouterr().out)
|
|
48
|
+
assert payload["nick"] == "face-cli"
|
|
49
|
+
|
|
50
|
+
|
|
27
51
|
def test_unknown_command_errors(capsys: pytest.CaptureFixture[str]) -> None:
|
|
28
52
|
with pytest.raises(SystemExit) as exc:
|
|
29
53
|
main(["bogus"])
|
|
File without changes
|
{face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/templates/skill-new-brief.md
RENAMED
|
File without changes
|
{face_cli-0.7.0 → face_cli-0.7.1}/.claude/skills/communicate/scripts/templates/skill-update-brief.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|