sparkecoder 0.1.113 → 0.1.114

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.
Files changed (113) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/agent/index.js +57 -1
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +57 -1
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/index.d.ts +2 -2
  7. package/dist/{index-Biy5JTop.d.ts → index-Bi8Ek02A.d.ts} +104 -104
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.js +57 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/{schema-CYSKJZ3m.d.ts → schema-ecQSnCMz.d.ts} +3 -3
  12. package/dist/{search-CVVfuBPZ.d.ts → search-DOzC4ojH.d.ts} +4 -4
  13. package/dist/server/index.js +57 -1
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/skills/default/computer-use.md +63 -2
  16. package/dist/skills/default/recording.md +172 -0
  17. package/dist/tools/index.d.ts +3 -3
  18. package/package.json +1 -1
  19. package/src/skills/default/computer-use.md +63 -2
  20. package/src/skills/default/recording.md +172 -0
  21. package/web/.next/BUILD_ID +1 -1
  22. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  23. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  24. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  25. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  26. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  41. package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
  46. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  77. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  81. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  83. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  84. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  86. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  87. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  88. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  89. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  90. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  92. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  93. package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
  94. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
  95. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  96. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
  97. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  98. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  99. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  100. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  101. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  102. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  103. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  104. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  105. /package/web/.next/standalone/web/.next/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_buildManifest.js +0 -0
  106. /package/web/.next/standalone/web/.next/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_clientMiddlewareManifest.json +0 -0
  107. /package/web/.next/standalone/web/.next/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_ssgManifest.js +0 -0
  108. /package/web/.next/standalone/web/.next/static/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_buildManifest.js +0 -0
  109. /package/web/.next/standalone/web/.next/static/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_clientMiddlewareManifest.json +0 -0
  110. /package/web/.next/standalone/web/.next/static/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_ssgManifest.js +0 -0
  111. /package/web/.next/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_buildManifest.js +0 -0
  112. /package/web/.next/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_clientMiddlewareManifest.json +0 -0
  113. /package/web/.next/static/{mC7Yp8aJpCL22mrYVzIEG → N09EiHl0JwEgsGMdCtwpB}/_ssgManifest.js +0 -0
@@ -6,9 +6,36 @@ platforms: ["darwin"]
6
6
 
7
7
  # Computer Use Skill
8
8
 
9
- Anthropic's `computer` tool gives Claude direct control of the actual macOS desktop. You take screenshots, then click/type/scroll at pixel coordinates anywhere on screen — Finder, Safari, native apps, anything visible. This is real desktop automation, not a sandboxed browser.
9
+ Anthropic's `computer` tool gives Claude direct control of the actual macOS desktop take screenshots, click/type/scroll at pixel coordinates, drive any app. Real desktop automation.
10
10
 
11
- For most browser work, **prefer `agent-browser` with refs from `snapshot -i`** (see the Browser Automation skill). Refs are deterministic, much cheaper in tokens, and don't depend on visual coordinates that shift between screenshots. Reach for computer use when the task involves a native macOS app, a non-browser GUI, complex visual verification, or cross-app workflows.
11
+ ## ⚠️ Computer use is the LAST RESORT read this first
12
+
13
+ Computer use is the slowest, most token-expensive, most error-prone tool you have. Almost every task you're tempted to use it for has a better alternative:
14
+
15
+ | If you're trying to … | Use this instead |
16
+ |---|---|
17
+ | Read / write / search / edit files | `read_file`, `write_file`, `bash` (`grep`, `sed`, `cat`, etc.) |
18
+ | Run a command, build, test, script | `bash` |
19
+ | Use git / npm / brew / any CLI | `bash` |
20
+ | **Anything in a web browser** | **`agent-browser` skill (`load_skill browser`)** — refs from `snapshot -i` are deterministic and ~100× cheaper in tokens than pixel-coordinate clicks |
21
+ | Look up info on the web | `web_fetch` / `web_search` |
22
+ | Call an HTTP API | `bash` (`curl`) |
23
+ | Render an HTML page, screenshot it, scrape it | `agent-browser` (`load_skill browser`) |
24
+ | Drive a Slack/Linear/Jira/etc. workflow | The integration's API via `bash` + `curl`, OR an MCP server (`load_skill manage-mcp`) |
25
+
26
+ **Decision tree**:
27
+
28
+ 1. Is there a CLI for this? → `bash`.
29
+ 2. Is it in a web browser? → `load_skill browser`, then drive `agent-browser` via refs.
30
+ 3. Is it something visible only in a native macOS GUI app with no CLI / API / accessibility shortcut? → **only now** consider computer use.
31
+
32
+ Computer use is appropriate for:
33
+ - Native macOS apps with no CLI (e.g. driving System Settings, Calculator, Finder for tasks that can't be done via `defaults`/`open`/`launchctl`).
34
+ - Complex visual verification ("does this app look right?").
35
+ - Cross-app workflows that genuinely require the desktop (drag a file from app A to app B's window).
36
+ - Demo-style tasks where the user wants to *see* the screen action.
37
+
38
+ Computer use is **NOT** appropriate for browser work — `agent-browser` snapshots + refs are deterministic, don't depend on pixel coordinates that shift between screenshots, work cross-platform (no macOS dependency), don't need Accessibility/Screen Recording permissions, and use a fraction of the tokens. Always reach for the browser skill first.
12
39
 
13
40
  ## Requirements (macOS only)
14
41
 
@@ -125,6 +152,40 @@ Coordinates are in the **logical points** of the primary display — same coordi
125
152
 
126
153
  `enable_computer_use` auto-detects the size and stores it. Always look at the most recent screenshot to find positions before clicking — windows move, apps quit, the desktop re-flows.
127
154
 
155
+ ## Record what you're doing (default ON)
156
+
157
+ Computer-use sessions are *visual* — the user can't see the screen you're driving, only your text summary. **Record almost every computer-use task** so the user can replay it. See the **Recording** skill for the details (`load_skill recording`); the short version:
158
+
159
+ ```bash
160
+ # At the start of the task, before your first `computer` action:
161
+ mkdir -p ~/recordings
162
+ RECORDING=~/recordings/cu-$(date +%s).mov
163
+ screencapture -v -V 180 -C "$RECORDING" &
164
+ REC_PID=$!
165
+
166
+ # ... do all your computer-use actions ...
167
+
168
+ # When you're done (success OR failure), stop the recording:
169
+ kill -INT $REC_PID 2>/dev/null
170
+ wait $REC_PID 2>/dev/null
171
+ echo "Recording: $RECORDING"
172
+ ```
173
+
174
+ Default behavior:
175
+
176
+ - **Always record** short / visually interesting tasks (open an app, click around, drag/drop, fill a form, demos, "show me X working").
177
+ - **Always announce** before starting: "Starting a screen recording — I'll send you the file when I'm done."
178
+ - **Include the file path in your final summary** (and in your `outputSchema` if you're a worker) so the orchestrator can post the file back via Slack/whatever channel.
179
+
180
+ Skip recording when:
181
+
182
+ - The task is **long-running and boring** (e.g. "every 15 minutes for the next hour, click Refresh"). A 60-minute screen video at full resolution gets huge fast.
183
+ - The screen contains **sensitive content** the user hasn't explicitly approved recording (1Password vaults, customer dashboards, banking, private DMs). Ask first.
184
+ - The user explicitly says "no recording" or "just describe what you did."
185
+ - The task is **purely keyboard-driven CLI work** that didn't need computer-use in the first place — that should be `bash`, not `computer`.
186
+
187
+ The auto-stop flag `-V 180` (3 minutes) is a generous default that prevents runaway recordings if you crash or forget to kill the process. For longer tasks, bump it or use a separate `asciinema` recording for the terminal half.
188
+
128
189
  ## Best practices
129
190
 
130
191
  1. **Screenshot before AND after each action.** Computer use is blind without screenshots. After clicking, re-screenshot to confirm the click had the expected effect before doing the next thing.
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: Recording
3
+ description: Record terminal sessions (asciinema, anywhere) or screen video (macOS / Linux with X) while a task runs so the user can replay what happened. Useful for demos, debugging visual bugs, capturing computer-use sessions, and producing evidence the task actually did what it claims.
4
+ platforms: ["darwin", "linux"]
5
+ ---
6
+
7
+ # Recording Skill
8
+
9
+ Sometimes a task is best explained by *showing* it. This skill teaches you to record a **terminal session** or **screen video** while you work, then hand the file to the user.
10
+
11
+ ## When to record
12
+
13
+ Reach for this when:
14
+
15
+ - The user explicitly asks for a recording / demo / video / proof.
16
+ - You're using **computer use** to drive the desktop and the user will want to see what you did.
17
+ - You're running a long-running command (build, test suite, deploy) and the user might want to scrub through it later.
18
+ - You're debugging a flaky visual issue — recording lets you and the user re-watch frames.
19
+
20
+ Skip recording when:
21
+
22
+ - The task is purely textual (reading/writing files, code analysis). The chat transcript already has everything.
23
+ - Recording would capture sensitive content (passwords on screen, private DMs, customer data). Ask first.
24
+
25
+ ## Terminal recording — asciinema
26
+
27
+ `asciinema` records the **content of a terminal session** as a tiny `.cast` text file. It's a fraction of the size of video, plays in any browser via [asciinema-player](https://github.com/asciinema/asciinema-player), and the output is also greppable.
28
+
29
+ ### Install (one-time per machine)
30
+
31
+ ```bash
32
+ # macOS
33
+ brew install asciinema
34
+
35
+ # Debian / Ubuntu
36
+ sudo apt-get install -y asciinema
37
+
38
+ # Other Linux
39
+ pip install asciinema
40
+ ```
41
+
42
+ ### Record
43
+
44
+ ```bash
45
+ # Start recording; everything you type and every command output goes into the cast.
46
+ asciinema rec ~/recordings/demo-$(date +%s).cast
47
+
48
+ # Run whatever you want to demo. Then exit the recording with Ctrl-D or `exit`.
49
+
50
+ # Replay locally:
51
+ asciinema play ~/recordings/demo-1700000000.cast
52
+
53
+ # Upload to asciinema.org (public, optional):
54
+ asciinema upload ~/recordings/demo-1700000000.cast
55
+ ```
56
+
57
+ ### Non-interactive recording (script-driven)
58
+
59
+ If you (the agent) are running a sequence of commands and want to record without sitting in an interactive prompt:
60
+
61
+ ```bash
62
+ # Record a single command's output:
63
+ asciinema rec --command "bash -c 'npm test; echo exit=$?'" out.cast
64
+
65
+ # Or record into a file while a script runs:
66
+ asciinema rec --idle-time-limit 2 --title "test run $(date)" out.cast \
67
+ --command "./scripts/run-the-thing.sh"
68
+ ```
69
+
70
+ `--idle-time-limit 2` collapses dead-air pauses longer than 2s so the playback isn't boring.
71
+
72
+ ### Hand the file to the user
73
+
74
+ When you're done:
75
+
76
+ 1. Move the `.cast` to a stable path under `~/recordings/` or the session workspace.
77
+ 2. Tell the user the path. If `agent-remote-server` is configured, you can upload via the storage API and give them a signed URL — see the bash example below.
78
+ 3. Mention they can either `asciinema play <file>` locally or open the URL.
79
+
80
+ ```bash
81
+ # Optional: upload to GCS via the storage route if configured
82
+ RECORDING=~/recordings/demo-$(date +%s).cast
83
+ curl -fsS -X POST "${SPARKECODER_REMOTE_URL}/storage/upload" \
84
+ -H "Authorization: Bearer ${SPARKECODER_AUTH_KEY}" \
85
+ -F "file=@${RECORDING}" | jq .url
86
+ ```
87
+
88
+ ## Screen recording — macOS native
89
+
90
+ macOS ships with `screencapture`, no extra install needed. It writes `.mov` (H.264) which any modern app/browser plays.
91
+
92
+ ### Requirements
93
+
94
+ - **Screen Recording permission** for the agent's parent process (Terminal, iTerm, IDE, or `node`).
95
+ - `sparkecoder check-permissions` verifies; `sparkecoder request-permissions` opens the right System Settings pane.
96
+
97
+ ### Record
98
+
99
+ ```bash
100
+ # Record the entire primary display until Ctrl-C (or the agent sends SIGINT to the process):
101
+ screencapture -v ~/recordings/screen-$(date +%s).mov &
102
+ REC_PID=$!
103
+
104
+ # ... do work via computer-use, bash, etc. ...
105
+
106
+ # Stop cleanly:
107
+ kill -INT $REC_PID
108
+ wait $REC_PID 2>/dev/null
109
+ ```
110
+
111
+ Useful flags:
112
+
113
+ - `-V <seconds>` — stop automatically after this many seconds (no need for kill).
114
+ - `-R x,y,w,h` — record just a rectangle.
115
+ - `-C` — also capture mouse cursor (off by default).
116
+ - `-G <displayID>` — pick a specific display (run `system_profiler SPDisplaysDataType` to list).
117
+ - `-T <seconds>` — pre-roll countdown before starting.
118
+
119
+ Example: 30-second auto-stop, full screen, with cursor:
120
+
121
+ ```bash
122
+ screencapture -v -V 30 -C ~/recordings/full-$(date +%s).mov
123
+ ```
124
+
125
+ ## Screen recording — Linux (`ffmpeg`)
126
+
127
+ ```bash
128
+ sudo apt-get install -y ffmpeg
129
+
130
+ # Record the X display. Adjust :0.0 / resolution for your setup.
131
+ ffmpeg -y -f x11grab -framerate 25 -video_size 1920x1080 -i :0.0 \
132
+ -c:v libx264 -preset veryfast -pix_fmt yuv420p \
133
+ ~/recordings/screen-$(date +%s).mp4
134
+
135
+ # Stop with Ctrl-C or kill the ffmpeg pid.
136
+ ```
137
+
138
+ On a headless server with no X, screen recording isn't meaningful — record the terminal with `asciinema` instead.
139
+
140
+ ## Quick recipes
141
+
142
+ | You want to … | Use |
143
+ |---|---|
144
+ | Capture a CLI demo, share a link | `asciinema rec → upload` |
145
+ | Show what a computer-use task did on the desktop | `screencapture -v -V <seconds>` (macOS) |
146
+ | Debug a flaky GUI test on Linux CI | `ffmpeg -f x11grab` around the test run |
147
+ | Capture a single command's output verbatim | `asciinema rec --command "cmd" out.cast` |
148
+ | Both terminal AND screen at once | start `asciinema rec` in a sub-shell AND `screencapture -v` in parallel |
149
+
150
+ ## Best practices
151
+
152
+ 1. **Always announce.** Before starting a recording, post a short message to the user: "Starting screen recording for the Calculator demo." So they can intervene if it'd capture something sensitive.
153
+ 2. **Auto-stop with a timer when you can.** `screencapture -V 60` is much safer than relying on the agent to remember to kill the process. Recordings that go forever fill disks.
154
+ 3. **Use stable file names.** `~/recordings/<task-name>-<unix-ts>.<ext>`. The unix timestamp prevents overwrites and makes sorting easy.
155
+ 4. **Clean up after yourself.** If the user only wanted to scrub through it once, delete the file when done — recordings are often huge.
156
+ 5. **Don't record secrets.** Refuse to record if the screen contains visible passwords, 1Password vaults, customer PII, etc. Ask the user to close those windows first.
157
+ 6. **For computer-use tasks: prefer recording the whole session, not per-action.** Starting `screencapture -v -V 120` once around your whole interaction is cheaper and produces a continuous video.
158
+ 7. **Mention the file in your final message.** "Recording saved to `~/recordings/calc-1700000000.mov`" — otherwise the user won't know where to look.
159
+
160
+ ## Returning the recording in your final task summary
161
+
162
+ For a **task worker** that captured a recording, include the path and a one-line description in your `result` so the orchestrator can route it back to the user:
163
+
164
+ ```ts
165
+ {
166
+ "summary": "Opened Calculator, typed 2+2, hit Return. Got 4.",
167
+ "screencapture": "~/recordings/calc-1700000000.mov",
168
+ "screencapture_description": "60s screen recording of the entire Calculator interaction"
169
+ }
170
+ ```
171
+
172
+ The orchestrator can then attach / post the file via Slack or whatever channel the original request came in on.
@@ -1,7 +1,7 @@
1
1
  import * as ai from 'ai';
2
2
  import { ToolSet } from 'ai';
3
- import { B as BashToolProgress, W as WriteFileProgress, S as SearchToolProgress } from '../search-CVVfuBPZ.js';
4
- export { b as BashToolOptions, d as SearchToolOptions, e as WriteFileToolOptions, c as createBashTool, f as createSearchTool, a as createWriteFileTool } from '../search-CVVfuBPZ.js';
3
+ import { B as BashToolProgress, W as WriteFileProgress, S as SearchToolProgress } from '../search-DOzC4ojH.js';
4
+ export { b as BashToolOptions, d as SearchToolOptions, e as WriteFileToolOptions, c as createBashTool, f as createSearchTool, a as createWriteFileTool } from '../search-DOzC4ojH.js';
5
5
 
6
6
  interface TaskCompletionSignal {
7
7
  status: 'completed' | 'failed';
@@ -110,7 +110,7 @@ interface TodoToolOptions {
110
110
  workingDirectory: string;
111
111
  }
112
112
  declare function createTodoTool(options: TodoToolOptions): ai.Tool<{
113
- action: "clear" | "add" | "list" | "mark" | "save_plan" | "list_plans" | "get_plan" | "delete_plan";
113
+ action: "list" | "add" | "mark" | "clear" | "save_plan" | "list_plans" | "get_plan" | "delete_plan";
114
114
  status?: "completed" | "pending" | "in_progress" | "cancelled" | undefined;
115
115
  items?: {
116
116
  content: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sparkecoder",
3
- "version": "0.1.113",
3
+ "version": "0.1.114",
4
4
  "description": "A powerful coding agent CLI with HTTP API for development environments",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -6,9 +6,36 @@ platforms: ["darwin"]
6
6
 
7
7
  # Computer Use Skill
8
8
 
9
- Anthropic's `computer` tool gives Claude direct control of the actual macOS desktop. You take screenshots, then click/type/scroll at pixel coordinates anywhere on screen — Finder, Safari, native apps, anything visible. This is real desktop automation, not a sandboxed browser.
9
+ Anthropic's `computer` tool gives Claude direct control of the actual macOS desktop take screenshots, click/type/scroll at pixel coordinates, drive any app. Real desktop automation.
10
10
 
11
- For most browser work, **prefer `agent-browser` with refs from `snapshot -i`** (see the Browser Automation skill). Refs are deterministic, much cheaper in tokens, and don't depend on visual coordinates that shift between screenshots. Reach for computer use when the task involves a native macOS app, a non-browser GUI, complex visual verification, or cross-app workflows.
11
+ ## ⚠️ Computer use is the LAST RESORT read this first
12
+
13
+ Computer use is the slowest, most token-expensive, most error-prone tool you have. Almost every task you're tempted to use it for has a better alternative:
14
+
15
+ | If you're trying to … | Use this instead |
16
+ |---|---|
17
+ | Read / write / search / edit files | `read_file`, `write_file`, `bash` (`grep`, `sed`, `cat`, etc.) |
18
+ | Run a command, build, test, script | `bash` |
19
+ | Use git / npm / brew / any CLI | `bash` |
20
+ | **Anything in a web browser** | **`agent-browser` skill (`load_skill browser`)** — refs from `snapshot -i` are deterministic and ~100× cheaper in tokens than pixel-coordinate clicks |
21
+ | Look up info on the web | `web_fetch` / `web_search` |
22
+ | Call an HTTP API | `bash` (`curl`) |
23
+ | Render an HTML page, screenshot it, scrape it | `agent-browser` (`load_skill browser`) |
24
+ | Drive a Slack/Linear/Jira/etc. workflow | The integration's API via `bash` + `curl`, OR an MCP server (`load_skill manage-mcp`) |
25
+
26
+ **Decision tree**:
27
+
28
+ 1. Is there a CLI for this? → `bash`.
29
+ 2. Is it in a web browser? → `load_skill browser`, then drive `agent-browser` via refs.
30
+ 3. Is it something visible only in a native macOS GUI app with no CLI / API / accessibility shortcut? → **only now** consider computer use.
31
+
32
+ Computer use is appropriate for:
33
+ - Native macOS apps with no CLI (e.g. driving System Settings, Calculator, Finder for tasks that can't be done via `defaults`/`open`/`launchctl`).
34
+ - Complex visual verification ("does this app look right?").
35
+ - Cross-app workflows that genuinely require the desktop (drag a file from app A to app B's window).
36
+ - Demo-style tasks where the user wants to *see* the screen action.
37
+
38
+ Computer use is **NOT** appropriate for browser work — `agent-browser` snapshots + refs are deterministic, don't depend on pixel coordinates that shift between screenshots, work cross-platform (no macOS dependency), don't need Accessibility/Screen Recording permissions, and use a fraction of the tokens. Always reach for the browser skill first.
12
39
 
13
40
  ## Requirements (macOS only)
14
41
 
@@ -125,6 +152,40 @@ Coordinates are in the **logical points** of the primary display — same coordi
125
152
 
126
153
  `enable_computer_use` auto-detects the size and stores it. Always look at the most recent screenshot to find positions before clicking — windows move, apps quit, the desktop re-flows.
127
154
 
155
+ ## Record what you're doing (default ON)
156
+
157
+ Computer-use sessions are *visual* — the user can't see the screen you're driving, only your text summary. **Record almost every computer-use task** so the user can replay it. See the **Recording** skill for the details (`load_skill recording`); the short version:
158
+
159
+ ```bash
160
+ # At the start of the task, before your first `computer` action:
161
+ mkdir -p ~/recordings
162
+ RECORDING=~/recordings/cu-$(date +%s).mov
163
+ screencapture -v -V 180 -C "$RECORDING" &
164
+ REC_PID=$!
165
+
166
+ # ... do all your computer-use actions ...
167
+
168
+ # When you're done (success OR failure), stop the recording:
169
+ kill -INT $REC_PID 2>/dev/null
170
+ wait $REC_PID 2>/dev/null
171
+ echo "Recording: $RECORDING"
172
+ ```
173
+
174
+ Default behavior:
175
+
176
+ - **Always record** short / visually interesting tasks (open an app, click around, drag/drop, fill a form, demos, "show me X working").
177
+ - **Always announce** before starting: "Starting a screen recording — I'll send you the file when I'm done."
178
+ - **Include the file path in your final summary** (and in your `outputSchema` if you're a worker) so the orchestrator can post the file back via Slack/whatever channel.
179
+
180
+ Skip recording when:
181
+
182
+ - The task is **long-running and boring** (e.g. "every 15 minutes for the next hour, click Refresh"). A 60-minute screen video at full resolution gets huge fast.
183
+ - The screen contains **sensitive content** the user hasn't explicitly approved recording (1Password vaults, customer dashboards, banking, private DMs). Ask first.
184
+ - The user explicitly says "no recording" or "just describe what you did."
185
+ - The task is **purely keyboard-driven CLI work** that didn't need computer-use in the first place — that should be `bash`, not `computer`.
186
+
187
+ The auto-stop flag `-V 180` (3 minutes) is a generous default that prevents runaway recordings if you crash or forget to kill the process. For longer tasks, bump it or use a separate `asciinema` recording for the terminal half.
188
+
128
189
  ## Best practices
129
190
 
130
191
  1. **Screenshot before AND after each action.** Computer use is blind without screenshots. After clicking, re-screenshot to confirm the click had the expected effect before doing the next thing.
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: Recording
3
+ description: Record terminal sessions (asciinema, anywhere) or screen video (macOS / Linux with X) while a task runs so the user can replay what happened. Useful for demos, debugging visual bugs, capturing computer-use sessions, and producing evidence the task actually did what it claims.
4
+ platforms: ["darwin", "linux"]
5
+ ---
6
+
7
+ # Recording Skill
8
+
9
+ Sometimes a task is best explained by *showing* it. This skill teaches you to record a **terminal session** or **screen video** while you work, then hand the file to the user.
10
+
11
+ ## When to record
12
+
13
+ Reach for this when:
14
+
15
+ - The user explicitly asks for a recording / demo / video / proof.
16
+ - You're using **computer use** to drive the desktop and the user will want to see what you did.
17
+ - You're running a long-running command (build, test suite, deploy) and the user might want to scrub through it later.
18
+ - You're debugging a flaky visual issue — recording lets you and the user re-watch frames.
19
+
20
+ Skip recording when:
21
+
22
+ - The task is purely textual (reading/writing files, code analysis). The chat transcript already has everything.
23
+ - Recording would capture sensitive content (passwords on screen, private DMs, customer data). Ask first.
24
+
25
+ ## Terminal recording — asciinema
26
+
27
+ `asciinema` records the **content of a terminal session** as a tiny `.cast` text file. It's a fraction of the size of video, plays in any browser via [asciinema-player](https://github.com/asciinema/asciinema-player), and the output is also greppable.
28
+
29
+ ### Install (one-time per machine)
30
+
31
+ ```bash
32
+ # macOS
33
+ brew install asciinema
34
+
35
+ # Debian / Ubuntu
36
+ sudo apt-get install -y asciinema
37
+
38
+ # Other Linux
39
+ pip install asciinema
40
+ ```
41
+
42
+ ### Record
43
+
44
+ ```bash
45
+ # Start recording; everything you type and every command output goes into the cast.
46
+ asciinema rec ~/recordings/demo-$(date +%s).cast
47
+
48
+ # Run whatever you want to demo. Then exit the recording with Ctrl-D or `exit`.
49
+
50
+ # Replay locally:
51
+ asciinema play ~/recordings/demo-1700000000.cast
52
+
53
+ # Upload to asciinema.org (public, optional):
54
+ asciinema upload ~/recordings/demo-1700000000.cast
55
+ ```
56
+
57
+ ### Non-interactive recording (script-driven)
58
+
59
+ If you (the agent) are running a sequence of commands and want to record without sitting in an interactive prompt:
60
+
61
+ ```bash
62
+ # Record a single command's output:
63
+ asciinema rec --command "bash -c 'npm test; echo exit=$?'" out.cast
64
+
65
+ # Or record into a file while a script runs:
66
+ asciinema rec --idle-time-limit 2 --title "test run $(date)" out.cast \
67
+ --command "./scripts/run-the-thing.sh"
68
+ ```
69
+
70
+ `--idle-time-limit 2` collapses dead-air pauses longer than 2s so the playback isn't boring.
71
+
72
+ ### Hand the file to the user
73
+
74
+ When you're done:
75
+
76
+ 1. Move the `.cast` to a stable path under `~/recordings/` or the session workspace.
77
+ 2. Tell the user the path. If `agent-remote-server` is configured, you can upload via the storage API and give them a signed URL — see the bash example below.
78
+ 3. Mention they can either `asciinema play <file>` locally or open the URL.
79
+
80
+ ```bash
81
+ # Optional: upload to GCS via the storage route if configured
82
+ RECORDING=~/recordings/demo-$(date +%s).cast
83
+ curl -fsS -X POST "${SPARKECODER_REMOTE_URL}/storage/upload" \
84
+ -H "Authorization: Bearer ${SPARKECODER_AUTH_KEY}" \
85
+ -F "file=@${RECORDING}" | jq .url
86
+ ```
87
+
88
+ ## Screen recording — macOS native
89
+
90
+ macOS ships with `screencapture`, no extra install needed. It writes `.mov` (H.264) which any modern app/browser plays.
91
+
92
+ ### Requirements
93
+
94
+ - **Screen Recording permission** for the agent's parent process (Terminal, iTerm, IDE, or `node`).
95
+ - `sparkecoder check-permissions` verifies; `sparkecoder request-permissions` opens the right System Settings pane.
96
+
97
+ ### Record
98
+
99
+ ```bash
100
+ # Record the entire primary display until Ctrl-C (or the agent sends SIGINT to the process):
101
+ screencapture -v ~/recordings/screen-$(date +%s).mov &
102
+ REC_PID=$!
103
+
104
+ # ... do work via computer-use, bash, etc. ...
105
+
106
+ # Stop cleanly:
107
+ kill -INT $REC_PID
108
+ wait $REC_PID 2>/dev/null
109
+ ```
110
+
111
+ Useful flags:
112
+
113
+ - `-V <seconds>` — stop automatically after this many seconds (no need for kill).
114
+ - `-R x,y,w,h` — record just a rectangle.
115
+ - `-C` — also capture mouse cursor (off by default).
116
+ - `-G <displayID>` — pick a specific display (run `system_profiler SPDisplaysDataType` to list).
117
+ - `-T <seconds>` — pre-roll countdown before starting.
118
+
119
+ Example: 30-second auto-stop, full screen, with cursor:
120
+
121
+ ```bash
122
+ screencapture -v -V 30 -C ~/recordings/full-$(date +%s).mov
123
+ ```
124
+
125
+ ## Screen recording — Linux (`ffmpeg`)
126
+
127
+ ```bash
128
+ sudo apt-get install -y ffmpeg
129
+
130
+ # Record the X display. Adjust :0.0 / resolution for your setup.
131
+ ffmpeg -y -f x11grab -framerate 25 -video_size 1920x1080 -i :0.0 \
132
+ -c:v libx264 -preset veryfast -pix_fmt yuv420p \
133
+ ~/recordings/screen-$(date +%s).mp4
134
+
135
+ # Stop with Ctrl-C or kill the ffmpeg pid.
136
+ ```
137
+
138
+ On a headless server with no X, screen recording isn't meaningful — record the terminal with `asciinema` instead.
139
+
140
+ ## Quick recipes
141
+
142
+ | You want to … | Use |
143
+ |---|---|
144
+ | Capture a CLI demo, share a link | `asciinema rec → upload` |
145
+ | Show what a computer-use task did on the desktop | `screencapture -v -V <seconds>` (macOS) |
146
+ | Debug a flaky GUI test on Linux CI | `ffmpeg -f x11grab` around the test run |
147
+ | Capture a single command's output verbatim | `asciinema rec --command "cmd" out.cast` |
148
+ | Both terminal AND screen at once | start `asciinema rec` in a sub-shell AND `screencapture -v` in parallel |
149
+
150
+ ## Best practices
151
+
152
+ 1. **Always announce.** Before starting a recording, post a short message to the user: "Starting screen recording for the Calculator demo." So they can intervene if it'd capture something sensitive.
153
+ 2. **Auto-stop with a timer when you can.** `screencapture -V 60` is much safer than relying on the agent to remember to kill the process. Recordings that go forever fill disks.
154
+ 3. **Use stable file names.** `~/recordings/<task-name>-<unix-ts>.<ext>`. The unix timestamp prevents overwrites and makes sorting easy.
155
+ 4. **Clean up after yourself.** If the user only wanted to scrub through it once, delete the file when done — recordings are often huge.
156
+ 5. **Don't record secrets.** Refuse to record if the screen contains visible passwords, 1Password vaults, customer PII, etc. Ask the user to close those windows first.
157
+ 6. **For computer-use tasks: prefer recording the whole session, not per-action.** Starting `screencapture -v -V 120` once around your whole interaction is cheaper and produces a continuous video.
158
+ 7. **Mention the file in your final message.** "Recording saved to `~/recordings/calc-1700000000.mov`" — otherwise the user won't know where to look.
159
+
160
+ ## Returning the recording in your final task summary
161
+
162
+ For a **task worker** that captured a recording, include the path and a one-line description in your `result` so the orchestrator can route it back to the user:
163
+
164
+ ```ts
165
+ {
166
+ "summary": "Opened Calculator, typed 2+2, hit Return. Got 4.",
167
+ "screencapture": "~/recordings/calc-1700000000.mov",
168
+ "screencapture_description": "60s screen recording of the entire Calculator interaction"
169
+ }
170
+ ```
171
+
172
+ The orchestrator can then attach / post the file via Slack or whatever channel the original request came in on.
@@ -1 +1 @@
1
- mC7Yp8aJpCL22mrYVzIEG
1
+ N09EiHl0JwEgsGMdCtwpB
@@ -1 +1 @@
1
- mC7Yp8aJpCL22mrYVzIEG
1
+ N09EiHl0JwEgsGMdCtwpB
@@ -7,8 +7,8 @@
7
7
  "static/chunks/a6dad97d9634a72d.js"
8
8
  ],
9
9
  "lowPriorityFiles": [
10
- "static/mC7Yp8aJpCL22mrYVzIEG/_ssgManifest.js",
11
- "static/mC7Yp8aJpCL22mrYVzIEG/_buildManifest.js"
10
+ "static/N09EiHl0JwEgsGMdCtwpB/_ssgManifest.js",
11
+ "static/N09EiHl0JwEgsGMdCtwpB/_buildManifest.js"
12
12
  ],
13
13
  "rootMainFiles": [
14
14
  "static/chunks/651e187cc15d66de.js",
@@ -367,8 +367,8 @@
367
367
  "dynamicRoutes": {},
368
368
  "notFoundRoutes": [],
369
369
  "preview": {
370
- "previewModeId": "79c2ff3b3e0e05351c87d5ce707e28a6",
371
- "previewModeSigningKey": "c1e0783b8b9f89caf7a9a27d7b457e7b897d5ad98f3e75e27d39ed1ae0f2078e",
372
- "previewModeEncryptionKey": "8bb1e0f83531b92db30d127bc55ce5b3ab0ad1a4ac2728cda33424894dec3a1b"
370
+ "previewModeId": "d7e724670d207f21c0f5034d346976e5",
371
+ "previewModeSigningKey": "9b405af8ca111a80edf9bbf89cd645933d0e2db6ad1e7409914619ea3fcf27e1",
372
+ "previewModeEncryptionKey": "f4162302e7d425faa461fa6c9ce01feab11721742085a3ff6f5d758670e7e6af"
373
373
  }
374
374
  }
@@ -1,2 +1,2 @@
1
- <!DOCTYPE html><!--mC7Yp8aJpCL22mrYVzIEG--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/651e187cc15d66de.js"/><script src="/_next/static/chunks/735a2408c315b2f0.js" async=""></script><script src="/_next/static/chunks/186e0c1b3ff43c9c.js" async=""></script><script src="/_next/static/chunks/a14243261b055626.js" async=""></script><script src="/_next/static/chunks/862ced58ce21a270.js" async=""></script><script src="/_next/static/chunks/turbopack-2c0905c7bbebae3f.js" async=""></script><script src="/_next/static/chunks/9b5512fb633ef95d.js" async=""></script><script src="/_next/static/chunks/0f1cf11540868e42.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><link rel="icon" href="/favicon.ico?favicon.e3cbed1b.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
- @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/651e187cc15d66de.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[488287,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"default\"]\n3:I[174895,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"default\"]\n4:I[151858,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[151858,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"ViewportBoundary\"]\n9:I[151858,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"MetadataBoundary\"]\nb:I[552576,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"mC7Yp8aJpCL22mrYVzIEG\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"c:I[349310,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"IconMark\"]\n6:null\na:[[\"$\",\"link\",\"0\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.e3cbed1b.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lc\",\"1\",{}]]\n"])</script></body></html>
1
+ <!DOCTYPE html><!--N09EiHl0JwEgsGMdCtwpB--><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/651e187cc15d66de.js"/><script src="/_next/static/chunks/735a2408c315b2f0.js" async=""></script><script src="/_next/static/chunks/186e0c1b3ff43c9c.js" async=""></script><script src="/_next/static/chunks/a14243261b055626.js" async=""></script><script src="/_next/static/chunks/862ced58ce21a270.js" async=""></script><script src="/_next/static/chunks/turbopack-2c0905c7bbebae3f.js" async=""></script><script src="/_next/static/chunks/9b5512fb633ef95d.js" async=""></script><script src="/_next/static/chunks/0f1cf11540868e42.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: Internal Server Error.</title><link rel="icon" href="/favicon.ico?favicon.e3cbed1b.ico" sizes="256x256" type="image/x-icon"/><script src="/_next/static/chunks/a6dad97d9634a72d.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}
2
+ @media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/651e187cc15d66de.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[488287,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"default\"]\n3:I[174895,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"default\"]\n4:I[151858,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n7:I[151858,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"ViewportBoundary\"]\n9:I[151858,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"MetadataBoundary\"]\nb:I[552576,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"N09EiHl0JwEgsGMdCtwpB\",\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"title\",null,{\"children\":\"500: Internal Server Error.\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"lineHeight\":\"48px\"},\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"paddingRight\":23,\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\"},\"children\":\"500\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"28px\"},\"children\":\"Internal Server Error.\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L7\",null,{\"children\":\"$L8\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L9\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$La\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$b\",\"$undefined\"],\"S\":true}\n"])</script><script>self.__next_f.push([1,"8:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"c:I[349310,[\"/_next/static/chunks/9b5512fb633ef95d.js\",\"/_next/static/chunks/0f1cf11540868e42.js\"],\"IconMark\"]\n6:null\na:[[\"$\",\"link\",\"0\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.e3cbed1b.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"$Lc\",\"1\",{}]]\n"])</script></body></html>
@@ -6,7 +6,7 @@
6
6
  7:I[151858,["/_next/static/chunks/9b5512fb633ef95d.js","/_next/static/chunks/0f1cf11540868e42.js"],"ViewportBoundary"]
7
7
  9:I[151858,["/_next/static/chunks/9b5512fb633ef95d.js","/_next/static/chunks/0f1cf11540868e42.js"],"MetadataBoundary"]
8
8
  b:I[552576,["/_next/static/chunks/9b5512fb633ef95d.js","/_next/static/chunks/0f1cf11540868e42.js"],"default"]
9
- 0:{"P":null,"b":"mC7Yp8aJpCL22mrYVzIEG","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b","$undefined"],"S":true}
9
+ 0:{"P":null,"b":"N09EiHl0JwEgsGMdCtwpB","c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":["$","title",null,{"children":"500: Internal Server Error."}]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"lineHeight":"48px"},"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}\n@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","paddingRight":23,"fontSize":24,"fontWeight":500,"verticalAlign":"top"},"children":"500"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"28px"},"children":"Internal Server Error."}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,false]},null,false,false],["$","$1","h",{"children":[null,["$","$L7",null,{"children":"$L8"}],["$","div",null,{"hidden":true,"children":["$","$L9",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$La"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],false]],"m":"$undefined","G":["$b","$undefined"],"S":true}
10
10
  8:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
11
11
  c:I[349310,["/_next/static/chunks/9b5512fb633ef95d.js","/_next/static/chunks/0f1cf11540868e42.js"],"IconMark"]
12
12
  6:null