Single-commit clean baseline after security scrub of niche-tells, project codenames, internal jargon, and contributor-email leaks. Contents: - 100 Rust crates (_primitives/_rust/) - 37 agent manifests (_manifests/) + generated specs (_generated/) - 67 user-invocable skills (skills/) - 33 hooks (hooks/) - Composition blocks (_blocks/) - Documentation (docs/, README.md) - TS adapter packages (_ts_packages/) - Assembler (_assembler/) - Roles (_roles/) - Templates (_templates/) - Forgejo CI (.forgejo/) Author: Denis Parfionovich <info@greendragon.info> License: see LICENSE.
5.3 KiB
Phase 4 — Emit
Compose the TOML from Phase 1-3 variables, ensure a keypair exists, write
~/.claude/pet/<user_id>.toml, display a summary, suggest next steps.
4a — User ID (keygen if needed)
Check whether a keypair already exists:
kei-pet keygen --status 2>/dev/null
Expected outputs:
keypair exists, user_id=<short-hash>→ reuse; setUSER_IDto the hash, setKEYGEN_ACTION = "reused existing"no keypairOR non-zero exit → create one:
kei-pet keygen --create
Capture the new user_id short-hash from stdout. Set USER_ID to that
hash, set KEYGEN_ACTION = "newly created".
If kei-pet keygen --create fails (non-zero exit, no hash in stdout) →
STOP and emit 3 constructive paths:
- (A) check that the
kei-petbinary is on$PATH; point user toinstall.sh --profile=dev - (B) invoke the raw primitive at
_primitives/_rust/kei-pet/target/release/kei-pet keygen --create - (C) manually set
USER_ID = "anonymous"for a one-off local pet; warn that this pet will not be portable across machines
Never silently fall through without a USER_ID.
4b — Compose TOML in memory
Build the TOML string exactly matching the schema in
_primitives/_rust/kei-pet/examples/minimal.toml. Use these variable
substitutions (all gathered in Phases 1-3 unless noted):
# Pet manifest for <PET_NAME> (owner <USER_NAME>, user_id <USER_ID>)
# Generated by /pet-init on <ISO8601-UTC-NOW>.
schema = 1
[identity]
pet_name = "<PET_NAME>"
user_name = "<USER_NAME>"
addressing = "<ADDRESSING>"
languages = [<comma-separated-quoted-LANGUAGES>]
[voice]
tone_primary = "<TONE_PRIMARY>"
tone_secondary = [<comma-separated-quoted-TONE_SECONDARY>]
humor_style = "<HUMOR_STYLE>"
humor_frequency = "<HUMOR_FREQUENCY>"
[edge]
profanity = "<PROFANITY>"
profanity_languages = []
directness = "<DIRECTNESS>"
initiative = "<INITIATIVE>"
[forbidden]
topics = [<comma-separated-quoted-FORBIDDEN_TOPICS>]
tone_patterns = []
[meta]
schema_version_written_by = "kei-pet 0.1.0"
created_at = "<ISO8601-UTC-NOW>"
last_tuned = "<ISO8601-UTC-NOW>"
tune_count = 0
String escaping rules inside double-quoted TOML values:
- escape
\→\\ - escape
"→\" - reject control chars other than TAB (should never appear; guard)
Timestamps: emit current UTC time in RFC 3339 with Z suffix, e.g.
2026-04-23T12:30:00Z. created_at and last_tuned are equal on first
init.
4c — Write the file
Target path: ~/.claude/pet/<USER_ID>.toml (absolute: expand ~ to $HOME).
mkdir -p "$HOME/.claude/pet"
Then write the composed TOML to $HOME/.claude/pet/<USER_ID>.toml. Use
the Write tool with the absolute path — do NOT echo TOML through shell
(quoting hazard).
If the file already exists at that path (re-run of /pet-init for the
same user_id), rename the existing file to
~/.claude/pet/<USER_ID>.toml.bak-<ISO8601-UTC-NOW> BEFORE writing the
new one. Tell the user: Previous pet.toml backed up to <bak-path>.
4d — Validate (best-effort)
Attempt a schema validation via the primitive:
kei-pet validate --pet "$HOME/.claude/pet/<USER_ID>.toml"
- exit 0 → good; proceed
- non-zero → emit the validator's stderr verbatim, keep the file on disk
(the user can re-run
/pet-initto fix), setVALIDATION = "FAILED" - command not found → set
VALIDATION = "SKIPPED (kei-pet not on PATH)"
4e — Summary table + next steps
Emit a plain-text summary (NOT AskUserQuestion — this is the closing message):
=== PET-INIT REPORT ===
Pet name: <PET_NAME>
Addressed by: <USER_NAME> via <ADDRESSING>
Languages: <LANGUAGES joined with comma-space>
Voice: <TONE_PRIMARY> (+ <TONE_SECONDARY or "no secondary">)
Humor: <HUMOR_STYLE> @ <HUMOR_FREQUENCY>
Edge: <DIRECTNESS> / <INITIATIVE> / profanity=<PROFANITY>
Forbidden: <FORBIDDEN_TOPICS joined with comma-space, or "(none)">
File: ~/.claude/pet/<USER_ID>.toml
Keygen: <KEYGEN_ACTION>
Validation: <PASSED | FAILED | SKIPPED>
Next:
/pet-chat
kei-pet render --pet ~/.claude/pet/<USER_ID>.toml
Verify-criterion
USER_IDis a non-empty short-hash OR the documented"anonymous"fallback (only via constructive path C in 4a)~/.claude/pet/<USER_ID>.tomlexists on disk and matches the composed TOML byte-for-byte- If a prior file existed, a
.bak-<ts>backup exists alongside it - Summary table is emitted with all 10 rows filled (no placeholders left)
kei-pet validatewas attempted; its verdict is surfaced
Failure modes (constructive paths)
If Write fails (permission denied, read-only filesystem, disk full):
- (A) fall back to
~/Desktop/<USER_ID>.tomland tell the user to move the file manually - (B) print the full TOML to stdout so the user can paste it anywhere
- (C) invite the user to re-run
/pet-initafter fixing the underlying disk/permission issue
If kei-pet validate reports a schema violation that the wizard could
not anticipate (schema drift between this skill and the binary):
- (A) keep the file; tell the user the specific validator error
- (B) suggest
kei-pet migrate --pet <path>if the primitive ships one - (C) open an issue link to the KeiSeiKit repo for schema-drift reports
Never silently succeed while validation is failing.