background-agents 0.1.2 → 1.0.2

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 (236) hide show
  1. package/README.md +46 -297
  2. package/app/assets/icon.png +0 -0
  3. package/app/assets/tray-icon.png +0 -0
  4. package/app/assets/tray-icon.svg +4 -0
  5. package/app/dist/main.js +932 -0
  6. package/app/dist/preload.cjs +70 -0
  7. package/app/package.json +6 -0
  8. package/bin/background-agents.js +298 -0
  9. package/lib/ui.js +110 -0
  10. package/package.json +33 -57
  11. package/dist/agents/claude/index.d.ts +0 -11
  12. package/dist/agents/claude/index.d.ts.map +0 -1
  13. package/dist/agents/claude/index.js +0 -78
  14. package/dist/agents/claude/index.js.map +0 -1
  15. package/dist/agents/claude/parser.d.ts +0 -16
  16. package/dist/agents/claude/parser.d.ts.map +0 -1
  17. package/dist/agents/claude/parser.js +0 -87
  18. package/dist/agents/claude/parser.js.map +0 -1
  19. package/dist/agents/claude/tools.d.ts +0 -7
  20. package/dist/agents/claude/tools.d.ts.map +0 -1
  21. package/dist/agents/claude/tools.js +0 -15
  22. package/dist/agents/claude/tools.js.map +0 -1
  23. package/dist/agents/codex/index.d.ts +0 -11
  24. package/dist/agents/codex/index.d.ts.map +0 -1
  25. package/dist/agents/codex/index.js +0 -60
  26. package/dist/agents/codex/index.js.map +0 -1
  27. package/dist/agents/codex/parser.d.ts +0 -12
  28. package/dist/agents/codex/parser.d.ts.map +0 -1
  29. package/dist/agents/codex/parser.js +0 -108
  30. package/dist/agents/codex/parser.js.map +0 -1
  31. package/dist/agents/codex/tools.d.ts +0 -11
  32. package/dist/agents/codex/tools.d.ts.map +0 -1
  33. package/dist/agents/codex/tools.js +0 -40
  34. package/dist/agents/codex/tools.js.map +0 -1
  35. package/dist/agents/eliza/bundle-content.d.ts +0 -6
  36. package/dist/agents/eliza/bundle-content.d.ts.map +0 -1
  37. package/dist/agents/eliza/bundle-content.js +0 -7
  38. package/dist/agents/eliza/bundle-content.js.map +0 -1
  39. package/dist/agents/eliza/cli.bundle.js +0 -579
  40. package/dist/agents/eliza/cli.d.ts +0 -10
  41. package/dist/agents/eliza/cli.d.ts.map +0 -1
  42. package/dist/agents/eliza/cli.js +0 -342
  43. package/dist/agents/eliza/cli.js.map +0 -1
  44. package/dist/agents/eliza/index.d.ts +0 -22
  45. package/dist/agents/eliza/index.d.ts.map +0 -1
  46. package/dist/agents/eliza/index.js +0 -54
  47. package/dist/agents/eliza/index.js.map +0 -1
  48. package/dist/agents/eliza/parser.d.ts +0 -16
  49. package/dist/agents/eliza/parser.d.ts.map +0 -1
  50. package/dist/agents/eliza/parser.js +0 -67
  51. package/dist/agents/eliza/parser.js.map +0 -1
  52. package/dist/agents/eliza/patterns.d.ts +0 -41
  53. package/dist/agents/eliza/patterns.d.ts.map +0 -1
  54. package/dist/agents/eliza/patterns.js +0 -259
  55. package/dist/agents/eliza/patterns.js.map +0 -1
  56. package/dist/agents/eliza/tools.d.ts +0 -7
  57. package/dist/agents/eliza/tools.d.ts.map +0 -1
  58. package/dist/agents/eliza/tools.js +0 -14
  59. package/dist/agents/eliza/tools.js.map +0 -1
  60. package/dist/agents/gemini/index.d.ts +0 -11
  61. package/dist/agents/gemini/index.d.ts.map +0 -1
  62. package/dist/agents/gemini/index.js +0 -46
  63. package/dist/agents/gemini/index.js.map +0 -1
  64. package/dist/agents/gemini/parser.d.ts +0 -31
  65. package/dist/agents/gemini/parser.d.ts.map +0 -1
  66. package/dist/agents/gemini/parser.js +0 -106
  67. package/dist/agents/gemini/parser.js.map +0 -1
  68. package/dist/agents/gemini/tools.d.ts +0 -7
  69. package/dist/agents/gemini/tools.d.ts.map +0 -1
  70. package/dist/agents/gemini/tools.js +0 -23
  71. package/dist/agents/gemini/tools.js.map +0 -1
  72. package/dist/agents/goose/index.d.ts +0 -11
  73. package/dist/agents/goose/index.d.ts.map +0 -1
  74. package/dist/agents/goose/index.js +0 -73
  75. package/dist/agents/goose/index.js.map +0 -1
  76. package/dist/agents/goose/parser.d.ts +0 -24
  77. package/dist/agents/goose/parser.d.ts.map +0 -1
  78. package/dist/agents/goose/parser.js +0 -86
  79. package/dist/agents/goose/parser.js.map +0 -1
  80. package/dist/agents/goose/tools.d.ts +0 -10
  81. package/dist/agents/goose/tools.d.ts.map +0 -1
  82. package/dist/agents/goose/tools.js +0 -30
  83. package/dist/agents/goose/tools.js.map +0 -1
  84. package/dist/agents/index.d.ts +0 -27
  85. package/dist/agents/index.d.ts.map +0 -1
  86. package/dist/agents/index.js +0 -46
  87. package/dist/agents/index.js.map +0 -1
  88. package/dist/agents/opencode/index.d.ts +0 -12
  89. package/dist/agents/opencode/index.d.ts.map +0 -1
  90. package/dist/agents/opencode/index.js +0 -53
  91. package/dist/agents/opencode/index.js.map +0 -1
  92. package/dist/agents/opencode/parser.d.ts +0 -15
  93. package/dist/agents/opencode/parser.d.ts.map +0 -1
  94. package/dist/agents/opencode/parser.js +0 -71
  95. package/dist/agents/opencode/parser.js.map +0 -1
  96. package/dist/agents/opencode/tools.d.ts +0 -7
  97. package/dist/agents/opencode/tools.d.ts.map +0 -1
  98. package/dist/agents/opencode/tools.js +0 -10
  99. package/dist/agents/opencode/tools.js.map +0 -1
  100. package/dist/agents/openhands/index.d.ts +0 -17
  101. package/dist/agents/openhands/index.d.ts.map +0 -1
  102. package/dist/agents/openhands/index.js +0 -67
  103. package/dist/agents/openhands/index.js.map +0 -1
  104. package/dist/agents/openhands/parser.d.ts +0 -16
  105. package/dist/agents/openhands/parser.d.ts.map +0 -1
  106. package/dist/agents/openhands/parser.js +0 -93
  107. package/dist/agents/openhands/parser.js.map +0 -1
  108. package/dist/agents/openhands/tools.d.ts +0 -7
  109. package/dist/agents/openhands/tools.d.ts.map +0 -1
  110. package/dist/agents/openhands/tools.js +0 -24
  111. package/dist/agents/openhands/tools.js.map +0 -1
  112. package/dist/agents/pi/index.d.ts +0 -14
  113. package/dist/agents/pi/index.d.ts.map +0 -1
  114. package/dist/agents/pi/index.js +0 -54
  115. package/dist/agents/pi/index.js.map +0 -1
  116. package/dist/agents/pi/parser.d.ts +0 -21
  117. package/dist/agents/pi/parser.d.ts.map +0 -1
  118. package/dist/agents/pi/parser.js +0 -91
  119. package/dist/agents/pi/parser.js.map +0 -1
  120. package/dist/agents/pi/tools.d.ts +0 -8
  121. package/dist/agents/pi/tools.d.ts.map +0 -1
  122. package/dist/agents/pi/tools.js +0 -16
  123. package/dist/agents/pi/tools.js.map +0 -1
  124. package/dist/agents/picocode/index.d.ts +0 -18
  125. package/dist/agents/picocode/index.d.ts.map +0 -1
  126. package/dist/agents/picocode/index.js +0 -68
  127. package/dist/agents/picocode/index.js.map +0 -1
  128. package/dist/agents/picocode/parser.d.ts +0 -19
  129. package/dist/agents/picocode/parser.d.ts.map +0 -1
  130. package/dist/agents/picocode/parser.js +0 -104
  131. package/dist/agents/picocode/parser.js.map +0 -1
  132. package/dist/agents/picocode/tools.d.ts +0 -9
  133. package/dist/agents/picocode/tools.d.ts.map +0 -1
  134. package/dist/agents/picocode/tools.js +0 -27
  135. package/dist/agents/picocode/tools.js.map +0 -1
  136. package/dist/background/index.d.ts +0 -6
  137. package/dist/background/index.d.ts.map +0 -1
  138. package/dist/background/index.js +0 -5
  139. package/dist/background/index.js.map +0 -1
  140. package/dist/background/session.d.ts +0 -47
  141. package/dist/background/session.d.ts.map +0 -1
  142. package/dist/background/session.js +0 -481
  143. package/dist/background/session.js.map +0 -1
  144. package/dist/background/types.d.ts +0 -55
  145. package/dist/background/types.d.ts.map +0 -1
  146. package/dist/background/types.js +0 -5
  147. package/dist/background/types.js.map +0 -1
  148. package/dist/core/agent.d.ts +0 -95
  149. package/dist/core/agent.d.ts.map +0 -1
  150. package/dist/core/agent.js +0 -8
  151. package/dist/core/agent.js.map +0 -1
  152. package/dist/core/index.d.ts +0 -7
  153. package/dist/core/index.d.ts.map +0 -1
  154. package/dist/core/index.js +0 -6
  155. package/dist/core/index.js.map +0 -1
  156. package/dist/core/registry.d.ts +0 -48
  157. package/dist/core/registry.d.ts.map +0 -1
  158. package/dist/core/registry.js +0 -68
  159. package/dist/core/registry.js.map +0 -1
  160. package/dist/core/tools.d.ts +0 -31
  161. package/dist/core/tools.d.ts.map +0 -1
  162. package/dist/core/tools.js +0 -82
  163. package/dist/core/tools.js.map +0 -1
  164. package/dist/debug.d.ts +0 -7
  165. package/dist/debug.d.ts.map +0 -1
  166. package/dist/debug.js +0 -19
  167. package/dist/debug.js.map +0 -1
  168. package/dist/factory.d.ts +0 -28
  169. package/dist/factory.d.ts.map +0 -1
  170. package/dist/factory.js +0 -44
  171. package/dist/factory.js.map +0 -1
  172. package/dist/index.d.ts +0 -48
  173. package/dist/index.d.ts.map +0 -1
  174. package/dist/index.js +0 -62
  175. package/dist/index.js.map +0 -1
  176. package/dist/providers/base.d.ts +0 -187
  177. package/dist/providers/base.d.ts.map +0 -1
  178. package/dist/providers/base.js +0 -619
  179. package/dist/providers/base.js.map +0 -1
  180. package/dist/providers/claude.d.ts +0 -14
  181. package/dist/providers/claude.d.ts.map +0 -1
  182. package/dist/providers/claude.js +0 -122
  183. package/dist/providers/claude.js.map +0 -1
  184. package/dist/providers/codex.d.ts +0 -14
  185. package/dist/providers/codex.d.ts.map +0 -1
  186. package/dist/providers/codex.js +0 -160
  187. package/dist/providers/codex.js.map +0 -1
  188. package/dist/providers/gemini.d.ts +0 -16
  189. package/dist/providers/gemini.d.ts.map +0 -1
  190. package/dist/providers/gemini.js +0 -101
  191. package/dist/providers/gemini.js.map +0 -1
  192. package/dist/providers/index.d.ts +0 -6
  193. package/dist/providers/index.d.ts.map +0 -1
  194. package/dist/providers/index.js +0 -6
  195. package/dist/providers/index.js.map +0 -1
  196. package/dist/providers/opencode.d.ts +0 -14
  197. package/dist/providers/opencode.d.ts.map +0 -1
  198. package/dist/providers/opencode.js +0 -100
  199. package/dist/providers/opencode.js.map +0 -1
  200. package/dist/sandbox/daytona.d.ts +0 -8
  201. package/dist/sandbox/daytona.d.ts.map +0 -1
  202. package/dist/sandbox/daytona.js +0 -181
  203. package/dist/sandbox/daytona.js.map +0 -1
  204. package/dist/sandbox/index.d.ts +0 -14
  205. package/dist/sandbox/index.d.ts.map +0 -1
  206. package/dist/sandbox/index.js +0 -15
  207. package/dist/sandbox/index.js.map +0 -1
  208. package/dist/session.d.ts +0 -75
  209. package/dist/session.d.ts.map +0 -1
  210. package/dist/session.js +0 -117
  211. package/dist/session.js.map +0 -1
  212. package/dist/types/events.d.ts +0 -114
  213. package/dist/types/events.d.ts.map +0 -1
  214. package/dist/types/events.js +0 -50
  215. package/dist/types/events.js.map +0 -1
  216. package/dist/types/index.d.ts +0 -3
  217. package/dist/types/index.d.ts.map +0 -1
  218. package/dist/types/index.js +0 -3
  219. package/dist/types/index.js.map +0 -1
  220. package/dist/types/provider.d.ts +0 -67
  221. package/dist/types/provider.d.ts.map +0 -1
  222. package/dist/types/provider.js +0 -5
  223. package/dist/types/provider.js.map +0 -1
  224. package/dist/utils/index.d.ts +0 -3
  225. package/dist/utils/index.d.ts.map +0 -1
  226. package/dist/utils/index.js +0 -3
  227. package/dist/utils/index.js.map +0 -1
  228. package/dist/utils/install.d.ts +0 -37
  229. package/dist/utils/install.d.ts.map +0 -1
  230. package/dist/utils/install.js +0 -122
  231. package/dist/utils/install.js.map +0 -1
  232. package/dist/utils/json.d.ts +0 -8
  233. package/dist/utils/json.d.ts.map +0 -1
  234. package/dist/utils/json.js +0 -15
  235. package/dist/utils/json.js.map +0 -1
  236. package/src/index.ts +0 -156
package/README.md CHANGED
@@ -1,334 +1,83 @@
1
- # Background Agents SDK
1
+ # background-agents
2
2
 
3
- A TypeScript SDK for running AI coding agents (Claude, Codex, Gemini, Goose, OpenCode, Pi) in secure [Daytona](https://daytona.io) sandboxes. Designed for background execution with polling-based event streaming.
4
-
5
- ```typescript
6
- import { Daytona } from "@daytonaio/sdk"
7
- import { createSession } from "background-agents"
8
-
9
- const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })
10
- const sandbox = await daytona.create()
11
-
12
- const session = await createSession("claude", {
13
- sandbox,
14
- env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY }
15
- })
16
-
17
- await session.start("Refactor the auth module")
18
-
19
- // Poll for events
20
- while (await session.isRunning()) {
21
- const { events } = await session.getEvents()
22
- for (const event of events) {
23
- if (event.type === "token") process.stdout.write(event.text)
24
- }
25
- await new Promise(r => setTimeout(r, 1000))
26
- }
27
-
28
- await sandbox.delete()
29
- ```
30
-
31
- ---
32
-
33
- ## Features
34
-
35
- - **Secure sandboxed execution** — Agents run in isolated Daytona sandboxes
36
- - **Background execution** — Start agents, poll for events, survive restarts
37
- - **Unified API** — One interface for [Claude](https://docs.anthropic.com/en/docs/claude-code), [Codex](https://developers.openai.com/codex/cli), [Gemini](https://geminicli.com/docs/), [Goose](https://block.github.io/goose/docs/), [OpenCode](https://opencode.ai/docs/), and [Pi](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent)
38
- - **Zero-friction setup** — Provider CLI auto-installed in sandbox
39
- - **Session persistence** — Resume conversations across runs and restarts
40
-
41
- ---
42
-
43
- ## Provider support
44
-
45
- | Provider | Status | Auth |
46
- |----------|--------|------|
47
- | [Claude](https://docs.anthropic.com/en/docs/claude-code) | ✅ | `ANTHROPIC_API_KEY` or `CLAUDE_CODE_CREDENTIALS` |
48
- | [Codex](https://developers.openai.com/codex/cli) | ✅ | `OPENAI_API_KEY` |
49
- | [Goose](https://block.github.io/goose/docs/) | ✅ | Provider-specific (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`) |
50
- | [OpenCode](https://opencode.ai/docs/) | ✅ | Provider-specific (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`) |
51
- | [Gemini](https://geminicli.com/docs/) | ✅ | `GEMINI_API_KEY` |
52
- | [Pi](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent) | ✅ | Provider-specific (e.g. `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`) |
53
-
54
- ### CLI reference commands
55
-
56
- | Provider | CLI Command |
57
- |----------|-------------|
58
- | Claude | `claude -p --output-format stream-json --verbose --dangerously-skip-permissions "prompt"` |
59
- | Codex | `codex exec --json --skip-git-repo-check --yolo "prompt"` |
60
- | Goose | `goose run --output-format stream-json --text "prompt"` |
61
- | OpenCode | `opencode run --format json --variant medium "prompt"` |
62
- | Gemini | `gemini --output-format stream-json --yolo -p "prompt"` |
63
- | Pi | `pi --mode json -p "prompt"` |
64
-
65
- ---
66
-
67
- ## Prerequisites
68
-
69
- A [Daytona](https://daytona.io) API key for secure sandboxed execution.
70
-
71
- ```bash
72
- export DAYTONA_API_KEY=dtn_your_api_key
73
- ```
74
-
75
- ---
76
-
77
- ## Installation
3
+ Launch the **Background Agents** desktop app with a single command no install, always the latest version:
78
4
 
79
5
  ```bash
80
- npm install background-agents @daytonaio/sdk
81
- ```
82
-
83
- ---
84
-
85
- ## Quick start
86
-
87
- ```typescript
88
- import { Daytona } from "@daytonaio/sdk"
89
- import { createSession } from "background-agents"
90
-
91
- // 1. Create sandbox
92
- const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })
93
- const sandbox = await daytona.create()
94
-
95
- // 2. Create session
96
- const session = await createSession("claude", {
97
- sandbox,
98
- env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY },
99
- model: "sonnet",
100
- systemPrompt: "You are a helpful coding assistant.",
101
- })
102
-
103
- // 3. Start a task
104
- await session.start("Create a hello world script")
105
-
106
- // 4. Poll for events
107
- while (await session.isRunning()) {
108
- const { events } = await session.getEvents()
109
- for (const event of events) {
110
- if (event.type === "token") process.stdout.write(event.text)
111
- if (event.type === "tool_start") console.log(`\n[Tool: ${event.name}]`)
112
- if (event.type === "end") console.log("\nDone.")
113
- }
114
- await new Promise(r => setTimeout(r, 1000))
115
- }
116
-
117
- // 5. Cleanup
118
- await sandbox.delete()
119
- ```
120
-
121
- ---
122
-
123
- ## Restart-tolerant workflows
124
-
125
- The SDK is designed for long-running tasks that may outlive your server process. Persist `sandbox.id` and `session.id`, then reattach after restart.
126
-
127
- ```typescript
128
- import { Daytona } from "@daytonaio/sdk"
129
- import { createSession, getSession } from "background-agents"
130
-
131
- const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY! })
132
- const sandbox = await daytona.create()
133
-
134
- // Start a task
135
- const session = await createSession("claude", {
136
- sandbox,
137
- env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
138
- model: "sonnet",
139
- })
140
- await session.start("Do a long-running refactor...")
141
-
142
- // Persist these IDs, then exit
143
- const sandboxId = sandbox.id
144
- const sessionId = session.id // Save this to reattach later
145
-
146
- // --- After restart ---
147
-
148
- // Reattach to existing session
149
- const sandbox = await daytona.get(sandboxId)
150
- const session = await getSession(sessionId, { sandbox })
151
-
152
- // Continue polling
153
- const { events, running } = await session.getEvents()
154
- for (const event of events) {
155
- if (event.type === "token") process.stdout.write(event.text)
156
- }
157
-
158
- // Cancel if needed
159
- await session.cancel()
6
+ npx background-agents@latest
160
7
  ```
161
8
 
162
- ---
163
-
164
- ## API reference
165
-
166
- ### `createSession(provider, options)`
167
-
168
- Creates a session. The provider CLI is installed automatically.
169
-
170
- ```typescript
171
- const session = await createSession("claude", {
172
- sandbox, // Daytona sandbox
173
- env: { ANTHROPIC_API_KEY: "sk-..." }, // Environment variables
174
- model: "sonnet", // Optional: model name
175
- systemPrompt: "You are helpful.", // Optional: system prompt
176
- })
177
- ```
178
-
179
- ### `session.start(prompt)`
180
-
181
- Starts a background task. Returns immediately with process info.
182
-
183
- ```typescript
184
- const { pid, outputFile } = await session.start("Your task here")
185
- ```
9
+ That's it. The first run downloads the Electron runtime (~once, then cached); every run loads the production app at <https://backgrounder.dev>.
186
10
 
187
- ### `session.getEvents()`
11
+ > **Naming:** the TypeScript SDK previously published as `background-agents` now lives at [`@background-agents/sdk`](../agents), which freed the `background-agents` name for this desktop launcher.
188
12
 
189
- Polls for new events since last call.
190
-
191
- ```typescript
192
- const { events, running } = await session.getEvents()
193
- // events: Event[] - new events since last poll
194
- // running: boolean - true if agent is still running
195
- ```
196
-
197
- ### `session.isRunning()`
198
-
199
- Returns `true` while the agent is running.
13
+ ## How it works
200
14
 
201
- ### `session.cancel()`
15
+ This is a thin launcher published to npm as [`background-agents`](https://www.npmjs.com/package/background-agents):
202
16
 
203
- Kills the running agent process.
17
+ 1. `npx background-agents@latest` resolves the **latest published version** of this package from the npm registry.
18
+ 2. npm installs it and its one dependency, **Electron**, downloading the platform binary on first run (cached for later runs).
19
+ 3. The launcher spawns the bundled Electron app (`app/`) pointed at the production backend, showing a small terminal UI while it starts.
204
20
 
205
- ### `getSession(sessionId, options)`
21
+ Because every launch pulls the latest npm version, **publishing a new version is the update mechanism** — there's no separate auto-updater to configure or code-sign.
206
22
 
207
- Reattaches to an existing session by ID.
23
+ ## Usage
208
24
 
209
- ```typescript
210
- const session = await getSession(
211
- sessionId, // session.id from createSession()
212
- { sandbox }
213
- )
25
+ ```bash
26
+ npx background-agents [options]
214
27
  ```
215
28
 
216
- ---
217
-
218
- ## Event types
29
+ | Option | Description |
30
+ |--------|-------------|
31
+ | `--url <url>` | Backend URL to load (default: `https://backgrounder.dev`) |
32
+ | `--dev` | Use the local dev server (`http://localhost:4000`) |
33
+ | `--verbose` | Stream the desktop app's logs to the terminal |
34
+ | `-v`, `--version` | Print the launcher version |
35
+ | `-h`, `--help` | Show help |
219
36
 
220
- | Event | Description | Fields |
221
- |-------|-------------|--------|
222
- | `session` | Session started | `id: string` |
223
- | `token` | Streamed text | `text: string` |
224
- | `tool_start` | Tool invoked | `name: string`, `input?: unknown` |
225
- | `tool_delta` | Tool streaming | `text: string` |
226
- | `tool_end` | Tool finished | `output?: string` |
227
- | `end` | Task complete | `error?: string` |
228
- | `agent_crashed` | Process crashed | `message?: string`, `output?: string` |
37
+ Environment variable `BACKGROUND_AGENTS_URL` does the same as `--url` (the flag wins).
229
38
 
230
- ```typescript
231
- type Event =
232
- | { type: "session"; id: string }
233
- | { type: "token"; text: string }
234
- | { type: "tool_start"; name: string; input?: unknown }
235
- | { type: "tool_delta"; text: string }
236
- | { type: "tool_end"; output?: string }
237
- | { type: "end"; error?: string }
238
- | { type: "agent_crashed"; message?: string; output?: string }
239
- ```
39
+ > Tip: plain `npx background-agents` may reuse an npx-cached copy. Use `npx background-agents@latest` to force the newest version.
240
40
 
241
- ---
41
+ ## Caveats
242
42
 
243
- ## Model selection
43
+ - **First run downloads Electron** (~100–150 MB) via npm; it's cached afterward and re-downloaded only when a new version ships a different Electron.
44
+ - The app runs **unpackaged**, so it relies on programmatic `background-agents://` deep-link registration for the OAuth round-trip (same code path as running the app from source). For a fully signed/notarized native install, use the packaged builds from GitHub Releases instead.
45
+ - This package was **0.1.1 / 0.1.2 as the SDK**; the launcher is published from **1.0.0** onward, so `latest` cleanly points at the desktop app.
244
46
 
245
- | Provider | Example | Docs |
246
- |----------|---------|------|
247
- | **Claude** | `model: "sonnet"` | [Claude Code models](https://code.claude.com/docs/en/model-config) |
248
- | **Codex** | `model: "gpt-4o"` | [Codex CLI models](https://developers.openai.com/codex/models) |
249
- | **Goose** | `model: "gpt-4o"` | [Goose providers](https://block.github.io/goose/docs/getting-started/providers) |
250
- | **OpenCode** | `model: "openai/gpt-4o"` | [OpenCode models](https://opencode.ai/docs/models/) |
251
- | **Gemini** | `model: "gemini-2.0-flash"` | [Gemini CLI model](https://geminicli.com/docs/cli/model) |
252
- | **Pi** | `model: "sonnet"` or `model: "openai/gpt-4o"` | [Pi CLI models](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent#providers--models) |
253
-
254
- ---
47
+ ## Development
255
48
 
256
- ## How it works
49
+ This package lives in the monorepo at `packages/launcher`. Its `app/` directory is generated — it's a copy of the compiled `@background-agents/electron` output.
257
50
 
258
- 1. **Sandbox** — Create a Daytona sandbox for isolated execution
259
- 2. **CLI install** — Provider CLI is installed in the sandbox automatically
260
- 3. **Background execution** Agent runs via `nohup`, outputs to a log file
261
- 4. **Polling** SDK polls the log file for new JSON events
262
- 5. **Completion** — A `.done` file signals when the agent finishes
263
- 6. **Cleanup** — You call `sandbox.delete()` when done
51
+ ```bash
52
+ # From the repo root:
53
+ npm run bundle -w background-agents # build the Electron app + copy it into app/
54
+ npm start -w background-agents # run the launcher locally (after bundling)
264
55
 
265
- ```
266
- ┌─────────────┐ ┌──────────────────────────────────────┐
267
- │ Your App │────▶│ Daytona Sandbox │
268
- │ │ │ ┌─────────────┐ ┌─────────────┐ │
269
- │ (polling) │◀────│ │ Log File │◀───│ Agent CLI │ │
270
- │ │ │ └─────────────┘ └─────────────┘ │
271
- └─────────────┘ └──────────────────────────────────────┘
56
+ # Verify the published tarball contents:
57
+ cd packages/launcher && npm pack --dry-run
272
58
  ```
273
59
 
274
- ---
60
+ `prepack` runs the bundle step automatically, so `npm publish` always ships a fresh build.
275
61
 
276
- ## Debug mode
62
+ ## Publishing
277
63
 
278
- Set `CODING_AGENTS_DEBUG=1` to enable debug logging:
279
-
280
- ```bash
281
- CODING_AGENTS_DEBUG=1 npx tsx your-script.ts
282
- ```
64
+ Two ways:
283
65
 
284
- ---
66
+ ### Automatic — on a version tag (GitHub Actions)
285
67
 
286
- ## Claude OAuth credentials
287
-
288
- Claude can authenticate via `ANTHROPIC_API_KEY` or `CLAUDE_CODE_CREDENTIALS`. The latter uses OAuth credentials from a Claude Pro/Max subscription.
289
-
290
- First, sign in locally:
68
+ Pushing a `v*` tag runs the publish workflow, which sets the package version from the tag and publishes to npm (requires the `NPM_TOKEN` repo secret).
291
69
 
292
70
  ```bash
293
- claude auth login
71
+ git tag v1.0.1 && git push origin v1.0.1
294
72
  ```
295
73
 
296
- Then retrieve your credentials:
297
-
298
- | OS | Command |
299
- |----|---------|
300
- | macOS | `security find-generic-password -s "Claude Code-credentials" -w` |
301
- | Linux | `cat ~/.claude/.credentials.json` |
302
- | Windows | `type %USERPROFILE%\.claude\.credentials.json` |
74
+ > The workflow ships as `.github/npm-publish-workflow.yml` (outside `.github/workflows/`, mirroring `release-workflow.yml`, because pushing into `.github/workflows/` needs the GitHub `workflow` OAuth scope). **Move it into `.github/workflows/` to activate it.** Note the same `v*` tag also triggers `release-workflow.yml` (the Electron installers), so the desktop installers and the npm launcher publish together.
303
75
 
304
- Pass the output as `CLAUDE_CODE_CREDENTIALS`. The SDK automatically writes it to `~/.claude/.credentials.json` in the sandbox.
305
-
306
- ---
307
-
308
- ## Development
309
-
310
- Build, test, and iterate locally. Start by installing dependencies and running the unit test suite:
76
+ ### Manual
311
77
 
312
78
  ```bash
313
- npm install
314
- npm run build
315
- npm test
79
+ npm ci # from the repo root
80
+ npm publish -w background-agents --access public
316
81
  ```
317
82
 
318
- For integration and end-to-end testing, see [TESTING.md](./TESTING.md).
319
-
320
- For testing scenarios, you can use the deterministic Eliza agent, which requires no provider API key.
321
-
322
- ---
323
-
324
- ## Resources
325
-
326
- **Sandbox** — [Daytona Docs](https://www.daytona.io/docs/) · [Daytona GitHub](https://github.com/daytonaio/daytona)
327
-
328
- **Agents** — [Claude Code](https://docs.anthropic.com/en/docs/claude-code) · [Codex CLI](https://developers.openai.com/codex/cli) · [Gemini CLI](https://geminicli.com/docs/) · [Goose](https://block.github.io/goose/docs/) · [OpenCode](https://opencode.ai/docs/) · [Pi](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent)
329
-
330
- ---
331
-
332
- ## License
333
-
334
- MIT
83
+ You must be logged in (`npm login`) with publish rights to the `background-agents` package. The first launcher publish must be version **≥ 1.0.0** (0.1.1 / 0.1.2 already exist from the SDK era).
Binary file
Binary file
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
2
+ <circle cx="8" cy="8" r="6" fill="none" stroke="currentColor" stroke-width="1.5"/>
3
+ <circle cx="8" cy="8" r="2" fill="currentColor"/>
4
+ </svg>