background-agents 0.1.1 → 1.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.
Files changed (90) hide show
  1. package/README.md +45 -364
  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/bin/background-agents.js +298 -0
  8. package/lib/ui.js +110 -0
  9. package/package.json +32 -47
  10. package/dist/debug.d.ts +0 -7
  11. package/dist/debug.d.ts.map +0 -1
  12. package/dist/debug.js +0 -19
  13. package/dist/debug.js.map +0 -1
  14. package/dist/factory.d.ts +0 -31
  15. package/dist/factory.d.ts.map +0 -1
  16. package/dist/factory.js +0 -47
  17. package/dist/factory.js.map +0 -1
  18. package/dist/index.d.ts +0 -30
  19. package/dist/index.d.ts.map +0 -1
  20. package/dist/index.js +0 -35
  21. package/dist/index.js.map +0 -1
  22. package/dist/providers/base.d.ts +0 -160
  23. package/dist/providers/base.d.ts.map +0 -1
  24. package/dist/providers/base.js +0 -656
  25. package/dist/providers/base.js.map +0 -1
  26. package/dist/providers/claude.d.ts +0 -14
  27. package/dist/providers/claude.d.ts.map +0 -1
  28. package/dist/providers/claude.js +0 -122
  29. package/dist/providers/claude.js.map +0 -1
  30. package/dist/providers/codex.d.ts +0 -14
  31. package/dist/providers/codex.d.ts.map +0 -1
  32. package/dist/providers/codex.js +0 -160
  33. package/dist/providers/codex.js.map +0 -1
  34. package/dist/providers/gemini.d.ts +0 -16
  35. package/dist/providers/gemini.d.ts.map +0 -1
  36. package/dist/providers/gemini.js +0 -91
  37. package/dist/providers/gemini.js.map +0 -1
  38. package/dist/providers/index.d.ts +0 -6
  39. package/dist/providers/index.d.ts.map +0 -1
  40. package/dist/providers/index.js +0 -6
  41. package/dist/providers/index.js.map +0 -1
  42. package/dist/providers/opencode.d.ts +0 -14
  43. package/dist/providers/opencode.d.ts.map +0 -1
  44. package/dist/providers/opencode.js +0 -100
  45. package/dist/providers/opencode.js.map +0 -1
  46. package/dist/sandbox/daytona-ssh.d.ts +0 -9
  47. package/dist/sandbox/daytona-ssh.d.ts.map +0 -1
  48. package/dist/sandbox/daytona-ssh.js +0 -113
  49. package/dist/sandbox/daytona-ssh.js.map +0 -1
  50. package/dist/sandbox/daytona.d.ts +0 -4
  51. package/dist/sandbox/daytona.d.ts.map +0 -1
  52. package/dist/sandbox/daytona.js +0 -238
  53. package/dist/sandbox/daytona.js.map +0 -1
  54. package/dist/sandbox/index.d.ts +0 -14
  55. package/dist/sandbox/index.d.ts.map +0 -1
  56. package/dist/sandbox/index.js +0 -15
  57. package/dist/sandbox/index.js.map +0 -1
  58. package/dist/session.d.ts +0 -64
  59. package/dist/session.d.ts.map +0 -1
  60. package/dist/session.js +0 -113
  61. package/dist/session.js.map +0 -1
  62. package/dist/types/events.d.ts +0 -114
  63. package/dist/types/events.d.ts.map +0 -1
  64. package/dist/types/events.js +0 -50
  65. package/dist/types/events.js.map +0 -1
  66. package/dist/types/index.d.ts +0 -3
  67. package/dist/types/index.d.ts.map +0 -1
  68. package/dist/types/index.js +0 -3
  69. package/dist/types/index.js.map +0 -1
  70. package/dist/types/provider.d.ts +0 -124
  71. package/dist/types/provider.d.ts.map +0 -1
  72. package/dist/types/provider.js +0 -2
  73. package/dist/types/provider.js.map +0 -1
  74. package/dist/utils/index.d.ts +0 -4
  75. package/dist/utils/index.d.ts.map +0 -1
  76. package/dist/utils/index.js +0 -4
  77. package/dist/utils/index.js.map +0 -1
  78. package/dist/utils/install.d.ts +0 -27
  79. package/dist/utils/install.d.ts.map +0 -1
  80. package/dist/utils/install.js +0 -86
  81. package/dist/utils/install.js.map +0 -1
  82. package/dist/utils/json.d.ts +0 -8
  83. package/dist/utils/json.d.ts.map +0 -1
  84. package/dist/utils/json.js +0 -15
  85. package/dist/utils/json.js.map +0 -1
  86. package/dist/utils/session.d.ts +0 -17
  87. package/dist/utils/session.d.ts.map +0 -1
  88. package/dist/utils/session.js +0 -59
  89. package/dist/utils/session.js.map +0 -1
  90. package/next.config.codeagentsdk.cjs +0 -22
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ // src/preload.ts
4
+ var import_electron = require("electron");
5
+ import_electron.contextBridge.exposeInMainWorld("electron", {
6
+ // Platform info
7
+ platform: process.platform,
8
+ // Notifications
9
+ showNotification: (options) => {
10
+ import_electron.ipcRenderer.send("show-notification", options);
11
+ },
12
+ // Badge count
13
+ updateBadge: (count) => {
14
+ import_electron.ipcRenderer.send("update-badge", count);
15
+ },
16
+ // Window control
17
+ toggleWindow: () => {
18
+ import_electron.ipcRenderer.send("toggle-window");
19
+ },
20
+ // Auth token (secure storage)
21
+ getAuthToken: () => import_electron.ipcRenderer.invoke("get-auth-token"),
22
+ setAuthToken: (token) => import_electron.ipcRenderer.invoke("set-auth-token", token),
23
+ // External links
24
+ openExternal: (url) => {
25
+ import_electron.ipcRenderer.send("open-external", url);
26
+ },
27
+ // Local repo sync (Backgrounder folder)
28
+ getGitSyncSettings: () => import_electron.ipcRenderer.invoke("git-sync:get-settings"),
29
+ setGitSyncSettings: (settings) => import_electron.ipcRenderer.invoke("git-sync:set-settings", settings),
30
+ pickSyncDirectory: () => import_electron.ipcRenderer.invoke("git-sync:pick-directory"),
31
+ getRepoSyncState: (repo) => import_electron.ipcRenderer.invoke("git-sync:get-repo-state", repo),
32
+ openRepoFolder: (data) => import_electron.ipcRenderer.invoke("git-sync:open-repo-folder", data),
33
+ setActiveChat: (data) => import_electron.ipcRenderer.invoke("git-sync:set-active-chat", data),
34
+ syncBranch: (data) => import_electron.ipcRenderer.invoke("git-sync:sync-branch", data),
35
+ // License auto-detection
36
+ getClaudeLicenseAutoDetect: () => import_electron.ipcRenderer.invoke("get-claude-license-auto-detect"),
37
+ getLicenseDetectSettings: () => import_electron.ipcRenderer.invoke("get-license-detect-settings"),
38
+ setLicenseDetectSettings: (settings) => import_electron.ipcRenderer.invoke("set-license-detect-settings", settings),
39
+ // Event listeners
40
+ onDeepLink: (callback) => {
41
+ const handler = (_event, data) => callback(data);
42
+ import_electron.ipcRenderer.on("deep-link", handler);
43
+ return () => import_electron.ipcRenderer.removeListener("deep-link", handler);
44
+ },
45
+ onNavigateToChat: (callback) => {
46
+ const handler = (_event, chatId) => callback(chatId);
47
+ import_electron.ipcRenderer.on("navigate-to-chat", handler);
48
+ return () => import_electron.ipcRenderer.removeListener("navigate-to-chat", handler);
49
+ },
50
+ onGitPushed: (callback) => {
51
+ const handler = (_event, data) => callback(data);
52
+ import_electron.ipcRenderer.on("git-pushed", handler);
53
+ return () => import_electron.ipcRenderer.removeListener("git-pushed", handler);
54
+ },
55
+ onShortcut: (callback) => {
56
+ const handler = (_event, action) => callback(action);
57
+ import_electron.ipcRenderer.on("shortcut", handler);
58
+ return () => import_electron.ipcRenderer.removeListener("shortcut", handler);
59
+ },
60
+ onSyncStatus: (callback) => {
61
+ const handler = (_event, data) => callback(data);
62
+ import_electron.ipcRenderer.on("sync-status", handler);
63
+ return () => import_electron.ipcRenderer.removeListener("sync-status", handler);
64
+ },
65
+ onSyncError: (callback) => {
66
+ const handler = (_event, data) => callback(data);
67
+ import_electron.ipcRenderer.on("sync-error", handler);
68
+ return () => import_electron.ipcRenderer.removeListener("sync-error", handler);
69
+ }
70
+ });
@@ -0,0 +1,298 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // Background Agents desktop launcher.
5
+ //
6
+ // `npx background-agents` resolves the latest published version of this package,
7
+ // then this script spawns the bundled Electron app (packages/launcher/app),
8
+ // pointed at the production backend by default. The heavy Electron runtime is a
9
+ // normal npm dependency, so npm/npx downloads it (with its own progress bar) on
10
+ // first run and caches it for subsequent launches.
11
+
12
+ const path = require("path");
13
+ const fs = require("fs");
14
+ const https = require("https");
15
+ const { spawn } = require("child_process");
16
+
17
+ const { colors, symbols, Spinner, line, showCursor } = require("../lib/ui");
18
+ const pkg = require("../package.json");
19
+
20
+ const PROD_URL = "https://backgrounder.dev";
21
+ const DEV_URL = "http://localhost:4000";
22
+ const APP_ENTRY = path.join(__dirname, "..", "app", "dist", "main.js");
23
+ const READY_MARKER = "background-agents:ready";
24
+
25
+ function parseArgs(argv) {
26
+ const opts = {
27
+ url: null,
28
+ dev: false,
29
+ verbose: false,
30
+ help: false,
31
+ version: false,
32
+ };
33
+ for (let i = 0; i < argv.length; i++) {
34
+ const arg = argv[i];
35
+ if (arg === "-h" || arg === "--help") opts.help = true;
36
+ else if (arg === "-v" || arg === "--version") opts.version = true;
37
+ else if (arg === "--dev") opts.dev = true;
38
+ else if (arg === "--verbose") opts.verbose = true;
39
+ else if (arg === "--url") opts.url = argv[++i];
40
+ else if (arg.startsWith("--url=")) opts.url = arg.slice("--url=".length);
41
+ }
42
+ return opts;
43
+ }
44
+
45
+ function printBanner() {
46
+ line();
47
+ line(
48
+ ` ${colors.bold(colors.magenta("Background Agents"))} ${colors.dim(
49
+ "desktop launcher v" + pkg.version
50
+ )}`
51
+ );
52
+ line(` ${colors.dim("https://backgrounder.dev")}`);
53
+ line();
54
+ }
55
+
56
+ function printHelp() {
57
+ printBanner();
58
+ line(` ${colors.bold("Usage")}`);
59
+ line(` npx ${pkg.name} [options]`);
60
+ line();
61
+ line(` ${colors.bold("Options")}`);
62
+ line(` --url <url> Backend URL to load (default: ${PROD_URL})`);
63
+ line(` --dev Use the local dev server (${DEV_URL})`);
64
+ line(` --verbose Stream the desktop app's logs to this terminal`);
65
+ line(` -v, --version Print the launcher version`);
66
+ line(` -h, --help Show this help`);
67
+ line();
68
+ line(` ${colors.bold("Environment")}`);
69
+ line(` BACKGROUND_AGENTS_URL Same as --url (the --url flag wins)`);
70
+ line();
71
+ line(
72
+ ` ${colors.dim(
73
+ "Tip: run `npx " + pkg.name + "@latest` to always get the newest version."
74
+ )}`
75
+ );
76
+ line();
77
+ }
78
+
79
+ // The `electron` package returns the absolute path to its binary when required
80
+ // from a normal Node process (i.e. not from inside Electron itself).
81
+ function resolveElectron() {
82
+ let electronPath;
83
+ try {
84
+ electronPath = require("electron");
85
+ } catch (_err) {
86
+ return {
87
+ error:
88
+ "Electron runtime is not installed. Reinstall with: npx " +
89
+ pkg.name +
90
+ "@latest",
91
+ };
92
+ }
93
+ if (typeof electronPath !== "string" || !fs.existsSync(electronPath)) {
94
+ return {
95
+ error:
96
+ "The Electron binary is missing or its download was skipped.\n" +
97
+ " Reinstall without ELECTRON_SKIP_BINARY_DOWNLOAD set, e.g.: npx background-agents@latest",
98
+ };
99
+ }
100
+ return { electronPath };
101
+ }
102
+
103
+ // Non-blocking check of the npm registry for a newer launcher version.
104
+ function checkLatestVersion(timeoutMs = 1500) {
105
+ return new Promise((resolve) => {
106
+ const req = https.get(
107
+ `https://registry.npmjs.org/${encodeURIComponent(pkg.name)}/latest`,
108
+ { headers: { accept: "application/json" }, timeout: timeoutMs },
109
+ (res) => {
110
+ if (res.statusCode !== 200) {
111
+ res.resume();
112
+ resolve(null);
113
+ return;
114
+ }
115
+ let data = "";
116
+ res.setEncoding("utf8");
117
+ res.on("data", (chunk) => (data += chunk));
118
+ res.on("end", () => {
119
+ try {
120
+ resolve(JSON.parse(data).version || null);
121
+ } catch (_err) {
122
+ resolve(null);
123
+ }
124
+ });
125
+ }
126
+ );
127
+ req.on("error", () => resolve(null));
128
+ req.on("timeout", () => {
129
+ req.destroy();
130
+ resolve(null);
131
+ });
132
+ });
133
+ }
134
+
135
+ function semverGt(a, b) {
136
+ const pa = String(a).split(".").map((n) => parseInt(n, 10) || 0);
137
+ const pb = String(b).split(".").map((n) => parseInt(n, 10) || 0);
138
+ for (let i = 0; i < 3; i++) {
139
+ if (pa[i] > pb[i]) return true;
140
+ if (pa[i] < pb[i]) return false;
141
+ }
142
+ return false;
143
+ }
144
+
145
+ function main() {
146
+ const opts = parseArgs(process.argv.slice(2));
147
+
148
+ if (opts.help) {
149
+ printHelp();
150
+ return;
151
+ }
152
+ if (opts.version) {
153
+ line(pkg.version);
154
+ return;
155
+ }
156
+
157
+ printBanner();
158
+
159
+ if (!fs.existsSync(APP_ENTRY)) {
160
+ line(
161
+ ` ${symbols.error} ${colors.red(
162
+ "App bundle is missing — this package was built incorrectly."
163
+ )}`
164
+ );
165
+ line(` ${colors.dim("Expected: " + APP_ENTRY)}`);
166
+ process.exitCode = 1;
167
+ return;
168
+ }
169
+
170
+ const { electronPath, error } = resolveElectron();
171
+ if (error) {
172
+ line(` ${symbols.error} ${colors.red(error)}`);
173
+ process.exitCode = 1;
174
+ return;
175
+ }
176
+
177
+ const backendUrl =
178
+ opts.url ||
179
+ (opts.dev ? DEV_URL : process.env.BACKGROUND_AGENTS_URL || PROD_URL);
180
+
181
+ const latestPromise = checkLatestVersion();
182
+
183
+ const spinner = new Spinner();
184
+ spinner.start(`Launching Background Agents ${colors.dim("→ " + backendUrl)}`);
185
+
186
+ const env = Object.assign({}, process.env, {
187
+ BACKGROUND_AGENTS_URL: backendUrl,
188
+ // Avoid Electron attaching to / spawning a console window on Windows.
189
+ ELECTRON_NO_ATTACH_CONSOLE: "1",
190
+ });
191
+
192
+ const child = spawn(electronPath, [APP_ENTRY], {
193
+ env,
194
+ stdio: ["ignore", "pipe", "pipe"],
195
+ windowsHide: false,
196
+ });
197
+
198
+ let ready = false;
199
+ let exited = false;
200
+
201
+ function announceRunning() {
202
+ if (ready) return;
203
+ ready = true;
204
+ clearTimeout(readyFallback);
205
+ spinner.succeed(
206
+ `Background Agents is running ${colors.dim("→ " + backendUrl)}`
207
+ );
208
+ line(
209
+ ` ${colors.dim("Close the app window (or press Ctrl+C here) to quit.")}`
210
+ );
211
+ latestPromise.then((latest) => {
212
+ if (!exited && latest && semverGt(latest, pkg.version)) {
213
+ line();
214
+ line(
215
+ ` ${symbols.info} ${colors.yellow(
216
+ "A newer version is available"
217
+ )} ${colors.dim("(" + pkg.version + " → " + latest + ")")}`
218
+ );
219
+ line(
220
+ ` ${colors.dim("Update with: ")}${colors.cyan(
221
+ "npx " + pkg.name + "@latest"
222
+ )}`
223
+ );
224
+ }
225
+ });
226
+ }
227
+
228
+ function handleOutput(buffer, stream) {
229
+ const text = buffer.toString();
230
+ if (text.includes(READY_MARKER)) announceRunning();
231
+ if (opts.verbose) {
232
+ const cleaned = text.split(READY_MARKER).join("").replace(/\n{2,}/g, "\n");
233
+ if (cleaned.trim()) stream.write(colors.dim(cleaned));
234
+ }
235
+ }
236
+
237
+ child.stdout.on("data", (b) => handleOutput(b, process.stdout));
238
+ child.stderr.on("data", (b) => handleOutput(b, process.stderr));
239
+
240
+ // Fallback: if the app never prints the ready marker (older build, or output
241
+ // buffered), assume it's up after a short grace period so the UI doesn't hang.
242
+ const readyFallback = setTimeout(announceRunning, 8000);
243
+ if (readyFallback.unref) readyFallback.unref();
244
+
245
+ let shuttingDown = false;
246
+ function shutdown(signal) {
247
+ if (shuttingDown) return;
248
+ shuttingDown = true;
249
+ clearTimeout(readyFallback);
250
+ try {
251
+ child.kill(signal || "SIGTERM");
252
+ } catch (_err) {
253
+ /* ignore */
254
+ }
255
+ }
256
+
257
+ process.on("SIGINT", () => shutdown("SIGINT"));
258
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
259
+
260
+ child.on("error", (err) => {
261
+ exited = true;
262
+ clearTimeout(readyFallback);
263
+ if (!ready) spinner.fail("Failed to launch Background Agents");
264
+ showCursor();
265
+ line(` ${symbols.error} ${colors.red(err.message)}`);
266
+ process.exitCode = 1;
267
+ });
268
+
269
+ child.on("exit", (code, signal) => {
270
+ exited = true;
271
+ clearTimeout(readyFallback);
272
+ showCursor();
273
+ if (!ready) {
274
+ spinner.fail("Background Agents exited before it finished starting");
275
+ if (code) {
276
+ line(
277
+ ` ${colors.dim(
278
+ "The app exited with code " +
279
+ code +
280
+ ". Re-run with --verbose to see its logs."
281
+ )}`
282
+ );
283
+ }
284
+ } else {
285
+ line(` ${symbols.arrow} ${colors.dim("Background Agents closed.")}`);
286
+ }
287
+ process.exitCode = signal ? 0 : code == null ? 0 : code;
288
+ });
289
+ }
290
+
291
+ try {
292
+ main();
293
+ } catch (err) {
294
+ showCursor();
295
+ // eslint-disable-next-line no-console
296
+ console.error(err);
297
+ process.exitCode = 1;
298
+ }
package/lib/ui.js ADDED
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+
3
+ // Tiny dependency-free terminal UI: colors + a spinner. Keeping this free of
4
+ // npm deps means `npx background-agents` installs fast (only Electron is heavy).
5
+
6
+ const useColor =
7
+ process.env.NO_COLOR == null &&
8
+ process.env.TERM !== "dumb" &&
9
+ (Boolean(process.stdout.isTTY) || process.env.FORCE_COLOR != null);
10
+
11
+ function wrap(open, close) {
12
+ return (s) => (useColor ? `[${open}m${s}[${close}m` : String(s));
13
+ }
14
+
15
+ const colors = {
16
+ bold: wrap(1, 22),
17
+ dim: wrap(2, 22),
18
+ red: wrap(31, 39),
19
+ green: wrap(32, 39),
20
+ yellow: wrap(33, 39),
21
+ blue: wrap(34, 39),
22
+ magenta: wrap(35, 39),
23
+ cyan: wrap(36, 39),
24
+ gray: wrap(90, 39),
25
+ };
26
+
27
+ const symbols = {
28
+ success: colors.green("✔"),
29
+ error: colors.red("✖"),
30
+ warn: colors.yellow("⚠"),
31
+ info: colors.cyan("ℹ"),
32
+ arrow: colors.gray("›"),
33
+ bullet: colors.gray("•"),
34
+ };
35
+
36
+ const isTTY = Boolean(process.stdout.isTTY);
37
+
38
+ const HIDE_CURSOR = "[?25l";
39
+ const SHOW_CURSOR = "[?25h";
40
+ const CLEAR_LINE = "\r";
41
+
42
+ function showCursor() {
43
+ if (isTTY) process.stdout.write(SHOW_CURSOR);
44
+ }
45
+
46
+ class Spinner {
47
+ constructor() {
48
+ this.frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
49
+ this.index = 0;
50
+ this.timer = null;
51
+ this.text = "";
52
+ }
53
+
54
+ start(text) {
55
+ this.text = text;
56
+ if (!isTTY) {
57
+ process.stdout.write(` ${text}\n`);
58
+ return this;
59
+ }
60
+ if (this.timer) return this;
61
+ process.stdout.write(HIDE_CURSOR);
62
+ this.render();
63
+ this.timer = setInterval(() => this.render(), 80);
64
+ if (this.timer.unref) this.timer.unref();
65
+ return this;
66
+ }
67
+
68
+ render() {
69
+ const frame = colors.cyan(this.frames[this.index]);
70
+ this.index = (this.index + 1) % this.frames.length;
71
+ process.stdout.write(`${CLEAR_LINE} ${frame} ${this.text}`);
72
+ }
73
+
74
+ update(text) {
75
+ this.text = text;
76
+ if (!isTTY) process.stdout.write(` ${text}\n`);
77
+ return this;
78
+ }
79
+
80
+ stop(symbol, text) {
81
+ if (this.timer) {
82
+ clearInterval(this.timer);
83
+ this.timer = null;
84
+ }
85
+ const message = text != null ? text : this.text;
86
+ const line = ` ${symbol} ${message}`;
87
+ if (isTTY) process.stdout.write(`${CLEAR_LINE}${line}\n${SHOW_CURSOR}`);
88
+ else process.stdout.write(`${line}\n`);
89
+ return this;
90
+ }
91
+
92
+ succeed(text) {
93
+ return this.stop(symbols.success, text);
94
+ }
95
+ fail(text) {
96
+ return this.stop(symbols.error, text);
97
+ }
98
+ warn(text) {
99
+ return this.stop(symbols.warn, text);
100
+ }
101
+ info(text) {
102
+ return this.stop(symbols.info, text);
103
+ }
104
+ }
105
+
106
+ function line(text = "") {
107
+ process.stdout.write(`${text}\n`);
108
+ }
109
+
110
+ module.exports = { colors, symbols, Spinner, line, isTTY, showCursor };
package/package.json CHANGED
@@ -1,57 +1,42 @@
1
1
  {
2
2
  "name": "background-agents",
3
- "version": "0.1.1",
4
- "description": "A TypeScript SDK for interacting with various AI coding agents (Claude, Codex, OpenCode, Gemini)",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "type": "module",
8
- "scripts": {
9
- "build": "tsc",
10
- "test": "vitest run",
11
- "test:watch": "vitest",
12
- "test:coverage": "vitest run --coverage",
13
- "lint": "eslint src --ext .ts",
14
- "clean": "rm -rf dist",
15
- "prepublishOnly": "npm run build"
3
+ "version": "1.0.0",
4
+ "description": "Launch the Background Agents desktop app with one command npx background-agents. Always runs the latest published version.",
5
+ "type": "commonjs",
6
+ "bin": {
7
+ "background-agents": "bin/background-agents.js"
16
8
  },
17
- "keywords": [
18
- "ai",
19
- "coding-agent",
20
- "claude",
21
- "codex",
22
- "opencode",
23
- "gemini",
24
- "sdk"
9
+ "files": [
10
+ "bin",
11
+ "lib",
12
+ "app",
13
+ "README.md"
25
14
  ],
26
- "author": "",
27
- "license": "MIT",
28
- "publishConfig": {
29
- "access": "public"
30
- },
31
- "devDependencies": {
32
- "@types/node": "^20.10.0",
33
- "@types/ssh2": "^1.15.5",
34
- "typescript": "^5.3.0",
35
- "vitest": "^1.0.0"
36
- },
37
15
  "engines": {
38
- "node": ">=18.0.0"
16
+ "node": ">=18"
39
17
  },
40
- "files": [
41
- "dist",
42
- "README.md",
43
- "next.config.codeagentsdk.cjs"
44
- ],
45
- "exports": {
46
- ".": {
47
- "import": "./dist/index.js",
48
- "types": "./dist/index.d.ts"
49
- },
50
- "./next.config": "./next.config.codeagentsdk.cjs"
18
+ "scripts": {
19
+ "bundle": "node scripts/bundle-app.mjs",
20
+ "prepack": "node scripts/bundle-app.mjs",
21
+ "start": "node bin/background-agents.js",
22
+ "typecheck": "node --check bin/background-agents.js && node --check lib/ui.js"
51
23
  },
52
24
  "dependencies": {
53
- "@daytonaio/sdk": "^0.150.0",
54
- "dotenv": "^17.3.1",
55
- "ssh2": "^1.17.0"
25
+ "electron": "^33.2.1"
26
+ },
27
+ "keywords": [
28
+ "background-agents",
29
+ "electron",
30
+ "launcher",
31
+ "npx",
32
+ "desktop"
33
+ ],
34
+ "license": "MIT",
35
+ "author": "James Murdza",
36
+ "homepage": "https://backgrounder.dev",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/jamesmurdza/background-agents.git",
40
+ "directory": "packages/launcher"
56
41
  }
57
42
  }
package/dist/debug.d.ts DELETED
@@ -1,7 +0,0 @@
1
- /**
2
- * Debug logging for the SDK. Enable with env CODING_AGENTS_DEBUG=1 (or non-empty).
3
- * Logs agent lifecycle (start/stop), background runs, and any lines that fail to parse.
4
- */
5
- export declare function isDebugEnabled(): boolean;
6
- export declare function debugLog(message: string, sessionId?: string | null, ...args: unknown[]): void;
7
- //# sourceMappingURL=debug.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAID,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAK7F"}
package/dist/debug.js DELETED
@@ -1,19 +0,0 @@
1
- /**
2
- * Debug logging for the SDK. Enable with env CODING_AGENTS_DEBUG=1 (or non-empty).
3
- * Logs agent lifecycle (start/stop), background runs, and any lines that fail to parse.
4
- */
5
- const DEBUG_ENABLED = typeof process !== "undefined" &&
6
- process.env &&
7
- String(process.env.CODING_AGENTS_DEBUG ?? "").trim() !== "";
8
- export function isDebugEnabled() {
9
- return DEBUG_ENABLED;
10
- }
11
- const PREFIX = "[background-agents]";
12
- export function debugLog(message, sessionId, ...args) {
13
- if (!DEBUG_ENABLED)
14
- return;
15
- const sessionTag = sessionId != null && sessionId !== "" ? ` sessionId=${sessionId}` : "";
16
- const line = args.length ? `${message} ${args.map(a => (typeof a === "object" ? JSON.stringify(a) : String(a))).join(" ")}` : message;
17
- process.stderr.write(`${PREFIX}${sessionTag} ${line}\n`);
18
- }
19
- //# sourceMappingURL=debug.js.map
package/dist/debug.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,aAAa,GACjB,OAAO,OAAO,KAAK,WAAW;IAC9B,OAAO,CAAC,GAAG;IACX,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;AAE7D,MAAM,UAAU,cAAc;IAC5B,OAAO,aAAa,CAAA;AACtB,CAAC;AAED,MAAM,MAAM,GAAG,qBAAqB,CAAA;AAEpC,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,SAAyB,EAAE,GAAG,IAAe;IACrF,IAAI,CAAC,aAAa;QAAE,OAAM;IAC1B,MAAM,UAAU,GAAG,SAAS,IAAI,IAAI,IAAI,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACzF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;IACrI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,UAAU,IAAI,IAAI,IAAI,CAAC,CAAA;AAC1D,CAAC"}
package/dist/factory.d.ts DELETED
@@ -1,31 +0,0 @@
1
- import type { ProviderName, ProviderOptions } from "./types/index.js";
2
- import { Provider } from "./providers/index.js";
3
- /**
4
- * Create a provider instance by name
5
- *
6
- * @param name - The provider name ("claude", "codex", "opencode", "gemini")
7
- * @param options - Provider options (sandbox or dangerouslyAllowLocalExecution)
8
- * @returns A provider instance
9
- * @throws Error if the provider name is unknown
10
- *
11
- * @example
12
- * ```typescript
13
- * import { Daytona } from "@daytonaio/sdk"
14
- * const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })
15
- * const sandbox = await daytona.create({ envVars: { ... } })
16
- * const provider = createProvider("claude", { sandbox })
17
- *
18
- * // Or with dangerous local execution:
19
- * const provider = createProvider("claude", { dangerouslyAllowLocalExecution: true })
20
- * ```
21
- */
22
- export declare function createProvider(name: ProviderName | string, options: ProviderOptions): Provider;
23
- /**
24
- * Get all available provider names
25
- */
26
- export declare function getProviderNames(): ProviderName[];
27
- /**
28
- * Check if a provider name is valid
29
- */
30
- export declare function isValidProvider(name: string): name is ProviderName;
31
- //# sourceMappingURL=factory.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,QAAQ,EAAmE,MAAM,sBAAsB,CAAA;AAEhH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,QAAQ,CAa9F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,EAAE,CAEjD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,YAAY,CAElE"}
package/dist/factory.js DELETED
@@ -1,47 +0,0 @@
1
- import { ClaudeProvider, CodexProvider, OpenCodeProvider, GeminiProvider } from "./providers/index.js";
2
- /**
3
- * Create a provider instance by name
4
- *
5
- * @param name - The provider name ("claude", "codex", "opencode", "gemini")
6
- * @param options - Provider options (sandbox or dangerouslyAllowLocalExecution)
7
- * @returns A provider instance
8
- * @throws Error if the provider name is unknown
9
- *
10
- * @example
11
- * ```typescript
12
- * import { Daytona } from "@daytonaio/sdk"
13
- * const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })
14
- * const sandbox = await daytona.create({ envVars: { ... } })
15
- * const provider = createProvider("claude", { sandbox })
16
- *
17
- * // Or with dangerous local execution:
18
- * const provider = createProvider("claude", { dangerouslyAllowLocalExecution: true })
19
- * ```
20
- */
21
- export function createProvider(name, options) {
22
- switch (name) {
23
- case "claude":
24
- return new ClaudeProvider(options);
25
- case "codex":
26
- return new CodexProvider(options);
27
- case "opencode":
28
- return new OpenCodeProvider(options);
29
- case "gemini":
30
- return new GeminiProvider(options);
31
- default:
32
- throw new Error(`Unknown provider: ${name}. Valid providers are: claude, codex, opencode, gemini`);
33
- }
34
- }
35
- /**
36
- * Get all available provider names
37
- */
38
- export function getProviderNames() {
39
- return ["claude", "codex", "opencode", "gemini"];
40
- }
41
- /**
42
- * Check if a provider name is valid
43
- */
44
- export function isValidProvider(name) {
45
- return getProviderNames().includes(name);
46
- }
47
- //# sourceMappingURL=factory.js.map