@base44-preview/cli 0.1.15-pr.630.80e82e8 → 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
@@ -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
  }
@@ -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;
@@ -270010,7 +270010,7 @@ function getModelCommand() {
270010
270010
  }
270011
270011
 
270012
270012
  // src/cli/commands/builder/shared.ts
270013
- 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";
270014
270014
  import { basename as basename6, join as join25, relative as relative6, resolve as resolve8 } from "node:path";
270015
270015
 
270016
270016
  // src/cli/commands/code/render.ts
@@ -270564,6 +270564,234 @@ async function getPreviewUrl() {
270564
270564
  return /^https?:\/\//.test(url) ? url : `https://${url}`;
270565
270565
  }
270566
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
+
270567
270795
  // src/cli/commands/builder/shared.ts
270568
270796
  var APP_NAME_RE = /^[A-Za-z0-9._-]+$/;
270569
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(" "));
@@ -270663,6 +270891,147 @@ async function assertBuilderApp(appId) {
270663
270891
  }
270664
270892
  return state;
270665
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
+ }
270666
271035
  function nextStepsLines(app) {
270667
271036
  const cd = app.here ? "" : `cd ${app.dirName} && `;
270668
271037
  return [
@@ -270817,7 +271186,8 @@ function diffConversation(state, messages) {
270817
271186
  kind: "waiting",
270818
271187
  id: tool.id,
270819
271188
  name: tool.name,
270820
- label: labelTense(meta.label, "running")
271189
+ label: labelTense(meta.label, "running"),
271190
+ pending: pendingInputs([message]).find((p) => p.toolCallId === tool.id)
270821
271191
  });
270822
271192
  }
270823
271193
  if (TOOL_SETTLED.has(status) && !progress.settledTools.has(tool.id)) {
@@ -270920,70 +271290,157 @@ function ndjsonWriter() {
270920
271290
  return (record) => process.stdout.write(`${JSON.stringify(record)}
270921
271291
  `);
270922
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
+ }
270923
271328
  async function sendAction(ctx, message, options) {
270924
271329
  if (options.streamJson && ctx.jsonMode) {
270925
271330
  throw new InvalidInputError("--stream-json and --json are exclusive.");
270926
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
+ }
270927
271339
  if (ctx.app)
270928
271340
  await assertBuilderApp(ctx.app.id);
270929
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
+ };
270930
271384
  if (options.streamJson) {
270931
271385
  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
- });
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 });
270940
271390
  return {};
270941
271391
  }
270942
271392
  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
- ` };
271393
+ const turn = await ctx.runTask("Agent working (a turn can take minutes)", start);
270947
271394
  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
- })}
271395
+ stdout: `${JSON.stringify(await finish(turn, () => {
271396
+ return;
271397
+ }))}
270953
271398
  `
270954
271399
  };
270955
271400
  }
270956
271401
  const stream = createTurnStream(process.stdout.isTTY === true, undefined, {
270957
271402
  verbose: options.verbose
270958
271403
  });
270959
- let turn;
271404
+ let result;
270960
271405
  try {
270961
- turn = await streamConversationDuring(() => sendTurn(message, branchId), stream.onEvent, { branchId });
271406
+ const turn = await streamConversationDuring(start, stream.onEvent, {
271407
+ branchId
271408
+ });
271409
+ result = await finish(turn, stream.onEvent);
270962
271410
  } finally {
270963
271411
  stream.stop();
270964
271412
  }
270965
- if (turn.queued) {
271413
+ if (result.queued === true) {
270966
271414
  return {
270967
271415
  outroMessage: "The agent is busy with an earlier message — yours was queued and runs next."
270968
271416
  };
270969
271417
  }
270970
- if (turn.status?.state === "error") {
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") {
270971
271427
  return {
270972
- outroMessage: `Turn failed (${turn.status.error_source ?? "unknown"}) — see the editor for details.`
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.`
270973
271429
  };
270974
271430
  }
270975
271431
  return { outroMessage: "Turn finished." };
270976
271432
  }
271433
+ var collect = (v, acc = []) => [...acc, v];
270977
271434
  function getSendCommand() {
270978
271435
  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);
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);
270980
271437
  return command;
270981
271438
  }
270982
271439
 
270983
271440
  // src/cli/commands/builder/new.ts
270984
271441
  var POLL_TIMEOUT_MS = 20 * 60000;
270985
271442
  var MODES = ["direct", "fork", "copy"];
270986
- async function readStdin2() {
271443
+ async function readStdin3() {
270987
271444
  const chunks = [];
270988
271445
  for await (const chunk of process.stdin)
270989
271446
  chunks.push(chunk);
@@ -271002,7 +271459,7 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271002
271459
  if (options.wixClientId && !options.wixInstance) {
271003
271460
  throw new InvalidInputError("--wix-client-id applies only with --wix-instance.");
271004
271461
  }
271005
- const signedInstance = options.wixInstance ? (options.wixInstance === "-" ? await readStdin2() : options.wixInstance).trim() : undefined;
271462
+ const signedInstance = options.wixInstance ? (options.wixInstance === "-" ? await readStdin3() : options.wixInstance).trim() : undefined;
271006
271463
  if (options.wixInstance && !signedInstance) {
271007
271464
  throw new InvalidInputError("--wix-instance is empty.");
271008
271465
  }
@@ -271055,6 +271512,7 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271055
271512
  }
271056
271513
  let finalState;
271057
271514
  let previewUrl;
271515
+ let pending = [];
271058
271516
  const startedAt = Date.now();
271059
271517
  if (prompt) {
271060
271518
  const branchId = await resolveActiveBranchId().catch(() => {
@@ -271073,6 +271531,20 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271073
271531
  stream.onEvent(event);
271074
271532
  }, { branchId, timeoutMs: POLL_TIMEOUT_MS });
271075
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
+ }
271076
271548
  if (finalState === "ready") {
271077
271549
  previewUrl = await getPreviewUrl().catch(() => {
271078
271550
  return;
@@ -271087,7 +271559,8 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271087
271559
  type: "result",
271088
271560
  id: app.id,
271089
271561
  preview_url: previewUrl ?? null,
271090
- status: finalState ?? "created"
271562
+ status: finalState ?? "created",
271563
+ ...pending.length ? { pending: pendingSummary(pending) } : {}
271091
271564
  });
271092
271565
  return {};
271093
271566
  }
@@ -271101,6 +271574,7 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271101
271574
  dir: app.dirName,
271102
271575
  path: app.targetDir,
271103
271576
  status: finalState ?? "created",
271577
+ ...pending.length ? { pending: pendingSummary(pending) } : {},
271104
271578
  ...app.clientCreationId ? { client_creation_id: app.clientCreationId } : {}
271105
271579
  })}
271106
271580
  `
@@ -271110,6 +271584,13 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271110
271584
  log.message(`preview ${previewUrl}`);
271111
271585
  for (const line of nextStepsLines(app))
271112
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
+ }
271113
271594
  if (finalState === "error") {
271114
271595
  return {
271115
271596
  outroMessage: `The first build reported an error — open the editor for details.`
@@ -271126,29 +271607,43 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
271126
271607
  }
271127
271608
  function getNewCommand() {
271128
271609
  const command = new Base44Command("new", { requireAppContext: false });
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);
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);
271130
271611
  return command;
271131
271612
  }
271132
271613
 
271133
271614
  // src/cli/commands/builder/status.ts
271134
271615
  async function statusAction(ctx) {
271135
271616
  const id = ctx.app?.id;
271136
- const app = await ctx.runTask("Reading app status", () => getAppState(id));
271137
- 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";
271138
271624
  if (ctx.jsonMode) {
271139
271625
  return {
271140
- 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
+ })}
271141
271632
  `
271142
271633
  };
271143
271634
  }
271144
271635
  ctx.log.message(`State: ${state}`);
271145
271636
  if (app.status?.message)
271146
271637
  ctx.log.message(`Note: ${app.status.message}`);
271147
- 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
+ };
271148
271643
  }
271149
271644
  function getStatusCommand() {
271150
- const command = new Base44Command("status");
271151
- 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);
271152
271647
  return command;
271153
271648
  }
271154
271649
 
@@ -276132,6 +276627,612 @@ function TextInput({ value: originalValue, placeholder = "", focus = true, mask,
276132
276627
  }
276133
276628
  var build_default = TextInput;
276134
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
+
276135
277236
  // src/cli/commands/code/session.tsx
276136
277237
  var import_react23 = __toESM(require_react(), 1);
276137
277238
 
@@ -276321,180 +277422,6 @@ function createPasteFriendlyStdin(real) {
276321
277422
  return proxy;
276322
277423
  }
276323
277424
 
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
277425
  // src/cli/commands/code/pending-card.ts
276499
277426
  function openCard(pending) {
276500
277427
  return {
@@ -276503,8 +277430,10 @@ function openCard(pending) {
276503
277430
  cursor: 0,
276504
277431
  selections: (pending.questions ?? []).map(() => ({ labels: [] })),
276505
277432
  granted: new Set((pending.permissions ?? []).map((p) => p.key)),
276506
- typing: pending.kind === "secrets" ? "secret" : null,
276507
- secretValues: {}
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" } } : {}
276508
277437
  };
276509
277438
  }
276510
277439
  var done = (action, input = {}) => ({ state: null, submit: { action, input } });
@@ -276519,7 +277448,7 @@ function advanceChoice(state) {
276519
277448
  state: { ...state, step: state.step + 1, cursor: 0, typing: null }
276520
277449
  };
276521
277450
  }
276522
- return done("approved", choiceAnswers(questions, state.selections));
277451
+ return done("approved", choiceAnswers(questions, state.selections, state.pending.answerKey));
276523
277452
  }
276524
277453
  function choiceKey(state, key) {
276525
277454
  const question = state.pending.questions?.[state.step];
@@ -276603,7 +277532,7 @@ function permissionsKey(state, key) {
276603
277532
  function cardKey(state, key) {
276604
277533
  if (state.typing) {
276605
277534
  if (key === "escape") {
276606
- return state.typing === "secret" ? later : { state: { ...state, typing: null } };
277535
+ return state.typing === "secret" || state.typing === "cred-secret" ? later : state.typing === "custom" ? { state: { ...state, typing: null } } : later;
276607
277536
  }
276608
277537
  return { state };
276609
277538
  }
@@ -276612,6 +277541,56 @@ function cardKey(state, key) {
276612
277541
  return choiceKey(state, key);
276613
277542
  case "permissions":
276614
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 };
276615
277594
  default:
276616
277595
  if (key === "y" || key === "enter")
276617
277596
  return done("approved");
@@ -276622,6 +277601,12 @@ function cardKey(state, key) {
276622
277601
  return { state };
276623
277602
  }
276624
277603
  }
277604
+ function browserUpdate(state, update) {
277605
+ return {
277606
+ ...state,
277607
+ browser: { url: update.url ?? state.browser?.url, status: update.status }
277608
+ };
277609
+ }
276625
277610
  function cardText(state, text) {
276626
277611
  const value = text.trim();
276627
277612
  if (state.typing === "custom") {
@@ -276632,6 +277617,34 @@ function cardText(state, text) {
276632
277617
  selections[state.step] = { ...current, customText: value };
276633
277618
  return advanceChoice({ ...state, selections, typing: null });
276634
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
+ }
276635
277648
  if (state.typing === "secret") {
276636
277649
  const fields = state.pending.secrets ?? [];
276637
277650
  const field = fields[state.step];
@@ -276697,11 +277710,63 @@ function cardLines(state) {
276697
277710
  source_default.dim(" type the value below (hidden) · Enter next · Esc later")
276698
277711
  ];
276699
277712
  }
276700
- case "browser":
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 ?? [];
276701
277753
  return [
276702
277754
  ...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")
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")
276705
277770
  ];
276706
277771
  default:
276707
277772
  return [...head, source_default.dim(" y approve · n reject · Esc later")];
@@ -276818,6 +277883,8 @@ function createSessionEngine(options) {
276818
277883
  });
276819
277884
  continue;
276820
277885
  }
277886
+ if (event.kind === "waiting" && answered.has(event.id))
277887
+ continue;
276821
277888
  const line = eventLine(event, undefined, {
276822
277889
  waitingHint: "answer in the card below"
276823
277890
  });
@@ -276849,7 +277916,7 @@ function createSessionEngine(options) {
276849
277916
  lastTurnMs = durationMs;
276850
277917
  const ok = !turn.backendStatus?.startsWith("error");
276851
277918
  lastTurnOk = ok;
276852
- 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)}`));
276853
277920
  const info = {
276854
277921
  turnIndex: settledCount++,
276855
277922
  ok,
@@ -276920,6 +277987,58 @@ function createSessionEngine(options) {
276920
277987
  };
276921
277988
  }
276922
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
+
276923
278042
  // src/cli/commands/code/session.tsx
276924
278043
  var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
276925
278044
  var FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
@@ -277030,14 +278149,67 @@ function SessionView({ engine, footer, subscribe }) {
277030
278149
  emit(source_default.red(` /model: ${error instanceof Error ? error.message : String(error)}`));
277031
278150
  }
277032
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
+ };
277033
278200
  const applyCard = (outcome) => {
277034
278201
  if (outcome.submit && card) {
278202
+ browserRunRef.current?.abort();
277035
278203
  engine.answer(card.pending, outcome.submit.action, outcome.submit.input);
277036
278204
  }
277037
278205
  if (outcome.dismissed && card) {
278206
+ browserRunRef.current?.abort();
277038
278207
  dismissedRef.current.add(card.pending.toolCallId);
277039
278208
  }
277040
278209
  setCard(outcome.state);
278210
+ if (outcome.startBrowser && outcome.state) {
278211
+ runBrowserStep(outcome.state);
278212
+ }
277041
278213
  };
277042
278214
  const pending = engine.status().pending;
277043
278215
  import_react23.useEffect(() => {
@@ -277077,7 +278249,7 @@ function SessionView({ engine, footer, subscribe }) {
277077
278249
  return;
277078
278250
  }
277079
278251
  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;
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;
277081
278253
  if (card.typing && mapped !== "escape")
277082
278254
  return;
277083
278255
  if (mapped)
@@ -277206,6 +278378,27 @@ function SessionView({ engine, footer, subscribe }) {
277206
278378
  source_default.dim(" — value is hidden · Enter to save · Esc to cancel")
277207
278379
  ]
277208
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),
277209
278402
  card?.typing === "custom" && /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
277210
278403
  wrap: "truncate-end",
277211
278404
  children: [
@@ -277222,7 +278415,7 @@ function SessionView({ engine, footer, subscribe }) {
277222
278415
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(build_default, {
277223
278416
  value: input,
277224
278417
  onChange: setInput,
277225
- mask: card?.typing === "secret" ? "•" : undefined,
278418
+ mask: card?.typing === "secret" || card?.typing === "cred-secret" ? "•" : undefined,
277226
278419
  onSubmit: (value) => {
277227
278420
  if (card?.typing) {
277228
278421
  applyCard(cardText(card, value));
@@ -277577,612 +278770,6 @@ function getCodeCommand() {
277577
278770
  return command;
277578
278771
  }
277579
278772
 
277580
- // ../../node_modules/open/index.js
277581
- import process30 from "node:process";
277582
- import path16 from "node:path";
277583
- import { fileURLToPath as fileURLToPath4 } from "node:url";
277584
- import childProcess3 from "node:child_process";
277585
- import fs20, { constants as fsConstants2 } from "node:fs/promises";
277586
-
277587
- // ../../node_modules/wsl-utils/index.js
277588
- import { promisify as promisify6 } from "node:util";
277589
- import childProcess2 from "node:child_process";
277590
- import fs19, { constants as fsConstants } from "node:fs/promises";
277591
-
277592
- // ../../node_modules/is-wsl/index.js
277593
- import process24 from "node:process";
277594
- import os4 from "node:os";
277595
- import fs18 from "node:fs";
277596
-
277597
- // ../../node_modules/is-inside-container/index.js
277598
- import fs17 from "node:fs";
277599
-
277600
- // ../../node_modules/is-docker/index.js
277601
- import fs16 from "node:fs";
277602
- var isDockerCached;
277603
- function hasDockerEnv() {
277604
- try {
277605
- fs16.statSync("/.dockerenv");
277606
- return true;
277607
- } catch {
277608
- return false;
277609
- }
277610
- }
277611
- function hasDockerCGroup() {
277612
- try {
277613
- return fs16.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
277614
- } catch {
277615
- return false;
277616
- }
277617
- }
277618
- function isDocker() {
277619
- if (isDockerCached === undefined) {
277620
- isDockerCached = hasDockerEnv() || hasDockerCGroup();
277621
- }
277622
- return isDockerCached;
277623
- }
277624
-
277625
- // ../../node_modules/is-inside-container/index.js
277626
- var cachedResult;
277627
- var hasContainerEnv = () => {
277628
- try {
277629
- fs17.statSync("/run/.containerenv");
277630
- return true;
277631
- } catch {
277632
- return false;
277633
- }
277634
- };
277635
- function isInsideContainer() {
277636
- if (cachedResult === undefined) {
277637
- cachedResult = hasContainerEnv() || isDocker();
277638
- }
277639
- return cachedResult;
277640
- }
277641
-
277642
- // ../../node_modules/is-wsl/index.js
277643
- var isWsl = () => {
277644
- if (process24.platform !== "linux") {
277645
- return false;
277646
- }
277647
- if (os4.release().toLowerCase().includes("microsoft")) {
277648
- if (isInsideContainer()) {
277649
- return false;
277650
- }
277651
- return true;
277652
- }
277653
- try {
277654
- return fs18.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
277655
- } catch {
277656
- return false;
277657
- }
277658
- };
277659
- var is_wsl_default = process24.env.__IS_WSL_TEST__ ? isWsl : isWsl();
277660
-
277661
- // ../../node_modules/powershell-utils/index.js
277662
- import process25 from "node:process";
277663
- import { Buffer as Buffer7 } from "node:buffer";
277664
- import { promisify as promisify5 } from "node:util";
277665
- import childProcess from "node:child_process";
277666
- var execFile = promisify5(childProcess.execFile);
277667
- var powerShellPath = () => `${process25.env.SYSTEMROOT || process25.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
277668
- var executePowerShell = async (command, options = {}) => {
277669
- const {
277670
- powerShellPath: psPath,
277671
- ...execFileOptions
277672
- } = options;
277673
- const encodedCommand = executePowerShell.encodeCommand(command);
277674
- return execFile(psPath ?? powerShellPath(), [
277675
- ...executePowerShell.argumentsPrefix,
277676
- encodedCommand
277677
- ], {
277678
- encoding: "utf8",
277679
- ...execFileOptions
277680
- });
277681
- };
277682
- executePowerShell.argumentsPrefix = [
277683
- "-NoProfile",
277684
- "-NonInteractive",
277685
- "-ExecutionPolicy",
277686
- "Bypass",
277687
- "-EncodedCommand"
277688
- ];
277689
- executePowerShell.encodeCommand = (command) => Buffer7.from(command, "utf16le").toString("base64");
277690
- executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
277691
-
277692
- // ../../node_modules/wsl-utils/utilities.js
277693
- function parseMountPointFromConfig(content) {
277694
- for (const line of content.split(`
277695
- `)) {
277696
- if (/^\s*#/.test(line)) {
277697
- continue;
277698
- }
277699
- const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
277700
- if (!match) {
277701
- continue;
277702
- }
277703
- return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
277704
- }
277705
- }
277706
-
277707
- // ../../node_modules/wsl-utils/index.js
277708
- var execFile2 = promisify6(childProcess2.execFile);
277709
- var wslDrivesMountPoint = (() => {
277710
- const defaultMountPoint = "/mnt/";
277711
- let mountPoint;
277712
- return async function() {
277713
- if (mountPoint) {
277714
- return mountPoint;
277715
- }
277716
- const configFilePath = "/etc/wsl.conf";
277717
- let isConfigFileExists = false;
277718
- try {
277719
- await fs19.access(configFilePath, fsConstants.F_OK);
277720
- isConfigFileExists = true;
277721
- } catch {}
277722
- if (!isConfigFileExists) {
277723
- return defaultMountPoint;
277724
- }
277725
- const configContent = await fs19.readFile(configFilePath, { encoding: "utf8" });
277726
- const parsedMountPoint = parseMountPointFromConfig(configContent);
277727
- if (parsedMountPoint === undefined) {
277728
- return defaultMountPoint;
277729
- }
277730
- mountPoint = parsedMountPoint;
277731
- mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
277732
- return mountPoint;
277733
- };
277734
- })();
277735
- var powerShellPathFromWsl = async () => {
277736
- const mountPoint = await wslDrivesMountPoint();
277737
- return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
277738
- };
277739
- var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
277740
- var canAccessPowerShellPromise;
277741
- var canAccessPowerShell = async () => {
277742
- canAccessPowerShellPromise ??= (async () => {
277743
- try {
277744
- const psPath = await powerShellPath2();
277745
- await fs19.access(psPath, fsConstants.X_OK);
277746
- return true;
277747
- } catch {
277748
- return false;
277749
- }
277750
- })();
277751
- return canAccessPowerShellPromise;
277752
- };
277753
- var wslDefaultBrowser = async () => {
277754
- const psPath = await powerShellPath2();
277755
- const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
277756
- const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
277757
- return stdout.trim();
277758
- };
277759
- var convertWslPathToWindows = async (path) => {
277760
- if (/^[a-z]+:\/\//i.test(path)) {
277761
- return path;
277762
- }
277763
- try {
277764
- const { stdout } = await execFile2("wslpath", ["-aw", path], { encoding: "utf8" });
277765
- return stdout.trim();
277766
- } catch {
277767
- return path;
277768
- }
277769
- };
277770
-
277771
- // ../../node_modules/define-lazy-prop/index.js
277772
- function defineLazyProperty(object, propertyName, valueGetter) {
277773
- const define2 = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
277774
- Object.defineProperty(object, propertyName, {
277775
- configurable: true,
277776
- enumerable: true,
277777
- get() {
277778
- const result = valueGetter();
277779
- define2(result);
277780
- return result;
277781
- },
277782
- set(value) {
277783
- define2(value);
277784
- }
277785
- });
277786
- return object;
277787
- }
277788
-
277789
- // ../../node_modules/default-browser/index.js
277790
- import { promisify as promisify10 } from "node:util";
277791
- import process28 from "node:process";
277792
- import { execFile as execFile6 } from "node:child_process";
277793
-
277794
- // ../../node_modules/default-browser-id/index.js
277795
- import { promisify as promisify7 } from "node:util";
277796
- import process26 from "node:process";
277797
- import { execFile as execFile3 } from "node:child_process";
277798
- var execFileAsync = promisify7(execFile3);
277799
- async function defaultBrowserId() {
277800
- if (process26.platform !== "darwin") {
277801
- throw new Error("macOS only");
277802
- }
277803
- const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
277804
- const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
277805
- const browserId = match?.groups.id ?? "com.apple.Safari";
277806
- if (browserId === "com.apple.safari") {
277807
- return "com.apple.Safari";
277808
- }
277809
- return browserId;
277810
- }
277811
-
277812
- // ../../node_modules/run-applescript/index.js
277813
- import process27 from "node:process";
277814
- import { promisify as promisify8 } from "node:util";
277815
- import { execFile as execFile4, execFileSync } from "node:child_process";
277816
- var execFileAsync2 = promisify8(execFile4);
277817
- async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
277818
- if (process27.platform !== "darwin") {
277819
- throw new Error("macOS only");
277820
- }
277821
- const outputArguments = humanReadableOutput ? [] : ["-ss"];
277822
- const execOptions = {};
277823
- if (signal) {
277824
- execOptions.signal = signal;
277825
- }
277826
- const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
277827
- return stdout.trim();
277828
- }
277829
-
277830
- // ../../node_modules/bundle-name/index.js
277831
- async function bundleName(bundleId) {
277832
- return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
277833
- tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
277834
- }
277835
-
277836
- // ../../node_modules/default-browser/windows.js
277837
- import { promisify as promisify9 } from "node:util";
277838
- import { execFile as execFile5 } from "node:child_process";
277839
- var execFileAsync3 = promisify9(execFile5);
277840
- var windowsBrowserProgIds = {
277841
- MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
277842
- MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
277843
- MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
277844
- AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
277845
- ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
277846
- ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
277847
- ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
277848
- ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
277849
- BraveHTML: { name: "Brave", id: "com.brave.Browser" },
277850
- BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
277851
- BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
277852
- BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
277853
- FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
277854
- OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
277855
- VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
277856
- "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
277857
- };
277858
- var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
277859
-
277860
- class UnknownBrowserError extends Error {
277861
- }
277862
- async function defaultBrowser(_execFileAsync = execFileAsync3) {
277863
- const { stdout } = await _execFileAsync("reg", [
277864
- "QUERY",
277865
- " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
277866
- "/v",
277867
- "ProgId"
277868
- ]);
277869
- const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
277870
- if (!match) {
277871
- throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
277872
- }
277873
- const { id } = match.groups;
277874
- const dotIndex = id.lastIndexOf(".");
277875
- const hyphenIndex = id.lastIndexOf("-");
277876
- const baseIdByDot = dotIndex === -1 ? undefined : id.slice(0, dotIndex);
277877
- const baseIdByHyphen = hyphenIndex === -1 ? undefined : id.slice(0, hyphenIndex);
277878
- return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
277879
- }
277880
-
277881
- // ../../node_modules/default-browser/index.js
277882
- var execFileAsync4 = promisify10(execFile6);
277883
- var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
277884
- async function defaultBrowser2() {
277885
- if (process28.platform === "darwin") {
277886
- const id = await defaultBrowserId();
277887
- const name = await bundleName(id);
277888
- return { name, id };
277889
- }
277890
- if (process28.platform === "linux") {
277891
- const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
277892
- const id = stdout.trim();
277893
- const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
277894
- return { name, id };
277895
- }
277896
- if (process28.platform === "win32") {
277897
- return defaultBrowser();
277898
- }
277899
- throw new Error("Only macOS, Linux, and Windows are supported");
277900
- }
277901
-
277902
- // ../../node_modules/is-in-ssh/index.js
277903
- import process29 from "node:process";
277904
- var isInSsh = Boolean(process29.env.SSH_CONNECTION || process29.env.SSH_CLIENT || process29.env.SSH_TTY);
277905
- var is_in_ssh_default = isInSsh;
277906
-
277907
- // ../../node_modules/open/index.js
277908
- var fallbackAttemptSymbol = Symbol("fallbackAttempt");
277909
- var __dirname2 = import.meta.url ? path16.dirname(fileURLToPath4(import.meta.url)) : "";
277910
- var localXdgOpenPath = path16.join(__dirname2, "xdg-open");
277911
- var { platform: platform7, arch } = process30;
277912
- var tryEachApp = async (apps, opener) => {
277913
- if (apps.length === 0) {
277914
- return;
277915
- }
277916
- const errors = [];
277917
- for (const app of apps) {
277918
- try {
277919
- return await opener(app);
277920
- } catch (error) {
277921
- errors.push(error);
277922
- }
277923
- }
277924
- throw new AggregateError(errors, "Failed to open in all supported apps");
277925
- };
277926
- var baseOpen = async (options) => {
277927
- options = {
277928
- wait: false,
277929
- background: false,
277930
- newInstance: false,
277931
- allowNonzeroExitCode: false,
277932
- ...options
277933
- };
277934
- const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
277935
- delete options[fallbackAttemptSymbol];
277936
- if (Array.isArray(options.app)) {
277937
- return tryEachApp(options.app, (singleApp) => baseOpen({
277938
- ...options,
277939
- app: singleApp,
277940
- [fallbackAttemptSymbol]: true
277941
- }));
277942
- }
277943
- let { name: app, arguments: appArguments = [] } = options.app ?? {};
277944
- appArguments = [...appArguments];
277945
- if (Array.isArray(app)) {
277946
- return tryEachApp(app, (appName) => baseOpen({
277947
- ...options,
277948
- app: {
277949
- name: appName,
277950
- arguments: appArguments
277951
- },
277952
- [fallbackAttemptSymbol]: true
277953
- }));
277954
- }
277955
- if (app === "browser" || app === "browserPrivate") {
277956
- const ids = {
277957
- "com.google.chrome": "chrome",
277958
- "google-chrome.desktop": "chrome",
277959
- "com.brave.browser": "brave",
277960
- "org.mozilla.firefox": "firefox",
277961
- "firefox.desktop": "firefox",
277962
- "com.microsoft.msedge": "edge",
277963
- "com.microsoft.edge": "edge",
277964
- "com.microsoft.edgemac": "edge",
277965
- "microsoft-edge.desktop": "edge",
277966
- "com.apple.safari": "safari"
277967
- };
277968
- const flags = {
277969
- chrome: "--incognito",
277970
- brave: "--incognito",
277971
- firefox: "--private-window",
277972
- edge: "--inPrivate"
277973
- };
277974
- let browser;
277975
- if (is_wsl_default) {
277976
- const progId = await wslDefaultBrowser();
277977
- const browserInfo = _windowsBrowserProgIdMap.get(progId);
277978
- browser = browserInfo ?? {};
277979
- } else {
277980
- browser = await defaultBrowser2();
277981
- }
277982
- if (browser.id in ids) {
277983
- const browserName = ids[browser.id.toLowerCase()];
277984
- if (app === "browserPrivate") {
277985
- if (browserName === "safari") {
277986
- throw new Error("Safari doesn't support opening in private mode via command line");
277987
- }
277988
- appArguments.push(flags[browserName]);
277989
- }
277990
- return baseOpen({
277991
- ...options,
277992
- app: {
277993
- name: apps[browserName],
277994
- arguments: appArguments
277995
- }
277996
- });
277997
- }
277998
- throw new Error(`${browser.name} is not supported as a default browser`);
277999
- }
278000
- let command;
278001
- const cliArguments = [];
278002
- const childProcessOptions = {};
278003
- let shouldUseWindowsInWsl = false;
278004
- if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
278005
- shouldUseWindowsInWsl = await canAccessPowerShell();
278006
- }
278007
- if (platform7 === "darwin") {
278008
- command = "open";
278009
- if (options.wait) {
278010
- cliArguments.push("--wait-apps");
278011
- }
278012
- if (options.background) {
278013
- cliArguments.push("--background");
278014
- }
278015
- if (options.newInstance) {
278016
- cliArguments.push("--new");
278017
- }
278018
- if (app) {
278019
- cliArguments.push("-a", app);
278020
- }
278021
- } else if (platform7 === "win32" || shouldUseWindowsInWsl) {
278022
- command = await powerShellPath2();
278023
- cliArguments.push(...executePowerShell.argumentsPrefix);
278024
- if (!is_wsl_default) {
278025
- childProcessOptions.windowsVerbatimArguments = true;
278026
- }
278027
- if (is_wsl_default && options.target) {
278028
- options.target = await convertWslPathToWindows(options.target);
278029
- }
278030
- const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
278031
- if (options.wait) {
278032
- encodedArguments.push("-Wait");
278033
- }
278034
- if (app) {
278035
- encodedArguments.push(executePowerShell.escapeArgument(app));
278036
- if (options.target) {
278037
- appArguments.push(options.target);
278038
- }
278039
- } else if (options.target) {
278040
- encodedArguments.push(executePowerShell.escapeArgument(options.target));
278041
- }
278042
- if (appArguments.length > 0) {
278043
- appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
278044
- encodedArguments.push("-ArgumentList", appArguments.join(","));
278045
- }
278046
- options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
278047
- if (!options.wait) {
278048
- childProcessOptions.stdio = "ignore";
278049
- }
278050
- } else {
278051
- if (app) {
278052
- command = app;
278053
- } else {
278054
- const isBundled = !__dirname2 || __dirname2 === "/";
278055
- let exeLocalXdgOpen = false;
278056
- try {
278057
- await fs20.access(localXdgOpenPath, fsConstants2.X_OK);
278058
- exeLocalXdgOpen = true;
278059
- } catch {}
278060
- const useSystemXdgOpen = process30.versions.electron ?? (platform7 === "android" || isBundled || !exeLocalXdgOpen);
278061
- command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
278062
- }
278063
- if (appArguments.length > 0) {
278064
- cliArguments.push(...appArguments);
278065
- }
278066
- if (!options.wait) {
278067
- childProcessOptions.stdio = "ignore";
278068
- childProcessOptions.detached = true;
278069
- }
278070
- }
278071
- if (platform7 === "darwin" && appArguments.length > 0) {
278072
- cliArguments.push("--args", ...appArguments);
278073
- }
278074
- if (options.target) {
278075
- cliArguments.push(options.target);
278076
- }
278077
- const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
278078
- if (options.wait) {
278079
- return new Promise((resolve, reject) => {
278080
- subprocess.once("error", reject);
278081
- subprocess.once("close", (exitCode) => {
278082
- if (!options.allowNonzeroExitCode && exitCode !== 0) {
278083
- reject(new Error(`Exited with code ${exitCode}`));
278084
- return;
278085
- }
278086
- resolve(subprocess);
278087
- });
278088
- });
278089
- }
278090
- if (isFallbackAttempt) {
278091
- return new Promise((resolve, reject) => {
278092
- subprocess.once("error", reject);
278093
- subprocess.once("spawn", () => {
278094
- subprocess.once("close", (exitCode) => {
278095
- subprocess.off("error", reject);
278096
- if (exitCode !== 0) {
278097
- reject(new Error(`Exited with code ${exitCode}`));
278098
- return;
278099
- }
278100
- subprocess.unref();
278101
- resolve(subprocess);
278102
- });
278103
- });
278104
- });
278105
- }
278106
- subprocess.unref();
278107
- return new Promise((resolve, reject) => {
278108
- subprocess.once("error", reject);
278109
- subprocess.once("spawn", () => {
278110
- subprocess.off("error", reject);
278111
- resolve(subprocess);
278112
- });
278113
- });
278114
- };
278115
- var open = (target, options) => {
278116
- if (typeof target !== "string") {
278117
- throw new TypeError("Expected a `target`");
278118
- }
278119
- return baseOpen({
278120
- ...options,
278121
- target
278122
- });
278123
- };
278124
- function detectArchBinary(binary) {
278125
- if (typeof binary === "string" || Array.isArray(binary)) {
278126
- return binary;
278127
- }
278128
- const { [arch]: archBinary } = binary;
278129
- if (!archBinary) {
278130
- throw new Error(`${arch} is not supported`);
278131
- }
278132
- return archBinary;
278133
- }
278134
- function detectPlatformBinary({ [platform7]: platformBinary }, { wsl } = {}) {
278135
- if (wsl && is_wsl_default) {
278136
- return detectArchBinary(wsl);
278137
- }
278138
- if (!platformBinary) {
278139
- throw new Error(`${platform7} is not supported`);
278140
- }
278141
- return detectArchBinary(platformBinary);
278142
- }
278143
- var apps = {
278144
- browser: "browser",
278145
- browserPrivate: "browserPrivate"
278146
- };
278147
- defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
278148
- darwin: "google chrome",
278149
- win32: "chrome",
278150
- linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
278151
- }, {
278152
- wsl: {
278153
- ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
278154
- x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
278155
- }
278156
- }));
278157
- defineLazyProperty(apps, "brave", () => detectPlatformBinary({
278158
- darwin: "brave browser",
278159
- win32: "brave",
278160
- linux: ["brave-browser", "brave"]
278161
- }, {
278162
- wsl: {
278163
- ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
278164
- x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
278165
- }
278166
- }));
278167
- defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
278168
- darwin: "firefox",
278169
- win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
278170
- linux: "firefox"
278171
- }, {
278172
- wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
278173
- }));
278174
- defineLazyProperty(apps, "edge", () => detectPlatformBinary({
278175
- darwin: "microsoft edge",
278176
- win32: "msedge",
278177
- linux: ["microsoft-edge", "microsoft-edge-dev"]
278178
- }, {
278179
- wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
278180
- }));
278181
- defineLazyProperty(apps, "safari", () => detectPlatformBinary({
278182
- darwin: "Safari"
278183
- }));
278184
- var open_default = open;
278185
-
278186
278773
  // src/cli/commands/connectors/oauth-prompt.ts
278187
278774
  var POLL_INTERVAL_MS = 2000;
278188
278775
  var POLL_TIMEOUT_MS2 = 2 * 60 * 1000;
@@ -279950,7 +280537,7 @@ async function callTool(appId, tool, payload, schema, context, timeout = 60000)
279950
280537
  function listDirectory(appId, params) {
279951
280538
  return callTool(appId, "list_directory", { ...params }, ListDirectoryResponseSchema, "listing directory");
279952
280539
  }
279953
- function readFile4(appId, params) {
280540
+ function readFile5(appId, params) {
279954
280541
  return callTool(appId, "read_file", { ...params }, ReadFileResponseSchema, "reading file");
279955
280542
  }
279956
280543
  function writeFile3(appId, params) {
@@ -280105,7 +280692,7 @@ async function readFileAction({ runTask, branchId }, paths, options) {
280105
280692
  const { id: appId } = getAppContext();
280106
280693
  const offset = parsePositiveInt(options.offset, "--offset");
280107
280694
  const limit = parsePositiveInt(options.limit, "--limit");
280108
- 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 }));
280109
280696
  return { outroMessage: "Read file", stdout: toJsonStdout(result) };
280110
280697
  }
280111
280698
  function getSandboxReadFileCommand() {
@@ -284956,7 +285543,7 @@ async function runScript(options) {
284956
285543
  }
284957
285544
  }
284958
285545
  // src/cli/commands/exec.ts
284959
- function readStdin3() {
285546
+ function readStdin4() {
284960
285547
  return new Promise((resolve, reject) => {
284961
285548
  let data = "";
284962
285549
  process.stdin.setEncoding("utf-8");
@@ -285000,7 +285587,7 @@ async function execAction({ app, isNonInteractive }, options) {
285000
285587
  if (!isNonInteractive) {
285001
285588
  throw noInputError;
285002
285589
  }
285003
- const code = await readStdin3();
285590
+ const code = await readStdin4();
285004
285591
  if (!code.trim()) {
285005
285592
  throw noInputError;
285006
285593
  }
@@ -289242,4 +289829,4 @@ export {
289242
289829
  runCLI
289243
289830
  };
289244
289831
 
289245
- //# debugId=F9AF4FAF927903AE64756E2164756E21
289832
+ //# debugId=C0EA00D7CF91E50E64756E2164756E21