farai 0.1.4 → 0.1.5

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
@@ -28832,6 +28832,24 @@ var init_runtime = __esm(() => {
28832
28832
  };
28833
28833
  });
28834
28834
 
28835
+ // src/branding.ts
28836
+ import figlet from "figlet";
28837
+ function renderFaraiBanner() {
28838
+ try {
28839
+ return figlet.textSync("farai", {
28840
+ font: "Ogre"
28841
+ }).trimEnd();
28842
+ } catch {
28843
+ return "farai";
28844
+ }
28845
+ }
28846
+ var FARAI_BANNER, FARAI_BANNER_LINES;
28847
+ var init_branding = __esm(() => {
28848
+ FARAI_BANNER = renderFaraiBanner();
28849
+ FARAI_BANNER_LINES = FARAI_BANNER.split(`
28850
+ `);
28851
+ });
28852
+
28835
28853
  // src/agent-knowledge/pack.ts
28836
28854
  import { existsSync as existsSync13, mkdirSync as mkdirSync7, readdirSync as readdirSync4, readFileSync as readFileSync12, renameSync as renameSync4, rmSync, writeFileSync as writeFileSync8 } from "fs";
28837
28855
  import { createHash as createHash5 } from "crypto";
@@ -34043,7 +34061,8 @@ function initialStore(workspace) {
34043
34061
  sessionStats: {},
34044
34062
  agentThreads: [],
34045
34063
  lastError: undefined,
34046
- requestUserInput: undefined
34064
+ requestUserInput: undefined,
34065
+ updateNotice: undefined
34047
34066
  }
34048
34067
  };
34049
34068
  }
@@ -34465,6 +34484,9 @@ function createActions(store, setStore) {
34465
34484
  statusDetailSet(detail) {
34466
34485
  setStore("ui", "statusDetail", detail);
34467
34486
  },
34487
+ updateNoticeSet(notice) {
34488
+ setStore("ui", "updateNotice", notice);
34489
+ },
34468
34490
  contextUsageUpdated(usage2) {
34469
34491
  if (!usage2) {
34470
34492
  setStore("ui", "contextUsage", undefined);
@@ -36829,6 +36851,14 @@ function TuiStoreProvider(props) {
36829
36851
  let sessionSelectionIntent = 0;
36830
36852
  let mcpOverlayGeneration = 0;
36831
36853
  let disposed = false;
36854
+ if (props.updateCheck?.cachedNotice)
36855
+ actions.updateNoticeSet(props.updateCheck.cachedNotice);
36856
+ if (props.updateCheck?.refresh) {
36857
+ props.updateCheck.refresh.then((notice) => {
36858
+ if (!disposed)
36859
+ actions.updateNoticeSet(notice);
36860
+ });
36861
+ }
36832
36862
  const timelineRows = createMemo(() => projectMessagesToRows(store.snapshot.messages, Math.max(1, dims().width - 4), store.snapshot.runningTurnId, store.snapshot.toolCalls, store.snapshot.toolInputPreviews));
36833
36863
  function setStatusDetail(detail, timeoutMs) {
36834
36864
  if (disposed)
@@ -42575,21 +42605,35 @@ function Transcript() {
42575
42605
  },
42576
42606
  get fallback() {
42577
42607
  return (() => {
42578
- var _el$2 = createElement("box"), _el$3 = createElement("text"), _el$5 = createElement("text");
42608
+ var _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$6 = createElement("text");
42579
42609
  insertNode(_el$2, _el$3);
42580
- insertNode(_el$2, _el$5);
42610
+ insertNode(_el$2, _el$4);
42611
+ insertNode(_el$2, _el$6);
42581
42612
  setProp(_el$2, "style", {
42582
42613
  flexDirection: "column",
42583
42614
  marginTop: 1,
42584
42615
  paddingLeft: 1,
42585
42616
  paddingRight: 1
42586
42617
  });
42587
- insertNode(_el$3, createTextNode(`\u203A message farai to get started`));
42588
- insertNode(_el$5, createTextNode(` / opens commands \xB7 ? shows shortcuts`));
42618
+ setProp(_el$3, "style", {
42619
+ flexDirection: "column",
42620
+ marginBottom: 1
42621
+ });
42622
+ insert(_el$3, createComponent2(For, {
42623
+ each: FARAI_BANNER_LINES,
42624
+ children: (line) => (() => {
42625
+ var _el$8 = createElement("text");
42626
+ insert(_el$8, () => truncateLine2(line, Math.max(1, dims().width - 4)));
42627
+ effect((_$p) => setProp(_el$8, "fg", COLOR.dim, _$p));
42628
+ return _el$8;
42629
+ })()
42630
+ }));
42631
+ insertNode(_el$4, createTextNode(`\u203A message farai to get started`));
42632
+ insertNode(_el$6, createTextNode(` / opens commands \xB7 ? shows shortcuts`));
42589
42633
  effect((_p$) => {
42590
42634
  var _v$ = COLOR.dim, _v$2 = COLOR.dim;
42591
- _v$ !== _p$.e && (_p$.e = setProp(_el$3, "fg", _v$, _p$.e));
42592
- _v$2 !== _p$.t && (_p$.t = setProp(_el$5, "fg", _v$2, _p$.t));
42635
+ _v$ !== _p$.e && (_p$.e = setProp(_el$4, "fg", _v$, _p$.e));
42636
+ _v$2 !== _p$.t && (_p$.t = setProp(_el$6, "fg", _v$2, _p$.t));
42593
42637
  return _p$;
42594
42638
  }, {
42595
42639
  e: undefined,
@@ -42621,26 +42665,26 @@ function Transcript() {
42621
42665
  return rawRows();
42622
42666
  },
42623
42667
  children: (row) => (() => {
42624
- var _el$7 = createElement("box");
42625
- setProp(_el$7, "style", {
42668
+ var _el$9 = createElement("box");
42669
+ setProp(_el$9, "style", {
42626
42670
  flexDirection: "column",
42627
42671
  marginBottom: 1,
42628
42672
  paddingLeft: 1,
42629
42673
  paddingRight: 1
42630
42674
  });
42631
- insert(_el$7, createComponent2(For, {
42675
+ insert(_el$9, createComponent2(For, {
42632
42676
  get each() {
42633
42677
  return row.split(`
42634
42678
  `);
42635
42679
  },
42636
42680
  children: (line) => (() => {
42637
- var _el$8 = createElement("text");
42638
- insert(_el$8, () => truncateLine2(line, Math.max(1, dims().width - 4)));
42639
- effect((_$p) => setProp(_el$8, "fg", COLOR.dim, _$p));
42640
- return _el$8;
42681
+ var _el$0 = createElement("text");
42682
+ insert(_el$0, () => truncateLine2(line, Math.max(1, dims().width - 4)));
42683
+ effect((_$p) => setProp(_el$0, "fg", COLOR.dim, _$p));
42684
+ return _el$0;
42641
42685
  })()
42642
42686
  }));
42643
- return _el$7;
42687
+ return _el$9;
42644
42688
  })()
42645
42689
  });
42646
42690
  }
@@ -42723,19 +42767,19 @@ function valuesEqual(left, right, seen) {
42723
42767
  function TranscriptRow(props) {
42724
42768
  const isUser = props.row.kind === "user";
42725
42769
  return (() => {
42726
- var _el$9 = createElement("box");
42727
- setProp(_el$9, "style", {
42770
+ var _el$1 = createElement("box");
42771
+ setProp(_el$1, "style", {
42728
42772
  flexDirection: "column",
42729
42773
  paddingLeft: isUser ? 0 : 1,
42730
42774
  paddingRight: isUser ? 0 : 1
42731
42775
  });
42732
- insert(_el$9, createComponent2(FaraiRow, {
42776
+ insert(_el$1, createComponent2(FaraiRow, {
42733
42777
  get row() {
42734
42778
  return props.row;
42735
42779
  }
42736
42780
  }));
42737
- effect((_$p) => setProp(_el$9, "id", props.row.id, _$p));
42738
- return _el$9;
42781
+ effect((_$p) => setProp(_el$1, "id", props.row.id, _$p));
42782
+ return _el$1;
42739
42783
  })();
42740
42784
  }
42741
42785
  var init_transcript = __esm(() => {
@@ -42754,6 +42798,7 @@ var init_transcript = __esm(() => {
42754
42798
  init_compaction();
42755
42799
  init_theme();
42756
42800
  init_cells();
42801
+ init_branding();
42757
42802
  });
42758
42803
 
42759
42804
  // src/agent-tui/surfaces/center-surface.tsx
@@ -44685,8 +44730,15 @@ function instructionalFooterLines(state) {
44685
44730
  function contextualFooter(state) {
44686
44731
  return state.context;
44687
44732
  }
44688
- function footerRightItems(backgroundActivities, subagents, browserContexts, queueSize, statusDetail, contextUsage) {
44733
+ function footerRightItems(backgroundActivities, subagents, browserContexts, queueSize, statusDetail, contextUsage, updateNotice) {
44689
44734
  const items = [];
44735
+ if (updateNotice) {
44736
+ items.push({
44737
+ id: "update",
44738
+ kind: "update",
44739
+ text: `update ${updateNotice.latestVersion}`
44740
+ });
44741
+ }
44690
44742
  if (contextUsage && contextUsage.tokens >= 0) {
44691
44743
  items.push({
44692
44744
  id: "context",
@@ -44880,10 +44932,12 @@ function Footer(props) {
44880
44932
  budget
44881
44933
  };
44882
44934
  };
44883
- const rightItems = createMemo(() => footerRightItems(tui.store.snapshot.backgroundActivities, tui.store.snapshot.subagents, tui.store.snapshot.browserContexts, tui.store.snapshot.queuedPrompts.length, tui.store.ui.statusDetail, contextUsage()));
44935
+ const rightItems = createMemo(() => footerRightItems(tui.store.snapshot.backgroundActivities, tui.store.snapshot.subagents, tui.store.snapshot.browserContexts, tui.store.snapshot.queuedPrompts.length, tui.store.ui.statusDetail, contextUsage(), tui.store.ui.updateNotice));
44884
44936
  const firstLine = () => fitFooterLine(left(), rightItems(), Math.max(0, dims().width - 4));
44937
+ const updateText = () => tui.store.ui.updateNotice ? `update ${tui.store.ui.updateNotice.latestVersion}` : undefined;
44938
+ const rightLine = createMemo(() => splitUpdateWarning(firstLine().right, updateText()));
44885
44939
  return (() => {
44886
- var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$4 = createElement("text");
44940
+ var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$4 = createElement("text"), _el$5 = createElement("span"), _el$6 = createElement("span");
44887
44941
  insertNode(_el$, _el$2);
44888
44942
  setProp(_el$, "style", {
44889
44943
  flexShrink: 0,
@@ -44897,33 +44951,64 @@ function Footer(props) {
44897
44951
  justifyContent: "space-between"
44898
44952
  });
44899
44953
  insert(_el$3, () => firstLine().left);
44900
- insert(_el$4, () => firstLine().right);
44954
+ insertNode(_el$4, _el$5);
44955
+ insertNode(_el$4, _el$6);
44956
+ insert(_el$5, () => rightLine().warning);
44957
+ insert(_el$6, () => rightLine().rest);
44901
44958
  insert(_el$, createComponent2(ShowShortcutLines, {
44902
44959
  get lines() {
44903
44960
  return lines().slice(1).map((line) => line.toLowerCase());
44904
44961
  }
44905
44962
  }), null);
44906
44963
  effect((_p$) => {
44907
- var _v$ = historySearch() ? COLOR.accent : COLOR.dim, _v$2 = COLOR.dim;
44964
+ var _v$ = historySearch() ? COLOR.accent : COLOR.dim, _v$2 = {
44965
+ fg: COLOR.warning
44966
+ }, _v$3 = {
44967
+ fg: COLOR.dim
44968
+ };
44908
44969
  _v$ !== _p$.e && (_p$.e = setProp(_el$3, "fg", _v$, _p$.e));
44909
- _v$2 !== _p$.t && (_p$.t = setProp(_el$4, "fg", _v$2, _p$.t));
44970
+ _v$2 !== _p$.t && (_p$.t = setProp(_el$5, "style", _v$2, _p$.t));
44971
+ _v$3 !== _p$.a && (_p$.a = setProp(_el$6, "style", _v$3, _p$.a));
44910
44972
  return _p$;
44911
44973
  }, {
44912
44974
  e: undefined,
44913
- t: undefined
44975
+ t: undefined,
44976
+ a: undefined
44914
44977
  });
44915
44978
  return _el$;
44916
44979
  })();
44917
44980
  }
44981
+ function splitUpdateWarning(line, updateText) {
44982
+ if (!line || !updateText)
44983
+ return {
44984
+ warning: "",
44985
+ rest: line
44986
+ };
44987
+ if (line.startsWith(updateText))
44988
+ return {
44989
+ warning: updateText,
44990
+ rest: line.slice(updateText.length)
44991
+ };
44992
+ const visible = line.endsWith("\u2026") ? line.slice(0, -1) : line;
44993
+ if (visible && updateText.startsWith(visible))
44994
+ return {
44995
+ warning: line,
44996
+ rest: ""
44997
+ };
44998
+ return {
44999
+ warning: "",
45000
+ rest: line
45001
+ };
45002
+ }
44918
45003
  function displayModel(sessionModel, workspace) {
44919
45004
  return displayModelSelection(workspace, sessionModel);
44920
45005
  }
44921
45006
  function ShowShortcutLines(props) {
44922
45007
  return memo2(() => props.lines.map((line) => (() => {
44923
- var _el$5 = createElement("text");
44924
- insert(_el$5, line);
44925
- effect((_$p) => setProp(_el$5, "fg", COLOR.dim, _$p));
44926
- return _el$5;
45008
+ var _el$7 = createElement("text");
45009
+ insert(_el$7, line);
45010
+ effect((_$p) => setProp(_el$7, "fg", COLOR.dim, _$p));
45011
+ return _el$7;
44927
45012
  })()));
44928
45013
  }
44929
45014
  var init_footer = __esm(() => {
@@ -47242,6 +47327,191 @@ var init_app = __esm(() => {
47242
47327
  init_app_shell();
47243
47328
  });
47244
47329
 
47330
+ // src/agent-tui/update-check.ts
47331
+ import { mkdirSync as mkdirSync13, readFileSync as readFileSync19, renameSync as renameSync7, writeFileSync as writeFileSync14 } from "fs";
47332
+ import { dirname as dirname8, join as join26 } from "path";
47333
+ function prepareUpdateCheck(options = {}) {
47334
+ if (updateCheckDisabled())
47335
+ return {
47336
+ cachedNotice: undefined,
47337
+ refresh: undefined
47338
+ };
47339
+ const currentVersion = options.currentVersion ?? readCurrentVersion();
47340
+ if (!currentVersion)
47341
+ return {
47342
+ cachedNotice: undefined,
47343
+ refresh: undefined
47344
+ };
47345
+ const now = options.now ?? Date.now();
47346
+ const cachePath = options.cachePath ?? updateCachePath();
47347
+ const cache = readUpdateCache(cachePath);
47348
+ const cachedNotice = cache ? createUpdateNotice(currentVersion, cache.latestVersion) : undefined;
47349
+ if (cache && isFreshCache(cache, now))
47350
+ return {
47351
+ cachedNotice,
47352
+ refresh: undefined
47353
+ };
47354
+ return {
47355
+ cachedNotice,
47356
+ refresh: refreshUpdateNotice({
47357
+ cachePath,
47358
+ currentVersion,
47359
+ fetcher: options.fetcher ?? fetch,
47360
+ now,
47361
+ timeoutMs: options.timeoutMs ?? UPDATE_CHECK_TIMEOUT_MS,
47362
+ fallback: cachedNotice
47363
+ })
47364
+ };
47365
+ }
47366
+ function createUpdateNotice(currentVersion, latestVersion) {
47367
+ if (compareSemver(latestVersion, currentVersion) <= 0)
47368
+ return;
47369
+ return {
47370
+ currentVersion,
47371
+ latestVersion,
47372
+ updateCommand: "npm install -g farai@latest"
47373
+ };
47374
+ }
47375
+ function compareSemver(left, right) {
47376
+ const a = parseSemver(left);
47377
+ const b = parseSemver(right);
47378
+ if (!a || !b)
47379
+ return 0;
47380
+ for (let index = 0;index < 3; index += 1) {
47381
+ const delta = a.core[index] - b.core[index];
47382
+ if (delta !== 0)
47383
+ return delta < 0 ? -1 : 1;
47384
+ }
47385
+ if (a.prerelease.length === 0 || b.prerelease.length === 0) {
47386
+ if (a.prerelease.length === b.prerelease.length)
47387
+ return 0;
47388
+ return a.prerelease.length === 0 ? 1 : -1;
47389
+ }
47390
+ const length = Math.max(a.prerelease.length, b.prerelease.length);
47391
+ for (let index = 0;index < length; index += 1) {
47392
+ const aPart = a.prerelease[index];
47393
+ const bPart = b.prerelease[index];
47394
+ if (aPart === undefined || bPart === undefined)
47395
+ return aPart === undefined ? -1 : 1;
47396
+ if (aPart === bPart)
47397
+ continue;
47398
+ const aNumber = numericIdentifier(aPart);
47399
+ const bNumber = numericIdentifier(bPart);
47400
+ if (aNumber !== undefined && bNumber !== undefined)
47401
+ return aNumber < bNumber ? -1 : 1;
47402
+ if (aNumber !== undefined || bNumber !== undefined)
47403
+ return aNumber !== undefined ? -1 : 1;
47404
+ return aPart < bPart ? -1 : 1;
47405
+ }
47406
+ return 0;
47407
+ }
47408
+ function readUpdateCache(path = updateCachePath()) {
47409
+ try {
47410
+ const parsed = JSON.parse(readFileSync19(path, "utf8"));
47411
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
47412
+ return;
47413
+ const value = parsed;
47414
+ if (typeof value.checkedAt !== "number" || !Number.isFinite(value.checkedAt))
47415
+ return;
47416
+ if (typeof value.latestVersion !== "string" || !parseSemver(value.latestVersion))
47417
+ return;
47418
+ return {
47419
+ checkedAt: value.checkedAt,
47420
+ latestVersion: value.latestVersion
47421
+ };
47422
+ } catch {
47423
+ return;
47424
+ }
47425
+ }
47426
+ function updateCachePath() {
47427
+ return join26(globalDataDir(), "update.json");
47428
+ }
47429
+ function readCurrentVersion() {
47430
+ try {
47431
+ const packagePath = join26(import.meta.dir, "..", "..", "package.json");
47432
+ const parsed = JSON.parse(readFileSync19(packagePath, "utf8"));
47433
+ return typeof parsed.version === "string" && parseSemver(parsed.version) ? parsed.version : undefined;
47434
+ } catch {
47435
+ return;
47436
+ }
47437
+ }
47438
+ async function refreshUpdateNotice(input) {
47439
+ try {
47440
+ const latestVersion = await fetchLatestVersion(input.fetcher, input.timeoutMs);
47441
+ writeUpdateCache(input.cachePath, {
47442
+ checkedAt: input.now,
47443
+ latestVersion
47444
+ });
47445
+ return createUpdateNotice(input.currentVersion, latestVersion);
47446
+ } catch {
47447
+ return input.fallback;
47448
+ }
47449
+ }
47450
+ async function fetchLatestVersion(fetcher, timeoutMs) {
47451
+ const controller = new AbortController;
47452
+ const timer = setTimeout(() => controller.abort(), Math.max(1, timeoutMs));
47453
+ timer.unref?.();
47454
+ try {
47455
+ const response = await fetcher(UPDATE_REGISTRY_URL, {
47456
+ headers: {
47457
+ accept: "application/json"
47458
+ },
47459
+ signal: controller.signal
47460
+ });
47461
+ if (!response.ok)
47462
+ throw new Error(`npm registry returned ${response.status}`);
47463
+ const parsed = await response.json();
47464
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
47465
+ throw new Error("invalid npm registry response");
47466
+ const version = parsed.version;
47467
+ if (typeof version !== "string" || !parseSemver(version))
47468
+ throw new Error("invalid npm package version");
47469
+ return version;
47470
+ } finally {
47471
+ clearTimeout(timer);
47472
+ }
47473
+ }
47474
+ function writeUpdateCache(path, cache) {
47475
+ try {
47476
+ mkdirSync13(dirname8(path), {
47477
+ recursive: true
47478
+ });
47479
+ const temporary = `${path}.${process.pid}.${Date.now()}.tmp`;
47480
+ writeFileSync14(temporary, `${JSON.stringify(cache)}
47481
+ `, "utf8");
47482
+ renameSync7(temporary, path);
47483
+ } catch {}
47484
+ }
47485
+ function isFreshCache(cache, now) {
47486
+ const age = now - cache.checkedAt;
47487
+ return age >= 0 && age < UPDATE_CACHE_TTL_MS;
47488
+ }
47489
+ function updateCheckDisabled() {
47490
+ return envEnabled(process.env.FARAI_DISABLE_UPDATE_CHECK) || envEnabled(process.env.NO_UPDATE_NOTIFIER);
47491
+ }
47492
+ function envEnabled(value) {
47493
+ return value === "1" || value?.toLowerCase() === "true" || value?.toLowerCase() === "yes";
47494
+ }
47495
+ function parseSemver(value) {
47496
+ const match = value.trim().match(/^(?:v)?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/);
47497
+ if (!match)
47498
+ return;
47499
+ return {
47500
+ core: [Number(match[1]), Number(match[2]), Number(match[3])],
47501
+ prerelease: match[4]?.split(".") ?? []
47502
+ };
47503
+ }
47504
+ function numericIdentifier(value) {
47505
+ if (!/^(0|[1-9]\d*)$/.test(value))
47506
+ return;
47507
+ return Number(value);
47508
+ }
47509
+ var UPDATE_CACHE_TTL_MS, UPDATE_CHECK_TIMEOUT_MS = 4000, UPDATE_REGISTRY_URL = "https://registry.npmjs.org/farai/latest";
47510
+ var init_update_check = __esm(() => {
47511
+ init_config();
47512
+ UPDATE_CACHE_TTL_MS = 20 * 60 * 60 * 1000;
47513
+ });
47514
+
47245
47515
  // src/agent-tui/index.tsx
47246
47516
  var exports_agent_tui = {};
47247
47517
  __export(exports_agent_tui, {
@@ -47265,6 +47535,7 @@ async function runOpenTui(input) {
47265
47535
  let handleRendererDestroy;
47266
47536
  const managedRenderer = await createManagedRenderer(() => handleRendererDestroy?.());
47267
47537
  const renderer = managedRenderer.renderer;
47538
+ const updateCheck = prepareUpdateCheck();
47268
47539
  let done;
47269
47540
  const finished = new Promise((resolve5) => {
47270
47541
  done = resolve5;
@@ -47326,6 +47597,7 @@ async function runOpenTui(input) {
47326
47597
  get children() {
47327
47598
  return createComponent2(TuiStoreProvider, {
47328
47599
  initialSessionId,
47600
+ updateCheck,
47329
47601
  onActiveSessionChange: (sessionId, title) => {
47330
47602
  activeSessionId = sessionId;
47331
47603
  renderer.setTerminalTitle(`farai \xB7 ${title?.trim() || DEFAULT_SESSION_TITLE}`);
@@ -47450,6 +47722,7 @@ var init_agent_tui = __esm(() => {
47450
47722
  init_runtime_port();
47451
47723
  init_session_title();
47452
47724
  init_session_catalog();
47725
+ init_update_check();
47453
47726
  SessionResolutionError = class SessionResolutionError extends Error {
47454
47727
  constructor(query, workspace, sessions2) {
47455
47728
  const recent = sessions2.slice(0, 5).map((session) => ` ${session.id} ${session.title?.trim() || DEFAULT_SESSION_TITLE}`).join(`
@@ -47726,8 +47999,8 @@ var init_csi_cybench_33 = __esm(() => {
47726
47999
 
47727
48000
  // src/agent-benchmark/hash.ts
47728
48001
  import { createHash as createHash7 } from "crypto";
47729
- import { readFileSync as readFileSync19, readdirSync as readdirSync9, statSync as statSync7 } from "fs";
47730
- import { join as join26, relative as relative9 } from "path";
48002
+ import { readFileSync as readFileSync20, readdirSync as readdirSync9, statSync as statSync7 } from "fs";
48003
+ import { join as join27, relative as relative9 } from "path";
47731
48004
  function stableStringify(value) {
47732
48005
  return JSON.stringify(sortValue(value));
47733
48006
  }
@@ -47737,10 +48010,10 @@ function sha256(value) {
47737
48010
  function hashPath(path) {
47738
48011
  const stat = statSync7(path);
47739
48012
  if (stat.isFile())
47740
- return sha256(readFileSync19(path));
48013
+ return sha256(readFileSync20(path));
47741
48014
  if (!stat.isDirectory())
47742
48015
  throw new Error(`unsupported benchmark input type: ${path}`);
47743
- const entries = walk(path).map((entry) => `${relative9(path, entry).replace(/\\/g, "/")}\x00${sha256(readFileSync19(entry))}`);
48016
+ const entries = walk(path).map((entry) => `${relative9(path, entry).replace(/\\/g, "/")}\x00${sha256(readFileSync20(entry))}`);
47744
48017
  return sha256(entries.join(`
47745
48018
  `));
47746
48019
  }
@@ -47798,7 +48071,7 @@ function sortValue(value) {
47798
48071
  function walk(root) {
47799
48072
  const out = [];
47800
48073
  for (const name of readdirSync9(root).sort()) {
47801
- const path = join26(root, name);
48074
+ const path = join27(root, name);
47802
48075
  const stat = statSync7(path);
47803
48076
  if (stat.isDirectory())
47804
48077
  out.push(...walk(path));
@@ -48144,8 +48417,8 @@ __export(exports_csi_suite, {
48144
48417
  loadCsiCampaignConfig: () => loadCsiCampaignConfig,
48145
48418
  generateCsiBenchmarkSuite: () => generateCsiBenchmarkSuite
48146
48419
  });
48147
- import { existsSync as existsSync20, readFileSync as readFileSync20, readdirSync as readdirSync10, statSync as statSync8, writeFileSync as writeFileSync14 } from "fs";
48148
- import { dirname as dirname8, isAbsolute as isAbsolute6, join as join27, relative as relative10, resolve as resolve5 } from "path";
48420
+ import { existsSync as existsSync20, readFileSync as readFileSync21, readdirSync as readdirSync10, statSync as statSync8, writeFileSync as writeFileSync15 } from "fs";
48421
+ import { dirname as dirname9, isAbsolute as isAbsolute6, join as join28, relative as relative10, resolve as resolve5 } from "path";
48149
48422
  async function loadCsiCampaignConfig(path) {
48150
48423
  return normalizeCsiCampaignConfig(JSON.parse(await Bun.file(path).text()));
48151
48424
  }
@@ -48172,7 +48445,7 @@ async function generateCsiBenchmarkSuite(configInput, materialRoot) {
48172
48445
  const promptPath = protectedPath(root, material.promptFile, `${challenge.id}.promptFile`);
48173
48446
  if (!existsSync20(promptPath) || !statSync8(promptPath).isFile())
48174
48447
  throw new Error(`missing prompt file for csi challenge: ${challenge.id}`);
48175
- const prompt = readFileSync20(promptPath, "utf8").trim();
48448
+ const prompt = readFileSync21(promptPath, "utf8").trim();
48176
48449
  if (!prompt)
48177
48450
  throw new Error(`empty prompt file for csi challenge: ${challenge.id}`);
48178
48451
  const files = material.files?.map((file, index) => {
@@ -48279,10 +48552,10 @@ async function generateCsiBenchmarkSuite(configInput, materialRoot) {
48279
48552
  });
48280
48553
  }
48281
48554
  function writeCsiBenchmarkSuite(suite, path) {
48282
- const directory = dirname8(resolve5(path));
48555
+ const directory = dirname9(resolve5(path));
48283
48556
  if (!existsSync20(directory))
48284
48557
  throw new Error(`suite output directory does not exist: ${directory}`);
48285
- writeFileSync14(path, `${JSON.stringify(suite, null, 2)}
48558
+ writeFileSync15(path, `${JSON.stringify(suite, null, 2)}
48286
48559
  `);
48287
48560
  }
48288
48561
  function normalizeCsiCampaignConfig(value) {
@@ -48417,7 +48690,7 @@ function protectedPath(root, path, name) {
48417
48690
  function listFiles(rootPath) {
48418
48691
  if (!statSync8(rootPath).isDirectory())
48419
48692
  return [rootPath];
48420
- return readdirSync10(rootPath).flatMap((name) => listFiles(join27(rootPath, name)));
48693
+ return readdirSync10(rootPath).flatMap((name) => listFiles(join28(rootPath, name)));
48421
48694
  }
48422
48695
  function object2(value, name) {
48423
48696
  if (!value || typeof value !== "object" || Array.isArray(value))
@@ -48475,30 +48748,30 @@ var init_csi_suite = __esm(() => {
48475
48748
 
48476
48749
  // src/agent-benchmark/bundle.ts
48477
48750
  import { createHash as createHash8 } from "crypto";
48478
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "fs";
48479
- import { join as join28 } from "path";
48751
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "fs";
48752
+ import { join as join29 } from "path";
48480
48753
  function writeBenchmarkBundle(bundle, directory) {
48481
- mkdirSync13(directory, {
48754
+ mkdirSync14(directory, {
48482
48755
  recursive: true
48483
48756
  });
48484
48757
  const files = new Map([["manifest.json", json(redactManifest(bundle.manifest))], ["result.json", json(bundle.result)], ["environment.json", json(bundle.result.frozen)], ["sessions.jsonl", jsonl(bundle.sessions)], ["turns.jsonl", jsonl(bundle.turns)], ["messages.jsonl", jsonl(bundle.messages)], ["events.jsonl", jsonl(bundle.events)], ["tool-calls.jsonl", jsonl(bundle.toolCalls)], ["jobs.jsonl", jsonl(bundle.jobs)], ["usage.jsonl", jsonl(bundle.usage)], ["compactions.jsonl", jsonl(bundle.compactions)], ["evidence.jsonl", jsonl(bundle.evidence)]]);
48485
48758
  for (const [name, content] of files)
48486
- writeFileSync15(join28(directory, name), content);
48487
- const checksums = [...files.keys()].sort().map((name) => `${sha2562(readFileSync21(join28(directory, name)))} ${name}`).join(`
48759
+ writeFileSync16(join29(directory, name), content);
48760
+ const checksums = [...files.keys()].sort().map((name) => `${sha2562(readFileSync22(join29(directory, name)))} ${name}`).join(`
48488
48761
  `);
48489
- writeFileSync15(join28(directory, "checksums.sha256"), `${checksums}
48762
+ writeFileSync16(join29(directory, "checksums.sha256"), `${checksums}
48490
48763
  `);
48491
48764
  for (const name of [...files.keys(), "checksums.sha256"])
48492
- chmodSync3(join28(directory, name), 292);
48765
+ chmodSync3(join29(directory, name), 292);
48493
48766
  return directory;
48494
48767
  }
48495
48768
  function writeBenchmarkResult(result, path) {
48496
48769
  const directory = path.slice(0, Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\")));
48497
48770
  if (directory)
48498
- mkdirSync13(directory, {
48771
+ mkdirSync14(directory, {
48499
48772
  recursive: true
48500
48773
  });
48501
- writeFileSync15(path, json(result));
48774
+ writeFileSync16(path, json(result));
48502
48775
  }
48503
48776
  function redactManifest(manifest) {
48504
48777
  return canonicalBenchmarkManifest(manifest);
@@ -48720,26 +48993,26 @@ __export(exports_runner, {
48720
48993
  normalizeBenchmarkManifest: () => normalizeBenchmarkManifest,
48721
48994
  loadBenchmarkManifest: () => loadBenchmarkManifest
48722
48995
  });
48723
- import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync3, readFileSync as readFileSync22, readdirSync as readdirSync11, statSync as statSync9 } from "fs";
48996
+ import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync3, readFileSync as readFileSync23, readdirSync as readdirSync11, statSync as statSync9 } from "fs";
48724
48997
  import { arch, platform, tmpdir as tmpdir4 } from "os";
48725
- import { dirname as dirname9, join as join29, relative as relative11, resolve as resolve7 } from "path";
48998
+ import { dirname as dirname10, join as join30, relative as relative11, resolve as resolve7 } from "path";
48726
48999
  async function runBenchmark(input, options = {}) {
48727
49000
  const manifest = normalizeBenchmarkManifest(input);
48728
49001
  assertExecutableIsolation(manifest);
48729
- const workspace = options.workspace ?? mkdtempSync3(join29(tmpdir4(), "farai-benchmark-"));
48730
- const artifactsRoot = options.artifactsDir ?? mkdtempSync3(join29(tmpdir4(), "farai-benchmark-artifacts-"));
49002
+ const workspace = options.workspace ?? mkdtempSync3(join30(tmpdir4(), "farai-benchmark-"));
49003
+ const artifactsRoot = options.artifactsDir ?? mkdtempSync3(join30(tmpdir4(), "farai-benchmark-artifacts-"));
48731
49004
  const repetition = options.repetition ?? 1;
48732
- mkdirSync14(workspace, {
49005
+ mkdirSync15(workspace, {
48733
49006
  recursive: true
48734
49007
  });
48735
49008
  assertCleanWorkspace(workspace);
48736
49009
  assertArtifactsOutsideWorkspace(workspace, artifactsRoot);
48737
- mkdirSync14(artifactsRoot, {
49010
+ mkdirSync15(artifactsRoot, {
48738
49011
  recursive: true
48739
49012
  });
48740
49013
  stageFiles(manifest, workspace);
48741
49014
  const runId = id();
48742
- const bundlePath = join29(artifactsRoot, `${safeName2(manifest.challenge.id)}-r${repetition}-${runId}`);
49015
+ const bundlePath = join30(artifactsRoot, `${safeName2(manifest.challenge.id)}-r${repetition}-${runId}`);
48743
49016
  const provider = options.provider ?? await createChatProviderForSession(syntheticSession(workspace, manifest));
48744
49017
  assertProvider(manifest, provider);
48745
49018
  const dockerLifecycle = manifest.isolation.backend === "docker" ? new BenchmarkDockerLifecycle(manifest, workspace, runId, options.dockerProcessRunner) : undefined;
@@ -49026,7 +49299,7 @@ function stageFiles(manifest, workspace) {
49026
49299
  const target = resolve7(workspace, file.destination);
49027
49300
  if (relative11(workspace, target).startsWith(".."))
49028
49301
  throw new Error(`benchmark destination escapes scratch workspace: ${file.destination}`);
49029
- mkdirSync14(dirname9(target), {
49302
+ mkdirSync15(dirname10(target), {
49030
49303
  recursive: true
49031
49304
  });
49032
49305
  cpSync(source, target, {
@@ -49043,7 +49316,7 @@ function listFiles2(rootPath) {
49043
49316
  return [];
49044
49317
  if (!statSync9(rootPath).isDirectory())
49045
49318
  return [rootPath];
49046
- return readdirSync11(rootPath).flatMap((name) => listFiles2(join29(rootPath, name)));
49319
+ return readdirSync11(rootPath).flatMap((name) => listFiles2(join30(rootPath, name)));
49047
49320
  }
49048
49321
 
49049
49322
  class BenchmarkHostBackend {
@@ -49087,7 +49360,7 @@ class BenchmarkHostBackend {
49087
49360
  hostPath(path) {
49088
49361
  if (path === "/workspace")
49089
49362
  return this.workspace;
49090
- return join29(this.workspace, path.slice("/workspace/".length));
49363
+ return join30(this.workspace, path.slice("/workspace/".length));
49091
49364
  }
49092
49365
  }
49093
49366
  function freezeRun(manifest, session, tools, faraiRoot, provider, kaliImageId) {
@@ -49141,7 +49414,7 @@ function freezeRun(manifest, session, tools, faraiRoot, provider, kaliImageId) {
49141
49414
  })),
49142
49415
  kaliImage: kaliImageId ?? DEFAULT_KALI_IMAGE,
49143
49416
  kaliContract: KALI_IMAGE_CONTRACT,
49144
- kaliToolManifestHash: sha256(readFileSync22(KALI_TOOL_MANIFEST_PATH)),
49417
+ kaliToolManifestHash: sha256(readFileSync23(KALI_TOOL_MANIFEST_PATH)),
49145
49418
  ...manifest.challenge.targetImage ? {
49146
49419
  targetImage: manifest.challenge.targetImage
49147
49420
  } : {},
@@ -49355,16 +49628,16 @@ __export(exports_suite, {
49355
49628
  normalizeBenchmarkSuiteManifest: () => normalizeBenchmarkSuiteManifest,
49356
49629
  loadBenchmarkSuiteManifest: () => loadBenchmarkSuiteManifest
49357
49630
  });
49358
- import { mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync4, writeFileSync as writeFileSync16 } from "fs";
49631
+ import { mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync4, writeFileSync as writeFileSync17 } from "fs";
49359
49632
  import { tmpdir as tmpdir5 } from "os";
49360
- import { join as join30 } from "path";
49633
+ import { join as join31 } from "path";
49361
49634
  async function runBenchmarkSuite(input, options = {}) {
49362
49635
  const manifest = normalizeBenchmarkSuiteManifest(input);
49363
49636
  const campaignId = id();
49364
- const root = options.artifactsDir ?? mkdtempSync4(join30(tmpdir5(), "farai-benchmark-campaign-"));
49365
- const bundlePath = join30(root, `${safeName3(manifest.id)}-${campaignId}`);
49366
- const runsPath = join30(bundlePath, "runs");
49367
- mkdirSync15(runsPath, {
49637
+ const root = options.artifactsDir ?? mkdtempSync4(join31(tmpdir5(), "farai-benchmark-campaign-"));
49638
+ const bundlePath = join31(root, `${safeName3(manifest.id)}-${campaignId}`);
49639
+ const runsPath = join31(bundlePath, "runs");
49640
+ mkdirSync16(runsPath, {
49368
49641
  recursive: true
49369
49642
  });
49370
49643
  const attempts = [];
@@ -49457,9 +49730,9 @@ async function runBenchmarkSuite(input, options = {}) {
49457
49730
  error: outcome.error
49458
49731
  })
49459
49732
  };
49460
- writeFileSync16(join30(bundlePath, "campaign.json"), `${JSON.stringify(result, null, 2)}
49733
+ writeFileSync17(join31(bundlePath, "campaign.json"), `${JSON.stringify(result, null, 2)}
49461
49734
  `);
49462
- writeFileSync16(join30(bundlePath, "suite.sha256"), `${result.manifestHash}
49735
+ writeFileSync17(join31(bundlePath, "suite.sha256"), `${result.manifestHash}
49463
49736
  `);
49464
49737
  return result;
49465
49738
  }
@@ -49511,8 +49784,9 @@ init_model_catalog();
49511
49784
  init_model_profiles();
49512
49785
  init_global_config();
49513
49786
  init_config();
49514
- import { readFileSync as readFileSync23 } from "fs";
49515
- import { join as join31 } from "path";
49787
+ init_branding();
49788
+ import { readFileSync as readFileSync24 } from "fs";
49789
+ import { join as join32 } from "path";
49516
49790
  var [, , command, ...args2] = process.argv;
49517
49791
  if (command === "--version" || command === "-v" || command === "version") {
49518
49792
  console.log(packageVersion());
@@ -49626,7 +49900,9 @@ async function setup(args3) {
49626
49900
  const baseUrl = flag(args3, "--base-url") ?? flag(args3, "--baseURL");
49627
49901
  const apiKeyEnv = flag(args3, "--api-key-env");
49628
49902
  const setDefault = args3.includes("--set-default") || args3.includes("--default") || Boolean(model);
49629
- console.log("[*] setting up Farai");
49903
+ console.log(FARAI_BANNER);
49904
+ console.log();
49905
+ console.log("[*] setting up farai");
49630
49906
  console.log(`[+] config: ${globalConfigPath()}`);
49631
49907
  console.log(`[+] auth: ${authPath("global")}`);
49632
49908
  if (model) {
@@ -49926,7 +50202,7 @@ function parseProviderModel(value) {
49926
50202
  }
49927
50203
  function packageVersion() {
49928
50204
  try {
49929
- const raw = readFileSync23(join31(import.meta.dir, "..", "..", "package.json"), "utf8");
50205
+ const raw = readFileSync24(join32(import.meta.dir, "..", "..", "package.json"), "utf8");
49930
50206
  const parsed = JSON.parse(raw);
49931
50207
  return typeof parsed.version === "string" ? parsed.version : "0.0.0";
49932
50208
  } catch {
@@ -50027,5 +50303,5 @@ Examples:
50027
50303
  `);
50028
50304
  }
50029
50305
 
50030
- //# debugId=B5CAF1E621BDD38864756E2164756E21
50306
+ //# debugId=A6CB55D8D7667DD664756E2164756E21
50031
50307
  //# sourceMappingURL=index.js.map