herm-tui 1.9.0-dev.16 → 1.9.0-dev.17
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.
- package/README.md +41 -7
- package/assets/eikons/nous/manifest.json +120 -0
- package/assets/eikons/{default/default.eikon → nous/nous.eikon} +1 -1
- package/assets/plugins/eikon/__init__.py +34 -11
- package/assets/plugins/eikon/plugin.yaml +6 -1
- package/assets/plugins/eikon/schemas.py +70 -2
- package/assets/plugins/eikon/tools.py +77 -21
- package/assets/skills/eikon/SKILL.md +37 -3
- package/assets/skills/eikon-create/SKILL.md +4 -1
- package/index.js +73 -59
- package/package.json +1 -1
- package/assets/eikons/ares/ares.eikon +0 -367
- package/assets/eikons/ares/manifest.json +0 -28
- package/assets/eikons/default/manifest.json +0 -28
- package/assets/eikons/mono/manifest.json +0 -28
- package/assets/eikons/mono/mono.eikon +0 -395
package/README.md
CHANGED
|
@@ -93,15 +93,49 @@ See [`.env.example`](./.env.example) for rarely-needed overrides.
|
|
|
93
93
|
|
|
94
94
|
### Share and install eikons
|
|
95
95
|
|
|
96
|
+
Eikons are 48×24 terminal avatars. The shipped lifecycle is deterministic:
|
|
97
|
+
discover, inspect, install, use, update, and remove.
|
|
98
|
+
|
|
99
|
+
In Herm:
|
|
100
|
+
|
|
96
101
|
- Open Eikon → Marketplace, or run `/marketplace`, to browse shared catalog
|
|
97
102
|
entries.
|
|
98
|
-
- Preview
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
- Preview rows before installing. Trust is shown as `Verified`, `Unverified`,
|
|
104
|
+
or `Mismatch` beside source and compatibility state.
|
|
105
|
+
- Install adds the eikon to your local library without activating it.
|
|
106
|
+
- Use selects an installed eikon as the active avatar.
|
|
107
|
+
- Update or remove an active eikon only after confirming that the active
|
|
108
|
+
avatar's backing package will change or be cleared.
|
|
109
|
+
|
|
110
|
+
From the shell:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
herm eikon search [query]
|
|
114
|
+
herm eikon inspect <name|github.com/user/repo/eikon-name|dir>
|
|
115
|
+
herm eikon install <name|github.com/user/repo/eikon-name|dir>
|
|
116
|
+
herm eikon use <name>
|
|
117
|
+
herm eikon info <name>
|
|
118
|
+
herm eikon update <name> --active-ok
|
|
119
|
+
herm eikon remove <name> --active-ok
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`install` never activates. `use` is the activation action. JSON output is
|
|
123
|
+
available for automation with `--json`.
|
|
124
|
+
|
|
125
|
+
Default Marketplace installs fetch built package artifacts referenced by the
|
|
126
|
+
catalog, not creator repositories. Direct GitHub installs are for sharing
|
|
127
|
+
outside the default catalog and support both single-package repos and
|
|
128
|
+
multi-eikon catalog repos addressed as `github.com/user/repo/eikon-name`.
|
|
129
|
+
Private GitHub repos use normal git authentication.
|
|
130
|
+
|
|
131
|
+
Creators can share eikons through normal GitHub repositories. Use upstream
|
|
132
|
+
`eikon pack`, `eikon index`, and `eikon manifest` to prepare single-package or
|
|
133
|
+
multi-eikon repos for direct installs. `eikon publish` remains a GitHub PR
|
|
134
|
+
contribution helper for the configured/default catalog repo; it is not a
|
|
135
|
+
hosted marketplace account, upload, dashboard, or moderation flow.
|
|
136
|
+
|
|
137
|
+
Use `eikon.liftaris.dev` as a discovery gallery only; it previews catalog
|
|
138
|
+
entries and gives copyable Herm install instructions.
|
|
105
139
|
|
|
106
140
|
Herm owns native Marketplace behavior. The eikon repo owns the registry,
|
|
107
141
|
browser mirror, shared catalog/player exports, install resolver, and publish
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "eikon.package",
|
|
3
|
+
"schemaVersion": "1.0",
|
|
4
|
+
"id": "liftaris/nous",
|
|
5
|
+
"name": "nous",
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"display": {
|
|
8
|
+
"title": "nous",
|
|
9
|
+
"author": "kaio",
|
|
10
|
+
"glyph": "⬡"
|
|
11
|
+
},
|
|
12
|
+
"compatibility": {
|
|
13
|
+
"eikon": ">=1 <2"
|
|
14
|
+
},
|
|
15
|
+
"legacy": {
|
|
16
|
+
"sourceFormat": "pre-launch .eikon draft",
|
|
17
|
+
"migration": "converted",
|
|
18
|
+
"notes": [
|
|
19
|
+
"moved legacy metadata: author, created, source_url"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"source": {
|
|
23
|
+
"base": "blobs/sha256/8c4dc411ca159253cc90fa31f5263799054592e6eaeb4e5c99881c8cac29e67b",
|
|
24
|
+
"states": {
|
|
25
|
+
"idle": {
|
|
26
|
+
"file": "blobs/sha256/481c010826d7cacb9c419455bd0f73d020f66492a1236b37e4e53353b7965902"
|
|
27
|
+
},
|
|
28
|
+
"listening": {
|
|
29
|
+
"file": "blobs/sha256/94f0f4f710c708f516128125142d5dce701f83558e9fad444c1bb376ee3c1fea"
|
|
30
|
+
},
|
|
31
|
+
"thinking": {
|
|
32
|
+
"file": "blobs/sha256/5ae0eb2e1889c72bed69144998acc6f80b9d11b67beffccd972842a9d6ed0f24"
|
|
33
|
+
},
|
|
34
|
+
"speaking": {
|
|
35
|
+
"file": "blobs/sha256/5c15fd3db3fba93b378eb5b23ab9ecf283e8fb5a08828f1393e91b323b65eab2"
|
|
36
|
+
},
|
|
37
|
+
"working": {
|
|
38
|
+
"file": "blobs/sha256/f63a864e84c4b4f672d6b02a4bcf610b2881fcf64166273b29a642fb76e00f09"
|
|
39
|
+
},
|
|
40
|
+
"error": {
|
|
41
|
+
"file": "blobs/sha256/5d1a1fa59ec9091d9c03d99728b15287ef58d397ea2c787a65c55519482683c8"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"entrypoints": {
|
|
46
|
+
"default": "blobs/sha256/b2685743b05ddf201920b69db58640d4fab644e637fa7d313c6dfa215fa41fb7"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
{
|
|
50
|
+
"path": "blobs/sha256/b2685743b05ddf201920b69db58640d4fab644e637fa7d313c6dfa215fa41fb7",
|
|
51
|
+
"role": "runtime",
|
|
52
|
+
"mediaType": "application/vnd.eikon.stream+jsonl",
|
|
53
|
+
"size": 1401439,
|
|
54
|
+
"digest": "sha256:b2685743b05ddf201920b69db58640d4fab644e637fa7d313c6dfa215fa41fb7"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"path": "blobs/sha256/8c4dc411ca159253cc90fa31f5263799054592e6eaeb4e5c99881c8cac29e67b",
|
|
58
|
+
"role": "source.base",
|
|
59
|
+
"mediaType": "image/png",
|
|
60
|
+
"size": 98644,
|
|
61
|
+
"digest": "sha256:8c4dc411ca159253cc90fa31f5263799054592e6eaeb4e5c99881c8cac29e67b"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"path": "blobs/sha256/481c010826d7cacb9c419455bd0f73d020f66492a1236b37e4e53353b7965902",
|
|
65
|
+
"role": "source.clip",
|
|
66
|
+
"mediaType": "video/mp4",
|
|
67
|
+
"size": 105789,
|
|
68
|
+
"digest": "sha256:481c010826d7cacb9c419455bd0f73d020f66492a1236b37e4e53353b7965902",
|
|
69
|
+
"signal": "state.idle"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"path": "blobs/sha256/94f0f4f710c708f516128125142d5dce701f83558e9fad444c1bb376ee3c1fea",
|
|
73
|
+
"role": "source.clip",
|
|
74
|
+
"mediaType": "video/mp4",
|
|
75
|
+
"size": 275110,
|
|
76
|
+
"digest": "sha256:94f0f4f710c708f516128125142d5dce701f83558e9fad444c1bb376ee3c1fea",
|
|
77
|
+
"signal": "state.listening"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"path": "blobs/sha256/5ae0eb2e1889c72bed69144998acc6f80b9d11b67beffccd972842a9d6ed0f24",
|
|
81
|
+
"role": "source.clip",
|
|
82
|
+
"mediaType": "video/mp4",
|
|
83
|
+
"size": 174520,
|
|
84
|
+
"digest": "sha256:5ae0eb2e1889c72bed69144998acc6f80b9d11b67beffccd972842a9d6ed0f24",
|
|
85
|
+
"signal": "state.thinking"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"path": "blobs/sha256/5c15fd3db3fba93b378eb5b23ab9ecf283e8fb5a08828f1393e91b323b65eab2",
|
|
89
|
+
"role": "source.clip",
|
|
90
|
+
"mediaType": "video/mp4",
|
|
91
|
+
"size": 96790,
|
|
92
|
+
"digest": "sha256:5c15fd3db3fba93b378eb5b23ab9ecf283e8fb5a08828f1393e91b323b65eab2",
|
|
93
|
+
"signal": "state.speaking"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"path": "blobs/sha256/f63a864e84c4b4f672d6b02a4bcf610b2881fcf64166273b29a642fb76e00f09",
|
|
97
|
+
"role": "source.clip",
|
|
98
|
+
"mediaType": "video/mp4",
|
|
99
|
+
"size": 160072,
|
|
100
|
+
"digest": "sha256:f63a864e84c4b4f672d6b02a4bcf610b2881fcf64166273b29a642fb76e00f09",
|
|
101
|
+
"signal": "state.working"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"path": "blobs/sha256/5d1a1fa59ec9091d9c03d99728b15287ef58d397ea2c787a65c55519482683c8",
|
|
105
|
+
"role": "source.clip",
|
|
106
|
+
"mediaType": "video/mp4",
|
|
107
|
+
"size": 168804,
|
|
108
|
+
"digest": "sha256:5d1a1fa59ec9091d9c03d99728b15287ef58d397ea2c787a65c55519482683c8",
|
|
109
|
+
"signal": "state.error"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"origin": {
|
|
113
|
+
"kind": "default-catalog",
|
|
114
|
+
"source": "https://eikon.liftaris.dev/packages/liftaris/nous/1.0.0.json",
|
|
115
|
+
"sourceKey": "registry:eikon.liftaris.dev:liftaris/nous@1.0.0",
|
|
116
|
+
"identityKey": "registry:eikon.liftaris.dev:liftaris/nous@1.0.0",
|
|
117
|
+
"packageUrl": "https://eikon.liftaris.dev/packages/liftaris/nous/1.0.0.json",
|
|
118
|
+
"trust": "verified"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{"type":"header","eikon":1,"id":"liftaris/
|
|
1
|
+
{"type":"header","eikon":1,"id":"liftaris/nous","version":"1.0.0","title":"nous","author":{"name":"kaio"},"size":{"cols":48,"rows":24},"defaultSignal":"state.idle","signals":{"state.idle":{"clip":"idle"},"state.listening":{"clip":"listening","fallback":"state.idle"},"state.thinking":{"clip":"thinking","fallback":"state.idle"},"state.speaking":{"clip":"speaking","fallback":"state.idle"},"state.working":{"clip":"working","fallback":"state.idle"},"state.error":{"clip":"error","fallback":"state.idle"}}}
|
|
2
2
|
{"type":"clip","name":"idle","fps":16,"frameCount":64,"loopFrom":0}
|
|
3
3
|
{"type":"frame","clip":"idle","index":0,"rows":["⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣠⣤⣤⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⣬⣥⣄⣀⠀⠉⠙⠻⣿⣿⣿⣿⣷⣶⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⡿⢦⡀⠀⠈⢿⣿⣿⣿⣿⣿⢿⡗⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⡰⣻⣿⣿⣿⢏⣿⣿⣿⣿⣿⣿⣿⡿⠙⠏⠀⠀⣮⡳⠀⠀⠈⢿⢿⠻⠿⡏⠁⠁⣸⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠌⠈⠉⢺⠻⢃⠊⠙⠛⢠⡀⢀⠙⠁⠁⠀⡘⣶⣷⣿⣷⣾⠀⠀⠈⣶⣆⣳⣶⣮⢔⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⡼⣴⢶⣤⣶⣾⣼⣿⣿⣿⣿⢿⣿⣿⣿⣾⣶⣿⣿⣿⣿⣿⣿⡇⣀⣠⣸⣿⣷⣻⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢯⣿⣚⣿⣿⣿⢿⣿⣿⣿⣿⣗⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⡘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⡿⠧⠻⠟⣻⠟⡓⠈⠛⠛⠛⠛⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣹⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠻⣿⡿⣿⣿⣉⣁⠀⠀⠀⠀⠸⢻⣿⡷⢦⡄⠀⠀⠀⢹⣿⣿⣿⣿⢟⣛⡻⣿⣿⣿⣯⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠈⠙⠊⢻⣏⢿⠇⠀⠀⠀⠀⠬⠿⠥⠊⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡼⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⣸⣯⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡾⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⣿⣇⠰⣄⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⡆⠣⠄⠈⠁⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣼⣿⣿⢹⣿⣇⠀⠀⠀⠀","⠀⠀⢠⠀⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⡏⢈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠄⣿⣿⡀⠀⠀⠀","⠀⠀⣟⠀⠀⠀⠀⣿⣿⣿⣿⣿⣦⣀⣀⣀⣀⣠⣄⡀⠀⠀⢸⣿⣿⣿⡾⠟⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⣹⣿⡇⠐⡄⠀","⠀⢀⣿⣦⣀⣠⣼⣿⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⣸⣿⣿⣯⡀⣀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⣿⣿⡇⠀⣷⠀","⠀⠘⣜⠿⣿⣿⠿⠋⣱⣿⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⡾⠋⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣣⣾⣿⣿⡇⢠⣿⠀","⠀⠀⠙⠿⣶⣤⣶⣾⣿⣿⢋⣿⣿⣿⣿⣿⣿⣿⣿⠛⢋⡠⢆⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢠⣿⠏⠀","⠀⠀⠀⠀⠀⠉⢯⣉⣉⣡⣾⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⢋⠝⠃⣀⣴⠟⠫⢛⣭⡿⠚⠋⠉⠁⠒⠫⣝⠻⣿⣿⣿⢟⣵⡿⠋⠀⠀","⠀⠀⠀⠀⠀⠀⠈⠛⠿⠿⠛⢁⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡶⠟⠉⠀⢀⣴⡟⠁⠀⠀⠀⠀⠀⠀⠀⠈⠳⣜⢿⡿⠟⠋⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⠿⣿⢯⡾⠋⠀⠀⢀⡔⠀⡾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠮⠅⠀⠀⠀⠀⠀⠀"]}
|
|
4
4
|
{"type":"frame","clip":"idle","index":1,"rows":["⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣠⣠⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⣤⣥⣤⣀⠀⠉⠉⠻⢿⣿⣿⣿⣷⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄⠀⠀⠙⢿⣿⣿⣿⣿⣿⣷⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⡿⢷⡀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣧⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⡠⣫⡿⣿⣿⢟⣾⣿⡟⣿⣿⣿⣿⣿⠎⠟⠀⠀⢴⡻⠄⠀⠀⢻⣿⠿⢿⣿⠃⠉⢠⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠔⠄⠀⠙⠳⠋⠎⠉⠚⢁⣄⣀⢸⠉⠁⠀⡈⢶⣾⣿⣷⣾⡀⠀⠀⢶⣦⡴⣦⣶⣂⣦⢿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⣸⣵⣦⣧⣶⣾⣿⣿⣿⣿⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⢀⣀⡸⣿⣿⣻⣿⣷⢾⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⢠⣷⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣏⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣌⣿⣰⢿⣿⣷⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⡜⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⣿⣿⣿⣿⣿⡃⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⠿⠇⠙⠛⡻⢟⣋⠉⠛⠛⠛⠛⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣹⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠙⢿⣟⢿⣿⣁⣐⠀⠀⠀⠀⠘⢻⣿⡷⢦⡄⠀⠀⠀⣸⣿⣿⣿⣿⠟⠛⠻⣿⣿⣿⣯⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠉⠃⢹⣏⢻⠇⠀⠀⠀⠀⠨⠽⠥⠊⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣹⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⢸⣏⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⣼⠇⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡾⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⣿⣇⠸⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⡆⠫⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢻⣿⡇⠀⠀⠀⠀","⠀⠀⡠⠀⠀⠀⠀⣸⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⠃⢘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠈⣿⣿⠀⠀⠀⠀","⠀⢠⣧⠀⠀⠀⢀⣿⣿⣿⣿⣿⣦⣀⣀⣀⣀⣠⣄⡀⠀⠀⣿⣿⣿⣯⡶⠟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⢹⣿⡇⢠⠀⠀","⠀⠈⣿⣶⣤⣤⣾⣿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⣿⣿⣿⣏⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢀⣿⣿⡇⠀⣧⠀","⠀⠘⣌⡻⠿⠿⠟⢋⣼⣿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡾⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣣⣾⣿⣿⡇⢰⣿⠀","⠀⠀⠘⠻⣷⣶⣾⣿⣿⡿⢳⣿⣿⣿⣿⣿⣿⣿⣿⠛⢋⡠⢆⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢠⣿⠇⠀","⠀⠀⠀⠀⠀⠈⣯⣉⣁⣴⣿⡿⣿⣿⣿⣿⣿⣿⣿⣧⡀⢋⠝⠃⣀⣴⠟⠻⢛⣭⡿⠚⠋⠉⠁⠒⠫⣙⠻⣿⣿⣿⡟⣱⣿⠋⠀⠀","⠀⠀⠀⠀⠀⠀⠈⠛⠛⠛⠋⣰⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡶⠟⠉⠀⢀⣴⠟⠁⠀⠀⠀⠀⠀⠀⠀⠈⠳⣜⢿⣿⠿⠋⠁⠀⠀⠀","⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⠿⣿⢯⡾⠋⠀⠀⢀⡔⢀⡾⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠺⠅⠀⠀⠀⠀⠀⠀"]}
|
|
@@ -1,17 +1,40 @@
|
|
|
1
|
-
"""Eikon
|
|
1
|
+
"""Eikon lifecycle plugin."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from .schemas import
|
|
6
|
-
|
|
5
|
+
from .schemas import (
|
|
6
|
+
EIKON_INSTALL_SCHEMA,
|
|
7
|
+
EIKON_LIST_SCHEMA,
|
|
8
|
+
EIKON_REMOVE_SCHEMA,
|
|
9
|
+
EIKON_SEARCH_SCHEMA,
|
|
10
|
+
EIKON_UPDATE_SCHEMA,
|
|
11
|
+
EIKON_USE_SCHEMA,
|
|
12
|
+
)
|
|
13
|
+
from .tools import (
|
|
14
|
+
_handle_eikon_install,
|
|
15
|
+
_handle_eikon_list,
|
|
16
|
+
_handle_eikon_remove,
|
|
17
|
+
_handle_eikon_search,
|
|
18
|
+
_handle_eikon_update,
|
|
19
|
+
_handle_eikon_use,
|
|
20
|
+
check_herm_available,
|
|
21
|
+
)
|
|
7
22
|
|
|
8
23
|
|
|
9
24
|
def register(ctx) -> None:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
for name, schema, handler in [
|
|
26
|
+
("eikon_install", EIKON_INSTALL_SCHEMA, _handle_eikon_install),
|
|
27
|
+
("eikon_search", EIKON_SEARCH_SCHEMA, _handle_eikon_search),
|
|
28
|
+
("eikon_list", EIKON_LIST_SCHEMA, _handle_eikon_list),
|
|
29
|
+
("eikon_use", EIKON_USE_SCHEMA, _handle_eikon_use),
|
|
30
|
+
("eikon_update", EIKON_UPDATE_SCHEMA, _handle_eikon_update),
|
|
31
|
+
("eikon_remove", EIKON_REMOVE_SCHEMA, _handle_eikon_remove),
|
|
32
|
+
]:
|
|
33
|
+
ctx.register_tool(
|
|
34
|
+
name=name,
|
|
35
|
+
toolset="eikon",
|
|
36
|
+
schema=schema,
|
|
37
|
+
handler=handler,
|
|
38
|
+
check_fn=check_herm_available,
|
|
39
|
+
emoji="⬡",
|
|
40
|
+
)
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
name: eikon
|
|
2
2
|
version: 1.0.0
|
|
3
|
-
description: "Herm eikon
|
|
3
|
+
description: "Herm eikon lifecycle tools. Lets Hermes chat search, install, activate, update, and remove terminal avatars through the existing `herm eikon` CLI path."
|
|
4
4
|
author: Liftaris
|
|
5
5
|
kind: standalone
|
|
6
6
|
provides_tools:
|
|
7
7
|
- eikon_install
|
|
8
|
+
- eikon_search
|
|
9
|
+
- eikon_list
|
|
10
|
+
- eikon_use
|
|
11
|
+
- eikon_update
|
|
12
|
+
- eikon_remove
|
|
@@ -7,7 +7,7 @@ EIKON_INSTALL_SCHEMA = {
|
|
|
7
7
|
"description": (
|
|
8
8
|
"Install a Herm eikon/avatar from the public catalog, a manifest URL, "
|
|
9
9
|
"a git repository, or a local directory. Uses `herm eikon install`; "
|
|
10
|
-
"
|
|
10
|
+
"set_active activates the installed avatar with `herm eikon use`."
|
|
11
11
|
),
|
|
12
12
|
"parameters": {
|
|
13
13
|
"type": "object",
|
|
@@ -32,10 +32,78 @@ EIKON_INSTALL_SCHEMA = {
|
|
|
32
32
|
},
|
|
33
33
|
"set_active": {
|
|
34
34
|
"type": "boolean",
|
|
35
|
-
"description": "
|
|
35
|
+
"description": "Activate the installed eikon after install. Default true.",
|
|
36
36
|
"default": True,
|
|
37
37
|
},
|
|
38
|
+
"active_ok": {
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"description": "Allow replacing the active eikon's backing package when installing over it.",
|
|
41
|
+
"default": False,
|
|
42
|
+
},
|
|
38
43
|
},
|
|
39
44
|
"required": ["source"],
|
|
40
45
|
},
|
|
41
46
|
}
|
|
47
|
+
|
|
48
|
+
EIKON_SEARCH_SCHEMA = {
|
|
49
|
+
"name": "eikon_search",
|
|
50
|
+
"description": "Search the Herm eikon marketplace/catalog via `herm eikon search --json`.",
|
|
51
|
+
"parameters": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"properties": {
|
|
54
|
+
"query": {"type": "string", "description": "Optional search query."},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
EIKON_LIST_SCHEMA = {
|
|
60
|
+
"name": "eikon_list",
|
|
61
|
+
"description": "List installed Herm eikons via `herm eikon list --json`.",
|
|
62
|
+
"parameters": {"type": "object", "properties": {}},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
EIKON_USE_SCHEMA = {
|
|
66
|
+
"name": "eikon_use",
|
|
67
|
+
"description": "Set an installed or bundled Herm eikon as active via `herm eikon use --json`.",
|
|
68
|
+
"parameters": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"name": {"type": "string", "description": "Installed or bundled eikon name."},
|
|
72
|
+
},
|
|
73
|
+
"required": ["name"],
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
EIKON_UPDATE_SCHEMA = {
|
|
78
|
+
"name": "eikon_update",
|
|
79
|
+
"description": "Update an installed Herm eikon from its recorded source via `herm eikon update --json`.",
|
|
80
|
+
"parameters": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"properties": {
|
|
83
|
+
"name": {"type": "string", "description": "Installed eikon name."},
|
|
84
|
+
"active_ok": {
|
|
85
|
+
"type": "boolean",
|
|
86
|
+
"description": "Allow updating the active avatar's backing package.",
|
|
87
|
+
"default": False,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
"required": ["name"],
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
EIKON_REMOVE_SCHEMA = {
|
|
95
|
+
"name": "eikon_remove",
|
|
96
|
+
"description": "Remove an installed Herm eikon via `herm eikon remove --json`.",
|
|
97
|
+
"parameters": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"properties": {
|
|
100
|
+
"name": {"type": "string", "description": "Installed eikon name."},
|
|
101
|
+
"active_ok": {
|
|
102
|
+
"type": "boolean",
|
|
103
|
+
"description": "Allow clearing the active avatar if this eikon is active.",
|
|
104
|
+
"default": False,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
"required": ["name"],
|
|
108
|
+
},
|
|
109
|
+
}
|
|
@@ -30,40 +30,96 @@ def check_herm_available() -> bool:
|
|
|
30
30
|
return shutil.which(binary) is not None
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def
|
|
34
|
-
source = str(args.get("source") or "").strip()
|
|
35
|
-
if not source:
|
|
36
|
-
return _json({"ok": False, "error": "source is required"})
|
|
37
|
-
|
|
33
|
+
def _run(parts: list[str], label: str, timeout: int = 120) -> dict[str, Any]:
|
|
38
34
|
binary = _herm_bin()
|
|
39
35
|
if not binary:
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
cmd = [binary, "eikon", "install", source, "--json"]
|
|
43
|
-
name = str(args.get("name") or "").strip()
|
|
44
|
-
if name:
|
|
45
|
-
cmd.extend(["--name", name])
|
|
46
|
-
if args.get("media") is False or args.get("no_source") is True:
|
|
47
|
-
cmd.append("--no-source")
|
|
48
|
-
if args.get("set_active") is False:
|
|
49
|
-
cmd.append("--no-use")
|
|
36
|
+
return {"ok": False, "error": "herm executable not found on PATH"}
|
|
50
37
|
|
|
51
38
|
try:
|
|
52
|
-
proc = subprocess.run(
|
|
39
|
+
proc = subprocess.run([binary, *parts], capture_output=True, text=True, timeout=timeout, check=False)
|
|
53
40
|
except FileNotFoundError:
|
|
54
|
-
return
|
|
41
|
+
return {"ok": False, "error": f"herm executable not found: {binary}"}
|
|
55
42
|
except subprocess.TimeoutExpired:
|
|
56
|
-
return
|
|
43
|
+
return {"ok": False, "error": f"herm eikon {label} timed out"}
|
|
57
44
|
|
|
58
45
|
stdout = (proc.stdout or "").strip()
|
|
59
46
|
stderr = (proc.stderr or "").strip()
|
|
60
47
|
if proc.returncode != 0:
|
|
61
48
|
detail = stderr or stdout or f"exit {proc.returncode}"
|
|
62
|
-
return
|
|
49
|
+
return {"ok": False, "error": f"herm eikon {label} failed: {detail}"}
|
|
63
50
|
|
|
64
51
|
line = next((ln for ln in reversed(stdout.splitlines()) if ln.strip()), "")
|
|
65
52
|
try:
|
|
66
53
|
payload = json.loads(line)
|
|
67
54
|
except json.JSONDecodeError:
|
|
68
|
-
return
|
|
69
|
-
|
|
55
|
+
return {"ok": False, "error": f"herm eikon {label} returned non-JSON output", "output": stdout}
|
|
56
|
+
if isinstance(payload, dict):
|
|
57
|
+
return payload
|
|
58
|
+
return {"ok": True, "result": payload}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _name(args: dict[str, Any]) -> str:
|
|
62
|
+
return str(args.get("name") or "").strip()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _handle_eikon_install(args: dict[str, Any], **_: Any) -> str:
|
|
66
|
+
source = str(args.get("source") or "").strip()
|
|
67
|
+
if not source:
|
|
68
|
+
return _json({"ok": False, "error": "source is required"})
|
|
69
|
+
|
|
70
|
+
cmd = ["eikon", "install", source, "--json"]
|
|
71
|
+
name = _name(args)
|
|
72
|
+
if name:
|
|
73
|
+
cmd.extend(["--name", name])
|
|
74
|
+
if args.get("media") is False or args.get("no_source") is True:
|
|
75
|
+
cmd.append("--no-source")
|
|
76
|
+
if args.get("active_ok") is True:
|
|
77
|
+
cmd.append("--active-ok")
|
|
78
|
+
|
|
79
|
+
payload = _run(cmd, "install")
|
|
80
|
+
if not payload.get("ok") or args.get("set_active") is False:
|
|
81
|
+
return _json(payload)
|
|
82
|
+
|
|
83
|
+
active = _run(["eikon", "use", str(payload.get("name") or source), "--json"], "use")
|
|
84
|
+
if not active.get("ok"):
|
|
85
|
+
return _json({"ok": False, "installed": payload, "error": f"installed but activation failed: {active.get('error', 'unknown error')}"})
|
|
86
|
+
return _json({**payload, "active": active.get("active")})
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _handle_eikon_search(args: dict[str, Any], **_: Any) -> str:
|
|
90
|
+
query = str(args.get("query") or "").strip()
|
|
91
|
+
cmd = ["eikon", "search"]
|
|
92
|
+
if query:
|
|
93
|
+
cmd.append(query)
|
|
94
|
+
return _json(_run([*cmd, "--json"], "search"))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _handle_eikon_list(args: dict[str, Any], **_: Any) -> str:
|
|
98
|
+
return _json(_run(["eikon", "list", "--json"], "list"))
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _handle_eikon_use(args: dict[str, Any], **_: Any) -> str:
|
|
102
|
+
name = _name(args)
|
|
103
|
+
if not name:
|
|
104
|
+
return _json({"ok": False, "error": "name is required"})
|
|
105
|
+
return _json(_run(["eikon", "use", name, "--json"], "use"))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _handle_eikon_update(args: dict[str, Any], **_: Any) -> str:
|
|
109
|
+
name = _name(args)
|
|
110
|
+
if not name:
|
|
111
|
+
return _json({"ok": False, "error": "name is required"})
|
|
112
|
+
cmd = ["eikon", "update", name, "--json"]
|
|
113
|
+
if args.get("active_ok") is True:
|
|
114
|
+
cmd.append("--active-ok")
|
|
115
|
+
return _json(_run(cmd, "update"))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _handle_eikon_remove(args: dict[str, Any], **_: Any) -> str:
|
|
119
|
+
name = _name(args)
|
|
120
|
+
if not name:
|
|
121
|
+
return _json({"ok": False, "error": "name is required"})
|
|
122
|
+
cmd = ["eikon", "remove", name, "--json"]
|
|
123
|
+
if args.get("active_ok") is True:
|
|
124
|
+
cmd.append("--active-ok")
|
|
125
|
+
return _json(_run(cmd, "remove"))
|
|
@@ -9,7 +9,7 @@ related_skills: [eikon-create]
|
|
|
9
9
|
An eikon is a 48×24 monochrome text avatar. It lives on disk as:
|
|
10
10
|
|
|
11
11
|
~/.hermes/eikons/<name>/
|
|
12
|
-
<name>.eikon packed NDJSON — written by Studio on Ctrl+S
|
|
12
|
+
<name>.eikon packed NDJSON — written by Studio on Ctrl+S / Ctrl+U
|
|
13
13
|
studio.json Studio's workspace state
|
|
14
14
|
source/ base.<ext>, <state>.<ext>
|
|
15
15
|
|
|
@@ -25,7 +25,8 @@ Herm's built-in **Eikon** tab (Gallery / Studio / Marketplace). Tell the user:
|
|
|
25
25
|
- `input` section → contrast / invert / flip (pixel-domain, shared)
|
|
26
26
|
- `<rasterizer>` section → symbols / fill / dither (glyph-domain)
|
|
27
27
|
- Preview pane → wheel pans, Ctrl+wheel zooms, Shift+wheel pans X
|
|
28
|
-
- **Ctrl+S** bakes all six states
|
|
28
|
+
- **Ctrl+S** bakes all six states without changing the active avatar
|
|
29
|
+
- **Ctrl+U** bakes all six states and uses it as the active avatar
|
|
29
30
|
|
|
30
31
|
## What makes a good source
|
|
31
32
|
|
|
@@ -40,11 +41,44 @@ everything.
|
|
|
40
41
|
| "make me an eikon of X" | Load `eikon-create` and follow it. |
|
|
41
42
|
| drops an image path | `cp` it to `~/.hermes/eikons/<name>/source/base.<ext>` → "Eikon tab, pick <name>". |
|
|
42
43
|
| "edit my <name> eikon" | "Eikon tab → `eikon` row → <name>." |
|
|
43
|
-
| "install/shared marketplace eikon" | "Eikon tab → Marketplace", or `/marketplace`. |
|
|
44
|
+
| "install/shared marketplace eikon" | "Eikon tab → Marketplace", or `/marketplace`. Install, then Use when ready. |
|
|
45
|
+
| "install from GitHub" | "Eikon tab → New… → inspect/install", or `herm eikon install github.com/user/repo/eikon-name`. |
|
|
44
46
|
| "too dark / washed out" | "invert toggle, then contrast slider — under `input`." |
|
|
45
47
|
| "off-center / too small" | "Ctrl+wheel to zoom, wheel/drag to pan on the preview." |
|
|
46
48
|
| "make it move" | `eikon-create` §5 (video), or Studio's `source` → Generate video…. |
|
|
47
49
|
|
|
50
|
+
## Install and manage shared eikons
|
|
51
|
+
|
|
52
|
+
For catalog eikons, use **Eikon → Marketplace**. Rows show source,
|
|
53
|
+
compatibility, and trust (`Verified`, `Unverified`, or `Mismatch`).
|
|
54
|
+
Marketplace installs fetch built package artifacts and do not clone creator
|
|
55
|
+
repos.
|
|
56
|
+
|
|
57
|
+
For direct sharing, use `github.com/user/repo/eikon-name` for a multi-eikon
|
|
58
|
+
GitHub catalog repo, `github.com/user/repo` for a single-package repo, or a
|
|
59
|
+
local package directory. Private GitHub repos use normal git authentication.
|
|
60
|
+
|
|
61
|
+
The local lifecycle is explicit:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
herm eikon search [query]
|
|
65
|
+
herm eikon inspect <name|github.com/user/repo/eikon-name|dir>
|
|
66
|
+
herm eikon install <name|github.com/user/repo/eikon-name|dir>
|
|
67
|
+
herm eikon use <name>
|
|
68
|
+
herm eikon info <name>
|
|
69
|
+
herm eikon update <name> --active-ok
|
|
70
|
+
herm eikon remove <name> --active-ok
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`install` never activates. `use` activates. Updating or removing the active
|
|
74
|
+
eikon requires explicit acknowledgement because it changes or clears the active
|
|
75
|
+
avatar.
|
|
76
|
+
|
|
77
|
+
Creators share through normal GitHub repositories. Use upstream `eikon pack`,
|
|
78
|
+
`eikon index`, and `eikon manifest` to prepare repo artifacts. `eikon publish`
|
|
79
|
+
is a GitHub PR contribution helper for the configured/default catalog repo, not
|
|
80
|
+
a hosted marketplace account or upload flow.
|
|
81
|
+
|
|
48
82
|
## Quick poster
|
|
49
83
|
|
|
50
84
|
To show a candidate in chat without Studio:
|
|
@@ -16,6 +16,8 @@ deliverable is one or more images/videos under
|
|
|
16
16
|
named so Studio resolves them: `base.*` for the default pose, `<state>.*`
|
|
17
17
|
for per-state overrides (`idle listening thinking speaking working
|
|
18
18
|
error`). Extensions: `png jpg jpeg webp gif bmp mp4 webm mov mkv`.
|
|
19
|
+
Studio bakes with **Ctrl+S** without activation; **Ctrl+U** bakes and uses the
|
|
20
|
+
eikon as the active avatar.
|
|
19
21
|
|
|
20
22
|
## What survives rasterization
|
|
21
23
|
|
|
@@ -140,7 +142,8 @@ Adopt as `<state>.mp4` (or `base.mp4` for an animated idle).
|
|
|
140
142
|
Once source files are in place:
|
|
141
143
|
|
|
142
144
|
> Open the **Eikon** tab → `eikon` row → **<name>**. Tune zoom /
|
|
143
|
-
> contrast / invert / symbols there, then **Ctrl+S** to bake
|
|
145
|
+
> contrast / invert / symbols there, then **Ctrl+S** to bake or **Ctrl+U**
|
|
146
|
+
> to bake and use.
|
|
144
147
|
|
|
145
148
|
Stop there. Studio writes `<name>.eikon` and `studio.json`.
|
|
146
149
|
|