@codeyam-editor/codeyam-editor 0.1.2 → 0.1.3

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.
package/npm/utils.js CHANGED
@@ -8,14 +8,20 @@ const serverStatePath = path.join(rootDir, ".codeyam", "server-state.json");
8
8
 
9
9
  /**
10
10
  * Map (process.platform, process.arch) → the platform sub-package that
11
- * carries the matching native binary. Kept as a small data table so adding
12
- * a new platform (e.g. linux/arm64) is one entry, not a new branch.
11
+ * carries the matching native binaries. Each sub-package ships TWO
12
+ * binaries side-by-side in its `bin/` dir: the `codeyam-editor` monolith
13
+ * and the dedicated `codeyam-editor-pty-broker` daemon (its own
14
+ * executable file / inode, for a stable honest process name). They live
15
+ * in the same dir so the broker auto-spawn's sibling-of-current-exe
16
+ * resolution finds the broker next to the monolith with no copying.
17
+ * Kept as a small data table so adding a new platform (e.g. linux/arm64)
18
+ * is one entry, not a new branch.
13
19
  */
14
20
  const PLATFORM_PACKAGES = {
15
- "darwin-arm64": { pkg: "@codeyam-editor/codeyam-editor-darwin-arm64", binary: "codeyam-editor" },
16
- "darwin-x64": { pkg: "@codeyam-editor/codeyam-editor-darwin-x64", binary: "codeyam-editor" },
17
- "linux-x64": { pkg: "@codeyam-editor/codeyam-editor-linux-x64", binary: "codeyam-editor" },
18
- "win32-x64": { pkg: "@codeyam-editor/codeyam-editor-win32-x64", binary: "codeyam-editor.exe" },
21
+ "darwin-arm64": { pkg: "@codeyam-editor/codeyam-editor-darwin-arm64", binary: "codeyam-editor", broker: "codeyam-editor-pty-broker" },
22
+ "darwin-x64": { pkg: "@codeyam-editor/codeyam-editor-darwin-x64", binary: "codeyam-editor", broker: "codeyam-editor-pty-broker" },
23
+ "linux-x64": { pkg: "@codeyam-editor/codeyam-editor-linux-x64", binary: "codeyam-editor", broker: "codeyam-editor-pty-broker" },
24
+ "win32-x64": { pkg: "@codeyam-editor/codeyam-editor-win32-x64", binary: "codeyam-editor.exe", broker: "codeyam-editor-pty-broker.exe" },
19
25
  };
20
26
 
21
27
  /**
@@ -27,6 +33,14 @@ function binaryName(platform = process.platform) {
27
33
  return platform === "win32" ? "codeyam-editor.exe" : "codeyam-editor";
28
34
  }
29
35
 
36
+ /**
37
+ * Platform-correct executable filename for the dedicated broker binary.
38
+ * Mirrors {@link binaryName} for the second shipped binary.
39
+ */
40
+ function brokerBinaryName(platform = process.platform) {
41
+ return platform === "win32" ? "codeyam-editor-pty-broker.exe" : "codeyam-editor-pty-broker";
42
+ }
43
+
30
44
  /** Look up the platform sub-package metadata for a given platform/arch pair. */
31
45
  function platformPackageInfo(platform = process.platform, arch = process.arch) {
32
46
  return PLATFORM_PACKAGES[`${platform}-${arch}`] || null;
@@ -62,10 +76,25 @@ function findBinary() {
62
76
  }
63
77
 
64
78
  const name = binaryName();
65
- const devCandidates = [
66
- path.join(rootDir, "target", "debug", name),
67
- path.join(rootDir, "target", "release", name),
68
- ];
79
+ // Target directories to search, in precedence order. A custom
80
+ // CARGO_TARGET_DIR (cloud VMs set CARGO_TARGET_DIR=/codeyam-build-target)
81
+ // wins over the default ./target — cargo builds ONLY into the configured
82
+ // dir, so ./target may be stale or absent. Honoring it here keeps
83
+ // `ensureBinary` from building successfully and then failing to locate the
84
+ // result. CARGO_TARGET_DIR may be absolute or relative to the workspace
85
+ // root; path.resolve handles both (an absolute value ignores rootDir).
86
+ const targetDirs = [];
87
+ const customTarget = process.env.CARGO_TARGET_DIR;
88
+ if (customTarget) {
89
+ targetDirs.push(path.resolve(rootDir, customTarget));
90
+ }
91
+ targetDirs.push(path.join(rootDir, "target"));
92
+
93
+ const devCandidates = [];
94
+ for (const dir of targetDirs) {
95
+ devCandidates.push(path.join(dir, "debug", name));
96
+ devCandidates.push(path.join(dir, "release", name));
97
+ }
69
98
  for (const candidate of devCandidates) {
70
99
  if (fs.existsSync(candidate)) return candidate;
71
100
  }
@@ -133,48 +162,71 @@ function ensureBinary() {
133
162
  console.error("Binary not found after build.");
134
163
  process.exit(1);
135
164
  }
165
+ verifyBrokerBinaryPresent(binary);
136
166
  return binary;
137
167
  }
138
168
 
139
- /** Resolve the UI dist directory for the binary to serve. */
140
- function uiDistDir() {
141
- return path.join(rootDir, "ui", "dist");
142
- }
143
-
144
169
  /**
145
- * True when `cwd` IS the editor repo root (or is nested under it), so the
146
- * wrapper is being used to develop the editor itself rather than against an
147
- * external client project. Compares realpath-resolved paths so a symlinked
148
- * checkout (`~/work/foo` → `/Volumes/dev/foo`) still matches — the same
149
- * convention `crates/control-api/src/state.rs:203` documents for the
150
- * server-side identity probe.
151
- *
152
- * Pure and synchronous (uses `fs.realpathSync`). On a realpath failure (an
153
- * unreadable path, race with a moved file) the un-resolved value is used as
154
- * a fallback — the same defensive shape `canonicalisePath` uses, so the
155
- * wrapper never bails on a transient fs hiccup.
156
- *
157
- * Gate for the dev wrapper's passthrough `cargo build`: when the target
158
- * project is the editor itself, rebuilding makes sense (the developer is
159
- * iterating on editor source). When it is any other project, the rebuild
160
- * does nothing of value and ripples into the stale-binary watcher's
161
- * SIGUSR1 re-exec, resetting the user's session for no reason. The
162
- * `CODEYAM_DEV_REBUILD=1` env preserves the one legitimate "editing the
163
- * editor against a client project" workflow.
170
+ * Resolve the dedicated broker binary path. Mirrors {@link findBinary}:
171
+ * the published platform sub-package ships it next to the monolith, and
172
+ * a dev `cargo build` produces it under target/debug|release. Returns
173
+ * null if it can't be located — the Rust broker auto-spawn then falls
174
+ * back to the monolith `editor pty-broker daemon` shim, so a missing
175
+ * broker binary degrades gracefully rather than breaking the editor.
164
176
  */
165
- function isSelfHostTarget(cwd, repoRoot) {
166
- const safeReal = (p) => {
177
+ function findBrokerBinary() {
178
+ const info = platformPackageInfo();
179
+ if (info && info.broker) {
167
180
  try {
168
- return fs.realpathSync(p);
169
- } catch {
170
- return p;
181
+ const resolved = require.resolve(`${info.pkg}/bin/${info.broker}`, {
182
+ paths: [rootDir],
183
+ });
184
+ if (fs.existsSync(resolved)) return resolved;
185
+ } catch (e) {
186
+ if (e.code !== "MODULE_NOT_FOUND") throw e;
171
187
  }
172
- };
173
- const cwdReal = safeReal(cwd);
174
- const repoReal = safeReal(repoRoot);
175
- if (cwdReal === repoReal) return true;
176
- const sep = path.sep;
177
- return cwdReal.startsWith(repoReal.endsWith(sep) ? repoReal : repoReal + sep);
188
+ }
189
+
190
+ const name = brokerBinaryName();
191
+ const targetDirs = [];
192
+ const customTarget = process.env.CARGO_TARGET_DIR;
193
+ if (customTarget) {
194
+ targetDirs.push(path.resolve(rootDir, customTarget));
195
+ }
196
+ targetDirs.push(path.join(rootDir, "target"));
197
+
198
+ for (const dir of targetDirs) {
199
+ for (const profile of ["debug", "release"]) {
200
+ const candidate = path.join(dir, profile, name);
201
+ if (fs.existsSync(candidate)) return candidate;
202
+ }
203
+ }
204
+ return null;
205
+ }
206
+
207
+ /**
208
+ * Best-effort check that the dedicated broker binary sits next to the
209
+ * monolith (the layout the broker auto-spawn's sibling resolution
210
+ * expects). Logs a one-line note when it's missing — never throws or
211
+ * exits, because the Rust side degrades to the monolith shim. `monolith`
212
+ * is the resolved monolith binary path; the broker is expected as its
213
+ * sibling.
214
+ */
215
+ function verifyBrokerBinaryPresent(monolith) {
216
+ const sibling = path.join(path.dirname(monolith), brokerBinaryName());
217
+ if (fs.existsSync(sibling)) return;
218
+ const located = findBrokerBinary();
219
+ if (located) return;
220
+ console.error(
221
+ "Note: dedicated broker binary (codeyam-editor-pty-broker) not found next to " +
222
+ `${monolith}. The PTY broker will fall back to the monolith \`editor pty-broker daemon\` ` +
223
+ "shim. Reinstall the platform sub-package, or run `cargo build -p codeyam-pty-broker`."
224
+ );
225
+ }
226
+
227
+ /** Resolve the UI dist directory for the binary to serve. */
228
+ function uiDistDir() {
229
+ return path.join(rootDir, "ui", "dist");
178
230
  }
179
231
 
180
232
  /**
@@ -734,11 +786,13 @@ module.exports = {
734
786
  rootDir,
735
787
  serverStatePath,
736
788
  binaryName,
789
+ brokerBinaryName,
737
790
  platformPackageInfo,
738
791
  PLATFORM_PACKAGES,
739
792
  findBinary,
793
+ findBrokerBinary,
794
+ verifyBrokerBinaryPresent,
740
795
  ensureBinary,
741
- isSelfHostTarget,
742
796
  staleBinaryBanner,
743
797
  enforceFreshBinary,
744
798
  uiDistDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeyam-editor/codeyam-editor",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Language-agnostic managed execution sandbox for scenario-driven development",
5
5
  "bin": {
6
6
  "codeyam-editor": "./npm/cli.js"
@@ -9,10 +9,10 @@
9
9
  "playwright": "^1.58.2"
10
10
  },
11
11
  "optionalDependencies": {
12
- "@codeyam-editor/codeyam-editor-darwin-arm64": "0.1.2",
13
- "@codeyam-editor/codeyam-editor-darwin-x64": "0.1.2",
14
- "@codeyam-editor/codeyam-editor-linux-x64": "0.1.2",
15
- "@codeyam-editor/codeyam-editor-win32-x64": "0.1.2"
12
+ "@codeyam-editor/codeyam-editor-darwin-arm64": "0.1.3",
13
+ "@codeyam-editor/codeyam-editor-darwin-x64": "0.1.3",
14
+ "@codeyam-editor/codeyam-editor-linux-x64": "0.1.3",
15
+ "@codeyam-editor/codeyam-editor-win32-x64": "0.1.3"
16
16
  },
17
17
  "keywords": [
18
18
  "codeyam",