@freibergergarcia/phone-a-friend 2.7.1 → 2.7.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "phone-a-friend",
3
3
  "description": "CLI relay that lets AI coding agents collaborate by sending prompts and repository context to backend agents.",
4
- "version": "2.7.1",
4
+ "version": "2.7.2",
5
5
  "author": {
6
6
  "name": "Bruno Freiberger"
7
7
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phone-a-friend",
3
- "version": "2.7.1",
3
+ "version": "2.7.2",
4
4
  "description": "CLI relay that lets AI coding agents collaborate by sending prompts and repository context to backend agents.",
5
5
  "author": {
6
6
  "name": "Bruno Freiberger"
package/dist/index.js CHANGED
@@ -6979,6 +6979,9 @@ function looksLikeCodexAlready(output) {
6979
6979
  "already registered"
6980
6980
  ].some((token) => text.includes(token));
6981
6981
  }
6982
+ function codexMarketplaceSource(resolvedRepo) {
6983
+ return resolvedRepo.includes("@") ? GITHUB_REPO : resolvedRepo;
6984
+ }
6982
6985
  function syncCodexPluginRegistration(source) {
6983
6986
  const lines = [];
6984
6987
  try {
@@ -7248,7 +7251,7 @@ function installHosts(opts) {
7248
7251
  }
7249
7252
  }
7250
7253
  if (shouldInstallCodex && syncCodexCli) {
7251
- lines.push(...syncCodexPluginRegistration(resolvedRepo));
7254
+ lines.push(...syncCodexPluginRegistration(codexMarketplaceSource(resolvedRepo)));
7252
7255
  }
7253
7256
  return lines;
7254
7257
  }
@@ -78071,9 +78074,27 @@ async function* parseNDJSONStream(body, signal) {
78071
78074
  throw new Error("Stream ended unexpectedly");
78072
78075
  }
78073
78076
  }
78077
+ function extractOpenCodeErrorMessage(event) {
78078
+ const error3 = event.error;
78079
+ if (error3 && typeof error3 === "object") {
78080
+ const data = error3.data;
78081
+ if (data && typeof data.message === "string" && data.message.trim()) {
78082
+ return data.message;
78083
+ }
78084
+ if (typeof error3.name === "string" && error3.name.trim()) {
78085
+ return error3.name;
78086
+ }
78087
+ try {
78088
+ return JSON.stringify(error3);
78089
+ } catch {
78090
+ }
78091
+ }
78092
+ return "opencode reported an error";
78093
+ }
78074
78094
  async function* parseOpenCodeStreamJSON(stdout, opts) {
78075
78095
  let buffer = "";
78076
78096
  let sessionReported = false;
78097
+ let errorReported = false;
78077
78098
  function* processLines(lines) {
78078
78099
  for (const line of lines) {
78079
78100
  const trimmed = line.trim();
@@ -78088,6 +78109,10 @@ async function* parseOpenCodeStreamJSON(stdout, opts) {
78088
78109
  opts.onSessionCreated(parsed.sessionID);
78089
78110
  sessionReported = true;
78090
78111
  }
78112
+ if (!errorReported && parsed.type === "error" && opts?.onError) {
78113
+ opts.onError(extractOpenCodeErrorMessage(parsed));
78114
+ errorReported = true;
78115
+ }
78091
78116
  if (parsed.type === "text") {
78092
78117
  const part = parsed.part;
78093
78118
  if (part?.text && typeof part.text === "string") {
@@ -78381,6 +78406,18 @@ function isClaudeAuthError(msg) {
78381
78406
  const text = msg.toLowerCase();
78382
78407
  return text.includes("not logged in") || text.includes("please run /login");
78383
78408
  }
78409
+ function extractClaudeSchemaOutput(stdout) {
78410
+ let parsed;
78411
+ try {
78412
+ parsed = JSON.parse(stdout);
78413
+ } catch {
78414
+ return stdout;
78415
+ }
78416
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && Object.prototype.hasOwnProperty.call(parsed, "structured_output")) {
78417
+ return JSON.stringify(parsed.structured_output);
78418
+ }
78419
+ return stdout;
78420
+ }
78384
78421
  var ClaudeBackend = class {
78385
78422
  name = "claude";
78386
78423
  localFileAccess = true;
@@ -78466,7 +78503,7 @@ var ClaudeBackend = class {
78466
78503
  label: "claude"
78467
78504
  });
78468
78505
  if (result.stdout) {
78469
- return result.stdout;
78506
+ return opts.schema ? extractClaudeSchemaOutput(result.stdout) : result.stdout;
78470
78507
  }
78471
78508
  throw new ClaudeBackendError("claude completed without producing output");
78472
78509
  } catch (err) {
@@ -78716,42 +78753,48 @@ var OpenCodeBackend = class {
78716
78753
  process.on("SIGINT", onSigint);
78717
78754
  const stderrChunks = [];
78718
78755
  child.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
78719
- const closePromise = new Promise((resolve5, reject) => {
78720
- child.on("close", (code, signal) => {
78721
- if (timedOut) {
78722
- reject(new OpenCodeBackendError(
78723
- `opencode timed out after ${opts.timeoutSeconds}s`
78724
- ));
78725
- } else if (signal) {
78726
- reject(new OpenCodeBackendError(
78727
- `opencode killed by signal ${signal}`
78728
- ));
78729
- } else if (code !== 0 && code !== null) {
78730
- const stderr = Buffer.concat(stderrChunks).toString().trim();
78731
- reject(new OpenCodeBackendError(
78732
- stderr || `opencode exited with code ${code}`
78733
- ));
78734
- } else {
78735
- resolve5();
78736
- }
78737
- });
78738
- });
78756
+ let streamError = null;
78757
+ const closePromise = new Promise(
78758
+ (resolve5) => {
78759
+ child.on("close", (code, signal) => resolve5({ code, signal }));
78760
+ }
78761
+ );
78739
78762
  let chunkCount = 0;
78740
78763
  try {
78741
78764
  for await (const chunk of parseOpenCodeStreamJSON(
78742
78765
  child.stdout,
78743
- { onSessionCreated: opts.onSessionCreated }
78766
+ {
78767
+ onSessionCreated: opts.onSessionCreated,
78768
+ onError: (msg) => {
78769
+ if (streamError === null) streamError = msg;
78770
+ }
78771
+ }
78744
78772
  )) {
78745
78773
  chunkCount++;
78746
78774
  yield chunk;
78747
78775
  }
78748
- await closePromise;
78776
+ const { code, signal } = await closePromise;
78777
+ if (timedOut) {
78778
+ throw new OpenCodeBackendError(
78779
+ `opencode timed out after ${opts.timeoutSeconds}s`
78780
+ );
78781
+ }
78782
+ if (signal) {
78783
+ throw new OpenCodeBackendError(`opencode killed by signal ${signal}`);
78784
+ }
78785
+ if (code !== 0 && code !== null) {
78786
+ const stderr = Buffer.concat(stderrChunks).toString().trim();
78787
+ throw new OpenCodeBackendError(
78788
+ stderr || streamError || `opencode exited with code ${code}`
78789
+ );
78790
+ }
78791
+ if (streamError) {
78792
+ throw new OpenCodeBackendError(streamError);
78793
+ }
78749
78794
  if (chunkCount === 0) {
78750
78795
  throw new OpenCodeBackendError(OPENCODE_NO_OUTPUT_MESSAGE);
78751
78796
  }
78752
78797
  } catch (err) {
78753
- closePromise.catch(() => {
78754
- });
78755
78798
  if (err instanceof OpenCodeBackendError) throw err;
78756
78799
  const msg = err instanceof Error ? err.message : String(err);
78757
78800
  if (timedOut) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freibergergarcia/phone-a-friend",
3
- "version": "2.7.1",
3
+ "version": "2.7.2",
4
4
  "description": "CLI relay that lets AI coding agents collaborate",
5
5
  "keywords": [
6
6
  "ai-agent",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phone-a-friend",
3
- "version": "2.7.1",
3
+ "version": "2.7.2",
4
4
  "description": "CLI relay that lets AI coding agents collaborate by sending prompts and repository context to backend agents.",
5
5
  "author": {
6
6
  "name": "Bruno Freiberger"