@ebay-dt/bonfire-node 0.1.0-alpha.0 → 0.1.0-alpha.1

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 (63) hide show
  1. package/README.md +69 -4
  2. package/dist/agent-service.d.ts +42 -0
  3. package/dist/agent-service.d.ts.map +1 -0
  4. package/dist/agent-service.js +116 -0
  5. package/dist/agent-service.js.map +1 -0
  6. package/dist/claude.d.ts +50 -0
  7. package/dist/claude.d.ts.map +1 -0
  8. package/dist/claude.js +119 -0
  9. package/dist/claude.js.map +1 -0
  10. package/dist/cursor.d.ts +30 -0
  11. package/dist/cursor.d.ts.map +1 -0
  12. package/dist/cursor.js +57 -0
  13. package/dist/cursor.js.map +1 -0
  14. package/dist/deployment-provider.d.ts +32 -0
  15. package/dist/deployment-provider.d.ts.map +1 -0
  16. package/dist/deployment-provider.js +167 -0
  17. package/dist/deployment-provider.js.map +1 -0
  18. package/dist/duplicate.d.ts +3 -2
  19. package/dist/duplicate.d.ts.map +1 -1
  20. package/dist/duplicate.js +18 -18
  21. package/dist/duplicate.js.map +1 -1
  22. package/dist/executable.d.ts +16 -0
  23. package/dist/executable.d.ts.map +1 -0
  24. package/dist/executable.js +65 -0
  25. package/dist/executable.js.map +1 -0
  26. package/dist/github-cli.d.ts.map +1 -1
  27. package/dist/github-cli.js +23 -3
  28. package/dist/github-cli.js.map +1 -1
  29. package/dist/index.d.ts +7 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +7 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/internal/owned-destination.d.ts +2 -2
  34. package/dist/internal/owned-destination.d.ts.map +1 -1
  35. package/dist/internal/owned-destination.js +2 -2
  36. package/dist/internal/owned-destination.js.map +1 -1
  37. package/dist/internal/prototype-templates.d.ts +3 -2
  38. package/dist/internal/prototype-templates.d.ts.map +1 -1
  39. package/dist/internal/prototype-templates.js +13 -8
  40. package/dist/internal/prototype-templates.js.map +1 -1
  41. package/dist/internal/utils.d.ts +2 -0
  42. package/dist/internal/utils.d.ts.map +1 -1
  43. package/dist/internal/utils.js +6 -0
  44. package/dist/internal/utils.js.map +1 -1
  45. package/dist/lifecycle/local-prototype-lifecycle.d.ts +22 -10
  46. package/dist/lifecycle/local-prototype-lifecycle.d.ts.map +1 -1
  47. package/dist/lifecycle/local-prototype-lifecycle.js +255 -6
  48. package/dist/lifecycle/local-prototype-lifecycle.js.map +1 -1
  49. package/dist/preferences.d.ts +19 -0
  50. package/dist/preferences.d.ts.map +1 -0
  51. package/dist/preferences.js +182 -0
  52. package/dist/preferences.js.map +1 -0
  53. package/dist/prototype-catalog.d.ts.map +1 -1
  54. package/dist/prototype-catalog.js +18 -7
  55. package/dist/prototype-catalog.js.map +1 -1
  56. package/dist/prototype-paths.d.ts +2 -0
  57. package/dist/prototype-paths.d.ts.map +1 -1
  58. package/dist/prototype-paths.js.map +1 -1
  59. package/dist/scaffold.d.ts +4 -2
  60. package/dist/scaffold.d.ts.map +1 -1
  61. package/dist/scaffold.js +7 -12
  62. package/dist/scaffold.js.map +1 -1
  63. package/package.json +2 -2
package/README.md CHANGED
@@ -28,6 +28,40 @@ A competing mutation returns `repository-busy` immediately rather than waiting.
28
28
  The gate covers the supported local Node process only; coordination across
29
29
  multiple processes or machines is not provided.
30
30
 
31
+ ## Deployment provider
32
+
33
+ Deployment is an optional development capability. Configure the generic provider
34
+ only in a server-only host module with a complete HTTP endpoint; never expose the
35
+ endpoint or provider to browser code:
36
+
37
+ ```ts
38
+ import { createDeploymentProvider } from "@ebay-dt/bonfire-node";
39
+
40
+ const deploymentProvider = createDeploymentProvider({
41
+ endpoint: process.env.BONFIRE_DEPLOYMENT_ENDPOINT!,
42
+ timeoutMs: 120_000,
43
+ });
44
+ ```
45
+
46
+ The provider sends exactly `{ applicationId, login }`. Bonfire supplies the
47
+ application ID from trusted application configuration and the login from the
48
+ verified authenticated identity; instances never provide owner/branch values.
49
+ The documented success response is returned with HTTP 201 and contains
50
+ `repository`, `ref`, `commitSha`, `sourceFileCount`, `project`, `deployed`,
51
+ `deploymentId`, `url`, and `readyState`. `readyState` is one of `BLOCKED`,
52
+ `BUILDING`, `CANCELED`, `ERROR`, `INITIALIZING`, `QUEUED`, or `READY`. HTTP 201
53
+ means deployment creation succeeded, not that the preview is ready. A failure
54
+ response contains `repository`, optional `ref`, `commitSha`, `project`, and
55
+ `stage`, plus `deployed: false`, `statusCode`, and `details`; those diagnostics
56
+ are validated and then intentionally hidden behind a safe provider error.
57
+
58
+ The provider preserves the deployment ID and reported ready state, but Bonfire
59
+ does not poll for later status. Provider failures are reduced to safe typed
60
+ lifecycle errors; response diagnostics, credentials, Vercel credentials, and
61
+ deployment-target selection remain outside Bonfire in the deployment service.
62
+ The provider validates the endpoint, response, HTTPS preview URL, and timeout
63
+ without exposing service details to the browser.
64
+
31
65
  ## Prototype shape and duplication
32
66
 
33
67
  Duplicate sources must contain valid `metadata.json` plus regular,
@@ -68,10 +102,13 @@ completed destination. The default callback is a no-op.
68
102
  prototype reference, then returns a `clean` or `dirty` observation based only on
69
103
  Git status within that prototype path. `LocalPrototypeLifecycle.save` creates a
70
104
  local, path-scoped checkpoint without pushing; `.discard` restores tracked
71
- files and removes untracked files within that path. `LocalPrototypeLifecycle.create`
72
- and `.duplicate` return typed results and serialize repository mutations through
73
- one process-local operation gate. They
74
- prepare the authenticated identity branch when automatic switching is enabled;
105
+ files and removes untracked files within that path. `LocalPrototypeLifecycle.create`,
106
+ `.duplicate`, `.edit`, and `.delete` return typed results and serialize repository
107
+ mutations through one process-local operation gate. Edit updates only title,
108
+ description, and `updatedAt` while preserving the existing ref/URL. Delete
109
+ removes the complete owned prototype directory, including uncommitted files,
110
+ after ownership and path validation. These operations prepare the authenticated
111
+ identity branch when automatic switching is enabled;
75
112
  `BF_DISABLE_AUTO_BRANCH_SWITCH=true` disables every automatic switch and leaves
76
113
  the current branch untouched. Git remains behind the Node-owned repository
77
114
  adapter, and `simple-git` is not part of the public API.
@@ -87,6 +124,34 @@ debounces filesystem events, and reports only clean/dirty transitions. The
87
124
  watcher subpath is intentionally separate so importing `@ebay-dt/bonfire-node` does
88
125
  not load Chokidar.
89
126
 
127
+ ## Agent launch preferences
128
+
129
+ `PrototypeAgentService` stores a user's selected Claude Code terminal at
130
+ `<prototypeRoot>/<login>/preferences.json`, using the explicit runtime context
131
+ provided by the host. This is a local preference file, not prototype source:
132
+ consuming applications must add their prototype-root preference pattern to
133
+ `.gitignore`, for example:
134
+
135
+ ```gitignore
136
+ /src/app/(prototypes)/*/preferences.json
137
+ ```
138
+
139
+ The service writes the file atomically and only after authenticated ownership
140
+ and command preflight have succeeded. Cursor launching requires `cursor` on the
141
+ Bonfire server process's inherited `PATH`. Claude Code launching requires
142
+ `claude` and, on macOS, `osascript` on that `PATH`; the service checks these
143
+ commands without executing them. GUI-launched Node processes may have a
144
+ different `PATH` from an interactive shell, so restart Bonfire after changing
145
+ shell profiles.
146
+
147
+ Claude Code supports the explicit terminal values `terminal` (Terminal.app),
148
+ `iterm` (iTerm2), and `warp` (Warp). Unsupported platforms, missing commands,
149
+ missing preferences, ownership failures, and launch failures are returned as
150
+ safe typed results; raw process output and absolute paths are never public
151
+ results. No skill, clipboard fallback, or copy/paste setup flow is involved.
152
+ Production hosts must not construct the service or expose its local preference
153
+ store.
154
+
90
155
  From the repository root, use Turbo filters so package dependencies are
91
156
  prepared in dependency order:
92
157
 
@@ -0,0 +1,42 @@
1
+ import { type AgentActionError, type AgentActionResult } from "@ebay-dt/bonfire-core";
2
+ import { type ClaudeCodeLauncherLike } from "./claude.js";
3
+ import { type CursorLauncherLike } from "./cursor.js";
4
+ import { type ExecutableResolverLike } from "./executable.js";
5
+ import { type PrototypePreferencesLike } from "./preferences.js";
6
+ import type { PrototypeCatalogLike } from "./prototype-catalog.js";
7
+ import type { PrototypeLifecycleRuntimeContext } from "./lifecycle/runtime-context.js";
8
+ export type PrototypeAgentServiceOptions = {
9
+ runtime: Pick<PrototypeLifecycleRuntimeContext, "prototypeRoot">;
10
+ catalog: PrototypeCatalogLike;
11
+ executableResolver?: ExecutableResolverLike;
12
+ preferences?: PrototypePreferencesLike;
13
+ cursor?: CursorLauncherLike;
14
+ claudeCode?: ClaudeCodeLauncherLike;
15
+ };
16
+ export interface PrototypeAgentServiceLike {
17
+ openInCursor(identity: unknown, input: unknown): Promise<AgentActionResult>;
18
+ openInClaudeCode(identity: unknown, input: unknown): Promise<AgentActionResult>;
19
+ }
20
+ export declare class PrototypeAgentService implements PrototypeAgentServiceLike {
21
+ #private;
22
+ constructor(options: PrototypeAgentServiceOptions);
23
+ openInCursor(identity: unknown, input: unknown): Promise<{
24
+ ok: true;
25
+ value: import("@ebay-dt/bonfire-core").AgentLaunchValue;
26
+ } | {
27
+ ok: false;
28
+ error: AgentActionError;
29
+ }>;
30
+ openInClaudeCode(identity: unknown, input: unknown): Promise<{
31
+ ok: true;
32
+ value: import("@ebay-dt/bonfire-core").AgentLaunchValue;
33
+ } | {
34
+ ok: false;
35
+ error: {
36
+ agent?: import("@ebay-dt/bonfire-core").Agent;
37
+ terminal?: import("@ebay-dt/bonfire-core").TerminalApp;
38
+ code: import("@ebay-dt/bonfire-core").AgentActionErrorCode;
39
+ };
40
+ }>;
41
+ }
42
+ //# sourceMappingURL=agent-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-service.d.ts","sourceRoot":"","sources":["../src/agent-service.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAGvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAsB,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAEvF,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,IAAI,CAAC,gCAAgC,EAAE,eAAe,CAAC,CAAC;IACjE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,sBAAsB,CAAC;CACrC,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5E,gBAAgB,CACd,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B;AAiCD,qBAAa,qBAAsB,YAAW,yBAAyB;;IAOrE,YAAY,OAAO,EAAE,4BAA4B,EAUhD;IA4CK,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;;;;;;OASnD;IAEK,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;;;;;;;;;;OA2CvD;CACF"}
@@ -0,0 +1,116 @@
1
+ import { join } from "node:path";
2
+ import { definePrototypeRef, parseBonfireIdentity, parseOpenInAgentInput, parseOpenInClaudeCodeInput, } from "@ebay-dt/bonfire-core";
3
+ import { ClaudeCodeLauncher } from "./claude.js";
4
+ import { CursorLauncher } from "./cursor.js";
5
+ import { PathExecutableResolver, } from "./executable.js";
6
+ import { PrototypePreferences, } from "./preferences.js";
7
+ function failure(code, extras = {}) {
8
+ return {
9
+ ok: false,
10
+ error: { code, ...extras },
11
+ };
12
+ }
13
+ function authenticate(identity) {
14
+ if (identity === null || identity === undefined)
15
+ return null;
16
+ try {
17
+ const parsed = parseBonfireIdentity(identity);
18
+ definePrototypeRef({ login: parsed.login, slug: "prototype" });
19
+ return parsed;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ export class PrototypeAgentService {
26
+ #runtime;
27
+ #catalog;
28
+ #preferences;
29
+ #cursor;
30
+ #claudeCode;
31
+ constructor(options) {
32
+ const executableResolver = options.executableResolver ?? new PathExecutableResolver();
33
+ this.#runtime = options.runtime;
34
+ this.#catalog = options.catalog;
35
+ this.#preferences =
36
+ options.preferences ?? new PrototypePreferences(options.runtime);
37
+ this.#cursor = options.cursor ?? new CursorLauncher({ executableResolver });
38
+ this.#claudeCode =
39
+ options.claudeCode ?? new ClaudeCodeLauncher({ executableResolver });
40
+ }
41
+ async #authorize(identity, input, parse) {
42
+ const authenticated = authenticate(identity);
43
+ if (authenticated === null) {
44
+ return { ok: false, result: failure("unauthenticated") };
45
+ }
46
+ let normalizedInput;
47
+ try {
48
+ normalizedInput = parse(input);
49
+ }
50
+ catch {
51
+ return { ok: false, result: failure("invalid-input") };
52
+ }
53
+ let summary;
54
+ try {
55
+ summary = await this.#catalog.getSummary(normalizedInput.ref);
56
+ }
57
+ catch {
58
+ summary = null;
59
+ }
60
+ if (summary === null) {
61
+ return { ok: false, result: failure("not-found") };
62
+ }
63
+ if (summary.authorLogin !== authenticated.login) {
64
+ return { ok: false, result: failure("forbidden") };
65
+ }
66
+ return {
67
+ ok: true,
68
+ identity: authenticated,
69
+ input: normalizedInput,
70
+ prototypePath: join(this.#runtime.prototypeRoot, normalizedInput.ref.login, normalizedInput.ref.slug),
71
+ };
72
+ }
73
+ async openInCursor(identity, input) {
74
+ const authorized = await this.#authorize(identity, input, parseOpenInAgentInput);
75
+ if (!authorized.ok)
76
+ return authorized.result;
77
+ return this.#cursor.launch(authorized.prototypePath);
78
+ }
79
+ async openInClaudeCode(identity, input) {
80
+ const authorized = await this.#authorize(identity, input, parseOpenInClaudeCodeInput);
81
+ if (!authorized.ok)
82
+ return authorized.result;
83
+ const preflight = await this.#claudeCode.preflight(authorized.input.terminal);
84
+ if (!preflight.ok)
85
+ return preflight;
86
+ let terminal = authorized.input.terminal;
87
+ if (terminal === undefined) {
88
+ let preferences;
89
+ try {
90
+ preferences = await this.#preferences.read(authorized.identity.login);
91
+ }
92
+ catch {
93
+ return failure("launch-failed", { agent: "claude-code" });
94
+ }
95
+ terminal = preferences.preferredTerminal;
96
+ if (terminal === undefined) {
97
+ return failure("needs-terminal", { agent: "claude-code" });
98
+ }
99
+ }
100
+ else {
101
+ try {
102
+ await this.#preferences.update(authorized.identity.login, {
103
+ preferredTerminal: terminal,
104
+ });
105
+ }
106
+ catch {
107
+ return failure("launch-failed", {
108
+ agent: "claude-code",
109
+ terminal,
110
+ });
111
+ }
112
+ }
113
+ return this.#claudeCode.launch(terminal, authorized.prototypePath, preflight);
114
+ }
115
+ }
116
+ //# sourceMappingURL=agent-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-service.js","sourceRoot":"","sources":["../src/agent-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type AgentActionError, type AgentActionResult, type AgentLaunchValue, type TerminalApp } from "@ebay-dt/bonfire-core";
2
+ import { type ExecutableResolverLike } from "./executable.js";
3
+ export type ClaudeCodeExecOptions = {
4
+ timeout: number;
5
+ maxBuffer: number;
6
+ };
7
+ export type ClaudeCodeExecResult = {
8
+ stdout: string;
9
+ stderr: string;
10
+ };
11
+ export type ClaudeCodeProcessRunner = {
12
+ execFile(executable: string, args: readonly string[], options: ClaudeCodeExecOptions): Promise<ClaudeCodeExecResult>;
13
+ };
14
+ export type ClaudeCodePreflightValue = {
15
+ osascript: string;
16
+ };
17
+ export type ClaudeCodePreflightResult = AgentActionResult<ClaudeCodePreflightValue>;
18
+ export type ClaudeCodeLauncherOptions = {
19
+ executableResolver?: ExecutableResolverLike;
20
+ platform?: NodeJS.Platform;
21
+ process?: ClaudeCodeProcessRunner;
22
+ };
23
+ export interface ClaudeCodeLauncherLike {
24
+ preflight(terminal?: TerminalApp): Promise<ClaudeCodePreflightResult>;
25
+ launch(terminal: TerminalApp, prototypePath: string, preflight?: ClaudeCodePreflightResult): Promise<AgentActionResult<AgentLaunchValue>>;
26
+ }
27
+ export declare function buildClaudeCodeAppleScript(terminal: TerminalApp, prototypePath: string): string;
28
+ export declare class ClaudeCodeLauncher implements ClaudeCodeLauncherLike {
29
+ #private;
30
+ constructor(options?: ClaudeCodeLauncherOptions);
31
+ preflight(terminal?: TerminalApp): Promise<{
32
+ ok: false;
33
+ error: AgentActionError;
34
+ } | {
35
+ ok: true;
36
+ value: {
37
+ osascript: string;
38
+ };
39
+ }>;
40
+ launch(terminal: TerminalApp, prototypePath: string, preflight?: ClaudeCodePreflightResult): Promise<{
41
+ ok: false;
42
+ error: AgentActionError;
43
+ } | {
44
+ ok: true;
45
+ value: {
46
+ agent: "claude-code";
47
+ };
48
+ }>;
49
+ }
50
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAOzB,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CACN,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACnC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;AAE9C,MAAM,MAAM,yBAAyB,GAAG;IACtC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACnC,CAAC;AAEF,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtE,MAAM,CACJ,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,yBAAyB,GACpC,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CACjD;AAuCD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,UA2BtB;AAoBD,qBAAa,kBAAmB,YAAW,sBAAsB;;IAK/D,YAAY,OAAO,GAAE,yBAA8B,EAKlD;IAEK,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW;;;;;;;;OAmBrC;IAEK,MAAM,CACV,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,CAAC,EAAE,yBAAyB;;;;;;;;OAmBtC;CACF"}
package/dist/claude.js ADDED
@@ -0,0 +1,119 @@
1
+ import { execFile as nodeExecFile } from "node:child_process";
2
+ import { PathExecutableResolver, } from "./executable.js";
3
+ const CLAUDE_COMMAND = "claude";
4
+ const OSASCRIPT_COMMAND = "osascript";
5
+ const APPLESCRIPT_TIMEOUT = 10_000;
6
+ const APPLESCRIPT_MAX_BUFFER = 1024 * 1024;
7
+ const defaultProcess = {
8
+ execFile(executable, args, options) {
9
+ return new Promise((resolve, reject) => {
10
+ nodeExecFile(executable, [...args], { ...options, encoding: "utf8" }, (error, stdout, stderr) => {
11
+ if (error) {
12
+ Object.assign(error, { stdout, stderr });
13
+ reject(error);
14
+ return;
15
+ }
16
+ resolve({ stdout, stderr });
17
+ });
18
+ });
19
+ },
20
+ };
21
+ function appleScriptString(value) {
22
+ return `"${value
23
+ .replaceAll("\\", "\\\\")
24
+ .replaceAll('"', '\\"')
25
+ .replaceAll("\r", "\\r")
26
+ .replaceAll("\n", "\\n")}"`;
27
+ }
28
+ function shellString(value) {
29
+ return `'${value.replaceAll("'", `'"'"'`)}'`;
30
+ }
31
+ function commandForPath(prototypePath) {
32
+ return `cd ${shellString(prototypePath)} && ${CLAUDE_COMMAND}`;
33
+ }
34
+ export function buildClaudeCodeAppleScript(terminal, prototypePath) {
35
+ const command = commandForPath(prototypePath);
36
+ switch (terminal) {
37
+ case "terminal":
38
+ return `tell application "Terminal" to do script ${appleScriptString(command)}`;
39
+ case "iterm":
40
+ return [
41
+ 'tell application "iTerm"',
42
+ " create window with default profile",
43
+ " tell current session of current window",
44
+ ` write text ${appleScriptString(command)}`,
45
+ " end tell",
46
+ "end tell",
47
+ ].join("\n");
48
+ case "warp": {
49
+ const uri = `warp://action/new_tab?path=${encodeURIComponent(prototypePath)}`;
50
+ return [
51
+ `do shell script ${appleScriptString(`open ${shellString(uri)}`)}`,
52
+ "delay 1",
53
+ 'tell application "Warp" to activate',
54
+ `tell application "System Events" to keystroke ${appleScriptString(command)}`,
55
+ 'tell application "System Events" to key code 36',
56
+ ].join("\n");
57
+ }
58
+ }
59
+ }
60
+ function actionFailure(code, terminal, command) {
61
+ const error = {
62
+ code,
63
+ agent: "claude-code",
64
+ ...(command ? { command } : {}),
65
+ ...(terminal ? { terminal } : {}),
66
+ };
67
+ return {
68
+ ok: false,
69
+ error,
70
+ };
71
+ }
72
+ export class ClaudeCodeLauncher {
73
+ #executableResolver;
74
+ #platform;
75
+ #process;
76
+ constructor(options = {}) {
77
+ this.#executableResolver =
78
+ options.executableResolver ?? new PathExecutableResolver();
79
+ this.#platform = options.platform ?? process.platform;
80
+ this.#process = options.process ?? defaultProcess;
81
+ }
82
+ async preflight(terminal) {
83
+ if (this.#platform !== "darwin") {
84
+ return actionFailure("unsupported-platform", terminal);
85
+ }
86
+ const claude = await this.#executableResolver.resolve(CLAUDE_COMMAND);
87
+ if (claude === null) {
88
+ return actionFailure("missing-command", terminal, CLAUDE_COMMAND);
89
+ }
90
+ const osascript = await this.#executableResolver.resolve(OSASCRIPT_COMMAND);
91
+ if (osascript === null) {
92
+ return actionFailure("missing-command", terminal, OSASCRIPT_COMMAND);
93
+ }
94
+ return {
95
+ ok: true,
96
+ value: { osascript },
97
+ };
98
+ }
99
+ async launch(terminal, prototypePath, preflight) {
100
+ const checked = preflight ?? (await this.preflight(terminal));
101
+ if (!checked.ok)
102
+ return checked;
103
+ const script = buildClaudeCodeAppleScript(terminal, prototypePath);
104
+ try {
105
+ await this.#process.execFile(checked.value.osascript, ["-e", script], {
106
+ timeout: APPLESCRIPT_TIMEOUT,
107
+ maxBuffer: APPLESCRIPT_MAX_BUFFER,
108
+ });
109
+ }
110
+ catch {
111
+ return actionFailure("launch-failed", terminal);
112
+ }
113
+ return {
114
+ ok: true,
115
+ value: { agent: "claude-code" },
116
+ };
117
+ }
118
+ }
119
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import { type AgentActionResult, type AgentLaunchValue } from "@ebay-dt/bonfire-core";
3
+ import { type ExecutableResolverLike } from "./executable.js";
4
+ export type CursorSpawnOptions = {
5
+ detached: true;
6
+ shell: false;
7
+ stdio: "ignore";
8
+ };
9
+ export type CursorChildProcess = Pick<ChildProcess, "once" | "unref">;
10
+ export type CursorSpawn = (executable: string, args: readonly string[], options: CursorSpawnOptions) => CursorChildProcess;
11
+ export type CursorLauncherOptions = {
12
+ executableResolver?: ExecutableResolverLike;
13
+ spawn?: CursorSpawn;
14
+ };
15
+ export interface CursorLauncherLike {
16
+ launch(prototypePath: string): Promise<AgentActionResult<AgentLaunchValue>>;
17
+ }
18
+ export declare class CursorLauncher implements CursorLauncherLike {
19
+ #private;
20
+ constructor(options?: CursorLauncherOptions);
21
+ launch(prototypePath: string): Promise<{
22
+ ok: false;
23
+ error: {
24
+ code: "launch-failed";
25
+ agent: "cursor";
26
+ command: "cursor";
27
+ };
28
+ } | AgentActionResult>;
29
+ }
30
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAIzB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,QAAQ,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AAEtE,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,kBAAkB,KACxB,kBAAkB,CAAC;AAExB,MAAM,MAAM,qBAAqB,GAAG;IAClC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC7E;AAgBD,qBAAa,cAAe,YAAW,kBAAkB;;IAIvD,YAAY,OAAO,GAAE,qBAA0B,EAI9C;IAEK,MAAM,CAAC,aAAa,EAAE,MAAM;;;;;;;2BAiCjC;CACF"}
package/dist/cursor.js ADDED
@@ -0,0 +1,57 @@
1
+ import { spawn as nodeSpawn } from "node:child_process";
2
+ import { PathExecutableResolver, } from "./executable.js";
3
+ const CURSOR_COMMAND = "cursor";
4
+ const defaultSpawn = (executable, args, options) => nodeSpawn(executable, [...args], options);
5
+ function launchFailure() {
6
+ return {
7
+ ok: false,
8
+ error: {
9
+ code: "launch-failed",
10
+ agent: "cursor",
11
+ command: CURSOR_COMMAND,
12
+ },
13
+ };
14
+ }
15
+ export class CursorLauncher {
16
+ #executableResolver;
17
+ #spawn;
18
+ constructor(options = {}) {
19
+ this.#executableResolver =
20
+ options.executableResolver ?? new PathExecutableResolver();
21
+ this.#spawn = options.spawn ?? defaultSpawn;
22
+ }
23
+ async launch(prototypePath) {
24
+ const executable = await this.#executableResolver.resolve(CURSOR_COMMAND);
25
+ if (executable === null) {
26
+ return {
27
+ ok: false,
28
+ error: {
29
+ code: "missing-command",
30
+ agent: "cursor",
31
+ command: CURSOR_COMMAND,
32
+ },
33
+ };
34
+ }
35
+ let child;
36
+ try {
37
+ child = this.#spawn(executable, [prototypePath], {
38
+ detached: true,
39
+ shell: false,
40
+ stdio: "ignore",
41
+ });
42
+ child.unref();
43
+ }
44
+ catch {
45
+ return launchFailure();
46
+ }
47
+ return new Promise((resolve) => {
48
+ child.once("spawn", () => {
49
+ resolve({ ok: true, value: { agent: "cursor" } });
50
+ });
51
+ child.once("error", () => {
52
+ resolve(launchFailure());
53
+ });
54
+ });
55
+ }
56
+ }
57
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../src/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AAK3E,OAAO,EACL,sBAAsB,GAEvB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,cAAc,GAAG,QAAQ,CAAC;AAyBhC,MAAM,YAAY,GAAgB,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAC9D,SAAS,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AAE5C,SAAS,aAAa;IACpB,OAAO;QACL,EAAE,EAAE,KAAK;QACT,KAAK,EAAE;YACL,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,cAAc;SACxB;KAC0B,CAAC;AAChC,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,mBAAmB,CAAyB;IAC5C,MAAM,CAAc;IAE7B,YAAY,OAAO,GAA0B,EAAE;QAC7C,IAAI,CAAC,mBAAmB;YACtB,OAAO,CAAC,kBAAkB,IAAI,IAAI,sBAAsB,EAAE,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,aAAqB;QAChC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1E,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,iBAAiB;oBACvB,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,cAAc;iBACxB;aAC0B,CAAC;QAChC,CAAC;QAED,IAAI,KAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,CAAC,EAAE;gBAC/C,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,EAAE;YAChD,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,32 @@
1
+ import type { DeploymentReadyState } from "@ebay-dt/bonfire-core";
2
+ /**
3
+ * The normalized result returned by a deployment provider. `url` is the
4
+ * deployment-root URL; the lifecycle service adds the active prototype route.
5
+ */
6
+ export type DeploymentProviderResult = {
7
+ url: string;
8
+ deploymentId: string;
9
+ readyState: DeploymentReadyState;
10
+ };
11
+ /** Server-side transport boundary for creating an application deployment. */
12
+ export interface DeploymentProvider {
13
+ deploy(input: {
14
+ applicationId: string;
15
+ login: string;
16
+ }): Promise<DeploymentProviderResult>;
17
+ }
18
+ export type CreateDeploymentProviderOptions = {
19
+ endpoint: string;
20
+ timeoutMs?: number;
21
+ };
22
+ export type DeploymentProviderErrorKind = "timeout" | "service-failure" | "invalid-response" | "invalid-url" | "invalid-configuration";
23
+ /**
24
+ * Safe provider failure classification. It intentionally carries no response
25
+ * body, endpoint credentials, or unbounded service diagnostics.
26
+ */
27
+ export declare class DeploymentProviderError extends Error {
28
+ readonly kind: DeploymentProviderErrorKind;
29
+ constructor(kind: DeploymentProviderErrorKind);
30
+ }
31
+ export declare function createDeploymentProvider({ endpoint: configuredEndpoint, timeoutMs: configuredTimeout, }: CreateDeploymentProviderOptions): DeploymentProvider;
32
+ //# sourceMappingURL=deployment-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-provider.d.ts","sourceRoot":"","sources":["../src/deployment-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAQlE;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,oBAAoB,CAAC;CAClC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACvC;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACnC,SAAS,GACT,iBAAiB,GACjB,kBAAkB,GAClB,aAAa,GACb,uBAAuB,CAAC;AAE5B;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAE3C,YAAY,IAAI,EAAE,2BAA2B,EAI5C;CACF;AA8KD,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EAAE,kBAAkB,EAC5B,SAAS,EAAE,iBAAiB,GAC7B,EAAE,+BAA+B,GAAG,kBAAkB,CA2CtD"}