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.
167 lines
5.3 KiB
Markdown
167 lines
5.3 KiB
Markdown
# 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:
|
|
|
|
```bash
|
|
kei-pet keygen --status 2>/dev/null
|
|
```
|
|
|
|
Expected outputs:
|
|
|
|
- `keypair exists, user_id=<short-hash>` → reuse; set `USER_ID` to the hash,
|
|
set `KEYGEN_ACTION = "reused existing"`
|
|
- `no keypair` OR non-zero exit → create one:
|
|
|
|
```bash
|
|
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-pet` binary is on `$PATH`; point user to
|
|
`install.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):
|
|
|
|
```toml
|
|
# 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`).
|
|
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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-init` to fix), set `VALIDATION = "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_ID` is a non-empty short-hash OR the documented `"anonymous"`
|
|
fallback (only via constructive path C in 4a)
|
|
- `~/.claude/pet/<USER_ID>.toml` exists 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 validate` was 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>.toml` and 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-init` after 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.
|