mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-13 18:30:47 +01:00
app_icons: add the anvil glyph and register octoforge
OctoForge (~/octoforge) is app #10 in the shared launcher-icon family. It was still shipping the stock Flutter icon, which is not a finished state. The glyph is a filled silhouette rather than a stroked outline: a stroked anvil is a long thin horn plus a narrow waist, and at the family's 72px stroke weight the waist closes up solid at 48dp. An octopus (GitHub trade dress, and a tangle of thin curves that blurs at launcher size) and a bare hammer (reads as a generic tool, not a forge) were both rejected. The horn is a separate wedge projecting off the face, not a rounded corner on it. Two earlier drafts folded the taper into the slab's left end and both rendered as a bump, leaving the shape reading as an I-beam. It now tapers to a 40px blunt tip, above MIN_NEGATIVE_SPACE so it survives at 48dp. Registered with linux=True: unlike the other phone-first apps this one has a real desktop target with a .desktop entry, so it needs the hicolor set. Verified: generated for Android and Linux, checked against the family preview sheet at all three sizes, and confirmed in the device app drawer next to todo. Committed from a temporary worktree: the working tree held another session's in-flight kuhylog entry in the same hunk, and git-rules.md forbids stashing around other agents' uncommitted work. That work is untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzEA5srk8VPn6mKKjCaGpb
This commit is contained in:
parent
143d260c1c
commit
137fc99a2e
@ -0,0 +1,52 @@
|
||||
{
|
||||
"intent": "Give OctoForge (~/octoforge) an on-style launcher icon from the shared family, replacing the stock Flutter logo it was still shipping. Registers it as app #10 with a new anvil glyph.",
|
||||
"scope": [
|
||||
"python_pkg/app_icons/glyphs.py: adds the _ANVIL fragment and its GLYPHS entry",
|
||||
"python_pkg/app_icons/apps.py: adds the octoforge AppIcon registry entry",
|
||||
"Non-goal: no change to style.py, the renderer, or any existing app's icon - a style change would restyle the whole family",
|
||||
"Non-goal: no iOS assets; OctoForge cannot be built for iOS here (no Xcode)"
|
||||
],
|
||||
"changes": [
|
||||
"Anvil drawn as a filled silhouette rather than a stroked outline: at the family's 72px stroke weight the narrow waist closes up solid at 48dp. Same reasoning as the existing quill-nib and receipt-split glyphs.",
|
||||
"The horn is a separate wedge projecting off the face, tapering to a 40px blunt tip (above MIN_NEGATIVE_SPACE so it survives at launcher size). Two earlier drafts folded the taper into the face slab and rendered as a bump, leaving the shape reading as an I-beam.",
|
||||
"Registered with linux=True: OctoForge has a real desktop target with a .desktop entry, unlike the phone-first apps that scaffolded linux/ but ship no entry.",
|
||||
"Accent is the shared #B8862E, matching all nine existing apps - apps are distinguished by glyph shape, not colour."
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "pre-commit run --files python_pkg/app_icons/glyphs.py python_pkg/app_icons/apps.py",
|
||||
"result": "pass",
|
||||
"evidence": "All hooks Passed or Skipped, including ruff, mypy, pylint, bandit, 'pytest with coverage enforcement' and 'Block binary/image files'."
|
||||
},
|
||||
{
|
||||
"command": "python3 -m pytest python_pkg/app_icons/tests/ -q --cov=python_pkg.app_icons",
|
||||
"result": "pass",
|
||||
"evidence": "44 passed; every app_icons module at 100% (apps.py, glyphs.py, cli.py, generate.py, preview.py, render.py, style.py). Registry tests are data-driven so they cover the new entry."
|
||||
},
|
||||
{
|
||||
"command": "python3 -m python_pkg.app_icons generate --app octoforge --android --linux-out <app>/desktop/icons",
|
||||
"result": "pass",
|
||||
"evidence": "Wrote 6 asset files, 8 hicolor PNGs and regenerated the Android mipmaps with no safe-box warning. All five mipmap-*/ic_launcher.png md5s changed from the stock Flutter values."
|
||||
},
|
||||
{
|
||||
"command": "python3 -m python_pkg.app_icons preview -o sheet.png",
|
||||
"result": "pass",
|
||||
"evidence": "Inspected the three rows (full size, circle-masked, 48dp). The anvil is legible at 48dp and sits with the family in weight and style."
|
||||
},
|
||||
{
|
||||
"command": "adb -s 23181JEGR08034 install -r app-debug.apk && open the app drawer",
|
||||
"result": "pass",
|
||||
"evidence": "Icon renders correctly in the launcher on the physical device, next to todo's checklist glyph on the same charcoal field."
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"Glyph legibility is a visual judgement; it was checked on the preview sheet at 48dp and in the real device app drawer, not asserted by a test.",
|
||||
"Committed from a temporary git worktree because the working tree held another session's in-flight kuhylog registry entry in the same hunk. Only the anvil and octoforge additions are in this commit; the kuhylog work is untouched and still uncommitted in the main checkout.",
|
||||
"app-icon/SKILL.md still documents charcoal #1B1D21 and accent #4C7DF0, which the live generator and all ten registered apps contradict. Following the skill text literally would produce an off-palette icon. Not fixed here."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit; it only adds a glyph and a registry entry, so nothing else depends on it.",
|
||||
"After rollback, run python3 -m python_pkg.app_icons list and confirm nine apps and nine glyphs, then re-run the app_icons test suite.",
|
||||
"OctoForge's already-generated icon assets live in its own repo and are unaffected by a revert here; regenerating them would then fail with 'unknown app octoforge', which is the expected signal."
|
||||
]
|
||||
}
|
||||
@ -130,6 +130,18 @@ APPS: Final[dict[str, AppIcon]] = {
|
||||
# the table, so it ships no desktop entry and gets no hicolor set.
|
||||
linux=False,
|
||||
),
|
||||
AppIcon(
|
||||
key="octoforge",
|
||||
# The Flutter app is a subdirectory of the repo: the repo root
|
||||
# holds the pure-Dart core and the tooling alongside it.
|
||||
repo=_HOME / "octoforge" / "octoforge" / "app",
|
||||
accent="#B8862E",
|
||||
glyph="anvil",
|
||||
icon_name="octoforge",
|
||||
# Unlike the other phone-first apps, this one is genuinely used on
|
||||
# the desktop too, so it gets the hicolor set and a desktop entry.
|
||||
linux=True,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -182,6 +182,36 @@ M 472 470 A 40 40 0 1 0 552 470 A 40 40 0 1 0 472 470 Z \
|
||||
M 512 700 L 492 580 L 532 580 Z"/>"""
|
||||
|
||||
|
||||
# A blacksmith's anvil: OctoForge is a GitHub client, and the forge is the
|
||||
# name. Filled rather than stroked, for the same reason as the nib — a stroked
|
||||
# anvil outline is a long thin horn plus a narrow waist, and at the family's
|
||||
# 72px weight the waist closes up solid at 48dp.
|
||||
#
|
||||
# The obvious alternatives were rejected: an octopus (the Octocat) is both
|
||||
# GitHub trade dress and a tangle of thin curves that blurs at launcher size,
|
||||
# and a hammer alone collides with nothing in the family but reads as a generic
|
||||
# tool rather than a forge. The anvil silhouette is unmistakable and shares no
|
||||
# shape language with the other nine glyphs.
|
||||
#
|
||||
# Geometry: the body is a face slab (x=336..768, y=316..420), a waist
|
||||
# (x=444..596, y=420..592) and a flared foot (x=304..716, y=592..708) — total
|
||||
# ink 512x392 including the horn, inside SAFE_BOX once the renderer scales it.
|
||||
#
|
||||
# The horn is what makes this an anvil rather than an I-beam, so it is a
|
||||
# separate wedge projecting left off the face, not a rounded corner on it: it
|
||||
# leaves the slab at full 104px depth (x=336) and tapers to a 40px blunt tip
|
||||
# at x=256, dropping the underside from y=420 to y=392 on the way. A sharp
|
||||
# point would disappear at 48dp; 40px is above MIN_NEGATIVE_SPACE so it
|
||||
# survives. The first two drafts folded the taper into the slab's left end and
|
||||
# both read as a bump.
|
||||
_ANVIL = """\
|
||||
<path fill="{{ACCENT}}" stroke="none" d="\
|
||||
M 768 316 L 768 420 L 596 420 \
|
||||
Q 592 512 592 592 L 716 592 L 716 708 L 304 708 L 304 592 L 428 592 \
|
||||
Q 428 512 424 420 L 336 420 \
|
||||
L 256 392 Q 248 376 256 360 L 336 316 Z"/>"""
|
||||
|
||||
|
||||
GLYPHS: Final[dict[str, Glyph]] = {
|
||||
glyph.name: glyph
|
||||
for glyph in (
|
||||
@ -194,6 +224,7 @@ GLYPHS: Final[dict[str, Glyph]] = {
|
||||
Glyph("storage-box", "Isometric storage carton", _STORAGE_BOX),
|
||||
Glyph("receipt-split", "Torn receipt with a perforated split", _RECEIPT_SPLIT),
|
||||
Glyph("quill-nib", "Dip-pen nib with vent hole and slit", _QUILL_NIB),
|
||||
Glyph("anvil", "Blacksmith's anvil with horn and flared foot", _ANVIL),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user