@base44-preview/cli 0.1.15-pr.630.68db200 → 0.1.15-pr.630.851b4db

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/dist/cli/index.js CHANGED
@@ -52822,7 +52822,7 @@ function canBreakFn(doc) {
52822
52822
  function canBreak(doc) {
52823
52823
  return findInDoc(doc, canBreakFn, false);
52824
52824
  }
52825
- function indent(contents) {
52825
+ function indent2(contents) {
52826
52826
  assertDoc(contents);
52827
52827
  return { type: DOC_TYPE_INDENT, contents };
52828
52828
  }
@@ -52845,7 +52845,7 @@ function addAlignmentToDoc(doc, size, tabWidth) {
52845
52845
  let aligned = doc;
52846
52846
  if (size > 0) {
52847
52847
  for (let level = 0;level < Math.floor(size / tabWidth); ++level) {
52848
- aligned = indent(aligned);
52848
+ aligned = indent2(aligned);
52849
52849
  }
52850
52850
  aligned = align(size % tabWidth, aligned);
52851
52851
  aligned = align(Number.NEGATIVE_INFINITY, aligned);
@@ -53179,7 +53179,7 @@ function printDocToString(doc, options) {
53179
53179
  propagateBreaks(doc);
53180
53180
  while (commands.length > 0) {
53181
53181
  const {
53182
- indent: indent2,
53182
+ indent: indent22,
53183
53183
  mode,
53184
53184
  doc: doc2
53185
53185
  } = commands.pop();
@@ -53199,7 +53199,7 @@ function printDocToString(doc, options) {
53199
53199
  case DOC_TYPE_ARRAY:
53200
53200
  for (let index = doc2.length - 1;index >= 0; index--) {
53201
53201
  commands.push({
53202
- indent: indent2,
53202
+ indent: indent22,
53203
53203
  mode,
53204
53204
  doc: doc2[index]
53205
53205
  });
@@ -53213,14 +53213,14 @@ function printDocToString(doc, options) {
53213
53213
  break;
53214
53214
  case DOC_TYPE_INDENT:
53215
53215
  commands.push({
53216
- indent: makeIndent(indent2, options),
53216
+ indent: makeIndent(indent22, options),
53217
53217
  mode,
53218
53218
  doc: doc2.contents
53219
53219
  });
53220
53220
  break;
53221
53221
  case DOC_TYPE_ALIGN:
53222
53222
  commands.push({
53223
- indent: makeAlign(indent2, doc2.n, options),
53223
+ indent: makeAlign(indent22, doc2.n, options),
53224
53224
  mode,
53225
53225
  doc: doc2.contents
53226
53226
  });
@@ -53233,7 +53233,7 @@ function printDocToString(doc, options) {
53233
53233
  case MODE_FLAT:
53234
53234
  if (!shouldRemeasure) {
53235
53235
  commands.push({
53236
- indent: indent2,
53236
+ indent: indent22,
53237
53237
  mode: doc2.break ? MODE_BREAK : MODE_FLAT,
53238
53238
  doc: doc2.contents
53239
53239
  });
@@ -53242,7 +53242,7 @@ function printDocToString(doc, options) {
53242
53242
  case MODE_BREAK: {
53243
53243
  shouldRemeasure = false;
53244
53244
  const next = {
53245
- indent: indent2,
53245
+ indent: indent22,
53246
53246
  mode: MODE_FLAT,
53247
53247
  doc: doc2.contents
53248
53248
  };
@@ -53255,7 +53255,7 @@ function printDocToString(doc, options) {
53255
53255
  const mostExpanded = method_at_default(0, doc2.expandedStates, -1);
53256
53256
  if (doc2.break) {
53257
53257
  commands.push({
53258
- indent: indent2,
53258
+ indent: indent22,
53259
53259
  mode: MODE_BREAK,
53260
53260
  doc: mostExpanded
53261
53261
  });
@@ -53264,7 +53264,7 @@ function printDocToString(doc, options) {
53264
53264
  for (let index = 1;index < doc2.expandedStates.length + 1; index++) {
53265
53265
  if (index >= doc2.expandedStates.length) {
53266
53266
  commands.push({
53267
- indent: indent2,
53267
+ indent: indent22,
53268
53268
  mode: MODE_BREAK,
53269
53269
  doc: mostExpanded
53270
53270
  });
@@ -53272,7 +53272,7 @@ function printDocToString(doc, options) {
53272
53272
  } else {
53273
53273
  const state = doc2.expandedStates[index];
53274
53274
  const cmd = {
53275
- indent: indent2,
53275
+ indent: indent22,
53276
53276
  mode: MODE_FLAT,
53277
53277
  doc: state
53278
53278
  };
@@ -53285,7 +53285,7 @@ function printDocToString(doc, options) {
53285
53285
  }
53286
53286
  } else {
53287
53287
  commands.push({
53288
- indent: indent2,
53288
+ indent: indent22,
53289
53289
  mode: MODE_BREAK,
53290
53290
  doc: doc2.contents
53291
53291
  });
@@ -53311,12 +53311,12 @@ function printDocToString(doc, options) {
53311
53311
  const content = parts[offset + 0];
53312
53312
  const whitespace = parts[offset + 1];
53313
53313
  const contentFlatCommand = {
53314
- indent: indent2,
53314
+ indent: indent22,
53315
53315
  mode: MODE_FLAT,
53316
53316
  doc: content
53317
53317
  };
53318
53318
  const contentBreakCommand = {
53319
- indent: indent2,
53319
+ indent: indent22,
53320
53320
  mode: MODE_BREAK,
53321
53321
  doc: content
53322
53322
  };
@@ -53330,12 +53330,12 @@ function printDocToString(doc, options) {
53330
53330
  break;
53331
53331
  }
53332
53332
  const whitespaceFlatCommand = {
53333
- indent: indent2,
53333
+ indent: indent22,
53334
53334
  mode: MODE_FLAT,
53335
53335
  doc: whitespace
53336
53336
  };
53337
53337
  const whitespaceBreakCommand = {
53338
- indent: indent2,
53338
+ indent: indent22,
53339
53339
  mode: MODE_BREAK,
53340
53340
  doc: whitespace
53341
53341
  };
@@ -53349,7 +53349,7 @@ function printDocToString(doc, options) {
53349
53349
  }
53350
53350
  const secondContent = parts[offset + 2];
53351
53351
  const remainingCommand = {
53352
- indent: indent2,
53352
+ indent: indent22,
53353
53353
  mode,
53354
53354
  doc: {
53355
53355
  ...doc2,
@@ -53357,7 +53357,7 @@ function printDocToString(doc, options) {
53357
53357
  }
53358
53358
  };
53359
53359
  const firstAndSecondContentFlatCommand = {
53360
- indent: indent2,
53360
+ indent: indent22,
53361
53361
  mode: MODE_FLAT,
53362
53362
  doc: [content, whitespace, secondContent]
53363
53363
  };
@@ -53376,20 +53376,20 @@ function printDocToString(doc, options) {
53376
53376
  case DOC_TYPE_INDENT_IF_BREAK: {
53377
53377
  const groupMode = doc2.groupId ? groupModeMap[doc2.groupId] : mode;
53378
53378
  if (groupMode === MODE_BREAK) {
53379
- const breakContents = doc2.type === DOC_TYPE_IF_BREAK ? doc2.breakContents : doc2.negate ? doc2.contents : indent(doc2.contents);
53379
+ const breakContents = doc2.type === DOC_TYPE_IF_BREAK ? doc2.breakContents : doc2.negate ? doc2.contents : indent2(doc2.contents);
53380
53380
  if (breakContents) {
53381
53381
  commands.push({
53382
- indent: indent2,
53382
+ indent: indent22,
53383
53383
  mode,
53384
53384
  doc: breakContents
53385
53385
  });
53386
53386
  }
53387
53387
  }
53388
53388
  if (groupMode === MODE_FLAT) {
53389
- const flatContents = doc2.type === DOC_TYPE_IF_BREAK ? doc2.flatContents : doc2.negate ? indent(doc2.contents) : doc2.contents;
53389
+ const flatContents = doc2.type === DOC_TYPE_IF_BREAK ? doc2.flatContents : doc2.negate ? indent2(doc2.contents) : doc2.contents;
53390
53390
  if (flatContents) {
53391
53391
  commands.push({
53392
- indent: indent2,
53392
+ indent: indent22,
53393
53393
  mode,
53394
53394
  doc: flatContents
53395
53395
  });
@@ -53399,7 +53399,7 @@ function printDocToString(doc, options) {
53399
53399
  }
53400
53400
  case DOC_TYPE_LINE_SUFFIX:
53401
53401
  lineSuffix2.push({
53402
- indent: indent2,
53402
+ indent: indent22,
53403
53403
  mode,
53404
53404
  doc: doc2.contents
53405
53405
  });
@@ -53407,7 +53407,7 @@ function printDocToString(doc, options) {
53407
53407
  case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
53408
53408
  if (lineSuffix2.length > 0) {
53409
53409
  commands.push({
53410
- indent: indent2,
53410
+ indent: indent22,
53411
53411
  mode,
53412
53412
  doc: hardlineWithoutBreakParent
53413
53413
  });
@@ -53428,7 +53428,7 @@ function printDocToString(doc, options) {
53428
53428
  case MODE_BREAK:
53429
53429
  if (lineSuffix2.length > 0) {
53430
53430
  commands.push({
53431
- indent: indent2,
53431
+ indent: indent22,
53432
53432
  mode,
53433
53433
  doc: doc2
53434
53434
  }, ...lineSuffix2.reverse());
@@ -53438,23 +53438,23 @@ function printDocToString(doc, options) {
53438
53438
  if (doc2.literal) {
53439
53439
  output += newLine;
53440
53440
  position = 0;
53441
- if (indent2.root) {
53442
- if (indent2.root.value) {
53443
- output += indent2.root.value;
53441
+ if (indent22.root) {
53442
+ if (indent22.root.value) {
53443
+ output += indent22.root.value;
53444
53444
  }
53445
- position = indent2.root.length;
53445
+ position = indent22.root.length;
53446
53446
  }
53447
53447
  } else {
53448
53448
  trim2();
53449
- output += newLine + indent2.value;
53450
- position = indent2.length;
53449
+ output += newLine + indent22.value;
53450
+ position = indent22.length;
53451
53451
  }
53452
53452
  break;
53453
53453
  }
53454
53454
  break;
53455
53455
  case DOC_TYPE_LABEL:
53456
53456
  commands.push({
53457
- indent: indent2,
53457
+ indent: indent22,
53458
53458
  mode,
53459
53459
  doc: doc2.contents
53460
53460
  });
@@ -53616,7 +53616,7 @@ var init_doc = __esm(() => {
53616
53616
  breakParent,
53617
53617
  ifBreak,
53618
53618
  trim: trim2,
53619
- indent,
53619
+ indent: indent2,
53620
53620
  indentIfBreak,
53621
53621
  align,
53622
53622
  addAlignmentToDoc,
@@ -140754,7 +140754,7 @@ import { pathToFileURL as pathToFileURL5 } from "url";
140754
140754
  import path122 from "path";
140755
140755
  import path142 from "path";
140756
140756
  import url22 from "url";
140757
- function diffLines(oldStr, newStr, options8) {
140757
+ function diffLines2(oldStr, newStr, options8) {
140758
140758
  return lineDiff.diff(oldStr, newStr, options8);
140759
140759
  }
140760
140760
  function tokenize4(value, options8) {
@@ -140796,10 +140796,10 @@ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, ne
140796
140796
  throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
140797
140797
  }
140798
140798
  if (!optionsObj.callback) {
140799
- return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
140799
+ return diffLinesResultToPatch(diffLines2(oldStr, newStr, optionsObj));
140800
140800
  } else {
140801
140801
  const { callback } = optionsObj;
140802
- diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
140802
+ diffLines2(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
140803
140803
  const patch = diffLinesResultToPatch(diff);
140804
140804
  callback(patch);
140805
140805
  } }));
@@ -142409,7 +142409,7 @@ function parse42(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
142409
142409
  }
142410
142410
  return res;
142411
142411
  }
142412
- async function readFile5(file) {
142412
+ async function readFile6(file) {
142413
142413
  if (isUrlString(file)) {
142414
142414
  file = new URL(file);
142415
142415
  }
@@ -146441,7 +146441,7 @@ var require2, __filename2, __dirname3, __create2, __defProp3, __getOwnPropDesc2,
146441
146441
  }
146442
146442
  }
146443
146443
  }, ast_path_default, is_object_default, skipWhitespace, skipSpaces, skipToLineEnd, skipEverythingButNewLine, isNewlineCharacter = (character) => character === `
146444
- ` || character === "\r" || character === "\u2028" || character === "\u2029", skip_newline_default, has_newline_default, is_non_empty_array_default, get_sorted_child_nodes_default, childNodesCache, returnFalse = () => false, isAllEmptyAndNoLineBreak = (text) => !/[\S\n\u2028\u2029]/u.test(text), is_previous_line_empty_default, breakParent2, hardline2, indent2, join32, line22, lineSuffix2, create_print_pre_check_function_default = () => noop_default2, core_options_evaluate_default, arrayToReversed, toReversed, method_to_reversed_default, import_n_readlines, get_interpreter_default, getFileBasename = (file) => {
146444
+ ` || character === "\r" || character === "\u2028" || character === "\u2029", skip_newline_default, has_newline_default, is_non_empty_array_default, get_sorted_child_nodes_default, childNodesCache, returnFalse = () => false, isAllEmptyAndNoLineBreak = (text) => !/[\S\n\u2028\u2029]/u.test(text), is_previous_line_empty_default, breakParent2, hardline2, indent3, join32, line22, lineSuffix2, create_print_pre_check_function_default = () => noop_default2, core_options_evaluate_default, arrayToReversed, toReversed, method_to_reversed_default, import_n_readlines, get_interpreter_default, getFileBasename = (file) => {
146445
146445
  try {
146446
146446
  return path112.basename(toPath4(file));
146447
146447
  } catch {
@@ -156203,7 +156203,7 @@ ${codeblock}`, options8);
156203
156203
  "\\": "\\"
156204
156204
  };
156205
156205
  KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
156206
- read_file_default = readFile5;
156206
+ read_file_default = readFile6;
156207
156207
  loadConfigFromPackageJson = process.versions.bun ? async function loadConfigFromBunPackageJson(file) {
156208
156208
  const { prettier } = await readBunPackageJson(file);
156209
156209
  return prettier;
@@ -156469,7 +156469,7 @@ ${codeblock}`, options8);
156469
156469
  ({
156470
156470
  breakParent: breakParent2,
156471
156471
  hardline: hardline2,
156472
- indent: indent2,
156472
+ indent: indent3,
156473
156473
  join: join32,
156474
156474
  line: line22,
156475
156475
  lineSuffix: lineSuffix2
@@ -268401,6 +268401,10 @@ async function captureRequestBody(request, options) {
268401
268401
  if (request.body == null) {
268402
268402
  return;
268403
268403
  }
268404
+ if (options.context.__redactBody) {
268405
+ options.context.__requestBody = "[redacted]";
268406
+ return;
268407
+ }
268404
268408
  try {
268405
268409
  const cloned = request.clone();
268406
268410
  const text = await cloned.text();
@@ -269956,7 +269960,7 @@ async function saveBuilderModel(userId, modelId) {
269956
269960
  });
269957
269961
  } catch (error) {
269958
269962
  if (error instanceof HTTPError && error.response.status === 400) {
269959
- throw new InvalidInputError("This account can't pick a builder model yet — enable the PER_USER_BUILDER_MODEL_SELECTION flag for it in PostHog, or the model isn't available in this workspace.");
269963
+ throw new InvalidInputError("This account can't pick a builder model yet, or the model isn't available in this workspace. Ask your workspace admin to enable model selection.");
269960
269964
  }
269961
269965
  throw await ApiError.fromHttpError(error, "saving your model choice");
269962
269966
  }
@@ -270006,7 +270010,7 @@ function getModelCommand() {
270006
270010
  }
270007
270011
 
270008
270012
  // src/cli/commands/builder/shared.ts
270009
- import { mkdir as mkdir3, writeFile as writeFile2 } from "node:fs/promises";
270013
+ import { mkdir as mkdir3, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
270010
270014
  import { basename as basename6, join as join25, relative as relative6, resolve as resolve8 } from "node:path";
270011
270015
 
270012
270016
  // src/cli/commands/code/render.ts
@@ -270015,6 +270019,10 @@ var TOOL_ALIASES = {
270015
270019
  read_repo_file: "read",
270016
270020
  write_repo_file: "write",
270017
270021
  edit_repo_file: "edit",
270022
+ read_file: "read",
270023
+ write_file: "write",
270024
+ find_replace: "edit",
270025
+ delete_file: "delete",
270018
270026
  set_secrets: "secrets",
270019
270027
  generate_development_secrets: "secrets",
270020
270028
  create_pull_request: "pr",
@@ -270028,7 +270036,55 @@ var TOOL_ALIASES = {
270028
270036
  preview_screenshot: "screenshot",
270029
270037
  connect_github_account: "github"
270030
270038
  };
270031
- var QUIET_OK_RESULTS = new Set(["read", "write", "edit", "reload"]);
270039
+ var QUIET_OK_RESULTS = new Set(["read", "write", "edit", "reload", "delete"]);
270040
+ var RESULT_LINE_MAX = 110;
270041
+ var DIFF_LINES_MAX = 12;
270042
+ var ERROR_LINES_MAX = 8;
270043
+ function renderEntry(entry, options = {}) {
270044
+ if (typeof entry === "string")
270045
+ return entry;
270046
+ if ("running" in entry)
270047
+ return runningLine(entry.running, entry.startedAt);
270048
+ return eventLine(entry.event, entry.elapsedMs, options) ?? "";
270049
+ }
270050
+ var RUNNING_DOT = "#E86B3C";
270051
+ var PULSE_MS = 500;
270052
+ function runningLine(event, startedAt, now = Date.now()) {
270053
+ const lit = Math.floor(now / PULSE_MS) % 2 === 0;
270054
+ const dot = lit ? source_default.hex(RUNNING_DOT)("●") : source_default.dim("●");
270055
+ const alias = toolAlias(event.name);
270056
+ const title = source_default.bold(event.label || alias);
270057
+ const inline = !event.label && event.summary ? ` ${source_default.dim(event.summary)}` : "";
270058
+ const seconds = Math.round((now - startedAt) / 1000);
270059
+ const took = seconds >= 3 ? ` ${source_default.dim(`· ${seconds}s`)}` : "";
270060
+ const detail = event.label && event.summary ? `
270061
+ ${source_default.dim(`└ ${alias}: ${event.summary}`)}` : "";
270062
+ return `${dot} ${title}${inline}${took}${detail}`;
270063
+ }
270064
+ function fold2(lines, max, options) {
270065
+ if (options.verbose || lines.length <= max)
270066
+ return lines;
270067
+ const hint = options.foldHint ? ` (${options.foldHint})` : "";
270068
+ return [
270069
+ ...lines.slice(0, max),
270070
+ source_default.dim(`… +${lines.length - max} lines${hint}`)
270071
+ ];
270072
+ }
270073
+ var str = (v) => typeof v === "string" ? v : undefined;
270074
+ function diffLines(args) {
270075
+ const find = str(args.find);
270076
+ const replace = str(args.replace);
270077
+ if (find == null && replace == null)
270078
+ return null;
270079
+ return [
270080
+ ...(find ?? "").split(`
270081
+ `).map((l) => source_default.red(`- ${l}`)),
270082
+ ...(replace ?? "").split(`
270083
+ `).map((l) => source_default.green(`+ ${l}`))
270084
+ ];
270085
+ }
270086
+ var indent = (lines) => lines.map((l) => ` ${l}`).join(`
270087
+ `);
270032
270088
  function toolAlias(name) {
270033
270089
  return TOOL_ALIASES[name] ?? name;
270034
270090
  }
@@ -270093,7 +270149,7 @@ function formatDuration2(ms) {
270093
270149
  return `${seconds}s`;
270094
270150
  return `${Math.floor(seconds / 60)}m ${String(seconds % 60).padStart(2, "0")}s`;
270095
270151
  }
270096
- function eventLine(event, elapsedMs) {
270152
+ function eventLine(event, elapsedMs, options = {}) {
270097
270153
  switch (event.kind) {
270098
270154
  case "thinking":
270099
270155
  return source_default.dim(`✻ ${event.text}`);
@@ -270103,7 +270159,7 @@ function eventLine(event, elapsedMs) {
270103
270159
  return null;
270104
270160
  case "waiting": {
270105
270161
  const what = event.label || toolAlias(event.name);
270106
- return source_default.yellow(`⏸ ${what} — needs your input (answer in the editor)`);
270162
+ return source_default.yellow(`⏸ ${what} — needs your input (${options.waitingHint ?? "answer in the editor"})`);
270107
270163
  }
270108
270164
  case "tool_end": {
270109
270165
  const alias = toolAlias(event.name);
@@ -270114,16 +270170,52 @@ function eventLine(event, elapsedMs) {
270114
270170
  const paramsLine = event.label && event.summary ? `
270115
270171
  ${source_default.dim(`${alias}: ${event.summary}`)}` : "";
270116
270172
  const head = `${mark} ${title}${inlineDetail}${took}${paramsLine}`;
270173
+ const args = event.args ?? null;
270174
+ if (event.ok && alias === "edit" && args) {
270175
+ const diff = diffLines(args);
270176
+ if (diff)
270177
+ return `${head}
270178
+ ${indent(fold2(diff, DIFF_LINES_MAX, options))}`;
270179
+ }
270180
+ if (event.ok && alias === "write" && args && str(args.content) != null) {
270181
+ const lines = str(args.content).split(`
270182
+ `);
270183
+ const count = source_default.dim(`+${lines.length} lines`);
270184
+ if (!options.verbose)
270185
+ return `${head} ${count}`;
270186
+ return `${head} ${count}
270187
+ ${indent(lines.map((l) => source_default.dim(l)))}`;
270188
+ }
270117
270189
  if (event.ok && (QUIET_OK_RESULTS.has(alias) || !event.result)) {
270118
270190
  return head;
270119
270191
  }
270120
- const result = event.ok ? source_default.dim(linkifyUrls(event.result)) : source_default.red(linkifyUrls(event.result));
270121
- return `${head}${event.result ? `
270122
- ${result}` : ""}`;
270192
+ const paint = event.ok ? source_default.dim : source_default.red;
270193
+ const lines = event.result.split(`
270194
+ `).map((l) => l.trimEnd()).filter((l, i, all) => l.length > 0 || i > 0 && i < all.length - 1);
270195
+ if (event.ok && !options.verbose) {
270196
+ const first = lines[0] ?? "";
270197
+ const cut = first.length > RESULT_LINE_MAX ? `${first.slice(0, RESULT_LINE_MAX)}…` : first;
270198
+ const more = lines.length - 1;
270199
+ const hint = options.foldHint ? ` (${options.foldHint})` : "";
270200
+ const tail = more > 0 ? source_default.dim(` … +${more} lines${hint}`) : "";
270201
+ return `${head}
270202
+ ${paint(linkifyUrls(cut))}${tail}`;
270203
+ }
270204
+ const shown = fold2(lines.map((l) => paint(linkifyUrls(l))), event.ok ? Number.POSITIVE_INFINITY : ERROR_LINES_MAX, options);
270205
+ return `${head}
270206
+ ${indent(shown)}`;
270123
270207
  }
270124
270208
  }
270125
270209
  }
270126
270210
  var FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
270211
+ var SHIMMER = ["·", "✢", "✳", "✶", "✻", "✽"];
270212
+ var SHIMMER_STEP_MS = 120;
270213
+ function shimmer(now = Date.now()) {
270214
+ const period = SHIMMER.length * 2 - 2;
270215
+ const step = Math.floor(now / SHIMMER_STEP_MS) % period;
270216
+ const index = step < SHIMMER.length ? step : period - step;
270217
+ return SHIMMER[index];
270218
+ }
270127
270219
  var MUSINGS = [
270128
270220
  "Shmoozing",
270129
270221
  "Shmoogling",
@@ -270187,7 +270279,7 @@ function createTurnStream(interactive, write = (text) => process.stdout.write(te
270187
270279
  return;
270188
270280
  const lines = [
270189
270281
  ...footer.length ? ["", ...footer] : [],
270190
- source_default.dim(`${FRAMES[frame]} ${statusLabel()}`)
270282
+ running.size === 0 ? `${source_default.magenta(shimmer())} ${source_default.dim(statusLabel())}` : source_default.dim(`${FRAMES[frame]} ${statusLabel()}`)
270191
270283
  ];
270192
270284
  write(lines.join(`
270193
270285
  `));
@@ -270225,7 +270317,10 @@ function createTurnStream(interactive, write = (text) => process.stdout.write(te
270225
270317
  elapsedMs = Date.now() - started;
270226
270318
  running.delete(event.id);
270227
270319
  }
270228
- const line = eventLine(event, elapsedMs);
270320
+ const line = eventLine(event, elapsedMs, {
270321
+ verbose: options.verbose,
270322
+ foldHint: "--verbose shows everything"
270323
+ });
270229
270324
  if (line == null)
270230
270325
  return;
270231
270326
  if (interactive) {
@@ -270260,6 +270355,10 @@ var CreatedAppSchema = object({
270260
270355
  name: string2().nullish(),
270261
270356
  imported_repo_url: string2().nullish()
270262
270357
  });
270358
+ var WixCreatedAppSchema = object({
270359
+ app_id: string2().min(1),
270360
+ client_creation_id: string2().min(1)
270361
+ });
270263
270362
  var AppStateSchema = object({
270264
270363
  id: string2(),
270265
270364
  app_type: string2().nullish(),
@@ -270299,7 +270398,8 @@ var ConversationMessageSchema = object({
270299
270398
  name: string2(),
270300
270399
  arguments_string: string2().nullish(),
270301
270400
  status: string2().nullish(),
270302
- results: unknown().nullish()
270401
+ results: unknown().nullish(),
270402
+ waiting_on: object({ kind: string2().nullish() }).nullish()
270303
270403
  })).nullish()
270304
270404
  });
270305
270405
  var FullConversationSchema = object({
@@ -270316,6 +270416,24 @@ function parseOrThrow(schema, payload, what) {
270316
270416
  function branchScope(branchId) {
270317
270417
  return branchId ? { branch_id: branchId } : {};
270318
270418
  }
270419
+ async function createWixLaunchedApp(options) {
270420
+ let response;
270421
+ try {
270422
+ response = await base44Client.post("api/wix/create-app", {
270423
+ timeout: false,
270424
+ context: { __redactBody: true },
270425
+ json: {
270426
+ prompt: options.prompt,
270427
+ signed_instance: options.signedInstance,
270428
+ ...options.wixClientId ? { wix_client_id: options.wixClientId } : {}
270429
+ }
270430
+ });
270431
+ } catch (error) {
270432
+ throw await ApiError.fromHttpError(error, "creating app via Wix launch");
270433
+ }
270434
+ const created = parseOrThrow(WixCreatedAppSchema, await response.json(), "app");
270435
+ return { id: created.app_id, client_creation_id: created.client_creation_id };
270436
+ }
270319
270437
  async function createApp(options) {
270320
270438
  let response;
270321
270439
  try {
@@ -270373,6 +270491,25 @@ async function getAppState(appId) {
270373
270491
  }
270374
270492
  return parseOrThrow(AppStateSchema, await response.json(), "app status");
270375
270493
  }
270494
+ async function answerToolCall(options, branchId) {
270495
+ let response;
270496
+ try {
270497
+ response = await getAppClient().post("chat/submit-tool-call-input", {
270498
+ timeout: false,
270499
+ context: { __redactBody: true },
270500
+ searchParams: branchScope(branchId),
270501
+ json: {
270502
+ tool_call_id: options.toolCallId,
270503
+ action: options.action,
270504
+ extra_user_input: options.input ?? {},
270505
+ ...options.messageId ? { message_id: options.messageId } : {}
270506
+ }
270507
+ });
270508
+ } catch (error) {
270509
+ throw await ApiError.fromHttpError(error, "answering the agent");
270510
+ }
270511
+ return parseOrThrow(ChatTurnSchema, await response.json(), "chat turn");
270512
+ }
270376
270513
  async function sendTurn(content, branchId) {
270377
270514
  let response;
270378
270515
  try {
@@ -270427,6 +270564,234 @@ async function getPreviewUrl() {
270427
270564
  return /^https?:\/\//.test(url) ? url : `https://${url}`;
270428
270565
  }
270429
270566
 
270567
+ // src/core/resources/apps/pending.ts
270568
+ var CHOICE_TOOLS = new Set([
270569
+ "ask_clarifying_questions",
270570
+ "ask_plan_questions"
270571
+ ]);
270572
+ var SECRET_TOOLS = new Set(["set_secrets"]);
270573
+ var LIST_CHOICE_TOOLS = {
270574
+ select_payment_provider: {
270575
+ key: "providers",
270576
+ question: "Which payment provider?",
270577
+ answer: "provider"
270578
+ }
270579
+ };
270580
+ var PERMISSION_TOOLS = new Set(["request_agent_tool_permissions"]);
270581
+ var CREDENTIALS_TOOLS = new Set(["register_workspace_connector"]);
270582
+ var BROWSER_TOOLS = new Set([
270583
+ "connect_github_account",
270584
+ "request_oauth_authorization",
270585
+ "configure_psp_credentials",
270586
+ "plaid_connect"
270587
+ ]);
270588
+ var str2 = (v) => typeof v === "string" && v.trim() ? v.trim() : undefined;
270589
+ function parseArgs(raw) {
270590
+ try {
270591
+ const parsed = JSON.parse(raw ?? "");
270592
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
270593
+ } catch {
270594
+ return {};
270595
+ }
270596
+ }
270597
+ function questionsFrom(args) {
270598
+ const raw = Array.isArray(args.questions) ? args.questions : [];
270599
+ return raw.flatMap((q) => {
270600
+ if (!q || typeof q !== "object")
270601
+ return [];
270602
+ const item = q;
270603
+ const question = str2(item.question);
270604
+ if (!question)
270605
+ return [];
270606
+ const options = (Array.isArray(item.options) ? item.options : []).flatMap((o) => {
270607
+ const opt = o;
270608
+ const label = str2(opt?.label);
270609
+ return label ? [{ label, description: str2(opt.description) }] : [];
270610
+ });
270611
+ return [
270612
+ {
270613
+ question,
270614
+ description: str2(item.description),
270615
+ options,
270616
+ multiSelect: item.multi_select === true
270617
+ }
270618
+ ];
270619
+ });
270620
+ }
270621
+ function secretsFrom(args) {
270622
+ const raw = Array.isArray(args.secrets_schema) ? args.secrets_schema : [];
270623
+ return raw.flatMap((s) => {
270624
+ const item = s;
270625
+ const name = str2(item?.secretName) ?? str2(item?.name);
270626
+ return name ? [{ name, description: str2(item.description) }] : [];
270627
+ });
270628
+ }
270629
+ function permissionKey(row) {
270630
+ switch (row.type) {
270631
+ case "entity":
270632
+ return row.entity_name ? `entity:${row.entity_name}` : null;
270633
+ case "backend_function":
270634
+ return row.function_name ? `backend_function:${row.function_name}` : null;
270635
+ case "app_user_connector":
270636
+ return row.connector_id ? `app_user_connector:${row.connector_id}` : null;
270637
+ default:
270638
+ return null;
270639
+ }
270640
+ }
270641
+ function permissionsFrom(args) {
270642
+ const raw = Array.isArray(args.requested_permissions) ? args.requested_permissions : [];
270643
+ return raw.flatMap((r) => {
270644
+ const row = r;
270645
+ const key = permissionKey(row);
270646
+ if (!key)
270647
+ return [];
270648
+ const ops = Array.isArray(row.allowed_operations) ? ` (${row.allowed_operations.join(", ")})` : "";
270649
+ const target = str2(row.entity_name) ?? str2(row.function_name) ?? str2(row.connector_name) ?? key;
270650
+ return [
270651
+ { key, label: `${row.type}: ${target}${ops}`, reason: str2(row.reason) }
270652
+ ];
270653
+ });
270654
+ }
270655
+ function guardFrom(results) {
270656
+ const value = typeof results === "string" ? (() => {
270657
+ try {
270658
+ return JSON.parse(results);
270659
+ } catch {
270660
+ return null;
270661
+ }
270662
+ })() : results;
270663
+ if (!value || typeof value !== "object")
270664
+ return null;
270665
+ const g = value;
270666
+ if (!str2(g.guard))
270667
+ return null;
270668
+ return { title: `${g.guard}: needs your approval`, detail: str2(g.reason) };
270669
+ }
270670
+ function humanize(tool) {
270671
+ return tool.replace(/_/g, " ");
270672
+ }
270673
+ function pendingInputs(messages) {
270674
+ const out = [];
270675
+ for (const message of messages) {
270676
+ for (const call of message.tool_calls ?? []) {
270677
+ if (call.status !== "waiting_for_user_input")
270678
+ continue;
270679
+ const args = parseArgs(call.arguments_string);
270680
+ const base = {
270681
+ toolCallId: call.id,
270682
+ messageId: message.id,
270683
+ tool: call.name
270684
+ };
270685
+ const summary = str2(args.summary);
270686
+ if (CHOICE_TOOLS.has(call.name)) {
270687
+ out.push({
270688
+ ...base,
270689
+ kind: "choice",
270690
+ title: summary ?? "The agent has a few questions",
270691
+ questions: questionsFrom(args)
270692
+ });
270693
+ } else if (SECRET_TOOLS.has(call.name)) {
270694
+ out.push({
270695
+ ...base,
270696
+ kind: "secrets",
270697
+ title: summary ?? "The agent needs secrets",
270698
+ secrets: secretsFrom(args)
270699
+ });
270700
+ } else if (PERMISSION_TOOLS.has(call.name)) {
270701
+ out.push({
270702
+ ...base,
270703
+ kind: "permissions",
270704
+ title: summary ?? "Grant the app's agent these permissions?",
270705
+ detail: str2(args.reason),
270706
+ permissions: permissionsFrom(args)
270707
+ });
270708
+ } else if (LIST_CHOICE_TOOLS[call.name]) {
270709
+ const spec = LIST_CHOICE_TOOLS[call.name];
270710
+ const raw = Array.isArray(args[spec.key]) ? args[spec.key] : [];
270711
+ const options = raw.flatMap((o) => {
270712
+ const label = typeof o === "string" ? o : str2(o?.label);
270713
+ return label ? [{ label }] : [];
270714
+ });
270715
+ out.push({
270716
+ ...base,
270717
+ kind: "choice",
270718
+ title: summary ?? spec.question,
270719
+ detail: str2(args.reason),
270720
+ questions: [{ question: spec.question, options, multiSelect: false }],
270721
+ answerKey: spec.answer
270722
+ });
270723
+ } else if (CREDENTIALS_TOOLS.has(call.name)) {
270724
+ const integration = str2(args.integration_type) ?? "connector";
270725
+ out.push({
270726
+ ...base,
270727
+ kind: "credentials",
270728
+ title: summary ?? `Register ${integration} credentials for this workspace`,
270729
+ detail: str2(args.description),
270730
+ credentials: {
270731
+ integrationType: integration,
270732
+ suggestedName: str2(args.name),
270733
+ scopes: Array.isArray(args.scopes) ? args.scopes.filter((x) => typeof x === "string") : []
270734
+ }
270735
+ });
270736
+ } else if (BROWSER_TOOLS.has(call.name)) {
270737
+ const integration = str2(args.integration_type);
270738
+ out.push({
270739
+ ...base,
270740
+ kind: "browser",
270741
+ title: summary ?? (call.name === "connect_github_account" ? "Connect your GitHub account" : integration ? `Authorize ${integration}` : humanize(call.name)),
270742
+ detail: str2(args.reason),
270743
+ browser: call.name === "connect_github_account" ? { flow: "github" } : {
270744
+ flow: "connector",
270745
+ integrationType: integration,
270746
+ connectorId: str2(args.connector_id),
270747
+ scopes: Array.isArray(args.scopes) ? args.scopes.filter((x) => typeof x === "string") : undefined,
270748
+ forceReconnect: args.force_reconnect === true
270749
+ }
270750
+ });
270751
+ } else if (call.waiting_on?.kind === "choice" || call.waiting_on?.kind === "input") {
270752
+ out.push({
270753
+ ...base,
270754
+ kind: "unknown",
270755
+ title: summary ?? humanize(call.name),
270756
+ detail: str2(args.reason)
270757
+ });
270758
+ } else {
270759
+ const guard = guardFrom(call.results);
270760
+ const integration = str2(args.integration_type);
270761
+ out.push({
270762
+ ...base,
270763
+ kind: "approval",
270764
+ title: guard?.title ?? (integration ? `Enable ${integration}?` : summary ?? `${humanize(call.name)}?`),
270765
+ detail: guard?.detail ?? (integration ? summary : undefined)
270766
+ });
270767
+ }
270768
+ }
270769
+ }
270770
+ return out;
270771
+ }
270772
+ function choiceAnswers(questions, selections, answerKey) {
270773
+ if (answerKey) {
270774
+ const first = selections[0];
270775
+ return { [answerKey]: first?.labels[0] ?? first?.customText ?? "" };
270776
+ }
270777
+ const answers = questions.flatMap((q, index) => {
270778
+ const sel = selections[index];
270779
+ if (!sel || sel.labels.length === 0 && !sel.customText)
270780
+ return [];
270781
+ const answer = { question_index: index };
270782
+ if (q.multiSelect) {
270783
+ if (sel.labels.length)
270784
+ answer.selected_labels = sel.labels;
270785
+ } else if (sel.labels[0]) {
270786
+ answer.selected_label = sel.labels[0];
270787
+ }
270788
+ if (sel.customText)
270789
+ answer.custom_text = sel.customText;
270790
+ return [answer];
270791
+ });
270792
+ return { answers };
270793
+ }
270794
+
270430
270795
  // src/cli/commands/builder/shared.ts
270431
270796
  var APP_NAME_RE = /^[A-Za-z0-9._-]+$/;
270432
270797
  var NAME_STOPWORDS = new Set("a an the and or of for with to in on that this its it my our your me".split(" "));
@@ -270461,7 +270826,15 @@ async function createAndLinkApp(options) {
270461
270826
  if (await appConfigExists(targetDir)) {
270462
270827
  throw new InvalidInputError(here ? "This directory is already linked to a Base44 app. Run `base44 code` here to keep building it, or pass --path for a new one." : `./${dirName} is already linked to a Base44 app. Pick another name or --path.`);
270463
270828
  }
270464
- const created = options.importRepo ? await createImportedApp({
270829
+ let clientCreationId;
270830
+ const created = options.wixInstance ? await createWixLaunchedApp({
270831
+ prompt: options.prompt ?? "",
270832
+ signedInstance: options.wixInstance.signedInstance,
270833
+ wixClientId: options.wixInstance.wixClientId
270834
+ }).then((c) => {
270835
+ clientCreationId = c.client_creation_id;
270836
+ return c;
270837
+ }) : options.importRepo ? await createImportedApp({
270465
270838
  appName: name,
270466
270839
  repoUrl: options.importRepo,
270467
270840
  sourceMode: options.mode ?? "direct",
@@ -270485,7 +270858,8 @@ async function createAndLinkApp(options) {
270485
270858
  repoUrl: created.imported_repo_url ?? undefined,
270486
270859
  dirName,
270487
270860
  targetDir,
270488
- here
270861
+ here,
270862
+ ...clientCreationId ? { clientCreationId } : {}
270489
270863
  };
270490
270864
  }
270491
270865
  function repoLabel(url) {
@@ -270517,6 +270891,147 @@ async function assertBuilderApp(appId) {
270517
270891
  }
270518
270892
  return state;
270519
270893
  }
270894
+ function pendingSummary(pending) {
270895
+ return pending.map((p) => ({
270896
+ id: p.toolCallId,
270897
+ kind: p.kind,
270898
+ tool: p.tool,
270899
+ title: p.title,
270900
+ ...p.detail ? { detail: p.detail } : {},
270901
+ ...p.questions ? { questions: p.questions } : {},
270902
+ ...p.answerKey ? { answer_key: p.answerKey } : {},
270903
+ ...p.secrets ? { secrets: p.secrets.map((x) => x.name) } : {},
270904
+ ...p.permissions ? { permissions: p.permissions } : {},
270905
+ ...p.browser ? { browser: p.browser } : {}
270906
+ }));
270907
+ }
270908
+ function hasAnswer(f) {
270909
+ return Boolean(f.approve || f.reject || f.skip || f.choose?.length || f.other || f.grant || f.secret?.length || f.input || f.connectorName);
270910
+ }
270911
+ async function secretValue(spec, readStdin) {
270912
+ const eq = spec.indexOf("=");
270913
+ if (eq <= 0) {
270914
+ throw new InvalidInputError(`--secret expects NAME=env:VAR, NAME=file:PATH or NAME=- (got "${spec}").`);
270915
+ }
270916
+ const name = spec.slice(0, eq);
270917
+ const source = spec.slice(eq + 1);
270918
+ if (source === "-")
270919
+ return [name, (await readStdin()).trim()];
270920
+ if (source.startsWith("env:")) {
270921
+ const v = process.env[source.slice(4)];
270922
+ if (!v) {
270923
+ throw new InvalidInputError(`--secret ${name}: environment variable ${source.slice(4)} is empty.`);
270924
+ }
270925
+ return [name, v];
270926
+ }
270927
+ if (source.startsWith("file:")) {
270928
+ return [name, (await readFile4(source.slice(5), "utf8")).trim()];
270929
+ }
270930
+ throw new InvalidInputError(`--secret ${name}: pass the value as env:VAR, file:PATH or - (stdin), never as plain text.`);
270931
+ }
270932
+ async function buildAnswer(pending, f, readStdin) {
270933
+ if (f.reject)
270934
+ return { action: "rejected", input: {} };
270935
+ if (f.input) {
270936
+ try {
270937
+ return {
270938
+ action: "approved",
270939
+ input: JSON.parse(f.input)
270940
+ };
270941
+ } catch {
270942
+ throw new InvalidInputError("--input must be a JSON object.");
270943
+ }
270944
+ }
270945
+ switch (pending.kind) {
270946
+ case "choice": {
270947
+ if (f.skip)
270948
+ return { action: "approved", input: { answers: [] } };
270949
+ const questions = pending.questions ?? [];
270950
+ if (!f.choose?.length && !f.other) {
270951
+ throw new InvalidInputError("This is a question: answer with --choose <label> per question (comma-separate for multi-select), --other <text>, or --skip.");
270952
+ }
270953
+ const selections = questions.map((q, i) => {
270954
+ const raw = f.choose?.[i];
270955
+ const labels = raw ? raw.split(",").map((x) => x.trim()).filter(Boolean) : [];
270956
+ for (const l of labels) {
270957
+ if (!q.options.some((o) => o.label === l)) {
270958
+ throw new InvalidInputError(`"${l}" is not an option for "${q.question}". Options: ${q.options.map((o) => o.label).join(", ")}.`);
270959
+ }
270960
+ }
270961
+ return {
270962
+ labels,
270963
+ ...i === questions.length - 1 && f.other ? { customText: f.other } : {}
270964
+ };
270965
+ });
270966
+ return {
270967
+ action: "approved",
270968
+ input: choiceAnswers(questions, selections, pending.answerKey)
270969
+ };
270970
+ }
270971
+ case "permissions": {
270972
+ if (!f.approve && !f.grant) {
270973
+ throw new InvalidInputError("This asks for permissions: --grant key1,key2 (or --approve for all, --reject).");
270974
+ }
270975
+ const all = (pending.permissions ?? []).map((p) => p.key);
270976
+ const keys = f.grant ? f.grant.split(",").map((x) => x.trim()).filter(Boolean) : all;
270977
+ for (const k of keys) {
270978
+ if (!all.includes(k)) {
270979
+ throw new InvalidInputError(`Unknown permission key "${k}". Keys: ${all.join(", ")}.`);
270980
+ }
270981
+ }
270982
+ return { action: "approved", input: { approved_permission_keys: keys } };
270983
+ }
270984
+ case "secrets": {
270985
+ const names = (pending.secrets ?? []).map((x) => x.name);
270986
+ if (!f.secret?.length) {
270987
+ throw new InvalidInputError(`This asks for secrets: --secret NAME=env:VAR for each of ${names.join(", ")}.`);
270988
+ }
270989
+ const values = {};
270990
+ for (const spec of f.secret) {
270991
+ const [name, value] = await secretValue(spec, readStdin);
270992
+ if (!names.includes(name)) {
270993
+ throw new InvalidInputError(`"${name}" is not one of the requested secrets: ${names.join(", ")}.`);
270994
+ }
270995
+ values[name] = value;
270996
+ }
270997
+ const missing = names.filter((n) => !(n in values));
270998
+ if (missing.length) {
270999
+ throw new InvalidInputError(`Missing --secret for: ${missing.join(", ")}.`);
271000
+ }
271001
+ return { action: "approved", input: { secrets: values } };
271002
+ }
271003
+ case "credentials": {
271004
+ const name = f.connectorName ?? pending.credentials?.suggestedName;
271005
+ if (!name) {
271006
+ throw new InvalidInputError("This registers a workspace connector: --connector-name <name> [--client-id <id> --client-secret env:VAR] (omit both to use Base44's credentials).");
271007
+ }
271008
+ const scopes = pending.credentials?.scopes ?? [];
271009
+ if (!f.clientId && !f.clientSecret) {
271010
+ return {
271011
+ action: "approved",
271012
+ input: { name, credential_source: "base44", scopes }
271013
+ };
271014
+ }
271015
+ if (!f.clientId || !f.clientSecret) {
271016
+ throw new InvalidInputError("Own credentials need both --client-id and --client-secret.");
271017
+ }
271018
+ const [, secret] = await secretValue(`client_secret=${f.clientSecret}`, readStdin);
271019
+ return {
271020
+ action: "approved",
271021
+ input: { name, client_id: f.clientId, client_secret: secret, scopes }
271022
+ };
271023
+ }
271024
+ case "browser":
271025
+ throw new InvalidInputError("This step needs a browser: finish the authorization in the editor (or run `base44 code`, which opens the link and waits), then answer with --approve.");
271026
+ case "unknown":
271027
+ throw new InvalidInputError("This question needs the editor — answer it there, or --reject.");
271028
+ default:
271029
+ if (!f.approve) {
271030
+ throw new InvalidInputError("This is an approval: --approve or --reject.");
271031
+ }
271032
+ return { action: "approved", input: {} };
271033
+ }
271034
+ }
270520
271035
  function nextStepsLines(app) {
270521
271036
  const cd = app.here ? "" : `cd ${app.dirName} && `;
270522
271037
  return [
@@ -270547,12 +271062,27 @@ function newStreamState() {
270547
271062
  return { perMessage: new Map };
270548
271063
  }
270549
271064
  var TOOL_SETTLED = new Set(["success", "error", "stopped"]);
271065
+ function fullText(value) {
271066
+ if (typeof value === "string")
271067
+ return value.trimEnd();
271068
+ if (value == null)
271069
+ return "";
271070
+ return JSON.stringify(value);
271071
+ }
271072
+ function toolArgs(argumentsString) {
271073
+ try {
271074
+ const parsed = JSON.parse(argumentsString ?? "");
271075
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
271076
+ } catch {
271077
+ return null;
271078
+ }
271079
+ }
270550
271080
  function oneLine(value, max) {
270551
271081
  const text = typeof value === "string" ? value : value == null ? "" : JSON.stringify(value);
270552
271082
  const flat = text.replace(/\s+/g, " ").trim();
270553
271083
  return flat.length > max ? `${flat.slice(0, max)}…` : flat;
270554
271084
  }
270555
- var SALIENT_KEYS = ["command", "path", "file_path", "title"];
271085
+ var SALIENT_KEYS = ["command", "path", "file_path", "title", "find"];
270556
271086
  function salvageKey(raw, keys) {
270557
271087
  for (const key of keys) {
270558
271088
  const match = raw.match(new RegExp(`"${key}"\\s*:\\s*"((?:[^"\\\\]|\\\\.)*)"`));
@@ -270581,6 +271111,10 @@ function toolMeta(name, argumentsString) {
270581
271111
  read_repo_file: pick("path") ?? pick("file_path"),
270582
271112
  write_repo_file: pick("path") ?? pick("file_path"),
270583
271113
  edit_repo_file: pick("path") ?? pick("file_path"),
271114
+ read_file: pick("file_path") ?? pick("path"),
271115
+ write_file: pick("file_path") ?? pick("path"),
271116
+ find_replace: pick("file_path") ?? pick("path"),
271117
+ delete_file: pick("file_path") ?? pick("path"),
270584
271118
  create_pull_request: pick("title"),
270585
271119
  reload_preview: ""
270586
271120
  };
@@ -270631,7 +271165,10 @@ function diffConversation(state, messages) {
270631
271165
  }
270632
271166
  for (const tool of message.tool_calls ?? []) {
270633
271167
  if (!progress.announcedTools.has(tool.id)) {
270634
- progress.announcedTools.set(tool.id, toolMeta(tool.name, tool.arguments_string));
271168
+ progress.announcedTools.set(tool.id, {
271169
+ ...toolMeta(tool.name, tool.arguments_string),
271170
+ args: toolArgs(tool.arguments_string)
271171
+ });
270635
271172
  const meta = progress.announcedTools.get(tool.id);
270636
271173
  events.push({
270637
271174
  kind: "tool_start",
@@ -270649,7 +271186,8 @@ function diffConversation(state, messages) {
270649
271186
  kind: "waiting",
270650
271187
  id: tool.id,
270651
271188
  name: tool.name,
270652
- label: labelTense(meta.label, "running")
271189
+ label: labelTense(meta.label, "running"),
271190
+ pending: pendingInputs([message]).find((p) => p.toolCallId === tool.id)
270653
271191
  });
270654
271192
  }
270655
271193
  if (TOOL_SETTLED.has(status) && !progress.settledTools.has(tool.id)) {
@@ -270662,7 +271200,8 @@ function diffConversation(state, messages) {
270662
271200
  label: labelTense(meta.label, "done"),
270663
271201
  summary: meta.summary,
270664
271202
  ok: status === "success",
270665
- result: oneLine(tool.results, 110)
271203
+ result: fullText(tool.results),
271204
+ args: meta.args
270666
271205
  });
270667
271206
  }
270668
271207
  }
@@ -270736,9 +271275,177 @@ async function streamConversationUntilSettled(onEvent, options = {}) {
270736
271275
  return "timeout";
270737
271276
  }
270738
271277
 
271278
+ // src/cli/commands/builder/send.ts
271279
+ function lastAssistantReply(turn) {
271280
+ const messages = turn.conversation?.messages ?? [];
271281
+ for (let i = messages.length - 1;i >= 0; i--) {
271282
+ const { role, content } = messages[i];
271283
+ if (role === "assistant" && typeof content === "string" && content.trim()) {
271284
+ return content.trim();
271285
+ }
271286
+ }
271287
+ return;
271288
+ }
271289
+ function ndjsonWriter() {
271290
+ return (record) => process.stdout.write(`${JSON.stringify(record)}
271291
+ `);
271292
+ }
271293
+ async function readStdin2() {
271294
+ const chunks = [];
271295
+ for await (const chunk of process.stdin)
271296
+ chunks.push(chunk);
271297
+ return Buffer.concat(chunks).toString("utf8");
271298
+ }
271299
+ function turnResult(turn, pending) {
271300
+ if (turn.queued)
271301
+ return { queued: true };
271302
+ const base = {
271303
+ status: pending.length ? "waiting" : turn.status?.state ?? "ready",
271304
+ error_source: turn.status?.error_source ?? null,
271305
+ reply: lastAssistantReply(turn) ?? null
271306
+ };
271307
+ return pending.length ? { ...base, pending: pendingSummary(pending) } : base;
271308
+ }
271309
+ async function applyPolicy(pending, options, branchId, onEvent) {
271310
+ let current = pending;
271311
+ for (let round = 0;round < 10 && current.length; round++) {
271312
+ const target = current.find((p) => options.autoApprove && (p.kind === "approval" || p.kind === "permissions") || options.skipQuestions && p.kind === "choice");
271313
+ if (!target)
271314
+ break;
271315
+ const input = target.kind === "permissions" ? {
271316
+ approved_permission_keys: (target.permissions ?? []).map((p) => p.key)
271317
+ } : target.kind === "choice" ? { answers: [] } : {};
271318
+ await streamConversationDuring(() => answerToolCall({
271319
+ toolCallId: target.toolCallId,
271320
+ messageId: target.messageId,
271321
+ action: "approved",
271322
+ input
271323
+ }, branchId), onEvent, { branchId });
271324
+ current = pendingInputs(await getFullConversation(30, branchId));
271325
+ }
271326
+ return current;
271327
+ }
271328
+ async function sendAction(ctx, message, options) {
271329
+ if (options.streamJson && ctx.jsonMode) {
271330
+ throw new InvalidInputError("--stream-json and --json are exclusive.");
271331
+ }
271332
+ const answering = hasAnswer(options);
271333
+ if (answering && message) {
271334
+ throw new InvalidInputError("Either send a message or answer the pending question (--approve / --choose / …), not both.");
271335
+ }
271336
+ if (!answering && !message) {
271337
+ throw new InvalidInputError('Send a message ("<message>") or answer what the agent asked (--approve, --reject, --choose, --grant, --secret, --skip, --input).');
271338
+ }
271339
+ if (ctx.app)
271340
+ await assertBuilderApp(ctx.app.id);
271341
+ const branchId = await resolveBranchId(ctx);
271342
+ const pendingBefore = pendingInputs(await getFullConversation(30, branchId).catch(() => []));
271343
+ let start;
271344
+ if (answering) {
271345
+ if (pendingBefore.length === 0) {
271346
+ throw new InvalidInputError("Nothing is waiting for an answer — send a message instead.");
271347
+ }
271348
+ const target = options.id ? pendingBefore.find((p) => p.toolCallId === options.id) : pendingBefore.length === 1 ? pendingBefore[0] : undefined;
271349
+ if (!target) {
271350
+ throw new InvalidInputError(options.id ? `No pending call with id ${options.id}. Pending: ${pendingBefore.map((p) => p.toolCallId).join(", ")}.` : `Several calls are waiting — pick one with --id: ${pendingBefore.map((p) => `${p.toolCallId} (${p.kind}: ${p.title})`).join("; ")}.`);
271351
+ }
271352
+ const answer = await buildAnswer(target, options, readStdin2);
271353
+ start = () => answerToolCall({
271354
+ toolCallId: target.toolCallId,
271355
+ messageId: target.messageId,
271356
+ action: answer.action,
271357
+ input: answer.input
271358
+ }, branchId);
271359
+ } else {
271360
+ if (pendingBefore.length) {
271361
+ const record = {
271362
+ status: "waiting",
271363
+ pending: pendingSummary(pendingBefore)
271364
+ };
271365
+ if (options.streamJson) {
271366
+ ndjsonWriter()({ type: "result", ...record });
271367
+ return {};
271368
+ }
271369
+ if (ctx.jsonMode)
271370
+ return { stdout: `${JSON.stringify(record)}
271371
+ ` };
271372
+ throw new InvalidInputError(`The agent is waiting on you before it can take a message: ${pendingBefore.map((p) => `${p.title} (${p.kind})`).join("; ")}. Answer with --approve / --choose / --grant / --secret, or --reject.`);
271373
+ }
271374
+ const text = message;
271375
+ start = () => sendTurn(text, branchId);
271376
+ }
271377
+ const finish = async (turn, onEvent) => {
271378
+ let pending = turn.queued ? [] : pendingInputs(await getFullConversation(30, branchId).catch(() => []));
271379
+ if (pending.length && (options.autoApprove || options.skipQuestions)) {
271380
+ pending = await applyPolicy(pending, options, branchId, onEvent);
271381
+ }
271382
+ return turnResult(turn, pending);
271383
+ };
271384
+ if (options.streamJson) {
271385
+ const write = ndjsonWriter();
271386
+ const onEvent = ({ kind, ...event }) => write({ type: kind, ...event });
271387
+ const turn = await streamConversationDuring(start, onEvent, { branchId });
271388
+ const result = await finish(turn, onEvent);
271389
+ write({ type: "result", queued: result.queued === true, ...result });
271390
+ return {};
271391
+ }
271392
+ if (ctx.jsonMode) {
271393
+ const turn = await ctx.runTask("Agent working (a turn can take minutes)", start);
271394
+ return {
271395
+ stdout: `${JSON.stringify(await finish(turn, () => {
271396
+ return;
271397
+ }))}
271398
+ `
271399
+ };
271400
+ }
271401
+ const stream = createTurnStream(process.stdout.isTTY === true, undefined, {
271402
+ verbose: options.verbose
271403
+ });
271404
+ let result;
271405
+ try {
271406
+ const turn = await streamConversationDuring(start, stream.onEvent, {
271407
+ branchId
271408
+ });
271409
+ result = await finish(turn, stream.onEvent);
271410
+ } finally {
271411
+ stream.stop();
271412
+ }
271413
+ if (result.queued === true) {
271414
+ return {
271415
+ outroMessage: "The agent is busy with an earlier message — yours was queued and runs next."
271416
+ };
271417
+ }
271418
+ if (result.status === "waiting") {
271419
+ for (const p of result.pending) {
271420
+ ctx.log.message(` ⏸ ${p.title} (${p.kind})`);
271421
+ }
271422
+ return {
271423
+ outroMessage: "The agent is waiting on you. Answer with `base44 builder send --approve` (or --choose, --grant, --secret, --reject), or open `base44 code`."
271424
+ };
271425
+ }
271426
+ if (result.status === "error") {
271427
+ return {
271428
+ outroMessage: result.error_source === "paywall" ? "The workspace is out of credits — nothing ran." : `Turn failed (${result.error_source ?? "unknown"}) — see the editor for details.`
271429
+ };
271430
+ }
271431
+ return { outroMessage: "Turn finished." };
271432
+ }
271433
+ var collect = (v, acc = []) => [...acc, v];
271434
+ function getSendCommand() {
271435
+ const command = new Base44Command("send", { supportsBranch: true });
271436
+ command.description('Send the agent one message and stream the turn until it finishes — or answer what it asked (--approve, --choose, …). A result with status "waiting" lists what the agent needs; the next send answers it.').argument("[message]", "What you want the agent to do").option("--approve", "Approve the pending call (permissions: grant all)").option("--reject", "Reject the pending call").option("--skip", "Skip the pending questions; the agent decides").option("--choose <label>", "Answer a question by option label; repeat per question, comma-separate for multi-select", collect).option("--other <text>", "Free-text answer for the last question").option("--grant <keys>", "Permission keys to grant, comma-separated").option("--secret <NAME=source>", "A requested secret from env:VAR, file:PATH or - (stdin); repeat per secret", collect).option("--connector-name <name>", "Register a workspace connector under this name (Base44's credentials unless --client-id/--client-secret are given)").option("--client-id <id>", "Your own OAuth app's client id").option("--client-secret <source>", "Your own OAuth app's client secret from env:VAR, file:PATH or - (stdin)").option("--input <json>", "Raw extra_user_input for the pending call").option("--id <tool-call-id>", "Which pending call to answer when several wait").option("--auto-approve", "Policy: approve approval-kind pauses (never secrets or browser steps)").option("--skip-questions", "Policy: skip clarifying questions; the agent decides").option("--verbose", "Show every tool result in full (no folding)").option("--stream-json", "Emit each stream event as a JSON line as it happens, then a final result line").action(sendAction);
271437
+ return command;
271438
+ }
271439
+
270739
271440
  // src/cli/commands/builder/new.ts
270740
271441
  var POLL_TIMEOUT_MS = 20 * 60000;
270741
271442
  var MODES = ["direct", "fork", "copy"];
271443
+ async function readStdin3() {
271444
+ const chunks = [];
271445
+ for await (const chunk of process.stdin)
271446
+ chunks.push(chunk);
271447
+ return Buffer.concat(chunks).toString("utf8");
271448
+ }
270742
271449
  async function newAction({ log, runTask, jsonMode }, prompt, options) {
270743
271450
  if (options.mode && !MODES.includes(options.mode)) {
270744
271451
  throw new InvalidInputError("--mode must be direct, fork, or copy.");
@@ -270746,9 +271453,27 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270746
271453
  if ((options.mode || options.repoName || options.fromBranch) && !options.import) {
270747
271454
  throw new InvalidInputError("--mode, --repo-name and --from-branch apply only with --import <repo>.");
270748
271455
  }
271456
+ if (options.wixInstance && options.import) {
271457
+ throw new InvalidInputError("--wix-instance and --import are exclusive.");
271458
+ }
271459
+ if (options.wixClientId && !options.wixInstance) {
271460
+ throw new InvalidInputError("--wix-client-id applies only with --wix-instance.");
271461
+ }
271462
+ const signedInstance = options.wixInstance ? (options.wixInstance === "-" ? await readStdin3() : options.wixInstance).trim() : undefined;
271463
+ if (options.wixInstance && !signedInstance) {
271464
+ throw new InvalidInputError("--wix-instance is empty.");
271465
+ }
271466
+ const wixInstance = signedInstance ? { signedInstance, wixClientId: options.wixClientId?.trim() || undefined } : undefined;
271467
+ if (wixInstance && !prompt) {
271468
+ throw new InvalidInputError("--wix-instance needs the prompt argument: what the agent should build.");
271469
+ }
270749
271470
  if (!prompt && !options.import) {
270750
271471
  throw new InvalidInputError('Describe the app ("<prompt>") or pass --import <repo>.');
270751
271472
  }
271473
+ if (options.streamJson && jsonMode) {
271474
+ throw new InvalidInputError("--stream-json and --json are exclusive.");
271475
+ }
271476
+ const ndjson = options.streamJson ? ndjsonWriter() : null;
270752
271477
  let app;
270753
271478
  try {
270754
271479
  app = await runTask(options.import ? "Importing the repository" : "Creating your app", () => createAndLinkApp({
@@ -270758,33 +271483,68 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270758
271483
  mode: options.mode,
270759
271484
  repoName: options.repoName,
270760
271485
  fromBranch: options.fromBranch,
270761
- path: options.path
271486
+ path: options.path,
271487
+ wixInstance
270762
271488
  }));
270763
271489
  } catch (error) {
270764
271490
  for (const line of await githubReauthLines(error) ?? [])
270765
271491
  log.message(line);
270766
271492
  throw error;
270767
271493
  }
270768
- if (!jsonMode) {
271494
+ if (ndjson) {
271495
+ ndjson({
271496
+ type: "created",
271497
+ id: app.id,
271498
+ repo_url: app.repoUrl ?? null,
271499
+ editor_url: app.editorUrl,
271500
+ dir: app.dirName,
271501
+ path: app.targetDir,
271502
+ ...app.clientCreationId ? { client_creation_id: app.clientCreationId } : {}
271503
+ });
271504
+ } else if (!jsonMode) {
270769
271505
  if (app.repoUrl)
270770
271506
  log.message(source_default.dim(`repo ${app.repoUrl}`));
271507
+ if (app.clientCreationId) {
271508
+ log.message(source_default.dim("wix launched — connector connected before the first turn"));
271509
+ }
270771
271510
  log.message(source_default.dim(`editor ${app.editorUrl}`));
270772
271511
  log.message(source_default.dim(`linked ${app.here ? "./ (this directory)" : `./${app.dirName}`}`));
270773
271512
  }
270774
271513
  let finalState;
270775
271514
  let previewUrl;
271515
+ let pending = [];
270776
271516
  const startedAt = Date.now();
270777
271517
  if (prompt) {
270778
271518
  const branchId = await resolveActiveBranchId().catch(() => {
270779
271519
  return;
270780
271520
  });
270781
- const stream = createTurnStream(process.stdout.isTTY === true && !jsonMode, undefined, { idleLabel: "provisioning the sandbox and starting the build" });
271521
+ const stream = createTurnStream(process.stdout.isTTY === true && !jsonMode && !ndjson, undefined, {
271522
+ idleLabel: "provisioning the sandbox and starting the build",
271523
+ verbose: options.verbose
271524
+ });
270782
271525
  try {
270783
271526
  const settled = await streamConversationUntilSettled((event) => {
270784
- if (!jsonMode)
271527
+ if (ndjson) {
271528
+ const { kind, ...rest } = event;
271529
+ ndjson({ type: kind, ...rest });
271530
+ } else if (!jsonMode)
270785
271531
  stream.onEvent(event);
270786
271532
  }, { branchId, timeoutMs: POLL_TIMEOUT_MS });
270787
271533
  finalState = settled === "timeout" ? "processing" : (await getAppState(app.id)).status?.state ?? "ready";
271534
+ if (settled === "settled") {
271535
+ pending = pendingInputs(await getFullConversation(30, branchId).catch(() => []));
271536
+ if (pending.length && (options.autoApprove || options.skipQuestions)) {
271537
+ pending = await applyPolicy(pending, options, branchId, (event) => {
271538
+ if (ndjson) {
271539
+ const { kind, ...rest } = event;
271540
+ ndjson({ type: kind, ...rest });
271541
+ } else if (!jsonMode)
271542
+ stream.onEvent(event);
271543
+ });
271544
+ }
271545
+ if (pending.length)
271546
+ finalState = "waiting";
271547
+ }
270788
271548
  if (finalState === "ready") {
270789
271549
  previewUrl = await getPreviewUrl().catch(() => {
270790
271550
  return;
@@ -270794,6 +271554,16 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270794
271554
  stream.stop();
270795
271555
  }
270796
271556
  }
271557
+ if (ndjson) {
271558
+ ndjson({
271559
+ type: "result",
271560
+ id: app.id,
271561
+ preview_url: previewUrl ?? null,
271562
+ status: finalState ?? "created",
271563
+ ...pending.length ? { pending: pendingSummary(pending) } : {}
271564
+ });
271565
+ return {};
271566
+ }
270797
271567
  if (jsonMode) {
270798
271568
  return {
270799
271569
  stdout: `${JSON.stringify({
@@ -270803,7 +271573,9 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270803
271573
  preview_url: previewUrl ?? null,
270804
271574
  dir: app.dirName,
270805
271575
  path: app.targetDir,
270806
- status: finalState ?? "created"
271576
+ status: finalState ?? "created",
271577
+ ...pending.length ? { pending: pendingSummary(pending) } : {},
271578
+ ...app.clientCreationId ? { client_creation_id: app.clientCreationId } : {}
270807
271579
  })}
270808
271580
  `
270809
271581
  };
@@ -270812,6 +271584,13 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270812
271584
  log.message(`preview ${previewUrl}`);
270813
271585
  for (const line of nextStepsLines(app))
270814
271586
  log.message(line);
271587
+ if (finalState === "waiting") {
271588
+ for (const p of pending)
271589
+ log.message(` ⏸ ${p.title} (${p.kind})`);
271590
+ return {
271591
+ outroMessage: "The agent is waiting on you. Answer with `base44 builder send --approve` (or --choose, --grant, --secret), or open `base44 code`."
271592
+ };
271593
+ }
270815
271594
  if (finalState === "error") {
270816
271595
  return {
270817
271596
  outroMessage: `The first build reported an error — open the editor for details.`
@@ -270828,83 +271607,43 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270828
271607
  }
270829
271608
  function getNewCommand() {
270830
271609
  const command = new Base44Command("new", { requireAppContext: false });
270831
- command.description("Create an app and start building: from a prompt (the Base44 template), or over an existing GitHub repo with --import").argument("[prompt]", "What to build; the first agent turn starts immediately").option("--import <repo>", "Build over an existing GitHub repository instead of the template").option("--mode <mode>", "How to import: direct, fork, or copy (default: direct)").option("--name <name>", "Directory and app name (invented when omitted)").option("--path <dir>", "Directory to link (default: the current directory when empty, else ./<name>)").option("--repo-name <name>", "Name for the new GitHub repo when forking/copying").option("--from-branch <name>", "Import a specific branch of the repo").action(newAction);
270832
- return command;
270833
- }
270834
-
270835
- // src/cli/commands/builder/send.ts
270836
- function lastAssistantReply(turn) {
270837
- const messages = turn.conversation?.messages ?? [];
270838
- for (let i = messages.length - 1;i >= 0; i--) {
270839
- const { role, content } = messages[i];
270840
- if (role === "assistant" && typeof content === "string" && content.trim()) {
270841
- return content.trim();
270842
- }
270843
- }
270844
- return;
270845
- }
270846
- async function sendAction(ctx, message) {
270847
- if (ctx.app)
270848
- await assertBuilderApp(ctx.app.id);
270849
- const branchId = await resolveBranchId(ctx);
270850
- if (ctx.jsonMode) {
270851
- const turn = await ctx.runTask("Agent working (a turn can take minutes)", () => sendTurn(message, branchId));
270852
- if (turn.queued)
270853
- return { stdout: `${JSON.stringify({ queued: true })}
270854
- ` };
270855
- return {
270856
- stdout: `${JSON.stringify({
270857
- status: turn.status?.state ?? "ready",
270858
- error_source: turn.status?.error_source ?? null,
270859
- reply: lastAssistantReply(turn) ?? null
270860
- })}
270861
- `
270862
- };
270863
- }
270864
- const stream = createTurnStream(process.stdout.isTTY === true);
270865
- let turn;
270866
- try {
270867
- turn = await streamConversationDuring(() => sendTurn(message, branchId), stream.onEvent, { branchId });
270868
- } finally {
270869
- stream.stop();
270870
- }
270871
- if (turn.queued) {
270872
- return {
270873
- outroMessage: "The agent is busy with an earlier message — yours was queued and runs next."
270874
- };
270875
- }
270876
- if (turn.status?.state === "error") {
270877
- return {
270878
- outroMessage: `Turn failed (${turn.status.error_source ?? "unknown"}) — see the editor for details.`
270879
- };
270880
- }
270881
- return { outroMessage: "Turn finished." };
270882
- }
270883
- function getSendCommand() {
270884
- const command = new Base44Command("send", { supportsBranch: true });
270885
- command.description("Send the agent one message and stream the turn until it finishes").argument("<message>", "What you want the agent to do").action(sendAction);
271610
+ command.description("Create an app and start building: from a prompt (the Base44 template), or over an existing GitHub repo with --import").argument("[prompt]", "What to build; the first agent turn starts immediately").option("--import <repo>", "Build over an existing GitHub repository instead of the template").option("--mode <mode>", "How to import: direct, fork, or copy (default: direct)").option("--name <name>", "Directory and app name (invented when omitted)").option("--path <dir>", "Directory to link (default: the current directory when empty, else ./<name>)").option("--repo-name <name>", "Name for the new GitHub repo when forking/copying").option("--from-branch <name>", "Import a specific branch of the repo").addOption(new Option2("--wix-instance <token>", 'Create through the Wix route with this signed instance (the Wix connector is connected before the first turn); "-" reads the token from stdin').env("BASE44_WIX_INSTANCE")).option("--wix-client-id <id>", "The companion OAuth app's client id, when the Wix launch has one").option("--auto-approve", "Policy: approve approval-kind pauses in the first build (never secrets or browser steps)").option("--skip-questions", "Policy: skip clarifying questions; the agent decides").option("--verbose", "Show every tool result in full (no folding)").option("--stream-json", "Emit each stream event as a JSON line as it happens, then a final result line").action(newAction);
270886
271611
  return command;
270887
271612
  }
270888
271613
 
270889
271614
  // src/cli/commands/builder/status.ts
270890
271615
  async function statusAction(ctx) {
270891
271616
  const id = ctx.app?.id;
270892
- const app = await ctx.runTask("Reading app status", () => getAppState(id));
270893
- const state = app.status?.state ?? "ready";
271617
+ const branchId = await resolveBranchId(ctx);
271618
+ const [app, messages] = await ctx.runTask("Reading app status", () => Promise.all([
271619
+ getAppState(id),
271620
+ getFullConversation(30, branchId).catch(() => [])
271621
+ ]));
271622
+ const pending = pendingInputs(messages);
271623
+ const state = pending.length ? "waiting" : app.status?.state ?? "ready";
270894
271624
  if (ctx.jsonMode) {
270895
271625
  return {
270896
- stdout: `${JSON.stringify({ id: app.id, state, message: app.status?.message ?? null })}
271626
+ stdout: `${JSON.stringify({
271627
+ id: app.id,
271628
+ state,
271629
+ message: app.status?.message ?? null,
271630
+ ...pending.length ? { pending: pendingSummary(pending) } : {}
271631
+ })}
270897
271632
  `
270898
271633
  };
270899
271634
  }
270900
271635
  ctx.log.message(`State: ${state}`);
270901
271636
  if (app.status?.message)
270902
271637
  ctx.log.message(`Note: ${app.status.message}`);
270903
- return { outroMessage: "Status read." };
271638
+ for (const p of pending)
271639
+ ctx.log.message(` ⏸ ${p.title} (${p.kind})`);
271640
+ return {
271641
+ outroMessage: pending.length ? "The agent is waiting on you — `base44 builder send --approve` (or --choose, --grant, --secret) answers it." : "Status read."
271642
+ };
270904
271643
  }
270905
271644
  function getStatusCommand() {
270906
- const command = new Base44Command("status");
270907
- command.description("Show whether the app is building, ready, or errored").action(statusAction);
271645
+ const command = new Base44Command("status", { supportsBranch: true });
271646
+ command.description("Show whether the app is building, ready, errored — or waiting on you, and for what").action(statusAction);
270908
271647
  return command;
270909
271648
  }
270910
271649
 
@@ -275888,9 +276627,728 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
275888
276627
  }
275889
276628
  var build_default = TextInput;
275890
276629
 
276630
+ // ../../node_modules/open/index.js
276631
+ import process30 from "node:process";
276632
+ import path16 from "node:path";
276633
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
276634
+ import childProcess3 from "node:child_process";
276635
+ import fs20, { constants as fsConstants2 } from "node:fs/promises";
276636
+
276637
+ // ../../node_modules/wsl-utils/index.js
276638
+ import { promisify as promisify6 } from "node:util";
276639
+ import childProcess2 from "node:child_process";
276640
+ import fs19, { constants as fsConstants } from "node:fs/promises";
276641
+
276642
+ // ../../node_modules/is-wsl/index.js
276643
+ import process24 from "node:process";
276644
+ import os4 from "node:os";
276645
+ import fs18 from "node:fs";
276646
+
276647
+ // ../../node_modules/is-inside-container/index.js
276648
+ import fs17 from "node:fs";
276649
+
276650
+ // ../../node_modules/is-docker/index.js
276651
+ import fs16 from "node:fs";
276652
+ var isDockerCached;
276653
+ function hasDockerEnv() {
276654
+ try {
276655
+ fs16.statSync("/.dockerenv");
276656
+ return true;
276657
+ } catch {
276658
+ return false;
276659
+ }
276660
+ }
276661
+ function hasDockerCGroup() {
276662
+ try {
276663
+ return fs16.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
276664
+ } catch {
276665
+ return false;
276666
+ }
276667
+ }
276668
+ function isDocker() {
276669
+ if (isDockerCached === undefined) {
276670
+ isDockerCached = hasDockerEnv() || hasDockerCGroup();
276671
+ }
276672
+ return isDockerCached;
276673
+ }
276674
+
276675
+ // ../../node_modules/is-inside-container/index.js
276676
+ var cachedResult;
276677
+ var hasContainerEnv = () => {
276678
+ try {
276679
+ fs17.statSync("/run/.containerenv");
276680
+ return true;
276681
+ } catch {
276682
+ return false;
276683
+ }
276684
+ };
276685
+ function isInsideContainer() {
276686
+ if (cachedResult === undefined) {
276687
+ cachedResult = hasContainerEnv() || isDocker();
276688
+ }
276689
+ return cachedResult;
276690
+ }
276691
+
276692
+ // ../../node_modules/is-wsl/index.js
276693
+ var isWsl = () => {
276694
+ if (process24.platform !== "linux") {
276695
+ return false;
276696
+ }
276697
+ if (os4.release().toLowerCase().includes("microsoft")) {
276698
+ if (isInsideContainer()) {
276699
+ return false;
276700
+ }
276701
+ return true;
276702
+ }
276703
+ try {
276704
+ return fs18.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
276705
+ } catch {
276706
+ return false;
276707
+ }
276708
+ };
276709
+ var is_wsl_default = process24.env.__IS_WSL_TEST__ ? isWsl : isWsl();
276710
+
276711
+ // ../../node_modules/powershell-utils/index.js
276712
+ import process25 from "node:process";
276713
+ import { Buffer as Buffer7 } from "node:buffer";
276714
+ import { promisify as promisify5 } from "node:util";
276715
+ import childProcess from "node:child_process";
276716
+ var execFile = promisify5(childProcess.execFile);
276717
+ var powerShellPath = () => `${process25.env.SYSTEMROOT || process25.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
276718
+ var executePowerShell = async (command, options = {}) => {
276719
+ const {
276720
+ powerShellPath: psPath,
276721
+ ...execFileOptions
276722
+ } = options;
276723
+ const encodedCommand = executePowerShell.encodeCommand(command);
276724
+ return execFile(psPath ?? powerShellPath(), [
276725
+ ...executePowerShell.argumentsPrefix,
276726
+ encodedCommand
276727
+ ], {
276728
+ encoding: "utf8",
276729
+ ...execFileOptions
276730
+ });
276731
+ };
276732
+ executePowerShell.argumentsPrefix = [
276733
+ "-NoProfile",
276734
+ "-NonInteractive",
276735
+ "-ExecutionPolicy",
276736
+ "Bypass",
276737
+ "-EncodedCommand"
276738
+ ];
276739
+ executePowerShell.encodeCommand = (command) => Buffer7.from(command, "utf16le").toString("base64");
276740
+ executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
276741
+
276742
+ // ../../node_modules/wsl-utils/utilities.js
276743
+ function parseMountPointFromConfig(content) {
276744
+ for (const line of content.split(`
276745
+ `)) {
276746
+ if (/^\s*#/.test(line)) {
276747
+ continue;
276748
+ }
276749
+ const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
276750
+ if (!match) {
276751
+ continue;
276752
+ }
276753
+ return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
276754
+ }
276755
+ }
276756
+
276757
+ // ../../node_modules/wsl-utils/index.js
276758
+ var execFile2 = promisify6(childProcess2.execFile);
276759
+ var wslDrivesMountPoint = (() => {
276760
+ const defaultMountPoint = "/mnt/";
276761
+ let mountPoint;
276762
+ return async function() {
276763
+ if (mountPoint) {
276764
+ return mountPoint;
276765
+ }
276766
+ const configFilePath = "/etc/wsl.conf";
276767
+ let isConfigFileExists = false;
276768
+ try {
276769
+ await fs19.access(configFilePath, fsConstants.F_OK);
276770
+ isConfigFileExists = true;
276771
+ } catch {}
276772
+ if (!isConfigFileExists) {
276773
+ return defaultMountPoint;
276774
+ }
276775
+ const configContent = await fs19.readFile(configFilePath, { encoding: "utf8" });
276776
+ const parsedMountPoint = parseMountPointFromConfig(configContent);
276777
+ if (parsedMountPoint === undefined) {
276778
+ return defaultMountPoint;
276779
+ }
276780
+ mountPoint = parsedMountPoint;
276781
+ mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
276782
+ return mountPoint;
276783
+ };
276784
+ })();
276785
+ var powerShellPathFromWsl = async () => {
276786
+ const mountPoint = await wslDrivesMountPoint();
276787
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
276788
+ };
276789
+ var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
276790
+ var canAccessPowerShellPromise;
276791
+ var canAccessPowerShell = async () => {
276792
+ canAccessPowerShellPromise ??= (async () => {
276793
+ try {
276794
+ const psPath = await powerShellPath2();
276795
+ await fs19.access(psPath, fsConstants.X_OK);
276796
+ return true;
276797
+ } catch {
276798
+ return false;
276799
+ }
276800
+ })();
276801
+ return canAccessPowerShellPromise;
276802
+ };
276803
+ var wslDefaultBrowser = async () => {
276804
+ const psPath = await powerShellPath2();
276805
+ const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
276806
+ const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
276807
+ return stdout.trim();
276808
+ };
276809
+ var convertWslPathToWindows = async (path) => {
276810
+ if (/^[a-z]+:\/\//i.test(path)) {
276811
+ return path;
276812
+ }
276813
+ try {
276814
+ const { stdout } = await execFile2("wslpath", ["-aw", path], { encoding: "utf8" });
276815
+ return stdout.trim();
276816
+ } catch {
276817
+ return path;
276818
+ }
276819
+ };
276820
+
276821
+ // ../../node_modules/define-lazy-prop/index.js
276822
+ function defineLazyProperty(object, propertyName, valueGetter) {
276823
+ const define2 = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
276824
+ Object.defineProperty(object, propertyName, {
276825
+ configurable: true,
276826
+ enumerable: true,
276827
+ get() {
276828
+ const result = valueGetter();
276829
+ define2(result);
276830
+ return result;
276831
+ },
276832
+ set(value) {
276833
+ define2(value);
276834
+ }
276835
+ });
276836
+ return object;
276837
+ }
276838
+
276839
+ // ../../node_modules/default-browser/index.js
276840
+ import { promisify as promisify10 } from "node:util";
276841
+ import process28 from "node:process";
276842
+ import { execFile as execFile6 } from "node:child_process";
276843
+
276844
+ // ../../node_modules/default-browser-id/index.js
276845
+ import { promisify as promisify7 } from "node:util";
276846
+ import process26 from "node:process";
276847
+ import { execFile as execFile3 } from "node:child_process";
276848
+ var execFileAsync = promisify7(execFile3);
276849
+ async function defaultBrowserId() {
276850
+ if (process26.platform !== "darwin") {
276851
+ throw new Error("macOS only");
276852
+ }
276853
+ const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
276854
+ const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
276855
+ const browserId = match?.groups.id ?? "com.apple.Safari";
276856
+ if (browserId === "com.apple.safari") {
276857
+ return "com.apple.Safari";
276858
+ }
276859
+ return browserId;
276860
+ }
276861
+
276862
+ // ../../node_modules/run-applescript/index.js
276863
+ import process27 from "node:process";
276864
+ import { promisify as promisify8 } from "node:util";
276865
+ import { execFile as execFile4, execFileSync } from "node:child_process";
276866
+ var execFileAsync2 = promisify8(execFile4);
276867
+ async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
276868
+ if (process27.platform !== "darwin") {
276869
+ throw new Error("macOS only");
276870
+ }
276871
+ const outputArguments = humanReadableOutput ? [] : ["-ss"];
276872
+ const execOptions = {};
276873
+ if (signal) {
276874
+ execOptions.signal = signal;
276875
+ }
276876
+ const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
276877
+ return stdout.trim();
276878
+ }
276879
+
276880
+ // ../../node_modules/bundle-name/index.js
276881
+ async function bundleName(bundleId) {
276882
+ return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
276883
+ tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
276884
+ }
276885
+
276886
+ // ../../node_modules/default-browser/windows.js
276887
+ import { promisify as promisify9 } from "node:util";
276888
+ import { execFile as execFile5 } from "node:child_process";
276889
+ var execFileAsync3 = promisify9(execFile5);
276890
+ var windowsBrowserProgIds = {
276891
+ MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
276892
+ MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
276893
+ MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
276894
+ AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
276895
+ ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
276896
+ ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
276897
+ ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
276898
+ ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
276899
+ BraveHTML: { name: "Brave", id: "com.brave.Browser" },
276900
+ BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
276901
+ BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
276902
+ BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
276903
+ FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
276904
+ OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
276905
+ VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
276906
+ "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
276907
+ };
276908
+ var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
276909
+
276910
+ class UnknownBrowserError extends Error {
276911
+ }
276912
+ async function defaultBrowser(_execFileAsync = execFileAsync3) {
276913
+ const { stdout } = await _execFileAsync("reg", [
276914
+ "QUERY",
276915
+ " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
276916
+ "/v",
276917
+ "ProgId"
276918
+ ]);
276919
+ const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
276920
+ if (!match) {
276921
+ throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
276922
+ }
276923
+ const { id } = match.groups;
276924
+ const dotIndex = id.lastIndexOf(".");
276925
+ const hyphenIndex = id.lastIndexOf("-");
276926
+ const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
276927
+ const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
276928
+ return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
276929
+ }
276930
+
276931
+ // ../../node_modules/default-browser/index.js
276932
+ var execFileAsync4 = promisify10(execFile6);
276933
+ var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
276934
+ async function defaultBrowser2() {
276935
+ if (process28.platform === "darwin") {
276936
+ const id = await defaultBrowserId();
276937
+ const name = await bundleName(id);
276938
+ return { name, id };
276939
+ }
276940
+ if (process28.platform === "linux") {
276941
+ const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
276942
+ const id = stdout.trim();
276943
+ const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
276944
+ return { name, id };
276945
+ }
276946
+ if (process28.platform === "win32") {
276947
+ return defaultBrowser();
276948
+ }
276949
+ throw new Error("Only macOS, Linux, and Windows are supported");
276950
+ }
276951
+
276952
+ // ../../node_modules/is-in-ssh/index.js
276953
+ import process29 from "node:process";
276954
+ var isInSsh = Boolean(process29.env.SSH_CONNECTION || process29.env.SSH_CLIENT || process29.env.SSH_TTY);
276955
+ var is_in_ssh_default = isInSsh;
276956
+
276957
+ // ../../node_modules/open/index.js
276958
+ var fallbackAttemptSymbol = Symbol("fallbackAttempt");
276959
+ var __dirname2 = import.meta.url ? path16.dirname(fileURLToPath4(import.meta.url)) : "";
276960
+ var localXdgOpenPath = path16.join(__dirname2, "xdg-open");
276961
+ var { platform: platform7, arch } = process30;
276962
+ var tryEachApp = async (apps, opener) => {
276963
+ if (apps.length === 0) {
276964
+ return;
276965
+ }
276966
+ const errors = [];
276967
+ for (const app of apps) {
276968
+ try {
276969
+ return await opener(app);
276970
+ } catch (error) {
276971
+ errors.push(error);
276972
+ }
276973
+ }
276974
+ throw new AggregateError(errors, "Failed to open in all supported apps");
276975
+ };
276976
+ var baseOpen = async (options) => {
276977
+ options = {
276978
+ wait: false,
276979
+ background: false,
276980
+ newInstance: false,
276981
+ allowNonzeroExitCode: false,
276982
+ ...options
276983
+ };
276984
+ const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
276985
+ delete options[fallbackAttemptSymbol];
276986
+ if (Array.isArray(options.app)) {
276987
+ return tryEachApp(options.app, (singleApp) => baseOpen({
276988
+ ...options,
276989
+ app: singleApp,
276990
+ [fallbackAttemptSymbol]: true
276991
+ }));
276992
+ }
276993
+ let { name: app, arguments: appArguments = [] } = options.app ?? {};
276994
+ appArguments = [...appArguments];
276995
+ if (Array.isArray(app)) {
276996
+ return tryEachApp(app, (appName) => baseOpen({
276997
+ ...options,
276998
+ app: {
276999
+ name: appName,
277000
+ arguments: appArguments
277001
+ },
277002
+ [fallbackAttemptSymbol]: true
277003
+ }));
277004
+ }
277005
+ if (app === "browser" || app === "browserPrivate") {
277006
+ const ids = {
277007
+ "com.google.chrome": "chrome",
277008
+ "google-chrome.desktop": "chrome",
277009
+ "com.brave.browser": "brave",
277010
+ "org.mozilla.firefox": "firefox",
277011
+ "firefox.desktop": "firefox",
277012
+ "com.microsoft.msedge": "edge",
277013
+ "com.microsoft.edge": "edge",
277014
+ "com.microsoft.edgemac": "edge",
277015
+ "microsoft-edge.desktop": "edge",
277016
+ "com.apple.safari": "safari"
277017
+ };
277018
+ const flags = {
277019
+ chrome: "--incognito",
277020
+ brave: "--incognito",
277021
+ firefox: "--private-window",
277022
+ edge: "--inPrivate"
277023
+ };
277024
+ let browser;
277025
+ if (is_wsl_default) {
277026
+ const progId = await wslDefaultBrowser();
277027
+ const browserInfo = _windowsBrowserProgIdMap.get(progId);
277028
+ browser = browserInfo ?? {};
277029
+ } else {
277030
+ browser = await defaultBrowser2();
277031
+ }
277032
+ if (browser.id in ids) {
277033
+ const browserName = ids[browser.id.toLowerCase()];
277034
+ if (app === "browserPrivate") {
277035
+ if (browserName === "safari") {
277036
+ throw new Error("Safari doesn't support opening in private mode via command line");
277037
+ }
277038
+ appArguments.push(flags[browserName]);
277039
+ }
277040
+ return baseOpen({
277041
+ ...options,
277042
+ app: {
277043
+ name: apps[browserName],
277044
+ arguments: appArguments
277045
+ }
277046
+ });
277047
+ }
277048
+ throw new Error(`${browser.name} is not supported as a default browser`);
277049
+ }
277050
+ let command;
277051
+ const cliArguments = [];
277052
+ const childProcessOptions = {};
277053
+ let shouldUseWindowsInWsl = false;
277054
+ if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
277055
+ shouldUseWindowsInWsl = await canAccessPowerShell();
277056
+ }
277057
+ if (platform7 === "darwin") {
277058
+ command = "open";
277059
+ if (options.wait) {
277060
+ cliArguments.push("--wait-apps");
277061
+ }
277062
+ if (options.background) {
277063
+ cliArguments.push("--background");
277064
+ }
277065
+ if (options.newInstance) {
277066
+ cliArguments.push("--new");
277067
+ }
277068
+ if (app) {
277069
+ cliArguments.push("-a", app);
277070
+ }
277071
+ } else if (platform7 === "win32" || shouldUseWindowsInWsl) {
277072
+ command = await powerShellPath2();
277073
+ cliArguments.push(...executePowerShell.argumentsPrefix);
277074
+ if (!is_wsl_default) {
277075
+ childProcessOptions.windowsVerbatimArguments = true;
277076
+ }
277077
+ if (is_wsl_default && options.target) {
277078
+ options.target = await convertWslPathToWindows(options.target);
277079
+ }
277080
+ const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
277081
+ if (options.wait) {
277082
+ encodedArguments.push("-Wait");
277083
+ }
277084
+ if (app) {
277085
+ encodedArguments.push(executePowerShell.escapeArgument(app));
277086
+ if (options.target) {
277087
+ appArguments.push(options.target);
277088
+ }
277089
+ } else if (options.target) {
277090
+ encodedArguments.push(executePowerShell.escapeArgument(options.target));
277091
+ }
277092
+ if (appArguments.length > 0) {
277093
+ appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
277094
+ encodedArguments.push("-ArgumentList", appArguments.join(","));
277095
+ }
277096
+ options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
277097
+ if (!options.wait) {
277098
+ childProcessOptions.stdio = "ignore";
277099
+ }
277100
+ } else {
277101
+ if (app) {
277102
+ command = app;
277103
+ } else {
277104
+ const isBundled = !__dirname2 || __dirname2 === "/";
277105
+ let exeLocalXdgOpen = false;
277106
+ try {
277107
+ await fs20.access(localXdgOpenPath, fsConstants2.X_OK);
277108
+ exeLocalXdgOpen = true;
277109
+ } catch {}
277110
+ const useSystemXdgOpen = process30.versions.electron ?? (platform7 === "android" || isBundled || !exeLocalXdgOpen);
277111
+ command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
277112
+ }
277113
+ if (appArguments.length > 0) {
277114
+ cliArguments.push(...appArguments);
277115
+ }
277116
+ if (!options.wait) {
277117
+ childProcessOptions.stdio = "ignore";
277118
+ childProcessOptions.detached = true;
277119
+ }
277120
+ }
277121
+ if (platform7 === "darwin" && appArguments.length > 0) {
277122
+ cliArguments.push("--args", ...appArguments);
277123
+ }
277124
+ if (options.target) {
277125
+ cliArguments.push(options.target);
277126
+ }
277127
+ const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
277128
+ if (options.wait) {
277129
+ return new Promise((resolve, reject) => {
277130
+ subprocess.once("error", reject);
277131
+ subprocess.once("close", (exitCode) => {
277132
+ if (!options.allowNonzeroExitCode && exitCode !== 0) {
277133
+ reject(new Error(`Exited with code ${exitCode}`));
277134
+ return;
277135
+ }
277136
+ resolve(subprocess);
277137
+ });
277138
+ });
277139
+ }
277140
+ if (isFallbackAttempt) {
277141
+ return new Promise((resolve, reject) => {
277142
+ subprocess.once("error", reject);
277143
+ subprocess.once("spawn", () => {
277144
+ subprocess.once("close", (exitCode) => {
277145
+ subprocess.off("error", reject);
277146
+ if (exitCode !== 0) {
277147
+ reject(new Error(`Exited with code ${exitCode}`));
277148
+ return;
277149
+ }
277150
+ subprocess.unref();
277151
+ resolve(subprocess);
277152
+ });
277153
+ });
277154
+ });
277155
+ }
277156
+ subprocess.unref();
277157
+ return new Promise((resolve, reject) => {
277158
+ subprocess.once("error", reject);
277159
+ subprocess.once("spawn", () => {
277160
+ subprocess.off("error", reject);
277161
+ resolve(subprocess);
277162
+ });
277163
+ });
277164
+ };
277165
+ var open = (target, options) => {
277166
+ if (typeof target !== "string") {
277167
+ throw new TypeError("Expected a `target`");
277168
+ }
277169
+ return baseOpen({
277170
+ ...options,
277171
+ target
277172
+ });
277173
+ };
277174
+ function detectArchBinary(binary) {
277175
+ if (typeof binary === "string" || Array.isArray(binary)) {
277176
+ return binary;
277177
+ }
277178
+ const { [arch]: archBinary } = binary;
277179
+ if (!archBinary) {
277180
+ throw new Error(`${arch} is not supported`);
277181
+ }
277182
+ return archBinary;
277183
+ }
277184
+ function detectPlatformBinary({ [platform7]: platformBinary }, { wsl } = {}) {
277185
+ if (wsl && is_wsl_default) {
277186
+ return detectArchBinary(wsl);
277187
+ }
277188
+ if (!platformBinary) {
277189
+ throw new Error(`${platform7} is not supported`);
277190
+ }
277191
+ return detectArchBinary(platformBinary);
277192
+ }
277193
+ var apps = {
277194
+ browser: "browser",
277195
+ browserPrivate: "browserPrivate"
277196
+ };
277197
+ defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
277198
+ darwin: "google chrome",
277199
+ win32: "chrome",
277200
+ linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
277201
+ }, {
277202
+ wsl: {
277203
+ ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
277204
+ x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
277205
+ }
277206
+ }));
277207
+ defineLazyProperty(apps, "brave", () => detectPlatformBinary({
277208
+ darwin: "brave browser",
277209
+ win32: "brave",
277210
+ linux: ["brave-browser", "brave"]
277211
+ }, {
277212
+ wsl: {
277213
+ ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
277214
+ x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
277215
+ }
277216
+ }));
277217
+ defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
277218
+ darwin: "firefox",
277219
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
277220
+ linux: "firefox"
277221
+ }, {
277222
+ wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
277223
+ }));
277224
+ defineLazyProperty(apps, "edge", () => detectPlatformBinary({
277225
+ darwin: "microsoft edge",
277226
+ win32: "msedge",
277227
+ linux: ["microsoft-edge", "microsoft-edge-dev"]
277228
+ }, {
277229
+ wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
277230
+ }));
277231
+ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
277232
+ darwin: "Safari"
277233
+ }));
277234
+ var open_default = open;
277235
+
275891
277236
  // src/cli/commands/code/session.tsx
275892
277237
  var import_react23 = __toESM(require_react(), 1);
275893
277238
 
277239
+ // src/cli/commands/code/logo.ts
277240
+ var ROWS = 6;
277241
+ var ASPECT = 0.44;
277242
+ var SAMPLES = 4;
277243
+ var FILL = 0.6;
277244
+ var GAP_ROW = 3.5 + 0.5;
277245
+ var GAP_HEIGHT_ROWS = 0.8;
277246
+ var LOGO_COLS = Math.max(2, Math.floor(ROWS / ASPECT + 0.5));
277247
+ var OCTANT = {
277248
+ rx: 2,
277249
+ ry: 4,
277250
+ table: Array.from(" \uD83E\uDF82\uD833\uDD00▘\uD833\uDD01\uD833\uDD02\uD833\uDD03\uD833\uDD04▝\uD833\uDD05\uD833\uDD06\uD833\uDD07\uD833\uDD08▀\uD833\uDD09\uD833\uDD0A\uD833\uDD0B\uD833\uDD0C\uD833\uDD00\uD833\uDD0D\uD833\uDD0E\uD833\uDD0F\uD833\uDD10\uD833\uDD11\uD833\uDD12\uD833\uDD13\uD833\uDD14\uD833\uDD15\uD833\uDD16\uD833\uDD17\uD833\uDD18\uD833\uDD19\uD833\uDD1A\uD833\uDD1B\uD833\uDD1C\uD833\uDD1D\uD833\uDD1E\uD833\uDD1F\uD833\uDD03\uD833\uDD20\uD833\uDD21\uD833\uDD22\uD833\uDD23\uD833\uDD24\uD833\uDD25\uD833\uDD26\uD833\uDD27\uD833\uDD28\uD833\uDD29\uD833\uDD2A\uD833\uDD2B\uD833\uDD2C\uD833\uDD2D\uD833\uDD2E\uD833\uDD2F\uD833\uDD30\uD833\uDD31\uD833\uDD32\uD833\uDD33\uD833\uDD34\uD833\uDD35\uD83E\uDF85 \uD833\uDD36\uD833\uDD37\uD833\uDD38\uD833\uDD39\uD833\uDD3A\uD833\uDD3B\uD833\uDD3C\uD833\uDD3D\uD833\uDD3E\uD833\uDD3F\uD833\uDD40\uD833\uDD41\uD833\uDD42\uD833\uDD43\uD833\uDD44▖\uD833\uDD45\uD833\uDD46\uD833\uDD47\uD833\uDD48▌\uD833\uDD49\uD833\uDD4A\uD833\uDD4B\uD833\uDD4C▞\uD833\uDD4D\uD833\uDD4E\uD833\uDD4F\uD833\uDD50▛\uD833\uDD51\uD833\uDD52\uD833\uDD53\uD833\uDD54\uD833\uDD55\uD833\uDD56\uD833\uDD57\uD833\uDD58\uD833\uDD59\uD833\uDD5A\uD833\uDD5B\uD833\uDD5C\uD833\uDD5D\uD833\uDD5E\uD833\uDD5F\uD833\uDD60\uD833\uDD61\uD833\uDD62\uD833\uDD63\uD833\uDD64\uD833\uDD65\uD833\uDD66\uD833\uDD67\uD833\uDD68\uD833\uDD69\uD833\uDD6A\uD833\uDD6B\uD833\uDD6C\uD833\uDD6D\uD833\uDD6E\uD833\uDD6F\uD833\uDD70 \uD833\uDD71\uD833\uDD72\uD833\uDD73\uD833\uDD74\uD833\uDD75\uD833\uDD76\uD833\uDD77\uD833\uDD78\uD833\uDD79\uD833\uDD7A\uD833\uDD7B\uD833\uDD7C\uD833\uDD7D\uD833\uDD7E\uD833\uDD7F\uD833\uDD80\uD833\uDD81\uD833\uDD82\uD833\uDD83\uD833\uDD84\uD833\uDD85\uD833\uDD86\uD833\uDD87\uD833\uDD88\uD833\uDD89\uD833\uDD8A\uD833\uDD8B\uD833\uDD8C\uD833\uDD8D\uD833\uDD8E\uD833\uDD8F▗\uD833\uDD90\uD833\uDD91\uD833\uDD92\uD833\uDD93▚\uD833\uDD94\uD833\uDD95\uD833\uDD96\uD833\uDD97▐\uD833\uDD98\uD833\uDD99\uD833\uDD9A\uD833\uDD9B▜\uD833\uDD9C\uD833\uDD9D\uD833\uDD9E\uD833\uDD9F\uD833\uDDA0\uD833\uDDA1\uD833\uDDA2\uD833\uDDA3\uD833\uDDA4\uD833\uDDA5\uD833\uDDA6\uD833\uDDA7\uD833\uDDA8\uD833\uDDA9\uD833\uDDAA\uD833\uDDAB▂\uD833\uDDAC\uD833\uDDAD\uD833\uDDAE\uD833\uDDAF\uD833\uDDB0\uD833\uDDB1\uD833\uDDB2\uD833\uDDB3\uD833\uDDB4\uD833\uDDB5\uD833\uDDB6\uD833\uDDB7\uD833\uDDB8\uD833\uDDB9\uD833\uDDBA\uD833\uDDBB\uD833\uDDBC\uD833\uDDBD\uD833\uDDBE\uD833\uDDBF\uD833\uDDC0\uD833\uDDC1\uD833\uDDC2\uD833\uDDC3\uD833\uDDC4\uD833\uDDC5\uD833\uDDC6\uD833\uDDC7\uD833\uDDC8\uD833\uDDC9\uD833\uDDCA\uD833\uDDCB\uD833\uDDCC\uD833\uDDCD\uD833\uDDCE\uD833\uDDCF\uD833\uDDD0\uD833\uDDD1\uD833\uDDD2\uD833\uDDD3\uD833\uDDD4\uD833\uDDD5\uD833\uDDD6\uD833\uDDD7\uD833\uDDD8\uD833\uDDD9\uD833\uDDDA▄\uD833\uDDDB\uD833\uDDDC\uD833\uDDDD\uD833\uDDDE▙\uD833\uDDDF\uD833\uDDE0\uD833\uDDE1\uD833\uDDE2▟\uD833\uDDE3▆\uD833\uDDE4\uD833\uDDE5█")
277251
+ };
277252
+ var QUAD = {
277253
+ rx: 2,
277254
+ ry: 2,
277255
+ table: Array.from(" ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█")
277256
+ };
277257
+ function detectTier(env = process.env) {
277258
+ const term = env.TERM ?? "";
277259
+ const prog = env.TERM_PROGRAM ?? "";
277260
+ if (prog === "ghostty" || term.includes("ghostty"))
277261
+ return "octant";
277262
+ if (env.KITTY_WINDOW_ID || term.includes("kitty"))
277263
+ return "octant";
277264
+ if (env.WEZTERM_PANE || env.WEZTERM_EXECUTABLE)
277265
+ return "octant";
277266
+ if (term.startsWith("foot") || prog === "contour")
277267
+ return "octant";
277268
+ return "quad";
277269
+ }
277270
+ function coverageGrid(rows, cols, aspect, pixelH) {
277271
+ const worldH = rows * pixelH;
277272
+ const worldW = cols * aspect;
277273
+ const radius = Math.min(worldH, worldW) / 2;
277274
+ const cx = worldW / 2;
277275
+ const cy = worldH / 2;
277276
+ const step = 1 / SAMPLES;
277277
+ const grid = [];
277278
+ for (let py = 0;py < rows; py++) {
277279
+ const y0 = py * pixelH;
277280
+ const y1 = y0 + pixelH;
277281
+ const dyLo = y0 <= cy && cy <= y1 ? 0 : Math.min(Math.abs(y0 - cy), Math.abs(y1 - cy));
277282
+ const dyHi = Math.max(Math.abs(y0 - cy), Math.abs(y1 - cy));
277283
+ const line = [];
277284
+ for (let px = 0;px < cols; px++) {
277285
+ const x0 = px * aspect;
277286
+ const x1 = x0 + aspect;
277287
+ const dxLo = x0 <= cx && cx <= x1 ? 0 : Math.min(Math.abs(x0 - cx), Math.abs(x1 - cx));
277288
+ const dxHi = Math.max(Math.abs(x0 - cx), Math.abs(x1 - cx));
277289
+ if (Math.hypot(dxLo, dyLo) >= radius) {
277290
+ line.push(0);
277291
+ continue;
277292
+ }
277293
+ if (Math.hypot(dxHi, dyHi) <= radius) {
277294
+ line.push(1);
277295
+ continue;
277296
+ }
277297
+ let hits = 0;
277298
+ for (let j = 0;j < SAMPLES; j++) {
277299
+ const dy = y0 + (j + 0.5) * step * pixelH - cy;
277300
+ for (let i = 0;i < SAMPLES; i++) {
277301
+ const dx = x0 + (i + 0.5) * step * aspect - cx;
277302
+ if (Math.hypot(dx, dy) <= radius)
277303
+ hits++;
277304
+ }
277305
+ }
277306
+ line.push(hits / (SAMPLES * SAMPLES));
277307
+ }
277308
+ grid.push(line);
277309
+ }
277310
+ return grid;
277311
+ }
277312
+ function carveGap(grid, ry) {
277313
+ const n = grid.length;
277314
+ const thick = Math.max(1, Math.round(GAP_HEIGHT_ROWS * ry));
277315
+ const centre = GAP_ROW >= 0 ? GAP_ROW * ry : n + GAP_ROW * ry;
277316
+ const start = Math.max(0, Math.min(n - thick, centre - thick / 2));
277317
+ for (let i = Math.trunc(start);i < Math.trunc(start + thick); i++) {
277318
+ grid[i].fill(0);
277319
+ }
277320
+ }
277321
+ function logoRows(color, tier = detectTier()) {
277322
+ const { rx, ry, table } = tier === "octant" ? OCTANT : QUAD;
277323
+ const grid = coverageGrid(ROWS * ry, LOGO_COLS * rx, ASPECT / rx, 1 / ry);
277324
+ carveGap(grid, ry);
277325
+ const fg = color ? source_default.hex(color) : (s) => s;
277326
+ const bg = color ? source_default.bgHex(color) : (s) => s;
277327
+ const full = (1 << rx * ry) - 1;
277328
+ const out = [];
277329
+ for (let r = 0;r < ROWS; r++) {
277330
+ let row = "";
277331
+ for (let c = 0;c < LOGO_COLS; c++) {
277332
+ let mask = 0;
277333
+ for (let sr = 0;sr < ry; sr++) {
277334
+ for (let sc = 0;sc < rx; sc++) {
277335
+ if (grid[r * ry + sr][c * rx + sc] >= FILL)
277336
+ mask |= 1 << sr * rx + sc;
277337
+ }
277338
+ }
277339
+ const glyph = table[mask];
277340
+ if (glyph === " ")
277341
+ row += " ";
277342
+ else if (mask === full && color)
277343
+ row += bg(" ");
277344
+ else
277345
+ row += fg(glyph);
277346
+ }
277347
+ out.push(row);
277348
+ }
277349
+ return out;
277350
+ }
277351
+
275894
277352
  // src/cli/commands/code/paste.ts
275895
277353
  import { PassThrough as PassThrough3 } from "node:stream";
275896
277354
  var START = "\x1B[200~";
@@ -275964,6 +277422,357 @@ function createPasteFriendlyStdin(real) {
275964
277422
  return proxy;
275965
277423
  }
275966
277424
 
277425
+ // src/cli/commands/code/pending-card.ts
277426
+ function openCard(pending) {
277427
+ return {
277428
+ pending,
277429
+ step: 0,
277430
+ cursor: 0,
277431
+ selections: (pending.questions ?? []).map(() => ({ labels: [] })),
277432
+ granted: new Set((pending.permissions ?? []).map((p) => p.key)),
277433
+ typing: pending.kind === "secrets" ? "secret" : pending.kind === "credentials" ? "cred-name" : null,
277434
+ ...pending.kind === "credentials" ? { cred: { name: pending.credentials?.suggestedName } } : {},
277435
+ secretValues: {},
277436
+ ...pending.kind === "browser" ? { browser: { status: "idle" } } : {}
277437
+ };
277438
+ }
277439
+ var done = (action, input = {}) => ({ state: null, submit: { action, input } });
277440
+ var later = { state: null, dismissed: true };
277441
+ function choiceRows(state) {
277442
+ return (state.pending.questions?.[state.step]?.options.length ?? 0) + 1;
277443
+ }
277444
+ function advanceChoice(state) {
277445
+ const questions = state.pending.questions ?? [];
277446
+ if (state.step + 1 < questions.length) {
277447
+ return {
277448
+ state: { ...state, step: state.step + 1, cursor: 0, typing: null }
277449
+ };
277450
+ }
277451
+ return done("approved", choiceAnswers(questions, state.selections, state.pending.answerKey));
277452
+ }
277453
+ function choiceKey(state, key) {
277454
+ const question = state.pending.questions?.[state.step];
277455
+ if (!question)
277456
+ return done("approved", { answers: [] });
277457
+ const rows = choiceRows(state);
277458
+ const custom = state.cursor === rows - 1;
277459
+ const sel = state.selections[state.step] ?? { labels: [] };
277460
+ const setSel = (next) => {
277461
+ const selections = [...state.selections];
277462
+ selections[state.step] = next;
277463
+ return { ...state, selections };
277464
+ };
277465
+ switch (key) {
277466
+ case "up":
277467
+ return { state: { ...state, cursor: (state.cursor - 1 + rows) % rows } };
277468
+ case "down":
277469
+ return { state: { ...state, cursor: (state.cursor + 1) % rows } };
277470
+ case "space": {
277471
+ if (custom)
277472
+ return { state: { ...state, typing: "custom" } };
277473
+ const label = question.options[state.cursor].label;
277474
+ const labels = question.multiSelect ? sel.labels.includes(label) ? sel.labels.filter((l) => l !== label) : [...sel.labels, label] : [label];
277475
+ return { state: setSel({ ...sel, labels }) };
277476
+ }
277477
+ case "enter": {
277478
+ if (custom)
277479
+ return { state: { ...state, typing: "custom" } };
277480
+ if (question.multiSelect) {
277481
+ if (sel.labels.length === 0 && !sel.customText)
277482
+ return { state };
277483
+ return advanceChoice(state);
277484
+ }
277485
+ const label = question.options[state.cursor].label;
277486
+ return advanceChoice(setSel({ labels: [label] }));
277487
+ }
277488
+ case "s":
277489
+ return done("approved", { answers: [] });
277490
+ case "escape":
277491
+ return later;
277492
+ default:
277493
+ return { state };
277494
+ }
277495
+ }
277496
+ function permissionsKey(state, key) {
277497
+ const rows = state.pending.permissions ?? [];
277498
+ switch (key) {
277499
+ case "up":
277500
+ return {
277501
+ state: {
277502
+ ...state,
277503
+ cursor: (state.cursor - 1 + rows.length) % rows.length
277504
+ }
277505
+ };
277506
+ case "down":
277507
+ return { state: { ...state, cursor: (state.cursor + 1) % rows.length } };
277508
+ case "space": {
277509
+ const k = rows[state.cursor]?.key;
277510
+ if (!k)
277511
+ return { state };
277512
+ const granted = new Set(state.granted);
277513
+ if (granted.has(k))
277514
+ granted.delete(k);
277515
+ else
277516
+ granted.add(k);
277517
+ return { state: { ...state, granted } };
277518
+ }
277519
+ case "enter":
277520
+ case "y":
277521
+ return done("approved", {
277522
+ approved_permission_keys: rows.map((r) => r.key).filter((k) => state.granted.has(k))
277523
+ });
277524
+ case "n":
277525
+ return done("rejected");
277526
+ case "escape":
277527
+ return later;
277528
+ default:
277529
+ return { state };
277530
+ }
277531
+ }
277532
+ function cardKey(state, key) {
277533
+ if (state.typing) {
277534
+ if (key === "escape") {
277535
+ return state.typing === "secret" || state.typing === "cred-secret" ? later : state.typing === "custom" ? { state: { ...state, typing: null } } : later;
277536
+ }
277537
+ return { state };
277538
+ }
277539
+ switch (state.pending.kind) {
277540
+ case "choice":
277541
+ return choiceKey(state, key);
277542
+ case "permissions":
277543
+ return permissionsKey(state, key);
277544
+ case "browser": {
277545
+ const status = state.browser?.status ?? "idle";
277546
+ if (key === "n")
277547
+ return done("rejected");
277548
+ if (key === "escape")
277549
+ return later;
277550
+ if (key === "y" || key === "enter") {
277551
+ if (status === "active")
277552
+ return done("approved");
277553
+ if (status !== "waiting") {
277554
+ return {
277555
+ state: {
277556
+ ...state,
277557
+ browser: { ...state.browser, status: "waiting" }
277558
+ },
277559
+ startBrowser: true
277560
+ };
277561
+ }
277562
+ }
277563
+ return { state };
277564
+ }
277565
+ case "credentials": {
277566
+ if (key === "n")
277567
+ return done("rejected");
277568
+ if (key === "escape")
277569
+ return later;
277570
+ if (key === "y") {
277571
+ return {
277572
+ state: {
277573
+ ...state,
277574
+ cred: { ...state.cred, source: "own" },
277575
+ typing: "cred-id"
277576
+ }
277577
+ };
277578
+ }
277579
+ if (key === "b") {
277580
+ return done("approved", {
277581
+ name: state.cred?.name ?? "",
277582
+ credential_source: "base44",
277583
+ scopes: state.pending.credentials?.scopes ?? []
277584
+ });
277585
+ }
277586
+ return { state };
277587
+ }
277588
+ case "unknown":
277589
+ if (key === "n")
277590
+ return done("rejected");
277591
+ if (key === "escape")
277592
+ return later;
277593
+ return { state };
277594
+ default:
277595
+ if (key === "y" || key === "enter")
277596
+ return done("approved");
277597
+ if (key === "n")
277598
+ return done("rejected");
277599
+ if (key === "escape")
277600
+ return later;
277601
+ return { state };
277602
+ }
277603
+ }
277604
+ function browserUpdate(state, update) {
277605
+ return {
277606
+ ...state,
277607
+ browser: { url: update.url ?? state.browser?.url, status: update.status }
277608
+ };
277609
+ }
277610
+ function cardText(state, text) {
277611
+ const value = text.trim();
277612
+ if (state.typing === "custom") {
277613
+ if (!value)
277614
+ return { state: { ...state, typing: null } };
277615
+ const selections = [...state.selections];
277616
+ const current = selections[state.step] ?? { labels: [] };
277617
+ selections[state.step] = { ...current, customText: value };
277618
+ return advanceChoice({ ...state, selections, typing: null });
277619
+ }
277620
+ if (state.typing === "cred-name") {
277621
+ const name = value || state.cred?.name || "";
277622
+ if (!name)
277623
+ return { state };
277624
+ return { state: { ...state, cred: { ...state.cred, name }, typing: null } };
277625
+ }
277626
+ if (state.typing === "cred-id") {
277627
+ if (!value)
277628
+ return { state };
277629
+ return {
277630
+ state: {
277631
+ ...state,
277632
+ cred: { ...state.cred, clientId: value },
277633
+ typing: "cred-secret"
277634
+ }
277635
+ };
277636
+ }
277637
+ if (state.typing === "cred-secret") {
277638
+ if (!value)
277639
+ return { state };
277640
+ const scopes = state.pending.credentials?.scopes ?? [];
277641
+ return done("approved", {
277642
+ name: state.cred?.name ?? "",
277643
+ client_id: state.cred?.clientId ?? "",
277644
+ client_secret: value,
277645
+ scopes
277646
+ });
277647
+ }
277648
+ if (state.typing === "secret") {
277649
+ const fields = state.pending.secrets ?? [];
277650
+ const field = fields[state.step];
277651
+ if (!field || !value)
277652
+ return { state };
277653
+ const secretValues = { ...state.secretValues, [field.name]: value };
277654
+ if (state.step + 1 < fields.length) {
277655
+ return { state: { ...state, secretValues, step: state.step + 1 } };
277656
+ }
277657
+ return done("approved", { secrets: secretValues });
277658
+ }
277659
+ return { state };
277660
+ }
277661
+ function cardLines(state) {
277662
+ const p = state.pending;
277663
+ const head = [source_default.bold(`⏸ ${p.title}`)];
277664
+ if (p.detail)
277665
+ head.push(source_default.dim(` ${p.detail}`));
277666
+ switch (p.kind) {
277667
+ case "choice": {
277668
+ const q = p.questions?.[state.step];
277669
+ if (!q)
277670
+ return [...head, source_default.dim(" (no questions) · Enter to continue")];
277671
+ const total = p.questions?.length ?? 1;
277672
+ const sel = state.selections[state.step] ?? { labels: [] };
277673
+ const rows = q.options.map((o, i) => {
277674
+ const on = sel.labels.includes(o.label);
277675
+ const mark = q.multiSelect ? on ? "☑" : "☐" : on ? "●" : "○";
277676
+ const text = `${state.cursor === i ? "▸" : " "} ${mark} ${o.label}${o.description ? source_default.dim(` — ${o.description}`) : ""}`;
277677
+ return state.cursor === i ? source_default.cyan(text) : text;
277678
+ });
277679
+ const customRow = `${state.cursor === q.options.length ? "▸" : " "} ✎ something else${sel.customText ? source_default.dim(` — ${sel.customText}`) : ""}`;
277680
+ rows.push(state.cursor === q.options.length ? source_default.cyan(customRow) : customRow);
277681
+ return [
277682
+ ...head,
277683
+ ` ${source_default.bold(q.question)} ${source_default.dim(`(${state.step + 1}/${total})`)}`,
277684
+ ...q.description ? [source_default.dim(` ${q.description}`)] : [],
277685
+ ...rows.map((r) => ` ${r}`),
277686
+ source_default.dim(q.multiSelect ? " ↑↓ move · space toggle · Enter next · s skip all · Esc later" : " ↑↓ move · Enter choose · s skip all · Esc later")
277687
+ ];
277688
+ }
277689
+ case "permissions": {
277690
+ const rows = (p.permissions ?? []).map((r, i) => {
277691
+ const text = `${state.cursor === i ? "▸" : " "} ${state.granted.has(r.key) ? "☑" : "☐"} ${r.label}${r.reason ? source_default.dim(` — ${r.reason}`) : ""}`;
277692
+ return ` ${state.cursor === i ? source_default.cyan(text) : text}`;
277693
+ });
277694
+ return [
277695
+ ...head,
277696
+ ...rows,
277697
+ source_default.dim(" space toggle · Enter grant ticked · n reject all · Esc later")
277698
+ ];
277699
+ }
277700
+ case "secrets": {
277701
+ const fields = p.secrets ?? [];
277702
+ const rows = fields.map((f, i) => {
277703
+ const filled = f.name in state.secretValues;
277704
+ const mark = filled ? source_default.green("✓") : i === state.step ? "▸" : "○";
277705
+ return ` ${mark} ${f.name}${f.description ? source_default.dim(` — ${f.description}`) : ""}`;
277706
+ });
277707
+ return [
277708
+ ...head,
277709
+ ...rows,
277710
+ source_default.dim(" type the value below (hidden) · Enter next · Esc later")
277711
+ ];
277712
+ }
277713
+ case "browser": {
277714
+ const b = state.browser ?? { status: "idle" };
277715
+ const link = b.url ? [` ${source_default.cyan(b.url)}`] : [];
277716
+ switch (b.status) {
277717
+ case "waiting":
277718
+ return [
277719
+ ...head,
277720
+ source_default.dim(" opened in your browser — or use the link:"),
277721
+ ...link,
277722
+ source_default.dim(" waiting for the authorization to complete… · n reject · Esc later")
277723
+ ];
277724
+ case "active":
277725
+ return [
277726
+ ...head,
277727
+ source_default.green(" ✓ connected"),
277728
+ source_default.dim(" y continue · n reject")
277729
+ ];
277730
+ case "failed":
277731
+ return [
277732
+ ...head,
277733
+ source_default.red(" ✗ authorization failed"),
277734
+ source_default.dim(" y try again · n reject · Esc later")
277735
+ ];
277736
+ case "timeout":
277737
+ return [
277738
+ ...head,
277739
+ source_default.yellow(" ⏱ no response yet"),
277740
+ ...link,
277741
+ source_default.dim(" y try again · n reject · Esc later")
277742
+ ];
277743
+ default:
277744
+ return [
277745
+ ...head,
277746
+ source_default.dim(" y open the authorization link · n reject · Esc later")
277747
+ ];
277748
+ }
277749
+ }
277750
+ case "credentials": {
277751
+ const c = state.cred ?? {};
277752
+ const scopes = state.pending.credentials?.scopes ?? [];
277753
+ return [
277754
+ ...head,
277755
+ ` ${c.name ? source_default.green("✓") : "▸"} name${c.name ? source_default.dim(` — ${c.name}`) : ""}`,
277756
+ ` ${c.source ? source_default.green("✓") : c.name ? "▸" : "○"} credentials${c.source === "own" ? source_default.dim(" — your own OAuth app") : c.source === "base44" ? source_default.dim(" — Base44's") : ""}`,
277757
+ ...c.source === "own" ? [
277758
+ ` ${c.clientId ? source_default.green("✓") : "▸"} client id${c.clientId ? source_default.dim(` — ${c.clientId}`) : ""}`,
277759
+ ` ${"▸"} client secret ${source_default.dim("(hidden)")}`
277760
+ ] : [],
277761
+ ...scopes.length ? [source_default.dim(` scopes: ${scopes.join(", ")}`)] : [],
277762
+ source_default.dim(!c.name ? " type the connector name below · Enter · Esc later" : !c.source ? " b use Base44's credentials · y enter your own client id + secret · n reject · Esc later" : " type the value below · Enter next · Esc cancel")
277763
+ ];
277764
+ }
277765
+ case "unknown":
277766
+ return [
277767
+ ...head,
277768
+ source_default.yellow(" this question needs the editor — answer it there and the session continues"),
277769
+ source_default.dim(" n reject · Esc later")
277770
+ ];
277771
+ default:
277772
+ return [...head, source_default.dim(" y approve · n reject · Esc later")];
277773
+ }
277774
+ }
277775
+
275967
277776
  // src/cli/commands/code/session-engine.ts
275968
277777
  var POLL_MS = 1000;
275969
277778
  function createSessionEngine(options) {
@@ -275983,6 +277792,28 @@ function createSessionEngine(options) {
275983
277792
  let awaitingTurn = options.awaitingTurnLabel ?? null;
275984
277793
  const awaitingSince = Date.now();
275985
277794
  let lastEventAt = Date.now();
277795
+ let pending = [];
277796
+ const answered = new Set;
277797
+ const answer = (p, action, input = {}) => {
277798
+ answered.add(p.toolCallId);
277799
+ pending = pending.filter((x) => x.toolCallId !== p.toolCallId);
277800
+ const verb = action === "rejected" ? source_default.red("✗ rejected") : Object.keys(input).length ? source_default.green("→ answered") : source_default.green("✓ approved");
277801
+ options.onLine(`${verb} ${source_default.dim("—")} ${p.title}`);
277802
+ pendingSubmitAt = Date.now();
277803
+ sendsInFlight++;
277804
+ answerToolCall({ toolCallId: p.toolCallId, messageId: p.messageId, action, input }, options.branchId).catch((error) => {
277805
+ const status = error instanceof ApiError ? error.statusCode : undefined;
277806
+ const edgeDrop = status === 502 || status === 503 || status === 504 || /timeout|gateway/i.test(error instanceof Error ? error.message : "");
277807
+ if (edgeDrop && (turnStartedAt != null || pendingSubmitAt == null)) {
277808
+ return;
277809
+ }
277810
+ answered.delete(p.toolCallId);
277811
+ pendingSubmitAt = null;
277812
+ options.onLine(source_default.red(`✗ answer failed: ${error instanceof Error ? error.message : String(error)}`));
277813
+ }).finally(() => {
277814
+ sendsInFlight--;
277815
+ });
277816
+ };
275986
277817
  const submit = (raw) => {
275987
277818
  const typed = raw.trim();
275988
277819
  if (!typed)
@@ -276023,25 +277854,40 @@ function createSessionEngine(options) {
276023
277854
  return;
276024
277855
  }
276025
277856
  const events = diffConversation(diffState, messages);
277857
+ const waiting = pendingInputs(messages);
277858
+ for (const id of answered) {
277859
+ if (!waiting.some((w) => w.toolCallId === id))
277860
+ answered.delete(id);
277861
+ }
277862
+ pending = waiting.filter((w) => !answered.has(w.toolCallId));
276026
277863
  if (!prime) {
276027
277864
  for (const event of events) {
276028
277865
  if (event.kind === "tool_start") {
277866
+ const startedAt = Date.now();
276029
277867
  running.set(event.id, {
276030
277868
  alias: toolAlias(event.name),
276031
277869
  label: event.label,
276032
277870
  summary: event.summary,
276033
- startedAt: Date.now()
277871
+ startedAt
276034
277872
  });
277873
+ options.onLine({ running: event, startedAt });
276035
277874
  continue;
276036
277875
  }
276037
- let elapsedMs;
276038
277876
  if (event.kind === "tool_end") {
276039
277877
  const started = running.get(event.id)?.startedAt;
276040
- if (started != null)
276041
- elapsedMs = Date.now() - started;
276042
277878
  running.delete(event.id);
277879
+ lastEventAt = Date.now();
277880
+ options.onLine({
277881
+ event,
277882
+ elapsedMs: started != null ? Date.now() - started : undefined
277883
+ });
277884
+ continue;
276043
277885
  }
276044
- const line = eventLine(event, elapsedMs);
277886
+ if (event.kind === "waiting" && answered.has(event.id))
277887
+ continue;
277888
+ const line = eventLine(event, undefined, {
277889
+ waitingHint: "answer in the card below"
277890
+ });
276045
277891
  if (line != null) {
276046
277892
  lastEventAt = Date.now();
276047
277893
  options.onLine(line);
@@ -276070,7 +277916,7 @@ function createSessionEngine(options) {
276070
277916
  lastTurnMs = durationMs;
276071
277917
  const ok = !turn.backendStatus?.startsWith("error");
276072
277918
  lastTurnOk = ok;
276073
- options.onLine(ok ? source_default.dim(`— turn finished · ${formatDuration2(durationMs)}`) : source_default.red(`— turn failed (${turn.backendStatus ?? "unknown"}) · ${formatDuration2(durationMs)}`));
277919
+ options.onLine(ok ? source_default.dim(`— turn finished · ${formatDuration2(durationMs)}`) : source_default.red(turn.backendStatus === "error_paywall" ? `— the workspace is out of credits; nothing ran · ${formatDuration2(durationMs)}` : `— turn failed (${turn.backendStatus ?? "unknown"}) · ${formatDuration2(durationMs)}`));
276074
277920
  const info = {
276075
277921
  turnIndex: settledCount++,
276076
277922
  ok,
@@ -276108,6 +277954,7 @@ function createSessionEngine(options) {
276108
277954
  });
276109
277955
  },
276110
277956
  submit,
277957
+ answer,
276111
277958
  status() {
276112
277959
  let phase = "idle";
276113
277960
  if (awaitingTurn != null)
@@ -276130,7 +277977,8 @@ function createSessionEngine(options) {
276130
277977
  turnStartedAt,
276131
277978
  runningTool,
276132
277979
  lastTurnMs,
276133
- lastTurnOk
277980
+ lastTurnOk,
277981
+ pending
276134
277982
  };
276135
277983
  },
276136
277984
  turnRunning() {
@@ -276139,6 +277987,58 @@ function createSessionEngine(options) {
276139
277987
  };
276140
277988
  }
276141
277989
 
277990
+ // src/core/resources/apps/connections.ts
277991
+ var InitiateSchema = object({
277992
+ redirect_url: string2().nullish(),
277993
+ connection_id: string2().nullish(),
277994
+ integration_type: string2().nullish()
277995
+ });
277996
+ async function startConnectorOAuth(options) {
277997
+ let response;
277998
+ try {
277999
+ response = await getAppClient().post("external-auth/initiate", {
278000
+ json: {
278001
+ integration_type: options.integrationType,
278002
+ scopes: options.scopes ?? null,
278003
+ connector_id: options.connectorId ?? null,
278004
+ force_reconnect: options.forceReconnect === true
278005
+ }
278006
+ });
278007
+ } catch (error) {
278008
+ throw await ApiError.fromHttpError(error, "starting connector authorization");
278009
+ }
278010
+ const parsed = InitiateSchema.parse(await response.json());
278011
+ if (!parsed.redirect_url || !parsed.connection_id) {
278012
+ throw new ApiError("The connector did not return an authorization link.");
278013
+ }
278014
+ return {
278015
+ url: parsed.redirect_url,
278016
+ connectionId: parsed.connection_id,
278017
+ integrationType: parsed.integration_type ?? options.integrationType
278018
+ };
278019
+ }
278020
+ async function waitForConnectorOAuth(started, options = {}) {
278021
+ const deadline = Date.now() + (options.timeoutMs ?? 10 * 60000);
278022
+ const interval = options.intervalMs ?? 3000;
278023
+ while (Date.now() < deadline && !options.signal?.aborted) {
278024
+ const status = await getOAuthStatus(started.integrationType, started.connectionId).catch(() => null);
278025
+ if (status?.status === "ACTIVE" || status?.status === "FAILED") {
278026
+ return status.status;
278027
+ }
278028
+ await new Promise((r) => setTimeout(r, interval));
278029
+ }
278030
+ return "PENDING";
278031
+ }
278032
+ var GithubStatusSchema = object({ connected: boolean2() });
278033
+ async function githubConnected() {
278034
+ try {
278035
+ const response = await base44Client.get("api/github/oauth/status");
278036
+ return GithubStatusSchema.parse(await response.json()).connected;
278037
+ } catch {
278038
+ return false;
278039
+ }
278040
+ }
278041
+
276142
278042
  // src/cli/commands/code/session.tsx
276143
278043
  var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
276144
278044
  var FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
@@ -276162,6 +278062,17 @@ function exitAltScreen() {
276162
278062
  altScreenActive = false;
276163
278063
  process.stdout.write("\x1B[?1007l\x1B[?1049l");
276164
278064
  }
278065
+ function withEntry(items, entry) {
278066
+ if (typeof entry !== "string" && "event" in entry) {
278067
+ const i = items.findIndex((e) => typeof e !== "string" && ("running" in e) && e.running.id === entry.event.id);
278068
+ if (i >= 0) {
278069
+ const next = [...items];
278070
+ next[i] = entry;
278071
+ return next;
278072
+ }
278073
+ }
278074
+ return [...items, entry];
278075
+ }
276165
278076
  function statusText(status, musingSeed) {
276166
278077
  const frame = FRAMES2[Math.floor(Date.now() / 120) % FRAMES2.length];
276167
278078
  switch (status.phase) {
@@ -276169,15 +278080,8 @@ function statusText(status, musingSeed) {
276169
278080
  return source_default.dim(`${frame} ${status.awaitingLabel} (${formatDuration2(Date.now() - status.awaitingSince)})`);
276170
278081
  case "running": {
276171
278082
  const turnFor = formatDuration2(Date.now() - (status.turnStartedAt ?? Date.now()));
276172
- const tool = status.runningTool;
276173
- if (tool) {
276174
- const toolFor = Math.round((Date.now() - tool.startedAt) / 1000);
276175
- const others = tool.others > 0 ? ` (+${tool.others})` : "";
276176
- const what = tool.label || `${tool.alias}${tool.summary ? ` ${tool.summary}` : ""}`;
276177
- return source_default.dim(`${frame} ${what}${others} · ${toolFor}s (turn ${turnFor})`);
276178
- }
276179
278083
  const quiet = status.quietForMs > 60000 ? " · a long private step — details render in the editor" : "";
276180
- return `${source_default.magenta("✻")} ${source_default.dim(`${idleMusing(musingSeed)} (${turnFor})${quiet}`)}`;
278084
+ return `${source_default.magenta(shimmer())} ${source_default.dim(`${idleMusing(musingSeed)} (${turnFor})${quiet}`)}`;
276181
278085
  }
276182
278086
  case "sending":
276183
278087
  return source_default.dim(`${frame} sending…`);
@@ -276191,18 +278095,19 @@ function statusText(status, musingSeed) {
276191
278095
  function SessionView({ engine, footer, subscribe }) {
276192
278096
  const { exit } = use_app_default();
276193
278097
  const [items, setItems] = import_react23.useState([]);
278098
+ const [verbose, setVerbose] = import_react23.useState(false);
276194
278099
  const [input, setInput] = import_react23.useState("");
276195
278100
  const [scroll, setScroll] = import_react23.useState(0);
276196
278101
  const [, tick] = import_react23.useReducer((x) => x + 1, 0);
276197
278102
  const [musingSeed] = import_react23.useState(() => Math.floor(Math.random() * 97));
276198
278103
  const [currentModel, setCurrentModel] = import_react23.useState(null);
276199
278104
  const [pickerIndex, setPickerIndex] = import_react23.useState(null);
278105
+ const [card, setCard] = import_react23.useState(null);
278106
+ const dismissedRef = import_react23.useRef(new Set);
276200
278107
  const maxScrollRef = import_react23.useRef(0);
276201
278108
  const meIdRef = import_react23.useRef(null);
276202
- const emit = (line) => setItems((h) => [...h, `${line}
276203
- `]);
276204
- import_react23.useEffect(() => subscribe((line) => setItems((h) => [...h, `${line}
276205
- `])), [subscribe]);
278109
+ const emit = (entry) => setItems((h) => withEntry(h, entry));
278110
+ import_react23.useEffect(() => subscribe((entry) => setItems((h) => withEntry(h, entry))), [subscribe]);
276206
278111
  import_react23.useEffect(() => {
276207
278112
  const timer = setInterval(tick, 120);
276208
278113
  return () => clearInterval(timer);
@@ -276244,6 +278149,82 @@ function SessionView({ engine, footer, subscribe }) {
276244
278149
  emit(source_default.red(` /model: ${error instanceof Error ? error.message : String(error)}`));
276245
278150
  }
276246
278151
  };
278152
+ const browserRunRef = import_react23.useRef(null);
278153
+ const runBrowserStep = async (state) => {
278154
+ browserRunRef.current?.abort();
278155
+ const run = new AbortController;
278156
+ browserRunRef.current = run;
278157
+ const step = state.pending.browser;
278158
+ try {
278159
+ let url;
278160
+ let wait;
278161
+ if (step?.flow === "github") {
278162
+ url = await startGithubReauth();
278163
+ wait = async () => {
278164
+ const deadline = Date.now() + 10 * 60000;
278165
+ while (Date.now() < deadline && !run.signal.aborted) {
278166
+ if (await githubConnected())
278167
+ return "ACTIVE";
278168
+ await new Promise((r) => setTimeout(r, 3000));
278169
+ }
278170
+ return "PENDING";
278171
+ };
278172
+ } else {
278173
+ const started = await startConnectorOAuth({
278174
+ integrationType: step?.integrationType ?? "",
278175
+ scopes: step?.scopes,
278176
+ connectorId: step?.connectorId,
278177
+ forceReconnect: step?.forceReconnect
278178
+ });
278179
+ url = started.url;
278180
+ wait = () => waitForConnectorOAuth(started, { signal: run.signal });
278181
+ }
278182
+ setCard((c) => c ? browserUpdate(c, { url, status: "waiting" }) : c);
278183
+ emit(source_default.dim(` authorization link: ${url}`));
278184
+ await open_default(url).catch(() => {
278185
+ return;
278186
+ });
278187
+ const outcome = await wait();
278188
+ if (run.signal.aborted)
278189
+ return;
278190
+ setCard((c) => c ? browserUpdate(c, {
278191
+ status: outcome === "ACTIVE" ? "active" : outcome === "FAILED" ? "failed" : "timeout"
278192
+ }) : c);
278193
+ } catch (error) {
278194
+ if (run.signal.aborted)
278195
+ return;
278196
+ emit(source_default.red(` authorization failed to start: ${error instanceof Error ? error.message : String(error)}`));
278197
+ setCard((c) => c ? browserUpdate(c, { status: "failed" }) : c);
278198
+ }
278199
+ };
278200
+ const applyCard = (outcome) => {
278201
+ if (outcome.submit && card) {
278202
+ browserRunRef.current?.abort();
278203
+ engine.answer(card.pending, outcome.submit.action, outcome.submit.input);
278204
+ }
278205
+ if (outcome.dismissed && card) {
278206
+ browserRunRef.current?.abort();
278207
+ dismissedRef.current.add(card.pending.toolCallId);
278208
+ }
278209
+ setCard(outcome.state);
278210
+ if (outcome.startBrowser && outcome.state) {
278211
+ runBrowserStep(outcome.state);
278212
+ }
278213
+ };
278214
+ const pending = engine.status().pending;
278215
+ import_react23.useEffect(() => {
278216
+ if (card) {
278217
+ if (!pending.some((p) => p.toolCallId === card.pending.toolCallId)) {
278218
+ setCard(null);
278219
+ }
278220
+ return;
278221
+ }
278222
+ if (pickerIndex !== null)
278223
+ return;
278224
+ const next = pending.find((p) => !dismissedRef.current.has(p.toolCallId));
278225
+ if (next)
278226
+ setCard(openCard(next));
278227
+ }, [pending, card, pickerIndex]);
276247
278228
  use_input_default((char, key) => {
276248
278229
  if (pickerIndex !== null) {
276249
278230
  if (key.upArrow)
@@ -276259,6 +278240,23 @@ function SessionView({ engine, footer, subscribe }) {
276259
278240
  }
276260
278241
  return;
276261
278242
  }
278243
+ if (key.tab && !card) {
278244
+ const next = pending.find((p) => dismissedRef.current.has(p.toolCallId));
278245
+ if (next) {
278246
+ dismissedRef.current.delete(next.toolCallId);
278247
+ setCard(openCard(next));
278248
+ }
278249
+ return;
278250
+ }
278251
+ if (card) {
278252
+ const mapped = key.upArrow ? "up" : key.downArrow ? "down" : key.return ? "enter" : key.escape ? "escape" : char === " " ? "space" : char === "y" || char === "n" || char === "s" || char === "b" ? char : null;
278253
+ if (card.typing && mapped !== "escape")
278254
+ return;
278255
+ if (mapped)
278256
+ applyCard(cardKey(card, mapped));
278257
+ if (mapped || !card.typing)
278258
+ return;
278259
+ }
276262
278260
  if (key.ctrl && char === "c") {
276263
278261
  if (input)
276264
278262
  setInput("");
@@ -276270,6 +278268,10 @@ function SessionView({ engine, footer, subscribe }) {
276270
278268
  exit();
276271
278269
  return;
276272
278270
  }
278271
+ if (key.ctrl && char === "o") {
278272
+ setVerbose((v) => !v);
278273
+ return;
278274
+ }
276273
278275
  if (key.upArrow) {
276274
278276
  setScroll((s) => Math.min(s + 3, maxScrollRef.current));
276275
278277
  return;
@@ -276295,14 +278297,17 @@ function SessionView({ engine, footer, subscribe }) {
276295
278297
  });
276296
278298
  const columns = process.stdout.columns || 80;
276297
278299
  const rows = process.stdout.rows || 24;
276298
- const width = Math.min(columns, 100);
278300
+ const width = columns;
276299
278301
  const innerWidth = Math.max(10, width - 4);
276300
278302
  const inputRows = Math.max(1, Math.ceil((input.length + 3) / innerWidth));
276301
278303
  const pickerOpen = pickerIndex !== null;
276302
- const inputBlockHeight = pickerOpen ? MODELS.length + 3 : inputRows + 2;
278304
+ const cardOpen = card !== null && !card.typing;
278305
+ const cardRows = card ? cardLines(card).length : 0;
278306
+ const inputBlockHeight = pickerOpen ? MODELS.length + 3 : cardOpen ? cardRows + 2 : inputRows + 2 + (card?.typing ? 1 : 0);
276303
278307
  const widgetHeight = inputBlockHeight + 3 + (footer.length ? 1 : 0);
276304
278308
  const viewHeight = Math.max(3, rows - widgetHeight - 1);
276305
- const lines = items.flatMap((item) => hardWrapAnsi(item, columns));
278309
+ const lines = items.flatMap((item) => hardWrapAnsi(`${renderEntry(item, { verbose, foldHint: "Ctrl+O to expand" })}
278310
+ `, columns));
276306
278311
  const maxScroll = Math.max(0, lines.length - viewHeight);
276307
278312
  maxScrollRef.current = maxScroll;
276308
278313
  const clamped = Math.min(scroll, maxScroll);
@@ -276349,29 +278354,85 @@ function SessionView({ engine, footer, subscribe }) {
276349
278354
  }, m.name, false, undefined, this);
276350
278355
  })
276351
278356
  ]
276352
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
278357
+ }, undefined, true, undefined, this) : cardOpen && card ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
278358
+ flexDirection: "column",
276353
278359
  borderStyle: "round",
276354
- borderColor: "gray",
278360
+ borderColor: "yellow",
278361
+ paddingX: 1,
278362
+ width,
278363
+ children: cardLines(card).map((line, i) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278364
+ wrap: "truncate-end",
278365
+ children: line
278366
+ }, i, false, undefined, this))
278367
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
278368
+ flexDirection: "column",
278369
+ borderStyle: "round",
278370
+ borderColor: card?.typing ? "yellow" : "gray",
276355
278371
  paddingX: 1,
276356
278372
  width,
276357
278373
  children: [
276358
- /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
276359
- color: "cyan",
276360
- children: "❯ "
276361
- }, undefined, false, undefined, this),
276362
- /* @__PURE__ */ jsx_dev_runtime.jsxDEV(build_default, {
276363
- value: input,
276364
- onChange: setInput,
276365
- onSubmit: (value) => {
276366
- const trimmed = value.trim();
276367
- if (trimmed === "/model" || trimmed.startsWith("/model ")) {
276368
- runModelSlash(trimmed.slice("/model".length).trim());
276369
- } else if (trimmed) {
276370
- engine.submit(value);
276371
- }
276372
- setInput("");
276373
- }
276374
- }, undefined, false, undefined, this)
278374
+ card?.typing === "secret" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278375
+ wrap: "truncate-end",
278376
+ children: [
278377
+ source_default.bold(card.pending.secrets?.[card.step]?.name ?? "secret"),
278378
+ source_default.dim(" — value is hidden · Enter to save · Esc to cancel")
278379
+ ]
278380
+ }, undefined, true, undefined, this),
278381
+ card?.typing === "cred-name" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278382
+ wrap: "truncate-end",
278383
+ children: [
278384
+ source_default.bold("connector name"),
278385
+ source_default.dim(card.cred?.name ? ` — Enter keeps "${card.cred.name}" · Esc later` : " — Enter to save · Esc later")
278386
+ ]
278387
+ }, undefined, true, undefined, this),
278388
+ card?.typing === "cred-id" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278389
+ wrap: "truncate-end",
278390
+ children: [
278391
+ source_default.bold("client id"),
278392
+ source_default.dim(" — Enter to save · Esc cancel")
278393
+ ]
278394
+ }, undefined, true, undefined, this),
278395
+ card?.typing === "cred-secret" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278396
+ wrap: "truncate-end",
278397
+ children: [
278398
+ source_default.bold("client secret"),
278399
+ source_default.dim(" — value is hidden · Enter to register · Esc cancel")
278400
+ ]
278401
+ }, undefined, true, undefined, this),
278402
+ card?.typing === "custom" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278403
+ wrap: "truncate-end",
278404
+ children: [
278405
+ source_default.bold(card.pending.questions?.[card.step]?.question ?? ""),
278406
+ source_default.dim(" — your own answer · Enter to save · Esc to go back")
278407
+ ]
278408
+ }, undefined, true, undefined, this),
278409
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
278410
+ children: [
278411
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
278412
+ color: "cyan",
278413
+ children: "❯ "
278414
+ }, undefined, false, undefined, this),
278415
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(build_default, {
278416
+ value: input,
278417
+ onChange: setInput,
278418
+ mask: card?.typing === "secret" || card?.typing === "cred-secret" ? "•" : undefined,
278419
+ onSubmit: (value) => {
278420
+ if (card?.typing) {
278421
+ applyCard(cardText(card, value));
278422
+ setInput("");
278423
+ return;
278424
+ }
278425
+ const trimmed = value.trim();
278426
+ if (trimmed === "/model" || trimmed.startsWith("/model ")) {
278427
+ runModelSlash(trimmed.slice("/model".length).trim());
278428
+ } else if (trimmed) {
278429
+ engine.submit(value);
278430
+ }
278431
+ setInput("");
278432
+ }
278433
+ }, undefined, false, undefined, this)
278434
+ ]
278435
+ }, undefined, true, undefined, this)
276375
278436
  ]
276376
278437
  }, undefined, true, undefined, this),
276377
278438
  footer.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
@@ -276385,48 +278446,16 @@ function SessionView({ engine, footer, subscribe }) {
276385
278446
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
276386
278447
  dimColor: true,
276387
278448
  wrap: "truncate-end",
276388
- children: pickerOpen ? " ↑↓ to move · Enter to select · Esc to cancel" : engine.turnRunning() ? " Esc to stop · type to queue · scroll to read · Ctrl+C to exit" : " Enter to send · /model to switch model · Esc for live · Ctrl+C to exit"
278449
+ children: pickerOpen ? " ↑↓ to move · Enter to select · Esc to cancel" : cardOpen ? " the agent is waiting on you · answer above, or Esc for later" : pending.length > 0 && !card ? ` ⏸ ${pending[0].title} — Tab to answer · Ctrl+C to exit` : engine.turnRunning() ? " Esc to stop · type to queue · scroll to read · Ctrl+O to expand · Ctrl+C to exit" : " Enter to send · /model to switch model · Esc for live · Ctrl+O to expand · Ctrl+C to exit"
276389
278450
  }, undefined, false, undefined, this)
276390
278451
  ]
276391
278452
  }, undefined, true, undefined, this);
276392
278453
  }
276393
- var LOGO_ROWS = 6;
276394
- var LOGO_GAP_SUBROW = 8;
276395
- var QUAD = " ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█";
276396
- function buildLogoRows() {
276397
- const sy = 2 * LOGO_ROWS;
276398
- const sx = 2 * sy;
276399
- const cx = (sx - 1) / 2;
276400
- const cy = (sy - 1) / 2;
276401
- const rad = sy / 2 - 0.5;
276402
- const on = (px, py) => {
276403
- if (py === LOGO_GAP_SUBROW)
276404
- return false;
276405
- const dx = (px - cx) * 0.5;
276406
- const dy = py - cy;
276407
- return dx * dx + dy * dy <= rad * rad;
276408
- };
276409
- const rows = [];
276410
- for (let ty = 0;ty < sy; ty += 2) {
276411
- let row = "";
276412
- for (let tx = 0;tx < sx; tx += 2) {
276413
- const bits = (on(tx, ty) ? 1 : 0) | (on(tx + 1, ty) ? 2 : 0) | (on(tx, ty + 1) ? 4 : 0) | (on(tx + 1, ty + 1) ? 8 : 0);
276414
- row += QUAD[bits];
276415
- }
276416
- rows.push(row.trim());
276417
- }
276418
- return rows.map((row) => row.trim());
276419
- }
276420
278454
  function renderHeader(who, mode) {
276421
278455
  const orange = source_default.hex(BRAND_ORANGE);
276422
278456
  const cwd = process.cwd().replace(process.env.HOME ?? "", "~");
276423
- const logo = buildLogoRows();
276424
- const logoW = Math.max(...logo.map((r) => r.length));
276425
- const center = (s) => {
276426
- const total = Math.max(0, logoW - s.length);
276427
- const left = Math.floor(total / 2);
276428
- return " ".repeat(left) + s + " ".repeat(total - left);
276429
- };
278457
+ const logo = logoRows(BRAND_ORANGE);
278458
+ const logoW = LOGO_COLS;
276430
278459
  const text = [
276431
278460
  `${orange.bold("Base44 Code")} ${source_default.dim(`v${package_default.version}`)}`,
276432
278461
  source_default.bold(who ? `Welcome back, ${who}!` : "Welcome!"),
@@ -276438,7 +278467,7 @@ function renderHeader(who, mode) {
276438
278467
  const textTop = Math.max(0, Math.floor((logo.length - text.length) / 2));
276439
278468
  const out = [];
276440
278469
  for (let i = 0;i < height; i++) {
276441
- const left = i < logo.length ? orange(center(logo[i])) : " ".repeat(logoW);
278470
+ const left = i < logo.length ? logo[i] : " ".repeat(logoW);
276442
278471
  const right = text[i - textTop] ?? "";
276443
278472
  out.push(` ${left} ${right}`.trimEnd());
276444
278473
  }
@@ -276542,6 +278571,7 @@ async function runGenesisSession(options) {
276542
278571
  runningTool: null,
276543
278572
  lastTurnMs: null,
276544
278573
  lastTurnOk: true,
278574
+ pending: [],
276545
278575
  quietForMs: 0
276546
278576
  };
276547
278577
  const genesis = {
@@ -276597,6 +278627,9 @@ async function runGenesisSession(options) {
276597
278627
  }
276598
278628
  return IDLE_STATUS;
276599
278629
  },
278630
+ answer(p, action, input) {
278631
+ inner?.answer(p, action, input);
278632
+ },
276600
278633
  turnRunning() {
276601
278634
  return inner?.turnRunning() ?? creating;
276602
278635
  }
@@ -276629,10 +278662,10 @@ async function runGenesisSession(options) {
276629
278662
 
276630
278663
  // src/cli/commands/code/index.ts
276631
278664
  var BRAND_ORANGE2 = "#E86B3C";
276632
- async function bootstrapApp(prompt, footer, emit, onCreated, importRepo, path) {
278665
+ async function bootstrapApp(prompt, footer, emit, onCreated, importRepo, path, wixInstance) {
276633
278666
  let app;
276634
278667
  try {
276635
- app = await createAndLinkApp({ prompt, importRepo, path });
278668
+ app = await createAndLinkApp({ prompt, importRepo, path, wixInstance });
276636
278669
  } catch (error) {
276637
278670
  for (const line of await githubReauthLines(error) ?? [])
276638
278671
  emit(line);
@@ -276679,8 +278712,8 @@ async function codeAction({ log }, options, appId) {
276679
278712
  linked = true;
276680
278713
  } catch {}
276681
278714
  if (linked) {
276682
- if (options.import || options.path) {
276683
- throw new InvalidInputError("--import and --path create a new app; run them outside a linked project, without --app-id.");
278715
+ if (options.import || options.path || options.wixInstance) {
278716
+ throw new InvalidInputError("--import, --path and --wix-instance create a new app; run them outside a linked project, without --app-id.");
276684
278717
  }
276685
278718
  const { id, projectRoot } = getAppContext();
276686
278719
  const state = await assertBuilderApp(id);
@@ -276703,16 +278736,25 @@ async function codeAction({ log }, options, appId) {
276703
278736
  outroMessage: `Session closed. Resume with \`base44 code --app-id ${id}\`.`
276704
278737
  };
276705
278738
  }
278739
+ if (options.wixInstance && options.import) {
278740
+ throw new InvalidInputError("--wix-instance and --import are exclusive.");
278741
+ }
278742
+ const wixInstance = options.wixInstance?.trim() ? {
278743
+ signedInstance: options.wixInstance.trim(),
278744
+ wixClientId: options.wixClientId?.trim() || undefined
278745
+ } : undefined;
276706
278746
  let created;
276707
- const footer = [chip(options.import ? repoLabel(options.import) : "web app")];
278747
+ const footer = [
278748
+ chip(options.import ? repoLabel(options.import) : wixInstance ? "web app · wix" : "web app")
278749
+ ];
276708
278750
  await runGenesisSession({
276709
278751
  idleHint: options.import ? "describe what to build over the repository" : "describe the app you want to build · have one already? base44 code --app-id <id>, or base44 link",
276710
278752
  creatingLabel: options.import ? "importing the repository" : "creating your app",
276711
- modeLabel: options.import ? `Repository — ${repoLabel(options.import)}` : "Web app — Base44 template + builder agent",
278753
+ modeLabel: options.import ? `Repository — ${repoLabel(options.import)}` : wixInstance ? "Web app — Wix launch (connector connected first)" : "Web app — Base44 template + builder agent",
276712
278754
  footer,
276713
278755
  createApp: (prompt, emit) => bootstrapApp(prompt, footer, emit, (app) => {
276714
278756
  created = app;
276715
- }, options.import, options.path)
278757
+ }, options.import, options.path, wixInstance)
276716
278758
  });
276717
278759
  if (!created) {
276718
278760
  return { outroMessage: "Session closed. No app was created." };
@@ -276724,616 +278766,10 @@ async function codeAction({ log }, options, appId) {
276724
278766
  }
276725
278767
  function getCodeCommand() {
276726
278768
  const command = new Base44Command("code", { requireAppContext: false });
276727
- command.description("Open Base44 Code, an interactive builder session. In a linked directory (or with --app-id <id>) it opens that app; anywhere else your first prompt creates one (--import <repo> to build over your own repository). Attach a directory to an existing app with base44 link.").option("--import <repo>", "Build over an existing GitHub repository instead of the Base44 template").option("--path <dir>", "Directory to link the new app to (default: the current directory when empty, else ./<name>)").action((ctx, options) => codeAction(ctx, options, command.optsWithGlobals().appId));
278769
+ command.description("Open Base44 Code, an interactive builder session. In a linked directory (or with --app-id <id>) it opens that app; anywhere else your first prompt creates one (--import <repo> to build over your own repository). Attach a directory to an existing app with base44 link.").option("--import <repo>", "Build over an existing GitHub repository instead of the Base44 template").option("--path <dir>", "Directory to link the new app to (default: the current directory when empty, else ./<name>)").option("--wix-instance <token>", "Create the new app through the Wix route with this signed instance (your first prompt is what the agent runs)").option("--wix-client-id <id>", "The companion OAuth app's client id").action((ctx, options) => codeAction(ctx, options, command.optsWithGlobals().appId));
276728
278770
  return command;
276729
278771
  }
276730
278772
 
276731
- // ../../node_modules/open/index.js
276732
- import process30 from "node:process";
276733
- import path16 from "node:path";
276734
- import { fileURLToPath as fileURLToPath4 } from "node:url";
276735
- import childProcess3 from "node:child_process";
276736
- import fs20, { constants as fsConstants2 } from "node:fs/promises";
276737
-
276738
- // ../../node_modules/wsl-utils/index.js
276739
- import { promisify as promisify6 } from "node:util";
276740
- import childProcess2 from "node:child_process";
276741
- import fs19, { constants as fsConstants } from "node:fs/promises";
276742
-
276743
- // ../../node_modules/is-wsl/index.js
276744
- import process24 from "node:process";
276745
- import os4 from "node:os";
276746
- import fs18 from "node:fs";
276747
-
276748
- // ../../node_modules/is-inside-container/index.js
276749
- import fs17 from "node:fs";
276750
-
276751
- // ../../node_modules/is-docker/index.js
276752
- import fs16 from "node:fs";
276753
- var isDockerCached;
276754
- function hasDockerEnv() {
276755
- try {
276756
- fs16.statSync("/.dockerenv");
276757
- return true;
276758
- } catch {
276759
- return false;
276760
- }
276761
- }
276762
- function hasDockerCGroup() {
276763
- try {
276764
- return fs16.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
276765
- } catch {
276766
- return false;
276767
- }
276768
- }
276769
- function isDocker() {
276770
- if (isDockerCached === undefined) {
276771
- isDockerCached = hasDockerEnv() || hasDockerCGroup();
276772
- }
276773
- return isDockerCached;
276774
- }
276775
-
276776
- // ../../node_modules/is-inside-container/index.js
276777
- var cachedResult;
276778
- var hasContainerEnv = () => {
276779
- try {
276780
- fs17.statSync("/run/.containerenv");
276781
- return true;
276782
- } catch {
276783
- return false;
276784
- }
276785
- };
276786
- function isInsideContainer() {
276787
- if (cachedResult === undefined) {
276788
- cachedResult = hasContainerEnv() || isDocker();
276789
- }
276790
- return cachedResult;
276791
- }
276792
-
276793
- // ../../node_modules/is-wsl/index.js
276794
- var isWsl = () => {
276795
- if (process24.platform !== "linux") {
276796
- return false;
276797
- }
276798
- if (os4.release().toLowerCase().includes("microsoft")) {
276799
- if (isInsideContainer()) {
276800
- return false;
276801
- }
276802
- return true;
276803
- }
276804
- try {
276805
- return fs18.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
276806
- } catch {
276807
- return false;
276808
- }
276809
- };
276810
- var is_wsl_default = process24.env.__IS_WSL_TEST__ ? isWsl : isWsl();
276811
-
276812
- // ../../node_modules/powershell-utils/index.js
276813
- import process25 from "node:process";
276814
- import { Buffer as Buffer7 } from "node:buffer";
276815
- import { promisify as promisify5 } from "node:util";
276816
- import childProcess from "node:child_process";
276817
- var execFile = promisify5(childProcess.execFile);
276818
- var powerShellPath = () => `${process25.env.SYSTEMROOT || process25.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
276819
- var executePowerShell = async (command, options = {}) => {
276820
- const {
276821
- powerShellPath: psPath,
276822
- ...execFileOptions
276823
- } = options;
276824
- const encodedCommand = executePowerShell.encodeCommand(command);
276825
- return execFile(psPath ?? powerShellPath(), [
276826
- ...executePowerShell.argumentsPrefix,
276827
- encodedCommand
276828
- ], {
276829
- encoding: "utf8",
276830
- ...execFileOptions
276831
- });
276832
- };
276833
- executePowerShell.argumentsPrefix = [
276834
- "-NoProfile",
276835
- "-NonInteractive",
276836
- "-ExecutionPolicy",
276837
- "Bypass",
276838
- "-EncodedCommand"
276839
- ];
276840
- executePowerShell.encodeCommand = (command) => Buffer7.from(command, "utf16le").toString("base64");
276841
- executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
276842
-
276843
- // ../../node_modules/wsl-utils/utilities.js
276844
- function parseMountPointFromConfig(content) {
276845
- for (const line of content.split(`
276846
- `)) {
276847
- if (/^\s*#/.test(line)) {
276848
- continue;
276849
- }
276850
- const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
276851
- if (!match) {
276852
- continue;
276853
- }
276854
- return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
276855
- }
276856
- }
276857
-
276858
- // ../../node_modules/wsl-utils/index.js
276859
- var execFile2 = promisify6(childProcess2.execFile);
276860
- var wslDrivesMountPoint = (() => {
276861
- const defaultMountPoint = "/mnt/";
276862
- let mountPoint;
276863
- return async function() {
276864
- if (mountPoint) {
276865
- return mountPoint;
276866
- }
276867
- const configFilePath = "/etc/wsl.conf";
276868
- let isConfigFileExists = false;
276869
- try {
276870
- await fs19.access(configFilePath, fsConstants.F_OK);
276871
- isConfigFileExists = true;
276872
- } catch {}
276873
- if (!isConfigFileExists) {
276874
- return defaultMountPoint;
276875
- }
276876
- const configContent = await fs19.readFile(configFilePath, { encoding: "utf8" });
276877
- const parsedMountPoint = parseMountPointFromConfig(configContent);
276878
- if (parsedMountPoint === undefined) {
276879
- return defaultMountPoint;
276880
- }
276881
- mountPoint = parsedMountPoint;
276882
- mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
276883
- return mountPoint;
276884
- };
276885
- })();
276886
- var powerShellPathFromWsl = async () => {
276887
- const mountPoint = await wslDrivesMountPoint();
276888
- return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
276889
- };
276890
- var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
276891
- var canAccessPowerShellPromise;
276892
- var canAccessPowerShell = async () => {
276893
- canAccessPowerShellPromise ??= (async () => {
276894
- try {
276895
- const psPath = await powerShellPath2();
276896
- await fs19.access(psPath, fsConstants.X_OK);
276897
- return true;
276898
- } catch {
276899
- return false;
276900
- }
276901
- })();
276902
- return canAccessPowerShellPromise;
276903
- };
276904
- var wslDefaultBrowser = async () => {
276905
- const psPath = await powerShellPath2();
276906
- const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
276907
- const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
276908
- return stdout.trim();
276909
- };
276910
- var convertWslPathToWindows = async (path) => {
276911
- if (/^[a-z]+:\/\//i.test(path)) {
276912
- return path;
276913
- }
276914
- try {
276915
- const { stdout } = await execFile2("wslpath", ["-aw", path], { encoding: "utf8" });
276916
- return stdout.trim();
276917
- } catch {
276918
- return path;
276919
- }
276920
- };
276921
-
276922
- // ../../node_modules/define-lazy-prop/index.js
276923
- function defineLazyProperty(object, propertyName, valueGetter) {
276924
- const define2 = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
276925
- Object.defineProperty(object, propertyName, {
276926
- configurable: true,
276927
- enumerable: true,
276928
- get() {
276929
- const result = valueGetter();
276930
- define2(result);
276931
- return result;
276932
- },
276933
- set(value) {
276934
- define2(value);
276935
- }
276936
- });
276937
- return object;
276938
- }
276939
-
276940
- // ../../node_modules/default-browser/index.js
276941
- import { promisify as promisify10 } from "node:util";
276942
- import process28 from "node:process";
276943
- import { execFile as execFile6 } from "node:child_process";
276944
-
276945
- // ../../node_modules/default-browser-id/index.js
276946
- import { promisify as promisify7 } from "node:util";
276947
- import process26 from "node:process";
276948
- import { execFile as execFile3 } from "node:child_process";
276949
- var execFileAsync = promisify7(execFile3);
276950
- async function defaultBrowserId() {
276951
- if (process26.platform !== "darwin") {
276952
- throw new Error("macOS only");
276953
- }
276954
- const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
276955
- const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
276956
- const browserId = match?.groups.id ?? "com.apple.Safari";
276957
- if (browserId === "com.apple.safari") {
276958
- return "com.apple.Safari";
276959
- }
276960
- return browserId;
276961
- }
276962
-
276963
- // ../../node_modules/run-applescript/index.js
276964
- import process27 from "node:process";
276965
- import { promisify as promisify8 } from "node:util";
276966
- import { execFile as execFile4, execFileSync } from "node:child_process";
276967
- var execFileAsync2 = promisify8(execFile4);
276968
- async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
276969
- if (process27.platform !== "darwin") {
276970
- throw new Error("macOS only");
276971
- }
276972
- const outputArguments = humanReadableOutput ? [] : ["-ss"];
276973
- const execOptions = {};
276974
- if (signal) {
276975
- execOptions.signal = signal;
276976
- }
276977
- const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
276978
- return stdout.trim();
276979
- }
276980
-
276981
- // ../../node_modules/bundle-name/index.js
276982
- async function bundleName(bundleId) {
276983
- return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
276984
- tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
276985
- }
276986
-
276987
- // ../../node_modules/default-browser/windows.js
276988
- import { promisify as promisify9 } from "node:util";
276989
- import { execFile as execFile5 } from "node:child_process";
276990
- var execFileAsync3 = promisify9(execFile5);
276991
- var windowsBrowserProgIds = {
276992
- MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
276993
- MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
276994
- MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
276995
- AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
276996
- ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
276997
- ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
276998
- ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
276999
- ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
277000
- BraveHTML: { name: "Brave", id: "com.brave.Browser" },
277001
- BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
277002
- BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
277003
- BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
277004
- FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
277005
- OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
277006
- VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
277007
- "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
277008
- };
277009
- var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
277010
-
277011
- class UnknownBrowserError extends Error {
277012
- }
277013
- async function defaultBrowser(_execFileAsync = execFileAsync3) {
277014
- const { stdout } = await _execFileAsync("reg", [
277015
- "QUERY",
277016
- " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
277017
- "/v",
277018
- "ProgId"
277019
- ]);
277020
- const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
277021
- if (!match) {
277022
- throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
277023
- }
277024
- const { id } = match.groups;
277025
- const dotIndex = id.lastIndexOf(".");
277026
- const hyphenIndex = id.lastIndexOf("-");
277027
- const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
277028
- const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
277029
- return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
277030
- }
277031
-
277032
- // ../../node_modules/default-browser/index.js
277033
- var execFileAsync4 = promisify10(execFile6);
277034
- var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
277035
- async function defaultBrowser2() {
277036
- if (process28.platform === "darwin") {
277037
- const id = await defaultBrowserId();
277038
- const name = await bundleName(id);
277039
- return { name, id };
277040
- }
277041
- if (process28.platform === "linux") {
277042
- const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
277043
- const id = stdout.trim();
277044
- const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
277045
- return { name, id };
277046
- }
277047
- if (process28.platform === "win32") {
277048
- return defaultBrowser();
277049
- }
277050
- throw new Error("Only macOS, Linux, and Windows are supported");
277051
- }
277052
-
277053
- // ../../node_modules/is-in-ssh/index.js
277054
- import process29 from "node:process";
277055
- var isInSsh = Boolean(process29.env.SSH_CONNECTION || process29.env.SSH_CLIENT || process29.env.SSH_TTY);
277056
- var is_in_ssh_default = isInSsh;
277057
-
277058
- // ../../node_modules/open/index.js
277059
- var fallbackAttemptSymbol = Symbol("fallbackAttempt");
277060
- var __dirname2 = import.meta.url ? path16.dirname(fileURLToPath4(import.meta.url)) : "";
277061
- var localXdgOpenPath = path16.join(__dirname2, "xdg-open");
277062
- var { platform: platform7, arch } = process30;
277063
- var tryEachApp = async (apps, opener) => {
277064
- if (apps.length === 0) {
277065
- return;
277066
- }
277067
- const errors = [];
277068
- for (const app of apps) {
277069
- try {
277070
- return await opener(app);
277071
- } catch (error) {
277072
- errors.push(error);
277073
- }
277074
- }
277075
- throw new AggregateError(errors, "Failed to open in all supported apps");
277076
- };
277077
- var baseOpen = async (options) => {
277078
- options = {
277079
- wait: false,
277080
- background: false,
277081
- newInstance: false,
277082
- allowNonzeroExitCode: false,
277083
- ...options
277084
- };
277085
- const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
277086
- delete options[fallbackAttemptSymbol];
277087
- if (Array.isArray(options.app)) {
277088
- return tryEachApp(options.app, (singleApp) => baseOpen({
277089
- ...options,
277090
- app: singleApp,
277091
- [fallbackAttemptSymbol]: true
277092
- }));
277093
- }
277094
- let { name: app, arguments: appArguments = [] } = options.app ?? {};
277095
- appArguments = [...appArguments];
277096
- if (Array.isArray(app)) {
277097
- return tryEachApp(app, (appName) => baseOpen({
277098
- ...options,
277099
- app: {
277100
- name: appName,
277101
- arguments: appArguments
277102
- },
277103
- [fallbackAttemptSymbol]: true
277104
- }));
277105
- }
277106
- if (app === "browser" || app === "browserPrivate") {
277107
- const ids = {
277108
- "com.google.chrome": "chrome",
277109
- "google-chrome.desktop": "chrome",
277110
- "com.brave.browser": "brave",
277111
- "org.mozilla.firefox": "firefox",
277112
- "firefox.desktop": "firefox",
277113
- "com.microsoft.msedge": "edge",
277114
- "com.microsoft.edge": "edge",
277115
- "com.microsoft.edgemac": "edge",
277116
- "microsoft-edge.desktop": "edge",
277117
- "com.apple.safari": "safari"
277118
- };
277119
- const flags = {
277120
- chrome: "--incognito",
277121
- brave: "--incognito",
277122
- firefox: "--private-window",
277123
- edge: "--inPrivate"
277124
- };
277125
- let browser;
277126
- if (is_wsl_default) {
277127
- const progId = await wslDefaultBrowser();
277128
- const browserInfo = _windowsBrowserProgIdMap.get(progId);
277129
- browser = browserInfo ?? {};
277130
- } else {
277131
- browser = await defaultBrowser2();
277132
- }
277133
- if (browser.id in ids) {
277134
- const browserName = ids[browser.id.toLowerCase()];
277135
- if (app === "browserPrivate") {
277136
- if (browserName === "safari") {
277137
- throw new Error("Safari doesn't support opening in private mode via command line");
277138
- }
277139
- appArguments.push(flags[browserName]);
277140
- }
277141
- return baseOpen({
277142
- ...options,
277143
- app: {
277144
- name: apps[browserName],
277145
- arguments: appArguments
277146
- }
277147
- });
277148
- }
277149
- throw new Error(`${browser.name} is not supported as a default browser`);
277150
- }
277151
- let command;
277152
- const cliArguments = [];
277153
- const childProcessOptions = {};
277154
- let shouldUseWindowsInWsl = false;
277155
- if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
277156
- shouldUseWindowsInWsl = await canAccessPowerShell();
277157
- }
277158
- if (platform7 === "darwin") {
277159
- command = "open";
277160
- if (options.wait) {
277161
- cliArguments.push("--wait-apps");
277162
- }
277163
- if (options.background) {
277164
- cliArguments.push("--background");
277165
- }
277166
- if (options.newInstance) {
277167
- cliArguments.push("--new");
277168
- }
277169
- if (app) {
277170
- cliArguments.push("-a", app);
277171
- }
277172
- } else if (platform7 === "win32" || shouldUseWindowsInWsl) {
277173
- command = await powerShellPath2();
277174
- cliArguments.push(...executePowerShell.argumentsPrefix);
277175
- if (!is_wsl_default) {
277176
- childProcessOptions.windowsVerbatimArguments = true;
277177
- }
277178
- if (is_wsl_default && options.target) {
277179
- options.target = await convertWslPathToWindows(options.target);
277180
- }
277181
- const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
277182
- if (options.wait) {
277183
- encodedArguments.push("-Wait");
277184
- }
277185
- if (app) {
277186
- encodedArguments.push(executePowerShell.escapeArgument(app));
277187
- if (options.target) {
277188
- appArguments.push(options.target);
277189
- }
277190
- } else if (options.target) {
277191
- encodedArguments.push(executePowerShell.escapeArgument(options.target));
277192
- }
277193
- if (appArguments.length > 0) {
277194
- appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
277195
- encodedArguments.push("-ArgumentList", appArguments.join(","));
277196
- }
277197
- options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
277198
- if (!options.wait) {
277199
- childProcessOptions.stdio = "ignore";
277200
- }
277201
- } else {
277202
- if (app) {
277203
- command = app;
277204
- } else {
277205
- const isBundled = !__dirname2 || __dirname2 === "/";
277206
- let exeLocalXdgOpen = false;
277207
- try {
277208
- await fs20.access(localXdgOpenPath, fsConstants2.X_OK);
277209
- exeLocalXdgOpen = true;
277210
- } catch {}
277211
- const useSystemXdgOpen = process30.versions.electron ?? (platform7 === "android" || isBundled || !exeLocalXdgOpen);
277212
- command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
277213
- }
277214
- if (appArguments.length > 0) {
277215
- cliArguments.push(...appArguments);
277216
- }
277217
- if (!options.wait) {
277218
- childProcessOptions.stdio = "ignore";
277219
- childProcessOptions.detached = true;
277220
- }
277221
- }
277222
- if (platform7 === "darwin" && appArguments.length > 0) {
277223
- cliArguments.push("--args", ...appArguments);
277224
- }
277225
- if (options.target) {
277226
- cliArguments.push(options.target);
277227
- }
277228
- const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
277229
- if (options.wait) {
277230
- return new Promise((resolve, reject) => {
277231
- subprocess.once("error", reject);
277232
- subprocess.once("close", (exitCode) => {
277233
- if (!options.allowNonzeroExitCode && exitCode !== 0) {
277234
- reject(new Error(`Exited with code ${exitCode}`));
277235
- return;
277236
- }
277237
- resolve(subprocess);
277238
- });
277239
- });
277240
- }
277241
- if (isFallbackAttempt) {
277242
- return new Promise((resolve, reject) => {
277243
- subprocess.once("error", reject);
277244
- subprocess.once("spawn", () => {
277245
- subprocess.once("close", (exitCode) => {
277246
- subprocess.off("error", reject);
277247
- if (exitCode !== 0) {
277248
- reject(new Error(`Exited with code ${exitCode}`));
277249
- return;
277250
- }
277251
- subprocess.unref();
277252
- resolve(subprocess);
277253
- });
277254
- });
277255
- });
277256
- }
277257
- subprocess.unref();
277258
- return new Promise((resolve, reject) => {
277259
- subprocess.once("error", reject);
277260
- subprocess.once("spawn", () => {
277261
- subprocess.off("error", reject);
277262
- resolve(subprocess);
277263
- });
277264
- });
277265
- };
277266
- var open = (target, options) => {
277267
- if (typeof target !== "string") {
277268
- throw new TypeError("Expected a `target`");
277269
- }
277270
- return baseOpen({
277271
- ...options,
277272
- target
277273
- });
277274
- };
277275
- function detectArchBinary(binary) {
277276
- if (typeof binary === "string" || Array.isArray(binary)) {
277277
- return binary;
277278
- }
277279
- const { [arch]: archBinary } = binary;
277280
- if (!archBinary) {
277281
- throw new Error(`${arch} is not supported`);
277282
- }
277283
- return archBinary;
277284
- }
277285
- function detectPlatformBinary({ [platform7]: platformBinary }, { wsl } = {}) {
277286
- if (wsl && is_wsl_default) {
277287
- return detectArchBinary(wsl);
277288
- }
277289
- if (!platformBinary) {
277290
- throw new Error(`${platform7} is not supported`);
277291
- }
277292
- return detectArchBinary(platformBinary);
277293
- }
277294
- var apps = {
277295
- browser: "browser",
277296
- browserPrivate: "browserPrivate"
277297
- };
277298
- defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
277299
- darwin: "google chrome",
277300
- win32: "chrome",
277301
- linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
277302
- }, {
277303
- wsl: {
277304
- ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
277305
- x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
277306
- }
277307
- }));
277308
- defineLazyProperty(apps, "brave", () => detectPlatformBinary({
277309
- darwin: "brave browser",
277310
- win32: "brave",
277311
- linux: ["brave-browser", "brave"]
277312
- }, {
277313
- wsl: {
277314
- ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
277315
- x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
277316
- }
277317
- }));
277318
- defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
277319
- darwin: "firefox",
277320
- win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
277321
- linux: "firefox"
277322
- }, {
277323
- wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
277324
- }));
277325
- defineLazyProperty(apps, "edge", () => detectPlatformBinary({
277326
- darwin: "microsoft edge",
277327
- win32: "msedge",
277328
- linux: ["microsoft-edge", "microsoft-edge-dev"]
277329
- }, {
277330
- wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
277331
- }));
277332
- defineLazyProperty(apps, "safari", () => detectPlatformBinary({
277333
- darwin: "Safari"
277334
- }));
277335
- var open_default = open;
277336
-
277337
278773
  // src/cli/commands/connectors/oauth-prompt.ts
277338
278774
  var POLL_INTERVAL_MS = 2000;
277339
278775
  var POLL_TIMEOUT_MS2 = 2 * 60 * 1000;
@@ -279101,7 +280537,7 @@ async function callTool(appId, tool, payload, schema, context, timeout = 60000)
279101
280537
  function listDirectory(appId, params) {
279102
280538
  return callTool(appId, "list_directory", { ...params }, ListDirectoryResponseSchema, "listing directory");
279103
280539
  }
279104
- function readFile4(appId, params) {
280540
+ function readFile5(appId, params) {
279105
280541
  return callTool(appId, "read_file", { ...params }, ReadFileResponseSchema, "reading file");
279106
280542
  }
279107
280543
  function writeFile3(appId, params) {
@@ -279256,7 +280692,7 @@ async function readFileAction({ runTask, branchId }, paths, options) {
279256
280692
  const { id: appId } = getAppContext();
279257
280693
  const offset = parsePositiveInt(options.offset, "--offset");
279258
280694
  const limit = parsePositiveInt(options.limit, "--limit");
279259
- const result = await runTask("Reading file", () => readFile4(appId, { paths, offset, limit, branch_id: branchId }));
280695
+ const result = await runTask("Reading file", () => readFile5(appId, { paths, offset, limit, branch_id: branchId }));
279260
280696
  return { outroMessage: "Read file", stdout: toJsonStdout(result) };
279261
280697
  }
279262
280698
  function getSandboxReadFileCommand() {
@@ -284107,7 +285543,7 @@ async function runScript(options) {
284107
285543
  }
284108
285544
  }
284109
285545
  // src/cli/commands/exec.ts
284110
- function readStdin2() {
285546
+ function readStdin4() {
284111
285547
  return new Promise((resolve, reject) => {
284112
285548
  let data = "";
284113
285549
  process.stdin.setEncoding("utf-8");
@@ -284151,7 +285587,7 @@ async function execAction({ app, isNonInteractive }, options) {
284151
285587
  if (!isNonInteractive) {
284152
285588
  throw noInputError;
284153
285589
  }
284154
- const code = await readStdin2();
285590
+ const code = await readStdin4();
284155
285591
  if (!code.trim()) {
284156
285592
  throw noInputError;
284157
285593
  }
@@ -288332,6 +289768,13 @@ function getFullCommandName(command) {
288332
289768
  }
288333
289769
  return parts.join(" ");
288334
289770
  }
289771
+ var SENSITIVE_OPTION = /secret|token|password|launch|instance|key$/i;
289772
+ function redactSensitiveOptions(options) {
289773
+ return Object.fromEntries(Object.entries(options).map(([k, v]) => [
289774
+ k,
289775
+ SENSITIVE_OPTION.test(k) && v != null && v !== false ? "[redacted]" : v
289776
+ ]));
289777
+ }
288335
289778
  function addCommandInfoToErrorReporter(program, errorReporter) {
288336
289779
  program.hook("preAction", (_, actionCommand) => {
288337
289780
  const fullCommandName = getFullCommandName(actionCommand);
@@ -288339,7 +289782,7 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
288339
289782
  command: {
288340
289783
  name: fullCommandName,
288341
289784
  args: actionCommand.args,
288342
- options: actionCommand.opts()
289785
+ options: redactSensitiveOptions(actionCommand.opts())
288343
289786
  }
288344
289787
  });
288345
289788
  });
@@ -288386,4 +289829,4 @@ export {
288386
289829
  runCLI
288387
289830
  };
288388
289831
 
288389
- //# debugId=DDB3983E5E326EC264756E2164756E21
289832
+ //# debugId=C0EA00D7CF91E50E64756E2164756E21