@base44-preview/cli 0.1.15-pr.630.68db200 → 0.1.15-pr.630.80e82e8

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
  } }));
@@ -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 {
@@ -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
  }
@@ -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 {
@@ -270461,7 +270598,15 @@ async function createAndLinkApp(options) {
270461
270598
  if (await appConfigExists(targetDir)) {
270462
270599
  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
270600
  }
270464
- const created = options.importRepo ? await createImportedApp({
270601
+ let clientCreationId;
270602
+ const created = options.wixInstance ? await createWixLaunchedApp({
270603
+ prompt: options.prompt ?? "",
270604
+ signedInstance: options.wixInstance.signedInstance,
270605
+ wixClientId: options.wixInstance.wixClientId
270606
+ }).then((c) => {
270607
+ clientCreationId = c.client_creation_id;
270608
+ return c;
270609
+ }) : options.importRepo ? await createImportedApp({
270465
270610
  appName: name,
270466
270611
  repoUrl: options.importRepo,
270467
270612
  sourceMode: options.mode ?? "direct",
@@ -270485,7 +270630,8 @@ async function createAndLinkApp(options) {
270485
270630
  repoUrl: created.imported_repo_url ?? undefined,
270486
270631
  dirName,
270487
270632
  targetDir,
270488
- here
270633
+ here,
270634
+ ...clientCreationId ? { clientCreationId } : {}
270489
270635
  };
270490
270636
  }
270491
270637
  function repoLabel(url) {
@@ -270547,12 +270693,27 @@ function newStreamState() {
270547
270693
  return { perMessage: new Map };
270548
270694
  }
270549
270695
  var TOOL_SETTLED = new Set(["success", "error", "stopped"]);
270696
+ function fullText(value) {
270697
+ if (typeof value === "string")
270698
+ return value.trimEnd();
270699
+ if (value == null)
270700
+ return "";
270701
+ return JSON.stringify(value);
270702
+ }
270703
+ function toolArgs(argumentsString) {
270704
+ try {
270705
+ const parsed = JSON.parse(argumentsString ?? "");
270706
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
270707
+ } catch {
270708
+ return null;
270709
+ }
270710
+ }
270550
270711
  function oneLine(value, max) {
270551
270712
  const text = typeof value === "string" ? value : value == null ? "" : JSON.stringify(value);
270552
270713
  const flat = text.replace(/\s+/g, " ").trim();
270553
270714
  return flat.length > max ? `${flat.slice(0, max)}…` : flat;
270554
270715
  }
270555
- var SALIENT_KEYS = ["command", "path", "file_path", "title"];
270716
+ var SALIENT_KEYS = ["command", "path", "file_path", "title", "find"];
270556
270717
  function salvageKey(raw, keys) {
270557
270718
  for (const key of keys) {
270558
270719
  const match = raw.match(new RegExp(`"${key}"\\s*:\\s*"((?:[^"\\\\]|\\\\.)*)"`));
@@ -270581,6 +270742,10 @@ function toolMeta(name, argumentsString) {
270581
270742
  read_repo_file: pick("path") ?? pick("file_path"),
270582
270743
  write_repo_file: pick("path") ?? pick("file_path"),
270583
270744
  edit_repo_file: pick("path") ?? pick("file_path"),
270745
+ read_file: pick("file_path") ?? pick("path"),
270746
+ write_file: pick("file_path") ?? pick("path"),
270747
+ find_replace: pick("file_path") ?? pick("path"),
270748
+ delete_file: pick("file_path") ?? pick("path"),
270584
270749
  create_pull_request: pick("title"),
270585
270750
  reload_preview: ""
270586
270751
  };
@@ -270631,7 +270796,10 @@ function diffConversation(state, messages) {
270631
270796
  }
270632
270797
  for (const tool of message.tool_calls ?? []) {
270633
270798
  if (!progress.announcedTools.has(tool.id)) {
270634
- progress.announcedTools.set(tool.id, toolMeta(tool.name, tool.arguments_string));
270799
+ progress.announcedTools.set(tool.id, {
270800
+ ...toolMeta(tool.name, tool.arguments_string),
270801
+ args: toolArgs(tool.arguments_string)
270802
+ });
270635
270803
  const meta = progress.announcedTools.get(tool.id);
270636
270804
  events.push({
270637
270805
  kind: "tool_start",
@@ -270662,7 +270830,8 @@ function diffConversation(state, messages) {
270662
270830
  label: labelTense(meta.label, "done"),
270663
270831
  summary: meta.summary,
270664
270832
  ok: status === "success",
270665
- result: oneLine(tool.results, 110)
270833
+ result: fullText(tool.results),
270834
+ args: meta.args
270666
270835
  });
270667
270836
  }
270668
270837
  }
@@ -270736,9 +270905,90 @@ async function streamConversationUntilSettled(onEvent, options = {}) {
270736
270905
  return "timeout";
270737
270906
  }
270738
270907
 
270908
+ // src/cli/commands/builder/send.ts
270909
+ function lastAssistantReply(turn) {
270910
+ const messages = turn.conversation?.messages ?? [];
270911
+ for (let i = messages.length - 1;i >= 0; i--) {
270912
+ const { role, content } = messages[i];
270913
+ if (role === "assistant" && typeof content === "string" && content.trim()) {
270914
+ return content.trim();
270915
+ }
270916
+ }
270917
+ return;
270918
+ }
270919
+ function ndjsonWriter() {
270920
+ return (record) => process.stdout.write(`${JSON.stringify(record)}
270921
+ `);
270922
+ }
270923
+ async function sendAction(ctx, message, options) {
270924
+ if (options.streamJson && ctx.jsonMode) {
270925
+ throw new InvalidInputError("--stream-json and --json are exclusive.");
270926
+ }
270927
+ if (ctx.app)
270928
+ await assertBuilderApp(ctx.app.id);
270929
+ const branchId = await resolveBranchId(ctx);
270930
+ if (options.streamJson) {
270931
+ const write = ndjsonWriter();
270932
+ const turn = await streamConversationDuring(() => sendTurn(message, branchId), ({ kind, ...event }) => write({ type: kind, ...event }), { branchId });
270933
+ write({
270934
+ type: "result",
270935
+ queued: turn.queued === true,
270936
+ status: turn.status?.state ?? "ready",
270937
+ error_source: turn.status?.error_source ?? null,
270938
+ reply: lastAssistantReply(turn) ?? null
270939
+ });
270940
+ return {};
270941
+ }
270942
+ if (ctx.jsonMode) {
270943
+ const turn = await ctx.runTask("Agent working (a turn can take minutes)", () => sendTurn(message, branchId));
270944
+ if (turn.queued)
270945
+ return { stdout: `${JSON.stringify({ queued: true })}
270946
+ ` };
270947
+ return {
270948
+ stdout: `${JSON.stringify({
270949
+ status: turn.status?.state ?? "ready",
270950
+ error_source: turn.status?.error_source ?? null,
270951
+ reply: lastAssistantReply(turn) ?? null
270952
+ })}
270953
+ `
270954
+ };
270955
+ }
270956
+ const stream = createTurnStream(process.stdout.isTTY === true, undefined, {
270957
+ verbose: options.verbose
270958
+ });
270959
+ let turn;
270960
+ try {
270961
+ turn = await streamConversationDuring(() => sendTurn(message, branchId), stream.onEvent, { branchId });
270962
+ } finally {
270963
+ stream.stop();
270964
+ }
270965
+ if (turn.queued) {
270966
+ return {
270967
+ outroMessage: "The agent is busy with an earlier message — yours was queued and runs next."
270968
+ };
270969
+ }
270970
+ if (turn.status?.state === "error") {
270971
+ return {
270972
+ outroMessage: `Turn failed (${turn.status.error_source ?? "unknown"}) — see the editor for details.`
270973
+ };
270974
+ }
270975
+ return { outroMessage: "Turn finished." };
270976
+ }
270977
+ function getSendCommand() {
270978
+ const command = new Base44Command("send", { supportsBranch: true });
270979
+ command.description("Send the agent one message and stream the turn until it finishes").argument("<message>", "What you want the agent to do").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);
270980
+ return command;
270981
+ }
270982
+
270739
270983
  // src/cli/commands/builder/new.ts
270740
270984
  var POLL_TIMEOUT_MS = 20 * 60000;
270741
270985
  var MODES = ["direct", "fork", "copy"];
270986
+ async function readStdin2() {
270987
+ const chunks = [];
270988
+ for await (const chunk of process.stdin)
270989
+ chunks.push(chunk);
270990
+ return Buffer.concat(chunks).toString("utf8");
270991
+ }
270742
270992
  async function newAction({ log, runTask, jsonMode }, prompt, options) {
270743
270993
  if (options.mode && !MODES.includes(options.mode)) {
270744
270994
  throw new InvalidInputError("--mode must be direct, fork, or copy.");
@@ -270746,9 +270996,27 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270746
270996
  if ((options.mode || options.repoName || options.fromBranch) && !options.import) {
270747
270997
  throw new InvalidInputError("--mode, --repo-name and --from-branch apply only with --import <repo>.");
270748
270998
  }
270999
+ if (options.wixInstance && options.import) {
271000
+ throw new InvalidInputError("--wix-instance and --import are exclusive.");
271001
+ }
271002
+ if (options.wixClientId && !options.wixInstance) {
271003
+ throw new InvalidInputError("--wix-client-id applies only with --wix-instance.");
271004
+ }
271005
+ const signedInstance = options.wixInstance ? (options.wixInstance === "-" ? await readStdin2() : options.wixInstance).trim() : undefined;
271006
+ if (options.wixInstance && !signedInstance) {
271007
+ throw new InvalidInputError("--wix-instance is empty.");
271008
+ }
271009
+ const wixInstance = signedInstance ? { signedInstance, wixClientId: options.wixClientId?.trim() || undefined } : undefined;
271010
+ if (wixInstance && !prompt) {
271011
+ throw new InvalidInputError("--wix-instance needs the prompt argument: what the agent should build.");
271012
+ }
270749
271013
  if (!prompt && !options.import) {
270750
271014
  throw new InvalidInputError('Describe the app ("<prompt>") or pass --import <repo>.');
270751
271015
  }
271016
+ if (options.streamJson && jsonMode) {
271017
+ throw new InvalidInputError("--stream-json and --json are exclusive.");
271018
+ }
271019
+ const ndjson = options.streamJson ? ndjsonWriter() : null;
270752
271020
  let app;
270753
271021
  try {
270754
271022
  app = await runTask(options.import ? "Importing the repository" : "Creating your app", () => createAndLinkApp({
@@ -270758,16 +271026,30 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270758
271026
  mode: options.mode,
270759
271027
  repoName: options.repoName,
270760
271028
  fromBranch: options.fromBranch,
270761
- path: options.path
271029
+ path: options.path,
271030
+ wixInstance
270762
271031
  }));
270763
271032
  } catch (error) {
270764
271033
  for (const line of await githubReauthLines(error) ?? [])
270765
271034
  log.message(line);
270766
271035
  throw error;
270767
271036
  }
270768
- if (!jsonMode) {
271037
+ if (ndjson) {
271038
+ ndjson({
271039
+ type: "created",
271040
+ id: app.id,
271041
+ repo_url: app.repoUrl ?? null,
271042
+ editor_url: app.editorUrl,
271043
+ dir: app.dirName,
271044
+ path: app.targetDir,
271045
+ ...app.clientCreationId ? { client_creation_id: app.clientCreationId } : {}
271046
+ });
271047
+ } else if (!jsonMode) {
270769
271048
  if (app.repoUrl)
270770
271049
  log.message(source_default.dim(`repo ${app.repoUrl}`));
271050
+ if (app.clientCreationId) {
271051
+ log.message(source_default.dim("wix launched — connector connected before the first turn"));
271052
+ }
270771
271053
  log.message(source_default.dim(`editor ${app.editorUrl}`));
270772
271054
  log.message(source_default.dim(`linked ${app.here ? "./ (this directory)" : `./${app.dirName}`}`));
270773
271055
  }
@@ -270778,10 +271060,16 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270778
271060
  const branchId = await resolveActiveBranchId().catch(() => {
270779
271061
  return;
270780
271062
  });
270781
- const stream = createTurnStream(process.stdout.isTTY === true && !jsonMode, undefined, { idleLabel: "provisioning the sandbox and starting the build" });
271063
+ const stream = createTurnStream(process.stdout.isTTY === true && !jsonMode && !ndjson, undefined, {
271064
+ idleLabel: "provisioning the sandbox and starting the build",
271065
+ verbose: options.verbose
271066
+ });
270782
271067
  try {
270783
271068
  const settled = await streamConversationUntilSettled((event) => {
270784
- if (!jsonMode)
271069
+ if (ndjson) {
271070
+ const { kind, ...rest } = event;
271071
+ ndjson({ type: kind, ...rest });
271072
+ } else if (!jsonMode)
270785
271073
  stream.onEvent(event);
270786
271074
  }, { branchId, timeoutMs: POLL_TIMEOUT_MS });
270787
271075
  finalState = settled === "timeout" ? "processing" : (await getAppState(app.id)).status?.state ?? "ready";
@@ -270794,6 +271082,15 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270794
271082
  stream.stop();
270795
271083
  }
270796
271084
  }
271085
+ if (ndjson) {
271086
+ ndjson({
271087
+ type: "result",
271088
+ id: app.id,
271089
+ preview_url: previewUrl ?? null,
271090
+ status: finalState ?? "created"
271091
+ });
271092
+ return {};
271093
+ }
270797
271094
  if (jsonMode) {
270798
271095
  return {
270799
271096
  stdout: `${JSON.stringify({
@@ -270803,7 +271100,8 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270803
271100
  preview_url: previewUrl ?? null,
270804
271101
  dir: app.dirName,
270805
271102
  path: app.targetDir,
270806
- status: finalState ?? "created"
271103
+ status: finalState ?? "created",
271104
+ ...app.clientCreationId ? { client_creation_id: app.clientCreationId } : {}
270807
271105
  })}
270808
271106
  `
270809
271107
  };
@@ -270828,61 +271126,7 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270828
271126
  }
270829
271127
  function getNewCommand() {
270830
271128
  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);
271129
+ 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("--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
271130
  return command;
270887
271131
  }
270888
271132
 
@@ -275891,6 +276135,119 @@ var build_default = TextInput;
275891
276135
  // src/cli/commands/code/session.tsx
275892
276136
  var import_react23 = __toESM(require_react(), 1);
275893
276137
 
276138
+ // src/cli/commands/code/logo.ts
276139
+ var ROWS = 6;
276140
+ var ASPECT = 0.44;
276141
+ var SAMPLES = 4;
276142
+ var FILL = 0.6;
276143
+ var GAP_ROW = 3.5 + 0.5;
276144
+ var GAP_HEIGHT_ROWS = 0.8;
276145
+ var LOGO_COLS = Math.max(2, Math.floor(ROWS / ASPECT + 0.5));
276146
+ var OCTANT = {
276147
+ rx: 2,
276148
+ ry: 4,
276149
+ 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█")
276150
+ };
276151
+ var QUAD = {
276152
+ rx: 2,
276153
+ ry: 2,
276154
+ table: Array.from(" ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█")
276155
+ };
276156
+ function detectTier(env = process.env) {
276157
+ const term = env.TERM ?? "";
276158
+ const prog = env.TERM_PROGRAM ?? "";
276159
+ if (prog === "ghostty" || term.includes("ghostty"))
276160
+ return "octant";
276161
+ if (env.KITTY_WINDOW_ID || term.includes("kitty"))
276162
+ return "octant";
276163
+ if (env.WEZTERM_PANE || env.WEZTERM_EXECUTABLE)
276164
+ return "octant";
276165
+ if (term.startsWith("foot") || prog === "contour")
276166
+ return "octant";
276167
+ return "quad";
276168
+ }
276169
+ function coverageGrid(rows, cols, aspect, pixelH) {
276170
+ const worldH = rows * pixelH;
276171
+ const worldW = cols * aspect;
276172
+ const radius = Math.min(worldH, worldW) / 2;
276173
+ const cx = worldW / 2;
276174
+ const cy = worldH / 2;
276175
+ const step = 1 / SAMPLES;
276176
+ const grid = [];
276177
+ for (let py = 0;py < rows; py++) {
276178
+ const y0 = py * pixelH;
276179
+ const y1 = y0 + pixelH;
276180
+ const dyLo = y0 <= cy && cy <= y1 ? 0 : Math.min(Math.abs(y0 - cy), Math.abs(y1 - cy));
276181
+ const dyHi = Math.max(Math.abs(y0 - cy), Math.abs(y1 - cy));
276182
+ const line = [];
276183
+ for (let px = 0;px < cols; px++) {
276184
+ const x0 = px * aspect;
276185
+ const x1 = x0 + aspect;
276186
+ const dxLo = x0 <= cx && cx <= x1 ? 0 : Math.min(Math.abs(x0 - cx), Math.abs(x1 - cx));
276187
+ const dxHi = Math.max(Math.abs(x0 - cx), Math.abs(x1 - cx));
276188
+ if (Math.hypot(dxLo, dyLo) >= radius) {
276189
+ line.push(0);
276190
+ continue;
276191
+ }
276192
+ if (Math.hypot(dxHi, dyHi) <= radius) {
276193
+ line.push(1);
276194
+ continue;
276195
+ }
276196
+ let hits = 0;
276197
+ for (let j = 0;j < SAMPLES; j++) {
276198
+ const dy = y0 + (j + 0.5) * step * pixelH - cy;
276199
+ for (let i = 0;i < SAMPLES; i++) {
276200
+ const dx = x0 + (i + 0.5) * step * aspect - cx;
276201
+ if (Math.hypot(dx, dy) <= radius)
276202
+ hits++;
276203
+ }
276204
+ }
276205
+ line.push(hits / (SAMPLES * SAMPLES));
276206
+ }
276207
+ grid.push(line);
276208
+ }
276209
+ return grid;
276210
+ }
276211
+ function carveGap(grid, ry) {
276212
+ const n = grid.length;
276213
+ const thick = Math.max(1, Math.round(GAP_HEIGHT_ROWS * ry));
276214
+ const centre = GAP_ROW >= 0 ? GAP_ROW * ry : n + GAP_ROW * ry;
276215
+ const start = Math.max(0, Math.min(n - thick, centre - thick / 2));
276216
+ for (let i = Math.trunc(start);i < Math.trunc(start + thick); i++) {
276217
+ grid[i].fill(0);
276218
+ }
276219
+ }
276220
+ function logoRows(color, tier = detectTier()) {
276221
+ const { rx, ry, table } = tier === "octant" ? OCTANT : QUAD;
276222
+ const grid = coverageGrid(ROWS * ry, LOGO_COLS * rx, ASPECT / rx, 1 / ry);
276223
+ carveGap(grid, ry);
276224
+ const fg = color ? source_default.hex(color) : (s) => s;
276225
+ const bg = color ? source_default.bgHex(color) : (s) => s;
276226
+ const full = (1 << rx * ry) - 1;
276227
+ const out = [];
276228
+ for (let r = 0;r < ROWS; r++) {
276229
+ let row = "";
276230
+ for (let c = 0;c < LOGO_COLS; c++) {
276231
+ let mask = 0;
276232
+ for (let sr = 0;sr < ry; sr++) {
276233
+ for (let sc = 0;sc < rx; sc++) {
276234
+ if (grid[r * ry + sr][c * rx + sc] >= FILL)
276235
+ mask |= 1 << sr * rx + sc;
276236
+ }
276237
+ }
276238
+ const glyph = table[mask];
276239
+ if (glyph === " ")
276240
+ row += " ";
276241
+ else if (mask === full && color)
276242
+ row += bg(" ");
276243
+ else
276244
+ row += fg(glyph);
276245
+ }
276246
+ out.push(row);
276247
+ }
276248
+ return out;
276249
+ }
276250
+
275894
276251
  // src/cli/commands/code/paste.ts
275895
276252
  import { PassThrough as PassThrough3 } from "node:stream";
275896
276253
  var START = "\x1B[200~";
@@ -275964,6 +276321,393 @@ function createPasteFriendlyStdin(real) {
275964
276321
  return proxy;
275965
276322
  }
275966
276323
 
276324
+ // src/core/resources/apps/pending.ts
276325
+ var CHOICE_TOOLS = new Set([
276326
+ "ask_clarifying_questions",
276327
+ "ask_plan_questions"
276328
+ ]);
276329
+ var SECRET_TOOLS = new Set(["set_secrets"]);
276330
+ var PERMISSION_TOOLS = new Set(["request_agent_tool_permissions"]);
276331
+ var BROWSER_TOOLS = new Set([
276332
+ "connect_github_account",
276333
+ "request_oauth_authorization",
276334
+ "register_workspace_connector",
276335
+ "configure_psp_credentials",
276336
+ "plaid_connect"
276337
+ ]);
276338
+ var str2 = (v) => typeof v === "string" && v.trim() ? v.trim() : undefined;
276339
+ function parseArgs(raw) {
276340
+ try {
276341
+ const parsed = JSON.parse(raw ?? "");
276342
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
276343
+ } catch {
276344
+ return {};
276345
+ }
276346
+ }
276347
+ function questionsFrom(args) {
276348
+ const raw = Array.isArray(args.questions) ? args.questions : [];
276349
+ return raw.flatMap((q) => {
276350
+ if (!q || typeof q !== "object")
276351
+ return [];
276352
+ const item = q;
276353
+ const question = str2(item.question);
276354
+ if (!question)
276355
+ return [];
276356
+ const options = (Array.isArray(item.options) ? item.options : []).flatMap((o) => {
276357
+ const opt = o;
276358
+ const label = str2(opt?.label);
276359
+ return label ? [{ label, description: str2(opt.description) }] : [];
276360
+ });
276361
+ return [
276362
+ {
276363
+ question,
276364
+ description: str2(item.description),
276365
+ options,
276366
+ multiSelect: item.multi_select === true
276367
+ }
276368
+ ];
276369
+ });
276370
+ }
276371
+ function secretsFrom(args) {
276372
+ const raw = Array.isArray(args.secrets_schema) ? args.secrets_schema : [];
276373
+ return raw.flatMap((s) => {
276374
+ const item = s;
276375
+ const name = str2(item?.secretName) ?? str2(item?.name);
276376
+ return name ? [{ name, description: str2(item.description) }] : [];
276377
+ });
276378
+ }
276379
+ function permissionKey(row) {
276380
+ switch (row.type) {
276381
+ case "entity":
276382
+ return row.entity_name ? `entity:${row.entity_name}` : null;
276383
+ case "backend_function":
276384
+ return row.function_name ? `backend_function:${row.function_name}` : null;
276385
+ case "app_user_connector":
276386
+ return row.connector_id ? `app_user_connector:${row.connector_id}` : null;
276387
+ default:
276388
+ return null;
276389
+ }
276390
+ }
276391
+ function permissionsFrom(args) {
276392
+ const raw = Array.isArray(args.requested_permissions) ? args.requested_permissions : [];
276393
+ return raw.flatMap((r) => {
276394
+ const row = r;
276395
+ const key = permissionKey(row);
276396
+ if (!key)
276397
+ return [];
276398
+ const ops = Array.isArray(row.allowed_operations) ? ` (${row.allowed_operations.join(", ")})` : "";
276399
+ const target = str2(row.entity_name) ?? str2(row.function_name) ?? str2(row.connector_name) ?? key;
276400
+ return [
276401
+ { key, label: `${row.type}: ${target}${ops}`, reason: str2(row.reason) }
276402
+ ];
276403
+ });
276404
+ }
276405
+ function guardFrom(results) {
276406
+ const value = typeof results === "string" ? (() => {
276407
+ try {
276408
+ return JSON.parse(results);
276409
+ } catch {
276410
+ return null;
276411
+ }
276412
+ })() : results;
276413
+ if (!value || typeof value !== "object")
276414
+ return null;
276415
+ const g = value;
276416
+ if (!str2(g.guard))
276417
+ return null;
276418
+ return { title: `${g.guard}: needs your approval`, detail: str2(g.reason) };
276419
+ }
276420
+ function humanize(tool) {
276421
+ return tool.replace(/_/g, " ");
276422
+ }
276423
+ function pendingInputs(messages) {
276424
+ const out = [];
276425
+ for (const message of messages) {
276426
+ for (const call of message.tool_calls ?? []) {
276427
+ if (call.status !== "waiting_for_user_input")
276428
+ continue;
276429
+ const args = parseArgs(call.arguments_string);
276430
+ const base = {
276431
+ toolCallId: call.id,
276432
+ messageId: message.id,
276433
+ tool: call.name
276434
+ };
276435
+ const summary = str2(args.summary);
276436
+ if (CHOICE_TOOLS.has(call.name)) {
276437
+ out.push({
276438
+ ...base,
276439
+ kind: "choice",
276440
+ title: summary ?? "The agent has a few questions",
276441
+ questions: questionsFrom(args)
276442
+ });
276443
+ } else if (SECRET_TOOLS.has(call.name)) {
276444
+ out.push({
276445
+ ...base,
276446
+ kind: "secrets",
276447
+ title: summary ?? "The agent needs secrets",
276448
+ secrets: secretsFrom(args)
276449
+ });
276450
+ } else if (PERMISSION_TOOLS.has(call.name)) {
276451
+ out.push({
276452
+ ...base,
276453
+ kind: "permissions",
276454
+ title: summary ?? "Grant the app's agent these permissions?",
276455
+ detail: str2(args.reason),
276456
+ permissions: permissionsFrom(args)
276457
+ });
276458
+ } else if (BROWSER_TOOLS.has(call.name)) {
276459
+ out.push({
276460
+ ...base,
276461
+ kind: "browser",
276462
+ title: summary ?? humanize(call.name),
276463
+ detail: str2(args.reason)
276464
+ });
276465
+ } else {
276466
+ const guard = guardFrom(call.results);
276467
+ const integration = str2(args.integration_type);
276468
+ out.push({
276469
+ ...base,
276470
+ kind: "approval",
276471
+ title: guard?.title ?? (integration ? `Enable ${integration}?` : summary ?? `${humanize(call.name)}?`),
276472
+ detail: guard?.detail ?? (integration ? summary : undefined)
276473
+ });
276474
+ }
276475
+ }
276476
+ }
276477
+ return out;
276478
+ }
276479
+ function choiceAnswers(questions, selections) {
276480
+ const answers = questions.flatMap((q, index) => {
276481
+ const sel = selections[index];
276482
+ if (!sel || sel.labels.length === 0 && !sel.customText)
276483
+ return [];
276484
+ const answer = { question_index: index };
276485
+ if (q.multiSelect) {
276486
+ if (sel.labels.length)
276487
+ answer.selected_labels = sel.labels;
276488
+ } else if (sel.labels[0]) {
276489
+ answer.selected_label = sel.labels[0];
276490
+ }
276491
+ if (sel.customText)
276492
+ answer.custom_text = sel.customText;
276493
+ return [answer];
276494
+ });
276495
+ return { answers };
276496
+ }
276497
+
276498
+ // src/cli/commands/code/pending-card.ts
276499
+ function openCard(pending) {
276500
+ return {
276501
+ pending,
276502
+ step: 0,
276503
+ cursor: 0,
276504
+ selections: (pending.questions ?? []).map(() => ({ labels: [] })),
276505
+ granted: new Set((pending.permissions ?? []).map((p) => p.key)),
276506
+ typing: pending.kind === "secrets" ? "secret" : null,
276507
+ secretValues: {}
276508
+ };
276509
+ }
276510
+ var done = (action, input = {}) => ({ state: null, submit: { action, input } });
276511
+ var later = { state: null, dismissed: true };
276512
+ function choiceRows(state) {
276513
+ return (state.pending.questions?.[state.step]?.options.length ?? 0) + 1;
276514
+ }
276515
+ function advanceChoice(state) {
276516
+ const questions = state.pending.questions ?? [];
276517
+ if (state.step + 1 < questions.length) {
276518
+ return {
276519
+ state: { ...state, step: state.step + 1, cursor: 0, typing: null }
276520
+ };
276521
+ }
276522
+ return done("approved", choiceAnswers(questions, state.selections));
276523
+ }
276524
+ function choiceKey(state, key) {
276525
+ const question = state.pending.questions?.[state.step];
276526
+ if (!question)
276527
+ return done("approved", { answers: [] });
276528
+ const rows = choiceRows(state);
276529
+ const custom = state.cursor === rows - 1;
276530
+ const sel = state.selections[state.step] ?? { labels: [] };
276531
+ const setSel = (next) => {
276532
+ const selections = [...state.selections];
276533
+ selections[state.step] = next;
276534
+ return { ...state, selections };
276535
+ };
276536
+ switch (key) {
276537
+ case "up":
276538
+ return { state: { ...state, cursor: (state.cursor - 1 + rows) % rows } };
276539
+ case "down":
276540
+ return { state: { ...state, cursor: (state.cursor + 1) % rows } };
276541
+ case "space": {
276542
+ if (custom)
276543
+ return { state: { ...state, typing: "custom" } };
276544
+ const label = question.options[state.cursor].label;
276545
+ const labels = question.multiSelect ? sel.labels.includes(label) ? sel.labels.filter((l) => l !== label) : [...sel.labels, label] : [label];
276546
+ return { state: setSel({ ...sel, labels }) };
276547
+ }
276548
+ case "enter": {
276549
+ if (custom)
276550
+ return { state: { ...state, typing: "custom" } };
276551
+ if (question.multiSelect) {
276552
+ if (sel.labels.length === 0 && !sel.customText)
276553
+ return { state };
276554
+ return advanceChoice(state);
276555
+ }
276556
+ const label = question.options[state.cursor].label;
276557
+ return advanceChoice(setSel({ labels: [label] }));
276558
+ }
276559
+ case "s":
276560
+ return done("approved", { answers: [] });
276561
+ case "escape":
276562
+ return later;
276563
+ default:
276564
+ return { state };
276565
+ }
276566
+ }
276567
+ function permissionsKey(state, key) {
276568
+ const rows = state.pending.permissions ?? [];
276569
+ switch (key) {
276570
+ case "up":
276571
+ return {
276572
+ state: {
276573
+ ...state,
276574
+ cursor: (state.cursor - 1 + rows.length) % rows.length
276575
+ }
276576
+ };
276577
+ case "down":
276578
+ return { state: { ...state, cursor: (state.cursor + 1) % rows.length } };
276579
+ case "space": {
276580
+ const k = rows[state.cursor]?.key;
276581
+ if (!k)
276582
+ return { state };
276583
+ const granted = new Set(state.granted);
276584
+ if (granted.has(k))
276585
+ granted.delete(k);
276586
+ else
276587
+ granted.add(k);
276588
+ return { state: { ...state, granted } };
276589
+ }
276590
+ case "enter":
276591
+ case "y":
276592
+ return done("approved", {
276593
+ approved_permission_keys: rows.map((r) => r.key).filter((k) => state.granted.has(k))
276594
+ });
276595
+ case "n":
276596
+ return done("rejected");
276597
+ case "escape":
276598
+ return later;
276599
+ default:
276600
+ return { state };
276601
+ }
276602
+ }
276603
+ function cardKey(state, key) {
276604
+ if (state.typing) {
276605
+ if (key === "escape") {
276606
+ return state.typing === "secret" ? later : { state: { ...state, typing: null } };
276607
+ }
276608
+ return { state };
276609
+ }
276610
+ switch (state.pending.kind) {
276611
+ case "choice":
276612
+ return choiceKey(state, key);
276613
+ case "permissions":
276614
+ return permissionsKey(state, key);
276615
+ default:
276616
+ if (key === "y" || key === "enter")
276617
+ return done("approved");
276618
+ if (key === "n")
276619
+ return done("rejected");
276620
+ if (key === "escape")
276621
+ return later;
276622
+ return { state };
276623
+ }
276624
+ }
276625
+ function cardText(state, text) {
276626
+ const value = text.trim();
276627
+ if (state.typing === "custom") {
276628
+ if (!value)
276629
+ return { state: { ...state, typing: null } };
276630
+ const selections = [...state.selections];
276631
+ const current = selections[state.step] ?? { labels: [] };
276632
+ selections[state.step] = { ...current, customText: value };
276633
+ return advanceChoice({ ...state, selections, typing: null });
276634
+ }
276635
+ if (state.typing === "secret") {
276636
+ const fields = state.pending.secrets ?? [];
276637
+ const field = fields[state.step];
276638
+ if (!field || !value)
276639
+ return { state };
276640
+ const secretValues = { ...state.secretValues, [field.name]: value };
276641
+ if (state.step + 1 < fields.length) {
276642
+ return { state: { ...state, secretValues, step: state.step + 1 } };
276643
+ }
276644
+ return done("approved", { secrets: secretValues });
276645
+ }
276646
+ return { state };
276647
+ }
276648
+ function cardLines(state) {
276649
+ const p = state.pending;
276650
+ const head = [source_default.bold(`⏸ ${p.title}`)];
276651
+ if (p.detail)
276652
+ head.push(source_default.dim(` ${p.detail}`));
276653
+ switch (p.kind) {
276654
+ case "choice": {
276655
+ const q = p.questions?.[state.step];
276656
+ if (!q)
276657
+ return [...head, source_default.dim(" (no questions) · Enter to continue")];
276658
+ const total = p.questions?.length ?? 1;
276659
+ const sel = state.selections[state.step] ?? { labels: [] };
276660
+ const rows = q.options.map((o, i) => {
276661
+ const on = sel.labels.includes(o.label);
276662
+ const mark = q.multiSelect ? on ? "☑" : "☐" : on ? "●" : "○";
276663
+ const text = `${state.cursor === i ? "▸" : " "} ${mark} ${o.label}${o.description ? source_default.dim(` — ${o.description}`) : ""}`;
276664
+ return state.cursor === i ? source_default.cyan(text) : text;
276665
+ });
276666
+ const customRow = `${state.cursor === q.options.length ? "▸" : " "} ✎ something else${sel.customText ? source_default.dim(` — ${sel.customText}`) : ""}`;
276667
+ rows.push(state.cursor === q.options.length ? source_default.cyan(customRow) : customRow);
276668
+ return [
276669
+ ...head,
276670
+ ` ${source_default.bold(q.question)} ${source_default.dim(`(${state.step + 1}/${total})`)}`,
276671
+ ...q.description ? [source_default.dim(` ${q.description}`)] : [],
276672
+ ...rows.map((r) => ` ${r}`),
276673
+ source_default.dim(q.multiSelect ? " ↑↓ move · space toggle · Enter next · s skip all · Esc later" : " ↑↓ move · Enter choose · s skip all · Esc later")
276674
+ ];
276675
+ }
276676
+ case "permissions": {
276677
+ const rows = (p.permissions ?? []).map((r, i) => {
276678
+ const text = `${state.cursor === i ? "▸" : " "} ${state.granted.has(r.key) ? "☑" : "☐"} ${r.label}${r.reason ? source_default.dim(` — ${r.reason}`) : ""}`;
276679
+ return ` ${state.cursor === i ? source_default.cyan(text) : text}`;
276680
+ });
276681
+ return [
276682
+ ...head,
276683
+ ...rows,
276684
+ source_default.dim(" space toggle · Enter grant ticked · n reject all · Esc later")
276685
+ ];
276686
+ }
276687
+ case "secrets": {
276688
+ const fields = p.secrets ?? [];
276689
+ const rows = fields.map((f, i) => {
276690
+ const filled = f.name in state.secretValues;
276691
+ const mark = filled ? source_default.green("✓") : i === state.step ? "▸" : "○";
276692
+ return ` ${mark} ${f.name}${f.description ? source_default.dim(` — ${f.description}`) : ""}`;
276693
+ });
276694
+ return [
276695
+ ...head,
276696
+ ...rows,
276697
+ source_default.dim(" type the value below (hidden) · Enter next · Esc later")
276698
+ ];
276699
+ }
276700
+ case "browser":
276701
+ return [
276702
+ ...head,
276703
+ source_default.dim(" finish this step in the editor (footer link), then press y"),
276704
+ source_default.dim(" y continue · n reject · Esc later")
276705
+ ];
276706
+ default:
276707
+ return [...head, source_default.dim(" y approve · n reject · Esc later")];
276708
+ }
276709
+ }
276710
+
275967
276711
  // src/cli/commands/code/session-engine.ts
275968
276712
  var POLL_MS = 1000;
275969
276713
  function createSessionEngine(options) {
@@ -275983,6 +276727,28 @@ function createSessionEngine(options) {
275983
276727
  let awaitingTurn = options.awaitingTurnLabel ?? null;
275984
276728
  const awaitingSince = Date.now();
275985
276729
  let lastEventAt = Date.now();
276730
+ let pending = [];
276731
+ const answered = new Set;
276732
+ const answer = (p, action, input = {}) => {
276733
+ answered.add(p.toolCallId);
276734
+ pending = pending.filter((x) => x.toolCallId !== p.toolCallId);
276735
+ const verb = action === "rejected" ? source_default.red("✗ rejected") : Object.keys(input).length ? source_default.green("→ answered") : source_default.green("✓ approved");
276736
+ options.onLine(`${verb} ${source_default.dim("—")} ${p.title}`);
276737
+ pendingSubmitAt = Date.now();
276738
+ sendsInFlight++;
276739
+ answerToolCall({ toolCallId: p.toolCallId, messageId: p.messageId, action, input }, options.branchId).catch((error) => {
276740
+ const status = error instanceof ApiError ? error.statusCode : undefined;
276741
+ const edgeDrop = status === 502 || status === 503 || status === 504 || /timeout|gateway/i.test(error instanceof Error ? error.message : "");
276742
+ if (edgeDrop && (turnStartedAt != null || pendingSubmitAt == null)) {
276743
+ return;
276744
+ }
276745
+ answered.delete(p.toolCallId);
276746
+ pendingSubmitAt = null;
276747
+ options.onLine(source_default.red(`✗ answer failed: ${error instanceof Error ? error.message : String(error)}`));
276748
+ }).finally(() => {
276749
+ sendsInFlight--;
276750
+ });
276751
+ };
275986
276752
  const submit = (raw) => {
275987
276753
  const typed = raw.trim();
275988
276754
  if (!typed)
@@ -276023,25 +276789,38 @@ function createSessionEngine(options) {
276023
276789
  return;
276024
276790
  }
276025
276791
  const events = diffConversation(diffState, messages);
276792
+ const waiting = pendingInputs(messages);
276793
+ for (const id of answered) {
276794
+ if (!waiting.some((w) => w.toolCallId === id))
276795
+ answered.delete(id);
276796
+ }
276797
+ pending = waiting.filter((w) => !answered.has(w.toolCallId));
276026
276798
  if (!prime) {
276027
276799
  for (const event of events) {
276028
276800
  if (event.kind === "tool_start") {
276801
+ const startedAt = Date.now();
276029
276802
  running.set(event.id, {
276030
276803
  alias: toolAlias(event.name),
276031
276804
  label: event.label,
276032
276805
  summary: event.summary,
276033
- startedAt: Date.now()
276806
+ startedAt
276034
276807
  });
276808
+ options.onLine({ running: event, startedAt });
276035
276809
  continue;
276036
276810
  }
276037
- let elapsedMs;
276038
276811
  if (event.kind === "tool_end") {
276039
276812
  const started = running.get(event.id)?.startedAt;
276040
- if (started != null)
276041
- elapsedMs = Date.now() - started;
276042
276813
  running.delete(event.id);
276814
+ lastEventAt = Date.now();
276815
+ options.onLine({
276816
+ event,
276817
+ elapsedMs: started != null ? Date.now() - started : undefined
276818
+ });
276819
+ continue;
276043
276820
  }
276044
- const line = eventLine(event, elapsedMs);
276821
+ const line = eventLine(event, undefined, {
276822
+ waitingHint: "answer in the card below"
276823
+ });
276045
276824
  if (line != null) {
276046
276825
  lastEventAt = Date.now();
276047
276826
  options.onLine(line);
@@ -276108,6 +276887,7 @@ function createSessionEngine(options) {
276108
276887
  });
276109
276888
  },
276110
276889
  submit,
276890
+ answer,
276111
276891
  status() {
276112
276892
  let phase = "idle";
276113
276893
  if (awaitingTurn != null)
@@ -276130,7 +276910,8 @@ function createSessionEngine(options) {
276130
276910
  turnStartedAt,
276131
276911
  runningTool,
276132
276912
  lastTurnMs,
276133
- lastTurnOk
276913
+ lastTurnOk,
276914
+ pending
276134
276915
  };
276135
276916
  },
276136
276917
  turnRunning() {
@@ -276162,6 +276943,17 @@ function exitAltScreen() {
276162
276943
  altScreenActive = false;
276163
276944
  process.stdout.write("\x1B[?1007l\x1B[?1049l");
276164
276945
  }
276946
+ function withEntry(items, entry) {
276947
+ if (typeof entry !== "string" && "event" in entry) {
276948
+ const i = items.findIndex((e) => typeof e !== "string" && ("running" in e) && e.running.id === entry.event.id);
276949
+ if (i >= 0) {
276950
+ const next = [...items];
276951
+ next[i] = entry;
276952
+ return next;
276953
+ }
276954
+ }
276955
+ return [...items, entry];
276956
+ }
276165
276957
  function statusText(status, musingSeed) {
276166
276958
  const frame = FRAMES2[Math.floor(Date.now() / 120) % FRAMES2.length];
276167
276959
  switch (status.phase) {
@@ -276169,15 +276961,8 @@ function statusText(status, musingSeed) {
276169
276961
  return source_default.dim(`${frame} ${status.awaitingLabel} (${formatDuration2(Date.now() - status.awaitingSince)})`);
276170
276962
  case "running": {
276171
276963
  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
276964
  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}`)}`;
276965
+ return `${source_default.magenta(shimmer())} ${source_default.dim(`${idleMusing(musingSeed)} (${turnFor})${quiet}`)}`;
276181
276966
  }
276182
276967
  case "sending":
276183
276968
  return source_default.dim(`${frame} sending…`);
@@ -276191,18 +276976,19 @@ function statusText(status, musingSeed) {
276191
276976
  function SessionView({ engine, footer, subscribe }) {
276192
276977
  const { exit } = use_app_default();
276193
276978
  const [items, setItems] = import_react23.useState([]);
276979
+ const [verbose, setVerbose] = import_react23.useState(false);
276194
276980
  const [input, setInput] = import_react23.useState("");
276195
276981
  const [scroll, setScroll] = import_react23.useState(0);
276196
276982
  const [, tick] = import_react23.useReducer((x) => x + 1, 0);
276197
276983
  const [musingSeed] = import_react23.useState(() => Math.floor(Math.random() * 97));
276198
276984
  const [currentModel, setCurrentModel] = import_react23.useState(null);
276199
276985
  const [pickerIndex, setPickerIndex] = import_react23.useState(null);
276986
+ const [card, setCard] = import_react23.useState(null);
276987
+ const dismissedRef = import_react23.useRef(new Set);
276200
276988
  const maxScrollRef = import_react23.useRef(0);
276201
276989
  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]);
276990
+ const emit = (entry) => setItems((h) => withEntry(h, entry));
276991
+ import_react23.useEffect(() => subscribe((entry) => setItems((h) => withEntry(h, entry))), [subscribe]);
276206
276992
  import_react23.useEffect(() => {
276207
276993
  const timer = setInterval(tick, 120);
276208
276994
  return () => clearInterval(timer);
@@ -276244,6 +277030,29 @@ function SessionView({ engine, footer, subscribe }) {
276244
277030
  emit(source_default.red(` /model: ${error instanceof Error ? error.message : String(error)}`));
276245
277031
  }
276246
277032
  };
277033
+ const applyCard = (outcome) => {
277034
+ if (outcome.submit && card) {
277035
+ engine.answer(card.pending, outcome.submit.action, outcome.submit.input);
277036
+ }
277037
+ if (outcome.dismissed && card) {
277038
+ dismissedRef.current.add(card.pending.toolCallId);
277039
+ }
277040
+ setCard(outcome.state);
277041
+ };
277042
+ const pending = engine.status().pending;
277043
+ import_react23.useEffect(() => {
277044
+ if (card) {
277045
+ if (!pending.some((p) => p.toolCallId === card.pending.toolCallId)) {
277046
+ setCard(null);
277047
+ }
277048
+ return;
277049
+ }
277050
+ if (pickerIndex !== null)
277051
+ return;
277052
+ const next = pending.find((p) => !dismissedRef.current.has(p.toolCallId));
277053
+ if (next)
277054
+ setCard(openCard(next));
277055
+ }, [pending, card, pickerIndex]);
276247
277056
  use_input_default((char, key) => {
276248
277057
  if (pickerIndex !== null) {
276249
277058
  if (key.upArrow)
@@ -276259,6 +277068,23 @@ function SessionView({ engine, footer, subscribe }) {
276259
277068
  }
276260
277069
  return;
276261
277070
  }
277071
+ if (key.tab && !card) {
277072
+ const next = pending.find((p) => dismissedRef.current.has(p.toolCallId));
277073
+ if (next) {
277074
+ dismissedRef.current.delete(next.toolCallId);
277075
+ setCard(openCard(next));
277076
+ }
277077
+ return;
277078
+ }
277079
+ if (card) {
277080
+ const mapped = key.upArrow ? "up" : key.downArrow ? "down" : key.return ? "enter" : key.escape ? "escape" : char === " " ? "space" : char === "y" || char === "n" || char === "s" ? char : null;
277081
+ if (card.typing && mapped !== "escape")
277082
+ return;
277083
+ if (mapped)
277084
+ applyCard(cardKey(card, mapped));
277085
+ if (mapped || !card.typing)
277086
+ return;
277087
+ }
276262
277088
  if (key.ctrl && char === "c") {
276263
277089
  if (input)
276264
277090
  setInput("");
@@ -276270,6 +277096,10 @@ function SessionView({ engine, footer, subscribe }) {
276270
277096
  exit();
276271
277097
  return;
276272
277098
  }
277099
+ if (key.ctrl && char === "o") {
277100
+ setVerbose((v) => !v);
277101
+ return;
277102
+ }
276273
277103
  if (key.upArrow) {
276274
277104
  setScroll((s) => Math.min(s + 3, maxScrollRef.current));
276275
277105
  return;
@@ -276295,14 +277125,17 @@ function SessionView({ engine, footer, subscribe }) {
276295
277125
  });
276296
277126
  const columns = process.stdout.columns || 80;
276297
277127
  const rows = process.stdout.rows || 24;
276298
- const width = Math.min(columns, 100);
277128
+ const width = columns;
276299
277129
  const innerWidth = Math.max(10, width - 4);
276300
277130
  const inputRows = Math.max(1, Math.ceil((input.length + 3) / innerWidth));
276301
277131
  const pickerOpen = pickerIndex !== null;
276302
- const inputBlockHeight = pickerOpen ? MODELS.length + 3 : inputRows + 2;
277132
+ const cardOpen = card !== null && !card.typing;
277133
+ const cardRows = card ? cardLines(card).length : 0;
277134
+ const inputBlockHeight = pickerOpen ? MODELS.length + 3 : cardOpen ? cardRows + 2 : inputRows + 2 + (card?.typing ? 1 : 0);
276303
277135
  const widgetHeight = inputBlockHeight + 3 + (footer.length ? 1 : 0);
276304
277136
  const viewHeight = Math.max(3, rows - widgetHeight - 1);
276305
- const lines = items.flatMap((item) => hardWrapAnsi(item, columns));
277137
+ const lines = items.flatMap((item) => hardWrapAnsi(`${renderEntry(item, { verbose, foldHint: "Ctrl+O to expand" })}
277138
+ `, columns));
276306
277139
  const maxScroll = Math.max(0, lines.length - viewHeight);
276307
277140
  maxScrollRef.current = maxScroll;
276308
277141
  const clamped = Math.min(scroll, maxScroll);
@@ -276349,29 +277182,64 @@ function SessionView({ engine, footer, subscribe }) {
276349
277182
  }, m.name, false, undefined, this);
276350
277183
  })
276351
277184
  ]
276352
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
277185
+ }, undefined, true, undefined, this) : cardOpen && card ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
277186
+ flexDirection: "column",
277187
+ borderStyle: "round",
277188
+ borderColor: "yellow",
277189
+ paddingX: 1,
277190
+ width,
277191
+ children: cardLines(card).map((line, i) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
277192
+ wrap: "truncate-end",
277193
+ children: line
277194
+ }, i, false, undefined, this))
277195
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
277196
+ flexDirection: "column",
276353
277197
  borderStyle: "round",
276354
- borderColor: "gray",
277198
+ borderColor: card?.typing ? "yellow" : "gray",
276355
277199
  paddingX: 1,
276356
277200
  width,
276357
277201
  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)
277202
+ card?.typing === "secret" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
277203
+ wrap: "truncate-end",
277204
+ children: [
277205
+ source_default.bold(card.pending.secrets?.[card.step]?.name ?? "secret"),
277206
+ source_default.dim(" — value is hidden · Enter to save · Esc to cancel")
277207
+ ]
277208
+ }, undefined, true, undefined, this),
277209
+ card?.typing === "custom" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
277210
+ wrap: "truncate-end",
277211
+ children: [
277212
+ source_default.bold(card.pending.questions?.[card.step]?.question ?? ""),
277213
+ source_default.dim(" — your own answer · Enter to save · Esc to go back")
277214
+ ]
277215
+ }, undefined, true, undefined, this),
277216
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
277217
+ children: [
277218
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
277219
+ color: "cyan",
277220
+ children: "❯ "
277221
+ }, undefined, false, undefined, this),
277222
+ /* @__PURE__ */ jsx_dev_runtime.jsxDEV(build_default, {
277223
+ value: input,
277224
+ onChange: setInput,
277225
+ mask: card?.typing === "secret" ? "•" : undefined,
277226
+ onSubmit: (value) => {
277227
+ if (card?.typing) {
277228
+ applyCard(cardText(card, value));
277229
+ setInput("");
277230
+ return;
277231
+ }
277232
+ const trimmed = value.trim();
277233
+ if (trimmed === "/model" || trimmed.startsWith("/model ")) {
277234
+ runModelSlash(trimmed.slice("/model".length).trim());
277235
+ } else if (trimmed) {
277236
+ engine.submit(value);
277237
+ }
277238
+ setInput("");
277239
+ }
277240
+ }, undefined, false, undefined, this)
277241
+ ]
277242
+ }, undefined, true, undefined, this)
276375
277243
  ]
276376
277244
  }, undefined, true, undefined, this),
276377
277245
  footer.length > 0 && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
@@ -276385,48 +277253,16 @@ function SessionView({ engine, footer, subscribe }) {
276385
277253
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
276386
277254
  dimColor: true,
276387
277255
  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"
277256
+ 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
277257
  }, undefined, false, undefined, this)
276390
277258
  ]
276391
277259
  }, undefined, true, undefined, this);
276392
277260
  }
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
277261
  function renderHeader(who, mode) {
276421
277262
  const orange = source_default.hex(BRAND_ORANGE);
276422
277263
  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
- };
277264
+ const logo = logoRows(BRAND_ORANGE);
277265
+ const logoW = LOGO_COLS;
276430
277266
  const text = [
276431
277267
  `${orange.bold("Base44 Code")} ${source_default.dim(`v${package_default.version}`)}`,
276432
277268
  source_default.bold(who ? `Welcome back, ${who}!` : "Welcome!"),
@@ -276438,7 +277274,7 @@ function renderHeader(who, mode) {
276438
277274
  const textTop = Math.max(0, Math.floor((logo.length - text.length) / 2));
276439
277275
  const out = [];
276440
277276
  for (let i = 0;i < height; i++) {
276441
- const left = i < logo.length ? orange(center(logo[i])) : " ".repeat(logoW);
277277
+ const left = i < logo.length ? logo[i] : " ".repeat(logoW);
276442
277278
  const right = text[i - textTop] ?? "";
276443
277279
  out.push(` ${left} ${right}`.trimEnd());
276444
277280
  }
@@ -276542,6 +277378,7 @@ async function runGenesisSession(options) {
276542
277378
  runningTool: null,
276543
277379
  lastTurnMs: null,
276544
277380
  lastTurnOk: true,
277381
+ pending: [],
276545
277382
  quietForMs: 0
276546
277383
  };
276547
277384
  const genesis = {
@@ -276597,6 +277434,9 @@ async function runGenesisSession(options) {
276597
277434
  }
276598
277435
  return IDLE_STATUS;
276599
277436
  },
277437
+ answer(p, action, input) {
277438
+ inner?.answer(p, action, input);
277439
+ },
276600
277440
  turnRunning() {
276601
277441
  return inner?.turnRunning() ?? creating;
276602
277442
  }
@@ -276629,10 +277469,10 @@ async function runGenesisSession(options) {
276629
277469
 
276630
277470
  // src/cli/commands/code/index.ts
276631
277471
  var BRAND_ORANGE2 = "#E86B3C";
276632
- async function bootstrapApp(prompt, footer, emit, onCreated, importRepo, path) {
277472
+ async function bootstrapApp(prompt, footer, emit, onCreated, importRepo, path, wixInstance) {
276633
277473
  let app;
276634
277474
  try {
276635
- app = await createAndLinkApp({ prompt, importRepo, path });
277475
+ app = await createAndLinkApp({ prompt, importRepo, path, wixInstance });
276636
277476
  } catch (error) {
276637
277477
  for (const line of await githubReauthLines(error) ?? [])
276638
277478
  emit(line);
@@ -276679,8 +277519,8 @@ async function codeAction({ log }, options, appId) {
276679
277519
  linked = true;
276680
277520
  } catch {}
276681
277521
  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.");
277522
+ if (options.import || options.path || options.wixInstance) {
277523
+ throw new InvalidInputError("--import, --path and --wix-instance create a new app; run them outside a linked project, without --app-id.");
276684
277524
  }
276685
277525
  const { id, projectRoot } = getAppContext();
276686
277526
  const state = await assertBuilderApp(id);
@@ -276703,16 +277543,25 @@ async function codeAction({ log }, options, appId) {
276703
277543
  outroMessage: `Session closed. Resume with \`base44 code --app-id ${id}\`.`
276704
277544
  };
276705
277545
  }
277546
+ if (options.wixInstance && options.import) {
277547
+ throw new InvalidInputError("--wix-instance and --import are exclusive.");
277548
+ }
277549
+ const wixInstance = options.wixInstance?.trim() ? {
277550
+ signedInstance: options.wixInstance.trim(),
277551
+ wixClientId: options.wixClientId?.trim() || undefined
277552
+ } : undefined;
276706
277553
  let created;
276707
- const footer = [chip(options.import ? repoLabel(options.import) : "web app")];
277554
+ const footer = [
277555
+ chip(options.import ? repoLabel(options.import) : wixInstance ? "web app · wix" : "web app")
277556
+ ];
276708
277557
  await runGenesisSession({
276709
277558
  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
277559
  creatingLabel: options.import ? "importing the repository" : "creating your app",
276711
- modeLabel: options.import ? `Repository — ${repoLabel(options.import)}` : "Web app — Base44 template + builder agent",
277560
+ modeLabel: options.import ? `Repository — ${repoLabel(options.import)}` : wixInstance ? "Web app — Wix launch (connector connected first)" : "Web app — Base44 template + builder agent",
276712
277561
  footer,
276713
277562
  createApp: (prompt, emit) => bootstrapApp(prompt, footer, emit, (app) => {
276714
277563
  created = app;
276715
- }, options.import, options.path)
277564
+ }, options.import, options.path, wixInstance)
276716
277565
  });
276717
277566
  if (!created) {
276718
277567
  return { outroMessage: "Session closed. No app was created." };
@@ -276724,7 +277573,7 @@ async function codeAction({ log }, options, appId) {
276724
277573
  }
276725
277574
  function getCodeCommand() {
276726
277575
  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));
277576
+ 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
277577
  return command;
276729
277578
  }
276730
277579
 
@@ -284107,7 +284956,7 @@ async function runScript(options) {
284107
284956
  }
284108
284957
  }
284109
284958
  // src/cli/commands/exec.ts
284110
- function readStdin2() {
284959
+ function readStdin3() {
284111
284960
  return new Promise((resolve, reject) => {
284112
284961
  let data = "";
284113
284962
  process.stdin.setEncoding("utf-8");
@@ -284151,7 +285000,7 @@ async function execAction({ app, isNonInteractive }, options) {
284151
285000
  if (!isNonInteractive) {
284152
285001
  throw noInputError;
284153
285002
  }
284154
- const code = await readStdin2();
285003
+ const code = await readStdin3();
284155
285004
  if (!code.trim()) {
284156
285005
  throw noInputError;
284157
285006
  }
@@ -288332,6 +289181,13 @@ function getFullCommandName(command) {
288332
289181
  }
288333
289182
  return parts.join(" ");
288334
289183
  }
289184
+ var SENSITIVE_OPTION = /secret|token|password|launch|instance|key$/i;
289185
+ function redactSensitiveOptions(options) {
289186
+ return Object.fromEntries(Object.entries(options).map(([k, v]) => [
289187
+ k,
289188
+ SENSITIVE_OPTION.test(k) && v != null && v !== false ? "[redacted]" : v
289189
+ ]));
289190
+ }
288335
289191
  function addCommandInfoToErrorReporter(program, errorReporter) {
288336
289192
  program.hook("preAction", (_, actionCommand) => {
288337
289193
  const fullCommandName = getFullCommandName(actionCommand);
@@ -288339,7 +289195,7 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
288339
289195
  command: {
288340
289196
  name: fullCommandName,
288341
289197
  args: actionCommand.args,
288342
- options: actionCommand.opts()
289198
+ options: redactSensitiveOptions(actionCommand.opts())
288343
289199
  }
288344
289200
  });
288345
289201
  });
@@ -288386,4 +289242,4 @@ export {
288386
289242
  runCLI
288387
289243
  };
288388
289244
 
288389
- //# debugId=DDB3983E5E326EC264756E2164756E21
289245
+ //# debugId=F9AF4FAF927903AE64756E2164756E21