{"_id":"@0xpv/gochi","_rev":"3-5f88fb7870562f5d007d3e4bb08a4c93","name":"@0xpv/gochi","dist-tags":{"latest":"1.1.0"},"versions":{"0.1.0":{"name":"@0xpv/gochi","version":"0.1.0","keywords":["tamagotchi","esp32","esp32-c3","oled","ssd1306","serial","cli","desk-pet"],"license":"MIT","_id":"@0xpv/gochi@0.1.0","maintainers":[{"name":"0xpv","email":"prathamistesting@gmail.com"}],"homepage":"https://github.com/devfolioco/gochi#readme","bugs":{"url":"https://github.com/devfolioco/gochi/issues"},"bin":{"gochi":"bin/gochi.js"},"dist":{"shasum":"5631436a1e34dc3118f937acac6d47ce6dfa7fc0","tarball":"https://registry.npmjs.org/@0xpv/gochi/-/gochi-0.1.0.tgz","fileCount":16,"integrity":"sha512-JRry8kXyxBlKdc/XY7LVuCr9sH3ZhYLix2R3ynnThXgUT47/Tl1VuOgaS6BRuTpoAL4vBjhCP/n2PBwH30aMzA==","signatures":[{"sig":"MEUCIQD/Ke3I9xwwhKyYBWc9cJuPILDMzEkFUnJ1KOz6ExSdEwIgZuk1Cc5eytfMwGBjWme1RWIsYojyeuRQ+5JTzXT31KE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70817},"type":"module","engines":{"node":">=18.0.0"},"gitHead":"d69136ab93bed2a80d147e64a7d5be7aad8c9ab5","scripts":{"start":"tsx src/cli.ts","server":"tsx src/cli.ts server run"},"_npmUser":{"name":"0xpv","email":"prathamistesting@gmail.com"},"repository":{"url":"git+https://github.com/devfolioco/gochi.git","type":"git","directory":"cli"},"_npmVersion":"11.13.0","description":"CLI + local HTTP server for the Tamagotchi desk pet.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"tsx":"^4.22.3","sharp":"0.34.5","commander":"^12.1.0","serialport":"^12.0.0","@inquirer/prompts":"^8.4.3","@serialport/parser-readline":"^12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/gochi_0.1.0_1779980516569_0.7514395942267129","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@0xpv/gochi","version":"1.0.0","keywords":["tamagotchi","esp32","esp32-c3","oled","ssd1306","serial","cli","desk-pet"],"license":"MIT","_id":"@0xpv/gochi@1.0.0","maintainers":[{"name":"0xpv","email":"prathamistesting@gmail.com"}],"homepage":"https://github.com/devfolioco/gochi#readme","bugs":{"url":"https://github.com/devfolioco/gochi/issues"},"bin":{"gochi":"bin/gochi.js"},"dist":{"shasum":"d28b7298daad1b80b327666261711558272ad4de","tarball":"https://registry.npmjs.org/@0xpv/gochi/-/gochi-1.0.0.tgz","fileCount":17,"integrity":"sha512-DxmhC2YcMOvgJeREhzlKOZEPlE4UKS+K85gYMSc2p+5MNEO/vR+N47EHejjqVDLZjDoYYJ9C4p5l50F6A21BxQ==","signatures":[{"sig":"MEQCIF5mkO3UBA3dgybptCWSf+m8PWiCpXLKgMRQpTGHh1LfAiA2YHYd8zcIWy8o78nlMWyHVCY6J5MWiGWQ+3LD7AV2Ow==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89804},"type":"module","engines":{"node":">=18.0.0"},"gitHead":"ec0b548ee18bb2688c420a3e2e7024a595bd7d7d","scripts":{"start":"tsx src/cli.ts","server":"tsx src/cli.ts server run"},"_npmUser":{"name":"0xpv","email":"prathamistesting@gmail.com"},"repository":{"url":"git+https://github.com/devfolioco/gochi.git","type":"git","directory":"cli"},"_npmVersion":"11.13.0","description":"CLI + local HTTP server for the Tamagotchi desk pet.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"tsx":"^4.22.3","sharp":"0.34.5","commander":"^12.1.0","serialport":"^12.0.0","@inquirer/prompts":"^8.4.3","@serialport/parser-readline":"^12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/gochi_1.0.0_1780318621079_0.5725080291921338","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@0xpv/gochi","version":"1.1.0","description":"CLI + local HTTP server for the Tamagotchi desk pet.","type":"module","license":"MIT","keywords":["tamagotchi","esp32","esp32-c3","oled","ssd1306","serial","cli","desk-pet"],"bin":{"gochi":"bin/gochi.js"},"repository":{"type":"git","url":"git+https://github.com/devfolioco/gochi.git","directory":"cli"},"homepage":"https://github.com/devfolioco/gochi#readme","bugs":{"url":"https://github.com/devfolioco/gochi/issues"},"publishConfig":{"access":"public"},"scripts":{"start":"tsx src/cli.ts","server":"tsx src/cli.ts server run"},"dependencies":{"@inquirer/prompts":"^8.4.3","@serialport/parser-readline":"^12.0.0","commander":"^12.1.0","serialport":"^12.0.0","sharp":"0.34.5","tsx":"^4.22.3"},"engines":{"node":">=18.0.0"},"devDependencies":{"@types/node":"^25.9.1"},"gitHead":"72a1e2627858e3bfcd3d053c38e55b70820f7c1f","_id":"@0xpv/gochi@1.1.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-q+03D4AbSU62K+KM+yT9wJDLeXVXTZDVQXeCZQF+ANbRgS9Mm97ng7A3/1Degnz0F9zrAWdRc9Zyyf96yx/xrQ==","shasum":"c19651c7cbbc4c7f8702cd30709b0d3b3a8df983","tarball":"https://registry.npmjs.org/@0xpv/gochi/-/gochi-1.1.0.tgz","fileCount":17,"unpackedSize":92515,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD30ChkGcK3pBnC7xvLLIh+nuyfgSeJhTU3+e8oct8DWQIgI7m44ob++wM4hHota5DntTeu40/vMFLBUmNL//QOtM4="}]},"_npmUser":{"name":"0xpv","email":"prathamistesting@gmail.com"},"directories":{},"maintainers":[{"name":"0xpv","email":"prathamistesting@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/gochi_1.1.0_1780324768423_0.7524980339039056"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-28T15:01:56.424Z","modified":"2026-06-01T14:39:28.702Z","0.1.0":"2026-05-28T15:01:56.747Z","1.0.0":"2026-06-01T12:57:01.231Z","1.1.0":"2026-06-01T14:39:28.594Z"},"bugs":{"url":"https://github.com/devfolioco/gochi/issues"},"license":"MIT","homepage":"https://github.com/devfolioco/gochi#readme","keywords":["tamagotchi","esp32","esp32-c3","oled","ssd1306","serial","cli","desk-pet"],"repository":{"type":"git","url":"git+https://github.com/devfolioco/gochi.git","directory":"cli"},"description":"CLI + local HTTP server for the Tamagotchi desk pet.","maintainers":[{"name":"0xpv","email":"prathamistesting@gmail.com"}],"readme":"# Tamagotchi CLI\n\nA Node CLI for driving the [Tamagotchi firmware](../firmware/) over USB\nserial, with an optional HTTP frontend for non-CLI clients.\nTypeScript sources are loaded under Node via [`tsx`](https://tsx.is) —\n`serialport`'s native module hits an unsupported libuv function under\nBun ([oven-sh/bun#18546](https://github.com/oven-sh/bun/issues/18546)),\nso Node owns the runtime. (Bun is fine for `install`/`link`.)\n\nThe CLI is a thin client. The real work happens in two long-lived\npieces:\n\n- **Daemon** — owns the USB serial port, listens on a Unix domain\n  socket (`~/.tamagotchi/daemon.sock`). Required. The CLI talks to it\n  directly.\n- **HTTP frontend** — optional TCP listener on `:7474` that\n  reverse-proxies to the daemon. Useful for `curl`, AI agents, web\n  UIs, or anything that's easier with HTTP than a Unix socket.\n\n`gochi setup` installs both as platform-native auto-start jobs that\ncome up at login:\n\n| Platform | Service backend             |\n| -------- | --------------------------- |\n| macOS    | `launchctl` LaunchAgents    |\n| Linux    | `systemctl --user` units    |\n| Windows  | Task Scheduler logon tasks  |\n\n**All command endpoints return HTTP 200** — even when the pet is\nunplugged — so agents see a steady, calm API and never see error codes\nfor a missing device. The `connected` flag in the body signals state.\n\n## Install\n\n```sh\nnpm i -g @0xpv/gochi\ngochi setup           # one-time: installs daemon + HTTP frontend\n```\n\nConfirm:\n\n```sh\ngochi daemon status   # daemon launchd + socket\ngochi health          # daemon-reported device state\n```\n\nLocal dev (no npm publish):\n\n```sh\ncd cli\nbun install\nbun link            # registers `gochi` globally\ngochi setup\n```\n\n## CLI\n\n```sh\ngochi --version\ngochi --help\n\n# faces — name it, or omit to pick from an interactive menu\ngochi face happy\ngochi face                # opens a select with all 12 faces\ngochi mood playful\ngochi mood                # opens a select with all 5 moods\n\n# text\ngochi text hello there    # extra args are joined\n\n# image — auto-resized to 128x64, dithered to 1-bit\ngochi image ./logo.png\ngochi image ./photo.jpg --no-dither -t 96   # plain threshold\ngochi image ./icon.png --invert --bg white  # invert + white letterbox\n\n# queries\ngochi get state\ngochi get fps\ngochi list faces\ngochi ping\ngochi health\n\n# enumerate every device on both I2C buses (handy when wiring a sensor)\ngochi i2c\n\n# interactive hardware self-test — picks a component from a menu,\n# asks y/n after each, drops troubleshooting tips on 'no'.\ngochi test               # menu: serial / OLED / buzzer / IMU / all\ngochi test oled          # jump straight to one component\ngochi test imu           # lift + shake the device, verify the face reacts\ngochi test all           # run them all in order\n```\n\nFaces: `neutral happy sad sleepy excited surprised angry blink love sexy shy dead`.\nMoods: `content playful grumpy sleepy affectionate`.\n\nThe CLI talks to the daemon over `~/.tamagotchi/daemon.sock` by default.\nSet `GOCHI_URL=http://host:port` to point it at a remote daemon's\nHTTP frontend instead.\n\n## Daemon\n\nThe daemon is the only process that holds the serial port. It's\nhotplug-aware: it polls the OS port list and only opens devices that\nadvertise the Espressif USB VID (`303a`), so plugging in an unrelated\nUSB-serial board (an Arduino, a different ESP) won't get probed or\nreset.\n\n```sh\ngochi daemon status   # plist + socket + connected device\ngochi daemon run      # foreground (used by launchd; rare for users)\n```\n\n### Releasing the port temporarily\n\n`gochi stop` tells the daemon to drop the serial port without\nshutting itself down. Use it before any tool that needs exclusive\naccess to `/dev/cu.usbmodem*` — most commonly `arduino-cli upload`.\n\n```sh\ngochi stop            # release the port\n# ...flash firmware, run a monitor, whatever...\ngochi start           # daemon reconnects on the next ~1.5s tick\n```\n\nThe firmware Makefile wraps `make flash` with this automatically, so\nyou don't normally type these by hand.\n\n### Picking up daemon code changes\n\nThe daemon is long-lived — it only restarts at login. If you edit\n`daemon.ts` (or any module it imports), the running process keeps\nserving the old code. `gochi kill` terminates it and lets the platform\nservice unit auto-respawn a fresh instance:\n\n```sh\ngochi kill            # SIGTERM the daemon; launchd/systemd brings it back\n```\n\nYou'll see `daemon killed; launchd is respawning it…` and within a\nsecond the new process is serving any newly-added endpoints.\n\n## HTTP frontend (optional)\n\nEnabled by default after `setup`. Turn it off if you don't need a TCP\nlistener on your machine:\n\n```sh\ngochi server status    # is the HTTP frontend running?\ngochi server disable   # turn it off (persists across reboots)\ngochi server enable    # bring it back\ngochi server run       # foreground (used by launchd)\n```\n\nDefault port: **7474**. Override with `GOCHI_PORT`.\n\n### HTTP API\n\nAll responses are JSON. `GET /health` is the only endpoint that lets\nyou know whether the pet is connected; **every command endpoint\nreturns 200 either way** — when offline, the response is\n`{\"ok\": true, \"connected\": false, \"message\": \"device offline; ...\"}`.\n\n| Method | Path     | Body                 | Sends to device |\n| ------ | -------- | -------------------- | --------------- |\n| GET    | /health  | —                    | (none)          |\n| POST   | /face    | `{\"name\":\"...\"}`     | `SHOW face …`   |\n| POST   | /text    | `{\"text\":\"...\"}`     | `SHOW text …`   |\n| POST   | /image   | `{\"data\":\"<b64>\"}`   | `SHOW image …` (128×64 1bpp, MSB-first) |\n| POST   | /mood    | `{\"name\":\"...\"}`     | `SET mood …`    |\n| GET    | /state   | —                    | `GET state`     |\n| GET    | /fps     | —                    | `GET fps`       |\n| GET    | /faces   | —                    | `LIST faces`    |\n| POST   | /ping    | —                    | `PING`          |\n\nQuick check (HTTP frontend must be enabled):\n\n```sh\ncurl http://localhost:7474/health\ncurl -X POST http://localhost:7474/face -H 'content-type: application/json' -d '{\"name\":\"happy\"}'\ncurl http://localhost:7474/state\n```\n\n## How it finds the pet\n\nThe daemon polls `SerialPort.list()` every ~1.5 s, filters to\nEspressif's VID (`303a`), and opens any newly-arrived matching port.\nUnplug the pet and the daemon notices on the next tick; plug it back in\nand it reconnects within ~1.5 s. The daemon never opens non-Espressif\nports, so unrelated USB-serial devices stay untouched.\n\n## Layout\n\n```\ncli/\n  bin/gochi.js            Node wrapper — spawns `node tsx src/cli.ts ...`\n  src/cli.ts              CLI dispatcher (commander)\n  src/transport.ts        wraps a serial port with the pet's protocol\n  src/discovery.ts        hotplug watcher (VID-filtered SerialPort.list polling)\n  src/daemon.ts           the UDS daemon, owns the serial port\n  src/server.ts           optional TCP HTTP reverse-proxy to the daemon\n  src/ipc.ts              shared UDS paths + HTTP-over-UDS helpers\n  src/service/            setup / enable / disable / status, per-platform\n    index.ts                platform dispatcher\n    common.ts               shared helpers (path resolution, health checks)\n    darwin.ts               macOS launchd backend\n    linux.ts                systemd --user backend\n    windows.ts              Task Scheduler backend\n  src/client.ts           CLI's transport (UDS by default, TCP if GOCHI_URL set)\n  src/image.ts            PNG/JPG → 128×64 1bpp (dither + MSB-pack)\n```\n\n## Notes\n\n- Auto-start is supported on macOS (launchd), Linux (`systemctl --user`),\n  and Windows (Task Scheduler). On Linux, services stop when you log\n  out unless you run `sudo loginctl enable-linger $USER` — `setup`\n  prints a hint if lingering isn't on. If your environment can't host\n  one of these (minimal container, WSL1, etc.), run `gochi daemon\n  run` (and optionally `gochi server run`) in a terminal manually.\n- The daemon is the only thing that holds the serial port — running\n  `arduino-cli monitor` or the Arduino IDE at the same time will fight\n  for it. Stop one of them.\n- Mood lives in firmware RAM (resets to `content` on reboot).\n- Upgrading from a pre-`setup` install: `gochi setup` will tear\n  down the legacy `com.tamagotchi.server` plist for you.\n","readmeFilename":"README.md"}