claude-pet 2.0.0

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.

Potentially problematic release.


This version of claude-pet might be problematic. Click here for more details.

Files changed (133) hide show
  1. package/.claude/commands/feed.md +28 -0
  2. package/.claude/commands/name.md +28 -0
  3. package/.claude/commands/pet.md +29 -0
  4. package/.claude/commands/play.md +29 -0
  5. package/.claude/settings.local.json +41 -0
  6. package/.github/workflows/AGENTS.md +60 -0
  7. package/.github/workflows/build.yml +87 -0
  8. package/AGENTS.md +66 -0
  9. package/LICENSE +15 -0
  10. package/README.md +292 -0
  11. package/bin/claude-pet.js +42 -0
  12. package/build/AGENTS.md +50 -0
  13. package/build/dmg-background.png +0 -0
  14. package/build/entitlements.mac.plist +14 -0
  15. package/build/icon.ico +0 -0
  16. package/build/icon.png +0 -0
  17. package/build/installerHeader.bmp +0 -0
  18. package/build/installerSidebar.bmp +0 -0
  19. package/build/tray-icon.png +0 -0
  20. package/dist/main/core/badge-manager.js +49 -0
  21. package/dist/main/core/badge-registry.js +72 -0
  22. package/dist/main/core/badge-triggers.js +45 -0
  23. package/dist/main/core/contextual-messages.js +372 -0
  24. package/dist/main/core/messages.js +440 -0
  25. package/dist/main/core/mood-engine.js +145 -0
  26. package/dist/main/core/pet-messages.js +612 -0
  27. package/dist/main/core/pet-state-engine.js +232 -0
  28. package/dist/main/core/quote-collection.js +60 -0
  29. package/dist/main/core/quote-registry.js +175 -0
  30. package/dist/main/core/quote-triggers.js +62 -0
  31. package/dist/main/core/usage-tracker.js +625 -0
  32. package/dist/main/main/auto-launch.js +39 -0
  33. package/dist/main/main/auto-updater.js +98 -0
  34. package/dist/main/main/event-watcher.js +174 -0
  35. package/dist/main/main/ipc-handlers.js +89 -0
  36. package/dist/main/main/main.js +422 -0
  37. package/dist/main/main/preload.js +93 -0
  38. package/dist/main/main/settings-window.js +49 -0
  39. package/dist/main/main/share-card.js +139 -0
  40. package/dist/main/main/skin-manager.js +118 -0
  41. package/dist/main/main/tray.js +88 -0
  42. package/dist/main/shared/i18n.js +392 -0
  43. package/dist/main/shared/types.js +25 -0
  44. package/dist/main/shared/utils.js +9 -0
  45. package/dist/renderer/assets/claude-pet.png +0 -0
  46. package/dist/renderer/assets/index-BMnMEuOf.js +9 -0
  47. package/dist/renderer/assets/index-qzlrlqpX.css +1 -0
  48. package/dist/renderer/index.html +30 -0
  49. package/dist/renderer/share-card-template/card.html +148 -0
  50. package/docs/AGENTS.md +42 -0
  51. package/docs/images/angry.png +0 -0
  52. package/docs/images/character.webp +0 -0
  53. package/docs/images/claude-mama.png +0 -0
  54. package/docs/images/happy.png +0 -0
  55. package/docs/images/proud.png +0 -0
  56. package/docs/images/share-card-example.png +0 -0
  57. package/docs/images/worried_1.png +0 -0
  58. package/docs/images/worried_2.png +0 -0
  59. package/docs/spritesheet-bugs.md +240 -0
  60. package/docs/superpowers/plans/2026-03-10-compact-widget.md +888 -0
  61. package/docs/superpowers/plans/2026-03-10-viral-features.md +1874 -0
  62. package/docs/superpowers/plans/2026-03-14-update-ux.md +362 -0
  63. package/docs/superpowers/plans/2026-03-14-v1.1-features.md +2139 -0
  64. package/docs/superpowers/specs/2026-03-10-compact-widget-design.md +150 -0
  65. package/docs/superpowers/specs/2026-03-10-viral-features-design.md +217 -0
  66. package/docs/superpowers/specs/2026-03-14-streak-calendar-design.md +26 -0
  67. package/docs/superpowers/specs/2026-03-14-update-ux-design.md +172 -0
  68. package/docs/superpowers/specs/2026-03-14-v1.1-features-design.md +342 -0
  69. package/electron-builder.yml +75 -0
  70. package/package.json +48 -0
  71. package/scripts/AGENTS.md +60 -0
  72. package/scripts/install.ps1 +47 -0
  73. package/scripts/install.sh +98 -0
  74. package/scripts/make-icon.js +119 -0
  75. package/scripts/notarize.js +18 -0
  76. package/src/AGENTS.md +47 -0
  77. package/src/core/AGENTS.md +58 -0
  78. package/src/core/__tests__/AGENTS.md +60 -0
  79. package/src/core/__tests__/badge-triggers.test.ts +83 -0
  80. package/src/core/__tests__/contextual-messages.test.ts +87 -0
  81. package/src/core/__tests__/pet-state-engine.test.ts +350 -0
  82. package/src/core/__tests__/quote-collection.test.ts +62 -0
  83. package/src/core/__tests__/quote-triggers.test.ts +110 -0
  84. package/src/core/badge-manager.ts +50 -0
  85. package/src/core/badge-registry.ts +71 -0
  86. package/src/core/badge-triggers.ts +41 -0
  87. package/src/core/contextual-messages.ts +381 -0
  88. package/src/core/pet-messages.ts +615 -0
  89. package/src/core/pet-state-engine.ts +272 -0
  90. package/src/core/quote-collection.ts +63 -0
  91. package/src/core/quote-registry.ts +181 -0
  92. package/src/core/quote-triggers.ts +64 -0
  93. package/src/core/usage-tracker.ts +680 -0
  94. package/src/main/AGENTS.md +70 -0
  95. package/src/main/auto-launch.ts +38 -0
  96. package/src/main/auto-updater.ts +106 -0
  97. package/src/main/event-watcher.ts +159 -0
  98. package/src/main/ipc-handlers.ts +107 -0
  99. package/src/main/main.ts +425 -0
  100. package/src/main/preload.ts +111 -0
  101. package/src/main/settings-window.ts +50 -0
  102. package/src/main/share-card.ts +153 -0
  103. package/src/main/skin-manager.ts +119 -0
  104. package/src/main/tray.ts +94 -0
  105. package/src/renderer/AGENTS.md +62 -0
  106. package/src/renderer/App.tsx +270 -0
  107. package/src/renderer/assets/claude-mama.png +0 -0
  108. package/src/renderer/assets/claude-pet.png +0 -0
  109. package/src/renderer/components/AGENTS.md +50 -0
  110. package/src/renderer/components/Character.tsx +327 -0
  111. package/src/renderer/components/SpeechBubble.tsx +182 -0
  112. package/src/renderer/components/UsageIndicator.tsx +268 -0
  113. package/src/renderer/electron.d.ts +34 -0
  114. package/src/renderer/hooks/AGENTS.md +55 -0
  115. package/src/renderer/hooks/usePetState.ts +59 -0
  116. package/src/renderer/hooks/useWidgetMode.ts +18 -0
  117. package/src/renderer/index.html +29 -0
  118. package/src/renderer/main.tsx +13 -0
  119. package/src/renderer/pages/AGENTS.md +53 -0
  120. package/src/renderer/pages/Collection.tsx +252 -0
  121. package/src/renderer/pages/Settings.tsx +815 -0
  122. package/src/renderer/share-card-template/card.html +148 -0
  123. package/src/renderer/styles/AGENTS.md +50 -0
  124. package/src/renderer/styles/styles.css +166 -0
  125. package/src/shared/AGENTS.md +48 -0
  126. package/src/shared/i18n.ts +395 -0
  127. package/src/shared/types.ts +163 -0
  128. package/src/shared/utils.ts +6 -0
  129. package/tsconfig.json +16 -0
  130. package/tsconfig.main.json +12 -0
  131. package/tsconfig.renderer.json +12 -0
  132. package/vite.config.ts +47 -0
  133. package/vitest.config.ts +9 -0
@@ -0,0 +1,28 @@
1
+ Feed your Claude Pet!
2
+
3
+ Appends a feed event to the pet's event file so your desktop pet reacts with a happy eating animation. Shows current pet status after feeding.
4
+
5
+ ```bash
6
+ mkdir -p ~/.claude-pet && echo '{"type":"feed","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.claude-pet/events.jsonl
7
+
8
+ node -e "
9
+ const fs=require('fs'),os=require('os'),p=require('path'),h=os.homedir();
10
+ const pl=os.platform();
11
+ const d=pl==='win32'?p.join(process.env.APPDATA||'','claude-pet'):pl==='darwin'?p.join(h,'Library/Application Support/claude-pet'):p.join(h,'.config/claude-pet');
12
+ try{
13
+ const c=JSON.parse(fs.readFileSync(p.join(d,'config.json'),'utf-8'));
14
+ const s=c.petState||{};
15
+ let n='';try{n=fs.readFileSync(p.join(h,'.claude-pet/name.txt'),'utf-8').trim()}catch{}
16
+ const name=n||'Your pet';
17
+ const oldH=s.hunger||50;const newH=Math.max(0,oldH-30);
18
+ const happy=s.happiness||50;const energy=s.energy||50;
19
+ const exp=(s.exp||0)+5;
20
+ const stage=exp>=500?'Adult':exp>=100?'Teen':'Baby';
21
+ const lv=exp>=500?3:exp>=100?2:1;
22
+ console.log();
23
+ console.log('🍖 *nom nom* '+name+' happily eats the food!');
24
+ console.log('📊 Lv.'+lv+' '+stage+' | 🍗 Hunger: '+oldH+'→'+newH+'% | 😊 Happy: '+happy+'% | ⚡ Energy: '+energy+'% | ⭐ EXP: '+exp);
25
+ console.log();
26
+ }catch{console.log('\n🍖 Your pet has been fed! It looks happy~\n')}
27
+ " 2>/dev/null || echo "🍖 Your pet has been fed! It looks happy~"
28
+ ```
@@ -0,0 +1,28 @@
1
+ Name your Claude Pet!
2
+
3
+ Give your pet a special name. Usage: `/name Buddy`
4
+
5
+ ```bash
6
+ NAME="$ARGUMENTS"
7
+ if [ -z "$NAME" ]; then
8
+ if [ -f ~/.claude-pet/name.txt ]; then
9
+ CURRENT=$(cat ~/.claude-pet/name.txt)
10
+ echo ""
11
+ echo "🏷️ Your pet's name is: $CURRENT"
12
+ echo "To rename, use: /name <new-name>"
13
+ echo ""
14
+ else
15
+ echo ""
16
+ echo "🏷️ Your pet doesn't have a name yet!"
17
+ echo "Give it one with: /name <name>"
18
+ echo ""
19
+ fi
20
+ else
21
+ mkdir -p ~/.claude-pet
22
+ echo "$NAME" > ~/.claude-pet/name.txt
23
+ echo ""
24
+ echo "🎉 Your pet is now named '$NAME'!"
25
+ echo "All interactions will use this name from now on."
26
+ echo ""
27
+ fi
28
+ ```
@@ -0,0 +1,29 @@
1
+ Pet your Claude Pet!
2
+
3
+ Appends a pet event to the pet's event file so your desktop pet reacts with a happy purring animation. Shows current pet status after petting.
4
+
5
+ ```bash
6
+ mkdir -p ~/.claude-pet && echo '{"type":"pet","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.claude-pet/events.jsonl
7
+
8
+ node -e "
9
+ const fs=require('fs'),os=require('os'),p=require('path'),h=os.homedir();
10
+ const pl=os.platform();
11
+ const d=pl==='win32'?p.join(process.env.APPDATA||'','claude-pet'):pl==='darwin'?p.join(h,'Library/Application Support/claude-pet'):p.join(h,'.config/claude-pet');
12
+ try{
13
+ const c=JSON.parse(fs.readFileSync(p.join(d,'config.json'),'utf-8'));
14
+ const s=c.petState||{};
15
+ let n='';try{n=fs.readFileSync(p.join(h,'.claude-pet/name.txt'),'utf-8').trim()}catch{}
16
+ const name=n||'Your pet';
17
+ const oldH=s.hunger||50;const newH=Math.max(0,oldH-10);
18
+ const oldHappy=s.happiness||50;const newHappy=Math.min(100,oldHappy+10);
19
+ const oldE=s.energy||50;const newE=Math.min(100,oldE+10);
20
+ const exp=(s.exp||0)+5;
21
+ const stage=exp>=500?'Adult':exp>=100?'Teen':'Baby';
22
+ const lv=exp>=500?3:exp>=100?2:1;
23
+ console.log();
24
+ console.log('💕 '+name+' purrs happily as you stroke it~');
25
+ console.log('📊 Lv.'+lv+' '+stage+' | 🍗 Hunger: '+oldH+'→'+newH+'% | 😊 Happy: '+oldHappy+'→'+newHappy+'% | ⚡ Energy: '+oldE+'→'+newE+'% | ⭐ EXP: '+exp);
26
+ console.log();
27
+ }catch{console.log('\n💕 You petted your pet! It purrs happily~\n')}
28
+ " 2>/dev/null || echo "💕 You petted your pet! It purrs happily~"
29
+ ```
@@ -0,0 +1,29 @@
1
+ Play with your Claude Pet!
2
+
3
+ Appends a play event to the pet's event file so your desktop pet reacts with an excited playing animation. Shows current pet status after playing.
4
+
5
+ ```bash
6
+ mkdir -p ~/.claude-pet && echo '{"type":"play","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' >> ~/.claude-pet/events.jsonl
7
+
8
+ node -e "
9
+ const fs=require('fs'),os=require('os'),p=require('path'),h=os.homedir();
10
+ const pl=os.platform();
11
+ const d=pl==='win32'?p.join(process.env.APPDATA||'','claude-pet'):pl==='darwin'?p.join(h,'Library/Application Support/claude-pet'):p.join(h,'.config/claude-pet');
12
+ try{
13
+ const c=JSON.parse(fs.readFileSync(p.join(d,'config.json'),'utf-8'));
14
+ const s=c.petState||{};
15
+ let n='';try{n=fs.readFileSync(p.join(h,'.claude-pet/name.txt'),'utf-8').trim()}catch{}
16
+ const name=n||'Your pet';
17
+ const hunger=s.hunger||50;
18
+ const oldHappy=s.happiness||50;const newHappy=Math.min(100,oldHappy+25);
19
+ const energy=s.energy||50;
20
+ const exp=(s.exp||0)+5;
21
+ const stage=exp>=500?'Adult':exp>=100?'Teen':'Baby';
22
+ const lv=exp>=500?3:exp>=100?2:1;
23
+ console.log();
24
+ console.log('🎮 '+name+' bounces around excitedly!');
25
+ console.log('📊 Lv.'+lv+' '+stage+' | 🍗 Hunger: '+hunger+'% | 😊 Happy: '+oldHappy+'→'+newHappy+'% | ⚡ Energy: '+energy+'% | ⭐ EXP: '+exp);
26
+ console.log();
27
+ }catch{console.log('\n🎮 You played with your pet! It\\'s so excited~\n')}
28
+ " 2>/dev/null || echo "🎮 You played with your pet! It's so excited~"
29
+ ```
@@ -0,0 +1,41 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(find:*)",
5
+ "Bash(npx tsc:*)",
6
+ "Bash(npm run:*)",
7
+ "Bash(node:*)",
8
+ "Bash(git status:*)",
9
+ "Bash(git add:*)",
10
+ "Bash(git commit:*)",
11
+ "Bash(wc -l ./src/core/*.ts ./src/main/*.ts ./src/renderer/*.tsx)",
12
+ "mcp__plugin_oh-my-claudecode_t__state_write",
13
+ "Bash(npx vitest:*)",
14
+ "Bash(grep -E \"\\\\.ts$\")",
15
+ "Bash(mkdir -p ~/.claude-pet)",
16
+ "Bash(~/.claude-pet/name.txt)",
17
+ "Bash(~/.claude-pet/events.jsonl)",
18
+ "Bash(npm link:*)",
19
+ "Bash(tasklist)",
20
+ "Skill(update-config)",
21
+ "Bash(claude-pet)",
22
+ "Bash(echo \"exit: $?\")",
23
+ "Bash(jq:*)",
24
+ "Bash(taskkill //F //IM electron.exe)",
25
+ "Bash(rm -f ~/.claude-pet/app.pid)"
26
+ ]
27
+ },
28
+ "hooks": {
29
+ "SessionStart": [
30
+ {
31
+ "hooks": [
32
+ {
33
+ "type": "command",
34
+ "command": "claude-pet",
35
+ "timeout": 10
36
+ }
37
+ ]
38
+ }
39
+ ]
40
+ }
41
+ }
@@ -0,0 +1,60 @@
1
+ <!-- Parent: ../../AGENTS.md -->
2
+ <!-- Generated: 2026-03-14 -->
3
+
4
+ # .github/workflows/
5
+
6
+ ## Purpose
7
+ GitHub Actions CI/CD pipeline for building and publishing platform installers. The single workflow file `build.yml` produces signed and notarized installers for both Windows (NSIS `.exe`) and macOS (DMG + ZIP) and publishes them to GitHub Releases whenever a version tag is pushed.
8
+
9
+ ## Key Files
10
+ | File | Description |
11
+ |------|-------------|
12
+ | `build.yml` | Defines two parallel jobs: `build-windows` (runs on `windows-latest`, produces `.exe` via electron-builder `--win --publish always`) and `build-mac` (runs on `macos-14`, imports code-signing certificate, builds with `--mac --publish always`, then notarizes DMG and ZIP with `xcrun notarytool`). Triggered on `v*` tag pushes and `workflow_dispatch`. |
13
+
14
+ ## Subdirectories
15
+ | Directory | Purpose |
16
+ |-----------|---------|
17
+ | *(none)* | — |
18
+
19
+ ## For AI Agents
20
+
21
+ ### Working In This Directory
22
+ - Trigger: push a tag matching `v*` (e.g., `git tag v1.2.0 && git push --tags`). The workflow can also be triggered manually via `workflow_dispatch` in the GitHub Actions UI.
23
+ - Both jobs use `--publish always`, which uploads artifacts to GitHub Releases using `GH_TOKEN` (automatically provided by `secrets.GITHUB_TOKEN`). The release must already exist or electron-builder will create a draft.
24
+ - The macOS job requires four repository secrets: `MAC_CERTIFICATE_P12` (base64-encoded P12), `MAC_CERTIFICATE_PASSWORD`, `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, `APPLE_TEAM_ID`. Without these, the macOS build will fail at the signing step.
25
+ - Notarization uses `xcrun notarytool submit --wait --timeout 10m` directly (not the `@electron/notarize` package used in `scripts/notarize.js`) — these are two separate notarization paths. The CI job notarizes the final DMG/ZIP artifacts; `notarize.js` is the electron-builder `afterSign` hook for the `.app` bundle itself.
26
+ - Windows artifacts are uploaded as `release/*.exe`; macOS artifacts as `release/*.dmg` and `release/*.zip`, both retained for 30 days.
27
+ - Node version is pinned to 20 with `npm` cache enabled. Do not change the Node version without testing compatibility with native modules (`sharp`, `png-to-ico`).
28
+
29
+ ### Testing Requirements
30
+ - Use `workflow_dispatch` to test the full pipeline without pushing a release tag.
31
+ - The Windows job can be validated independently of macOS secrets.
32
+ - Check that `npm run build` succeeds locally on both platforms before pushing a release tag — the CI build mirrors the local build steps exactly (`npm ci`, `npm run build`, then `electron-builder`).
33
+
34
+ ### Common Patterns
35
+ - Publishing pattern: `npx electron-builder --platform --publish always` with `GH_TOKEN` in the environment.
36
+ - Notarization pattern (CI):
37
+ ```bash
38
+ xcrun notarytool submit "$FILE" \
39
+ --apple-id "${{ secrets.APPLE_ID }}" \
40
+ --password "${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}" \
41
+ --team-id "${{ secrets.APPLE_TEAM_ID }}" \
42
+ --wait --timeout 10m
43
+ xcrun stapler staple "$FILE"
44
+ ```
45
+ - Artifact upload: `actions/upload-artifact@v4` with `retention-days: 30`.
46
+
47
+ ## Dependencies
48
+ ### Internal
49
+ - Executes `npm ci`, `npm run build`, `npx electron-builder`
50
+ - Reads secrets: `GITHUB_TOKEN`, `MAC_CERTIFICATE_P12`, `MAC_CERTIFICATE_PASSWORD`, `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, `APPLE_TEAM_ID`
51
+ - Consumes `build/` assets (icons, installer images) generated by `scripts/make-icon.js`
52
+
53
+ ### External
54
+ - `actions/checkout@v4`
55
+ - `actions/setup-node@v4`
56
+ - `apple-actions/import-codesign-certs@v3`
57
+ - `actions/upload-artifact@v4`
58
+ - Apple Notary Service (`xcrun notarytool`)
59
+
60
+ <!-- MANUAL: -->
@@ -0,0 +1,87 @@
1
+ name: Build Installers
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: write
11
+
12
+ jobs:
13
+ build-windows:
14
+ runs-on: self-hosted
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 20
21
+ cache: npm
22
+
23
+ - run: npm ci
24
+
25
+ - run: npm run build
26
+
27
+ - run: npx electron-builder --win --publish always
28
+ env:
29
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30
+
31
+ - uses: actions/upload-artifact@v4
32
+ with:
33
+ name: windows-installer
34
+ path: release/*.exe
35
+ retention-days: 30
36
+
37
+ build-linux:
38
+ runs-on: self-hosted
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+
42
+ - uses: actions/setup-node@v4
43
+ with:
44
+ node-version: 20
45
+ cache: npm
46
+
47
+ - run: npm ci
48
+
49
+ - run: npm run build
50
+
51
+ - run: npx electron-builder --linux --publish always
52
+ env:
53
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54
+
55
+ - uses: actions/upload-artifact@v4
56
+ with:
57
+ name: linux-installer
58
+ path: |
59
+ release/*.AppImage
60
+ release/*.deb
61
+ retention-days: 30
62
+
63
+ build-mac:
64
+ runs-on: macos-latest
65
+ steps:
66
+ - uses: actions/checkout@v4
67
+
68
+ - uses: actions/setup-node@v4
69
+ with:
70
+ node-version: 20
71
+ cache: npm
72
+
73
+ - run: npm ci
74
+
75
+ - run: npm run build
76
+
77
+ - run: npx electron-builder --mac --publish always
78
+ env:
79
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
80
+
81
+ - uses: actions/upload-artifact@v4
82
+ with:
83
+ name: mac-installer
84
+ path: |
85
+ release/*.dmg
86
+ release/*.zip
87
+ retention-days: 30
package/AGENTS.md ADDED
@@ -0,0 +1,66 @@
1
+ # Claude Mama
2
+
3
+ ## Purpose
4
+ Claude Mama is an Electron desktop mascot widget that monitors Claude Code API usage. It reads the user's OAuth credentials from `~/.claude/.credentials.json` (or platform keychains), polls the Anthropic usage API every 5 minutes, and displays a pixel-art character whose mood (angry / worried / happy / proud) reflects weekly token utilization. The app ships as a frameless, always-on-top, transparent window with no taskbar entry. It supports a quote collection system, badge achievements, share-card generation, custom character skins, and i18n across Korean, English, Japanese, and Chinese.
5
+
6
+ ## Key Files
7
+ | File | Description |
8
+ |------|-------------|
9
+ | `package.json` | npm scripts, dependencies (Electron 40, React 19, electron-store, electron-updater) |
10
+ | `tsconfig.json` | Base TypeScript config shared by renderer |
11
+ | `tsconfig.main.json` | TypeScript config for the main process (CommonJS output to `dist/main/`) |
12
+ | `tsconfig.renderer.json` | TypeScript config for the renderer |
13
+ | `vite.config.ts` | Vite bundler config for the renderer |
14
+ | `vitest.config.ts` | Vitest unit test config |
15
+ | `electron-builder.yml` | electron-builder packaging config for Windows/macOS |
16
+ | `README.md` | User-facing documentation |
17
+
18
+ ## Subdirectories
19
+ | Directory | Purpose |
20
+ |-----------|---------|
21
+ | `src/` | All application source code |
22
+ | `scripts/` | Build-time utilities (icon generation, notarization) |
23
+ | `build/` | Static assets consumed by electron-builder (icons, installer images) |
24
+ | `docs/` | Design specs, planning documents, reference images |
25
+ | `.github/workflows/` | CI/CD pipeline for cross-platform builds and releases |
26
+ | `dist/` | Build output (gitignored) |
27
+ | `release/` | Packaged installers output (gitignored) |
28
+ | `node_modules/` | Dependencies (gitignored) |
29
+
30
+ ## For AI Agents
31
+
32
+ ### Working In This Directory
33
+ - The project uses **two separate TypeScript compilation targets**: `tsconfig.main.json` compiles the Electron main process to `dist/main/` as CommonJS; Vite compiles the renderer to `dist/renderer/`.
34
+ - Run `npm run dev` to start in development mode (Vite dev server + Electron). Run `npm run build` for a full production build before packaging.
35
+ - `package.json` `"type": "commonjs"` means all `.js` files are CommonJS by default; the renderer uses ESM via Vite.
36
+ - Never import Electron APIs from `src/core/` or `src/shared/` — these layers must stay pure Node/browser-compatible.
37
+ - The entry point for the packaged app is `dist/main/main/main.js`.
38
+
39
+ ### Testing Requirements
40
+ - Run `npm test` (vitest) to execute all unit tests in `src/core/__tests__/`.
41
+ - Tests cover: mood engine, quote triggers, badge triggers, quote collection, contextual messages.
42
+ - There are no integration or E2E tests; test only via `vitest run`.
43
+ - When adding new core logic, add a corresponding test in `src/core/__tests__/`.
44
+
45
+ ### Common Patterns
46
+ - Mood thresholds: `<15%` = angry, `15–50%` = worried, `50–85%` = happy, `≥85%` = proud.
47
+ - Error states use `MamaErrorExpression`: `'confused'` (API error) or `'sleeping'` (no credentials).
48
+ - IPC channel names are defined as constants in `src/shared/types.ts` (`IPC_CHANNELS`).
49
+ - Locale detection happens at module load time via `detectLocale()` in `src/shared/i18n.ts`.
50
+ - All user preferences are persisted through `electron-store` (accessed via `getStore()` in `src/main/ipc-handlers.ts`).
51
+
52
+ ## Dependencies
53
+ ### Internal
54
+ - `src/` → `build/` (icons referenced in `electron-builder.yml`)
55
+ - `scripts/make-icon.js` reads from `docs/images/character.webp` and writes to `build/`
56
+
57
+ ### External
58
+ - `electron` ^40 — desktop shell
59
+ - `react` / `react-dom` ^19 — renderer UI
60
+ - `electron-store` 8.2.0 — persistent settings
61
+ - `electron-updater` ^6 — auto-update via GitHub Releases
62
+ - `auto-launch` ^5 — system startup registration
63
+ - `vite` ^7, `vitest` ^4, `typescript` ^5.9 — build and test toolchain
64
+ - `sharp`, `png-to-ico` — icon generation (dev only)
65
+
66
+ <!-- MANUAL: -->
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2025 scm1400
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.