nairon-bench 0.0.18 → 0.0.19

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.
Files changed (2) hide show
  1. package/dist/index.js +2495 -1646
  2. package/package.json +7 -15
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ var __export = (target, all) => {
30
30
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
31
31
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
32
32
 
33
- // ../../node_modules/.bun/consola@3.4.2/node_modules/consola/dist/core.mjs
33
+ // ../../node_modules/consola/dist/core.mjs
34
34
  function isPlainObject$1(value) {
35
35
  if (value === null || typeof value !== "object") {
36
36
  return false;
@@ -429,7 +429,7 @@ var init_core = __esm(() => {
429
429
  Consola.prototype.resume = Consola.prototype.resumeLogs;
430
430
  });
431
431
 
432
- // ../../node_modules/.bun/consola@3.4.2/node_modules/consola/dist/shared/consola.DRwqZj3T.mjs
432
+ // ../../node_modules/consola/dist/shared/consola.DRwqZj3T.mjs
433
433
  import { formatWithOptions } from "node:util";
434
434
  import { sep } from "node:path";
435
435
  function parseStack(stack, message) {
@@ -507,7 +507,7 @@ ${indent}`);
507
507
  var bracket = (x) => x ? `[${x}]` : "";
508
508
  var init_consola_DRwqZj3T = () => {};
509
509
 
510
- // ../../node_modules/.bun/consola@3.4.2/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs
510
+ // ../../node_modules/consola/dist/shared/consola.DXBYu-KD.mjs
511
511
  import * as tty from "node:tty";
512
512
  function replaceClose(index, string, close, replace, head = string.slice(0, Math.max(0, index)) + replace, tail = string.slice(Math.max(0, index + close.length)), next = tail.indexOf(close)) {
513
513
  return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
@@ -723,7 +723,7 @@ var init_consola_DXBYu_KD = __esm(() => {
723
723
  };
724
724
  });
725
725
 
726
- // ../../node_modules/.bun/consola@3.4.2/node_modules/consola/dist/chunks/prompt.mjs
726
+ // ../../node_modules/consola/dist/chunks/prompt.mjs
727
727
  var exports_prompt = {};
728
728
  __export(exports_prompt, {
729
729
  prompt: () => prompt,
@@ -1479,7 +1479,7 @@ var init_prompt = __esm(() => {
1479
1479
  kCancel = Symbol.for("cancel");
1480
1480
  });
1481
1481
 
1482
- // ../../node_modules/.bun/consola@3.4.2/node_modules/consola/dist/index.mjs
1482
+ // ../../node_modules/consola/dist/index.mjs
1483
1483
  import g$1 from "node:process";
1484
1484
  function b() {
1485
1485
  if (globalThis.process?.env)
@@ -1767,7 +1767,7 @@ ${indent}`);
1767
1767
  consola = createConsola2();
1768
1768
  });
1769
1769
 
1770
- // ../../node_modules/.bun/ms@2.1.3/node_modules/ms/index.js
1770
+ // ../../node_modules/ms/index.js
1771
1771
  var require_ms = __commonJS((exports, module) => {
1772
1772
  var s2 = 1000;
1773
1773
  var m2 = s2 * 60;
@@ -1877,7 +1877,7 @@ var require_ms = __commonJS((exports, module) => {
1877
1877
  }
1878
1878
  });
1879
1879
 
1880
- // ../../node_modules/.bun/debug@4.4.3/node_modules/debug/src/common.js
1880
+ // ../../node_modules/debug/src/common.js
1881
1881
  var require_common = __commonJS((exports, module) => {
1882
1882
  function setup(env2) {
1883
1883
  createDebug.debug = createDebug;
@@ -2052,7 +2052,7 @@ var require_common = __commonJS((exports, module) => {
2052
2052
  module.exports = setup;
2053
2053
  });
2054
2054
 
2055
- // ../../node_modules/.bun/debug@4.4.3/node_modules/debug/src/browser.js
2055
+ // ../../node_modules/debug/src/browser.js
2056
2056
  var require_browser = __commonJS((exports, module) => {
2057
2057
  exports.formatArgs = formatArgs;
2058
2058
  exports.save = save;
@@ -2212,7 +2212,7 @@ var require_browser = __commonJS((exports, module) => {
2212
2212
  };
2213
2213
  });
2214
2214
 
2215
- // ../../node_modules/.bun/debug@4.4.3/node_modules/debug/src/node.js
2215
+ // ../../node_modules/debug/src/node.js
2216
2216
  var require_node = __commonJS((exports, module) => {
2217
2217
  var tty2 = __require("tty");
2218
2218
  var util = __require("util");
@@ -2383,7 +2383,7 @@ var require_node = __commonJS((exports, module) => {
2383
2383
  };
2384
2384
  });
2385
2385
 
2386
- // ../../node_modules/.bun/debug@4.4.3/node_modules/debug/src/index.js
2386
+ // ../../node_modules/debug/src/index.js
2387
2387
  var require_src = __commonJS((exports, module) => {
2388
2388
  if (typeof process === "undefined" || process.type === "renderer" || false || process.__nwjs) {
2389
2389
  module.exports = require_browser();
@@ -2392,7 +2392,7 @@ var require_src = __commonJS((exports, module) => {
2392
2392
  }
2393
2393
  });
2394
2394
 
2395
- // ../../node_modules/.bun/@kwsites+file-exists@1.1.1/node_modules/@kwsites/file-exists/dist/src/index.js
2395
+ // ../../node_modules/@kwsites/file-exists/dist/src/index.js
2396
2396
  var require_src2 = __commonJS((exports) => {
2397
2397
  var __importDefault = exports && exports.__importDefault || function(mod) {
2398
2398
  return mod && mod.__esModule ? mod : { default: mod };
@@ -2433,7 +2433,7 @@ var require_src2 = __commonJS((exports) => {
2433
2433
  exports.READABLE = exports.FILE + exports.FOLDER;
2434
2434
  });
2435
2435
 
2436
- // ../../node_modules/.bun/@kwsites+file-exists@1.1.1/node_modules/@kwsites/file-exists/dist/index.js
2436
+ // ../../node_modules/@kwsites/file-exists/dist/index.js
2437
2437
  var require_dist = __commonJS((exports) => {
2438
2438
  function __export2(m2) {
2439
2439
  for (var p in m2)
@@ -2444,7 +2444,7 @@ var require_dist = __commonJS((exports) => {
2444
2444
  __export2(require_src2());
2445
2445
  });
2446
2446
 
2447
- // ../../node_modules/.bun/@kwsites+promise-deferred@1.1.1/node_modules/@kwsites/promise-deferred/dist/index.js
2447
+ // ../../node_modules/@kwsites/promise-deferred/dist/index.js
2448
2448
  var require_dist2 = __commonJS((exports) => {
2449
2449
  Object.defineProperty(exports, "__esModule", { value: true });
2450
2450
  exports.createDeferred = exports.deferred = undefined;
@@ -2483,10 +2483,10 @@ var require_dist2 = __commonJS((exports) => {
2483
2483
  exports.default = deferred;
2484
2484
  });
2485
2485
 
2486
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/index.js
2486
+ // ../../node_modules/convex/dist/esm/index.js
2487
2487
  var version = "1.31.7";
2488
2488
 
2489
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/values/base64.js
2489
+ // ../../node_modules/convex/dist/esm/values/base64.js
2490
2490
  function getLens(b64) {
2491
2491
  var len2 = b64.length;
2492
2492
  if (len2 % 4 > 0) {
@@ -2570,7 +2570,7 @@ var init_base64 = __esm(() => {
2570
2570
  revLookup[95] = 63;
2571
2571
  });
2572
2572
 
2573
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/common/index.js
2573
+ // ../../node_modules/convex/dist/esm/common/index.js
2574
2574
  function parseArgs2(args) {
2575
2575
  if (args === undefined) {
2576
2576
  return {};
@@ -2606,7 +2606,7 @@ function isSimpleObject(value) {
2606
2606
  return isObject && isSimple;
2607
2607
  }
2608
2608
 
2609
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/values/value.js
2609
+ // ../../node_modules/convex/dist/esm/values/value.js
2610
2610
  function isSpecial(n2) {
2611
2611
  return Number.isNaN(n2) || !Number.isFinite(n2) || Object.is(n2, -0);
2612
2612
  }
@@ -2847,1241 +2847,959 @@ var init_value = __esm(() => {
2847
2847
  base64ToBigInt = DataView.prototype.getBigInt64 ? modernBase64ToBigInt : slowBase64ToBigInt;
2848
2848
  });
2849
2849
 
2850
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/values/errors.js
2851
- var __defProp3, __defNormalProp = (obj, key, value) => (key in obj) ? __defProp3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), _a2, _b, IDENTIFYING_FIELD, ConvexError;
2852
- var init_errors = __esm(() => {
2853
- init_value();
2854
- __defProp3 = Object.defineProperty;
2855
- IDENTIFYING_FIELD = Symbol.for("ConvexError");
2856
- ConvexError = class ConvexError extends (_b = Error, _a2 = IDENTIFYING_FIELD, _b) {
2857
- constructor(data) {
2858
- super(typeof data === "string" ? data : stringifyValueForError(data));
2859
- __publicField(this, "name", "ConvexError");
2860
- __publicField(this, "data");
2861
- __publicField(this, _a2, true);
2862
- this.data = data;
2863
- }
2864
- };
2865
- });
2866
-
2867
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/values/index.js
2868
- var init_values = __esm(() => {
2869
- init_value();
2870
- init_errors();
2871
- });
2872
-
2873
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/browser/logging.js
2874
- function prefix_for_source(source) {
2875
- switch (source) {
2876
- case "query":
2877
- return "Q";
2878
- case "mutation":
2879
- return "M";
2880
- case "action":
2881
- return "A";
2882
- case "any":
2883
- return "?";
2884
- }
2850
+ // ../../node_modules/convex/dist/esm/values/validators.js
2851
+ function throwUndefinedValidatorError(context, fieldName) {
2852
+ const fieldInfo = fieldName !== undefined ? ` for field "${fieldName}"` : "";
2853
+ throw new Error(`A validator is undefined${fieldInfo} in ${context}. This is often caused by circular imports. See ${UNDEFINED_VALIDATOR_ERROR_URL} for details.`);
2885
2854
  }
2886
2855
 
2887
- class DefaultLogger {
2888
- constructor(options) {
2889
- __publicField2(this, "_onLogLineFuncs");
2890
- __publicField2(this, "_verbose");
2891
- this._onLogLineFuncs = {};
2892
- this._verbose = options.verbose;
2856
+ class BaseValidator {
2857
+ constructor({ isOptional }) {
2858
+ __publicField(this, "type");
2859
+ __publicField(this, "fieldPaths");
2860
+ __publicField(this, "isOptional");
2861
+ __publicField(this, "isConvexValidator");
2862
+ this.isOptional = isOptional;
2863
+ this.isConvexValidator = true;
2893
2864
  }
2894
- addLogLineListener(func) {
2895
- let id = Math.random().toString(36).substring(2, 15);
2896
- for (let i3 = 0;i3 < 10; i3++) {
2897
- if (this._onLogLineFuncs[id] === undefined) {
2898
- break;
2865
+ }
2866
+ var __defProp3, __defNormalProp = (obj, key, value) => (key in obj) ? __defProp3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), UNDEFINED_VALIDATOR_ERROR_URL = "https://docs.convex.dev/error#undefined-validator", VId, VFloat64, VInt64, VBoolean, VBytes, VString, VNull, VAny, VObject, VLiteral, VArray, VRecord, VUnion;
2867
+ var init_validators = __esm(() => {
2868
+ init_value();
2869
+ __defProp3 = Object.defineProperty;
2870
+ VId = class VId extends BaseValidator {
2871
+ constructor({
2872
+ isOptional,
2873
+ tableName
2874
+ }) {
2875
+ super({ isOptional });
2876
+ __publicField(this, "tableName");
2877
+ __publicField(this, "kind", "id");
2878
+ if (typeof tableName !== "string") {
2879
+ throw new Error("v.id(tableName) requires a string");
2899
2880
  }
2900
- id = Math.random().toString(36).substring(2, 15);
2881
+ this.tableName = tableName;
2901
2882
  }
2902
- this._onLogLineFuncs[id] = func;
2903
- return () => {
2904
- delete this._onLogLineFuncs[id];
2905
- };
2906
- }
2907
- logVerbose(...args) {
2908
- if (this._verbose) {
2909
- for (const func of Object.values(this._onLogLineFuncs)) {
2910
- func("debug", `${(/* @__PURE__ */ new Date()).toISOString()}`, ...args);
2911
- }
2883
+ get json() {
2884
+ return { type: "id", tableName: this.tableName };
2912
2885
  }
2913
- }
2914
- log(...args) {
2915
- for (const func of Object.values(this._onLogLineFuncs)) {
2916
- func("info", ...args);
2886
+ asOptional() {
2887
+ return new VId({
2888
+ isOptional: "optional",
2889
+ tableName: this.tableName
2890
+ });
2917
2891
  }
2918
- }
2919
- warn(...args) {
2920
- for (const func of Object.values(this._onLogLineFuncs)) {
2921
- func("warn", ...args);
2892
+ };
2893
+ VFloat64 = class VFloat64 extends BaseValidator {
2894
+ constructor() {
2895
+ super(...arguments);
2896
+ __publicField(this, "kind", "float64");
2922
2897
  }
2923
- }
2924
- error(...args) {
2925
- for (const func of Object.values(this._onLogLineFuncs)) {
2926
- func("error", ...args);
2898
+ get json() {
2899
+ return { type: "number" };
2927
2900
  }
2928
- }
2929
- }
2930
- function instantiateDefaultLogger(options) {
2931
- const logger = new DefaultLogger(options);
2932
- logger.addLogLineListener((level, ...args) => {
2933
- switch (level) {
2934
- case "debug":
2935
- console.debug(...args);
2936
- break;
2937
- case "info":
2938
- console.log(...args);
2939
- break;
2940
- case "warn":
2941
- console.warn(...args);
2942
- break;
2943
- case "error":
2944
- console.error(...args);
2945
- break;
2946
- default: {
2947
- console.log(...args);
2948
- }
2901
+ asOptional() {
2902
+ return new VFloat64({
2903
+ isOptional: "optional"
2904
+ });
2949
2905
  }
2950
- });
2951
- return logger;
2952
- }
2953
- function instantiateNoopLogger(options) {
2954
- return new DefaultLogger(options);
2955
- }
2956
- function logForFunction(logger, type, source, udfPath, message) {
2957
- const prefix = prefix_for_source(source);
2958
- if (typeof message === "object") {
2959
- message = `ConvexError ${JSON.stringify(message.errorData, null, 2)}`;
2960
- }
2961
- if (type === "info") {
2962
- const match = message.match(/^\[.*?\] /);
2963
- if (match === null) {
2964
- logger.error(`[CONVEX ${prefix}(${udfPath})] Could not parse console.log`);
2965
- return;
2906
+ };
2907
+ VInt64 = class VInt64 extends BaseValidator {
2908
+ constructor() {
2909
+ super(...arguments);
2910
+ __publicField(this, "kind", "int64");
2966
2911
  }
2967
- const level = message.slice(1, match[0].length - 2);
2968
- const args = message.slice(match[0].length);
2969
- logger.log(`%c[CONVEX ${prefix}(${udfPath})] [${level}]`, INFO_COLOR, args);
2970
- } else {
2971
- logger.error(`[CONVEX ${prefix}(${udfPath})] ${message}`);
2972
- }
2973
- }
2974
- var __defProp4, __defNormalProp2 = (obj, key, value) => (key in obj) ? __defProp4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value), INFO_COLOR = "color:rgb(0, 145, 255)";
2975
- var init_logging = __esm(() => {
2976
- __defProp4 = Object.defineProperty;
2977
- });
2978
-
2979
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/server/functionName.js
2980
- var functionName;
2981
- var init_functionName = __esm(() => {
2982
- functionName = Symbol.for("functionName");
2983
- });
2984
-
2985
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/server/components/paths.js
2986
- function extractReferencePath(reference) {
2987
- return reference[toReferencePath] ?? null;
2988
- }
2989
- function isFunctionHandle(s2) {
2990
- return s2.startsWith("function://");
2991
- }
2992
- function getFunctionAddress(functionReference) {
2993
- let functionAddress;
2994
- if (typeof functionReference === "string") {
2995
- if (isFunctionHandle(functionReference)) {
2996
- functionAddress = { functionHandle: functionReference };
2997
- } else {
2998
- functionAddress = { name: functionReference };
2912
+ get json() {
2913
+ return { type: "bigint" };
2999
2914
  }
3000
- } else if (functionReference[functionName]) {
3001
- functionAddress = { name: functionReference[functionName] };
3002
- } else {
3003
- const referencePath = extractReferencePath(functionReference);
3004
- if (!referencePath) {
3005
- throw new Error(`${functionReference} is not a functionReference`);
2915
+ asOptional() {
2916
+ return new VInt64({ isOptional: "optional" });
3006
2917
  }
3007
- functionAddress = { reference: referencePath };
3008
- }
3009
- return functionAddress;
3010
- }
3011
- var toReferencePath;
3012
- var init_paths = __esm(() => {
3013
- init_functionName();
3014
- toReferencePath = Symbol.for("toReferencePath");
3015
- });
3016
-
3017
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/server/api.js
3018
- function getFunctionName(functionReference) {
3019
- const address = getFunctionAddress(functionReference);
3020
- if (address.name === undefined) {
3021
- if (address.functionHandle !== undefined) {
3022
- throw new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received function handle ${address.functionHandle}`);
3023
- } else if (address.reference !== undefined) {
3024
- throw new Error(`Expected function reference in the current component like "api.file.func" or "internal.file.func", but received reference ${address.reference}`);
2918
+ };
2919
+ VBoolean = class VBoolean extends BaseValidator {
2920
+ constructor() {
2921
+ super(...arguments);
2922
+ __publicField(this, "kind", "boolean");
3025
2923
  }
3026
- throw new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received ${JSON.stringify(address)}`);
3027
- }
3028
- if (typeof functionReference === "string")
3029
- return functionReference;
3030
- const name = functionReference[functionName];
3031
- if (!name) {
3032
- throw new Error(`${functionReference} is not a functionReference`);
3033
- }
3034
- return name;
3035
- }
3036
- function createApi(pathParts = []) {
3037
- const handler = {
3038
- get(_3, prop) {
3039
- if (typeof prop === "string") {
3040
- const newParts = [...pathParts, prop];
3041
- return createApi(newParts);
3042
- } else if (prop === functionName) {
3043
- if (pathParts.length < 2) {
3044
- const found = ["api", ...pathParts].join(".");
3045
- throw new Error(`API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`${found}\``);
3046
- }
3047
- const path = pathParts.slice(0, -1).join("/");
3048
- const exportName = pathParts[pathParts.length - 1];
3049
- if (exportName === "default") {
3050
- return path;
3051
- } else {
3052
- return path + ":" + exportName;
3053
- }
3054
- } else if (prop === Symbol.toStringTag) {
3055
- return "FunctionReference";
3056
- } else {
3057
- return;
3058
- }
2924
+ get json() {
2925
+ return { type: this.kind };
2926
+ }
2927
+ asOptional() {
2928
+ return new VBoolean({
2929
+ isOptional: "optional"
2930
+ });
3059
2931
  }
3060
2932
  };
3061
- return new Proxy({}, handler);
3062
- }
3063
- var anyApi;
3064
- var init_api = __esm(() => {
3065
- init_functionName();
3066
- init_paths();
3067
- anyApi = createApi();
3068
- });
3069
-
3070
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/browser/http_client.js
3071
- class ConvexHttpClient {
3072
- constructor(address, options) {
3073
- __publicField3(this, "address");
3074
- __publicField3(this, "auth");
3075
- __publicField3(this, "adminAuth");
3076
- __publicField3(this, "encodedTsPromise");
3077
- __publicField3(this, "debug");
3078
- __publicField3(this, "fetchOptions");
3079
- __publicField3(this, "fetch");
3080
- __publicField3(this, "logger");
3081
- __publicField3(this, "mutationQueue", []);
3082
- __publicField3(this, "isProcessingQueue", false);
3083
- if (typeof options === "boolean") {
3084
- throw new Error("skipConvexDeploymentUrlCheck as the second argument is no longer supported. Please pass an options object, `{ skipConvexDeploymentUrlCheck: true }`.");
2933
+ VBytes = class VBytes extends BaseValidator {
2934
+ constructor() {
2935
+ super(...arguments);
2936
+ __publicField(this, "kind", "bytes");
3085
2937
  }
3086
- const opts = options ?? {};
3087
- if (opts.skipConvexDeploymentUrlCheck !== true) {
3088
- validateDeploymentUrl(address);
2938
+ get json() {
2939
+ return { type: this.kind };
3089
2940
  }
3090
- this.logger = options?.logger === false ? instantiateNoopLogger({ verbose: false }) : options?.logger !== true && options?.logger ? options.logger : instantiateDefaultLogger({ verbose: false });
3091
- this.address = address;
3092
- this.debug = true;
3093
- this.auth = undefined;
3094
- this.adminAuth = undefined;
3095
- this.fetch = options?.fetch;
3096
- if (options?.auth) {
3097
- this.setAuth(options.auth);
2941
+ asOptional() {
2942
+ return new VBytes({ isOptional: "optional" });
3098
2943
  }
3099
- }
3100
- backendUrl() {
3101
- return `${this.address}/api`;
3102
- }
3103
- get url() {
3104
- return this.address;
3105
- }
3106
- setAuth(value) {
3107
- this.clearAuth();
3108
- this.auth = value;
3109
- }
3110
- setAdminAuth(token, actingAsIdentity) {
3111
- this.clearAuth();
3112
- if (actingAsIdentity !== undefined) {
3113
- const bytes = new TextEncoder().encode(JSON.stringify(actingAsIdentity));
3114
- const actingAsIdentityEncoded = btoa(String.fromCodePoint(...bytes));
3115
- this.adminAuth = `${token}:${actingAsIdentityEncoded}`;
3116
- } else {
3117
- this.adminAuth = token;
2944
+ };
2945
+ VString = class VString extends BaseValidator {
2946
+ constructor() {
2947
+ super(...arguments);
2948
+ __publicField(this, "kind", "string");
3118
2949
  }
3119
- }
3120
- clearAuth() {
3121
- this.auth = undefined;
3122
- this.adminAuth = undefined;
3123
- }
3124
- setDebug(debug2) {
3125
- this.debug = debug2;
3126
- }
3127
- setFetchOptions(fetchOptions) {
3128
- this.fetchOptions = fetchOptions;
3129
- }
3130
- async consistentQuery(query, ...args) {
3131
- const queryArgs = parseArgs2(args[0]);
3132
- const timestampPromise = this.getTimestamp();
3133
- return await this.queryInner(query, queryArgs, { timestampPromise });
3134
- }
3135
- async getTimestamp() {
3136
- if (this.encodedTsPromise) {
3137
- return this.encodedTsPromise;
2950
+ get json() {
2951
+ return { type: this.kind };
3138
2952
  }
3139
- return this.encodedTsPromise = this.getTimestampInner();
3140
- }
3141
- async getTimestampInner() {
3142
- const localFetch = this.fetch || specifiedFetch || fetch;
3143
- const headers = {
3144
- "Content-Type": "application/json",
3145
- "Convex-Client": `npm-${version}`
3146
- };
3147
- const response = await localFetch(`${this.address}/api/query_ts`, {
3148
- ...this.fetchOptions,
3149
- method: "POST",
3150
- headers
3151
- });
3152
- if (!response.ok) {
3153
- throw new Error(await response.text());
2953
+ asOptional() {
2954
+ return new VString({
2955
+ isOptional: "optional"
2956
+ });
3154
2957
  }
3155
- const { ts } = await response.json();
3156
- return ts;
3157
- }
3158
- async query(query, ...args) {
3159
- const queryArgs = parseArgs2(args[0]);
3160
- return await this.queryInner(query, queryArgs, {});
3161
- }
3162
- async queryInner(query, queryArgs, options) {
3163
- const name = getFunctionName(query);
3164
- const args = [convexToJson(queryArgs)];
3165
- const headers = {
3166
- "Content-Type": "application/json",
3167
- "Convex-Client": `npm-${version}`
3168
- };
3169
- if (this.adminAuth) {
3170
- headers["Authorization"] = `Convex ${this.adminAuth}`;
3171
- } else if (this.auth) {
3172
- headers["Authorization"] = `Bearer ${this.auth}`;
2958
+ };
2959
+ VNull = class VNull extends BaseValidator {
2960
+ constructor() {
2961
+ super(...arguments);
2962
+ __publicField(this, "kind", "null");
3173
2963
  }
3174
- const localFetch = this.fetch || specifiedFetch || fetch;
3175
- const timestamp = options.timestampPromise ? await options.timestampPromise : undefined;
3176
- const body = JSON.stringify({
3177
- path: name,
3178
- format: "convex_encoded_json",
3179
- args,
3180
- ...timestamp ? { ts: timestamp } : {}
3181
- });
3182
- const endpoint = timestamp ? `${this.address}/api/query_at_ts` : `${this.address}/api/query`;
3183
- const response = await localFetch(endpoint, {
3184
- ...this.fetchOptions,
3185
- body,
3186
- method: "POST",
3187
- headers
3188
- });
3189
- if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3190
- throw new Error(await response.text());
2964
+ get json() {
2965
+ return { type: this.kind };
3191
2966
  }
3192
- const respJSON = await response.json();
3193
- if (this.debug) {
3194
- for (const line of respJSON.logLines ?? []) {
3195
- logForFunction(this.logger, "info", "query", name, line);
3196
- }
2967
+ asOptional() {
2968
+ return new VNull({ isOptional: "optional" });
3197
2969
  }
3198
- switch (respJSON.status) {
3199
- case "success":
3200
- return jsonToConvex(respJSON.value);
3201
- case "error":
3202
- if (respJSON.errorData !== undefined) {
3203
- throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
2970
+ };
2971
+ VAny = class VAny extends BaseValidator {
2972
+ constructor() {
2973
+ super(...arguments);
2974
+ __publicField(this, "kind", "any");
2975
+ }
2976
+ get json() {
2977
+ return {
2978
+ type: this.kind
2979
+ };
2980
+ }
2981
+ asOptional() {
2982
+ return new VAny({
2983
+ isOptional: "optional"
2984
+ });
2985
+ }
2986
+ };
2987
+ VObject = class VObject extends BaseValidator {
2988
+ constructor({
2989
+ isOptional,
2990
+ fields
2991
+ }) {
2992
+ super({ isOptional });
2993
+ __publicField(this, "fields");
2994
+ __publicField(this, "kind", "object");
2995
+ globalThis.Object.entries(fields).forEach(([fieldName, validator]) => {
2996
+ if (validator === undefined) {
2997
+ throwUndefinedValidatorError("v.object()", fieldName);
3204
2998
  }
3205
- throw new Error(respJSON.errorMessage);
3206
- default:
3207
- throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
2999
+ if (!validator.isConvexValidator) {
3000
+ throw new Error("v.object() entries must be validators");
3001
+ }
3002
+ });
3003
+ this.fields = fields;
3208
3004
  }
3209
- }
3210
- async mutationInner(mutation, mutationArgs) {
3211
- const name = getFunctionName(mutation);
3212
- const body = JSON.stringify({
3213
- path: name,
3214
- format: "convex_encoded_json",
3215
- args: [convexToJson(mutationArgs)]
3216
- });
3217
- const headers = {
3218
- "Content-Type": "application/json",
3219
- "Convex-Client": `npm-${version}`
3220
- };
3221
- if (this.adminAuth) {
3222
- headers["Authorization"] = `Convex ${this.adminAuth}`;
3223
- } else if (this.auth) {
3224
- headers["Authorization"] = `Bearer ${this.auth}`;
3005
+ get json() {
3006
+ return {
3007
+ type: this.kind,
3008
+ value: globalThis.Object.fromEntries(globalThis.Object.entries(this.fields).map(([k2, v2]) => [
3009
+ k2,
3010
+ {
3011
+ fieldType: v2.json,
3012
+ optional: v2.isOptional === "optional" ? true : false
3013
+ }
3014
+ ]))
3015
+ };
3225
3016
  }
3226
- const localFetch = this.fetch || specifiedFetch || fetch;
3227
- const response = await localFetch(`${this.address}/api/mutation`, {
3228
- ...this.fetchOptions,
3229
- body,
3230
- method: "POST",
3231
- headers
3232
- });
3233
- if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3234
- throw new Error(await response.text());
3017
+ asOptional() {
3018
+ return new VObject({
3019
+ isOptional: "optional",
3020
+ fields: this.fields
3021
+ });
3235
3022
  }
3236
- const respJSON = await response.json();
3237
- if (this.debug) {
3238
- for (const line of respJSON.logLines ?? []) {
3239
- logForFunction(this.logger, "info", "mutation", name, line);
3023
+ omit(...fields) {
3024
+ const newFields = { ...this.fields };
3025
+ for (const field of fields) {
3026
+ delete newFields[field];
3240
3027
  }
3028
+ return new VObject({
3029
+ isOptional: this.isOptional,
3030
+ fields: newFields
3031
+ });
3241
3032
  }
3242
- switch (respJSON.status) {
3243
- case "success":
3244
- return jsonToConvex(respJSON.value);
3245
- case "error":
3246
- if (respJSON.errorData !== undefined) {
3247
- throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3248
- }
3249
- throw new Error(respJSON.errorMessage);
3250
- default:
3251
- throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3252
- }
3253
- }
3254
- async processMutationQueue() {
3255
- if (this.isProcessingQueue) {
3256
- return;
3033
+ pick(...fields) {
3034
+ const newFields = {};
3035
+ for (const field of fields) {
3036
+ newFields[field] = this.fields[field];
3037
+ }
3038
+ return new VObject({
3039
+ isOptional: this.isOptional,
3040
+ fields: newFields
3041
+ });
3257
3042
  }
3258
- this.isProcessingQueue = true;
3259
- while (this.mutationQueue.length > 0) {
3260
- const { mutation, args, resolve, reject } = this.mutationQueue.shift();
3261
- try {
3262
- const result = await this.mutationInner(mutation, args);
3263
- resolve(result);
3264
- } catch (error) {
3265
- reject(error);
3043
+ partial() {
3044
+ const newFields = {};
3045
+ for (const [key, validator] of globalThis.Object.entries(this.fields)) {
3046
+ newFields[key] = validator.asOptional();
3266
3047
  }
3048
+ return new VObject({
3049
+ isOptional: this.isOptional,
3050
+ fields: newFields
3051
+ });
3267
3052
  }
3268
- this.isProcessingQueue = false;
3269
- }
3270
- enqueueMutation(mutation, args) {
3271
- return new Promise((resolve, reject) => {
3272
- this.mutationQueue.push({ mutation, args, resolve, reject });
3273
- this.processMutationQueue();
3274
- });
3275
- }
3276
- async mutation(mutation, ...args) {
3277
- const [fnArgs, options] = args;
3278
- const mutationArgs = parseArgs2(fnArgs);
3279
- const queued = !options?.skipQueue;
3280
- if (queued) {
3281
- return await this.enqueueMutation(mutation, mutationArgs);
3282
- } else {
3283
- return await this.mutationInner(mutation, mutationArgs);
3053
+ extend(fields) {
3054
+ return new VObject({
3055
+ isOptional: this.isOptional,
3056
+ fields: { ...this.fields, ...fields }
3057
+ });
3284
3058
  }
3285
- }
3286
- async action(action, ...args) {
3287
- const actionArgs = parseArgs2(args[0]);
3288
- const name = getFunctionName(action);
3289
- const body = JSON.stringify({
3290
- path: name,
3291
- format: "convex_encoded_json",
3292
- args: [convexToJson(actionArgs)]
3293
- });
3294
- const headers = {
3295
- "Content-Type": "application/json",
3296
- "Convex-Client": `npm-${version}`
3297
- };
3298
- if (this.adminAuth) {
3299
- headers["Authorization"] = `Convex ${this.adminAuth}`;
3300
- } else if (this.auth) {
3301
- headers["Authorization"] = `Bearer ${this.auth}`;
3059
+ };
3060
+ VLiteral = class VLiteral extends BaseValidator {
3061
+ constructor({ isOptional, value }) {
3062
+ super({ isOptional });
3063
+ __publicField(this, "value");
3064
+ __publicField(this, "kind", "literal");
3065
+ if (typeof value !== "string" && typeof value !== "boolean" && typeof value !== "number" && typeof value !== "bigint") {
3066
+ throw new Error("v.literal(value) must be a string, number, or boolean");
3067
+ }
3068
+ this.value = value;
3302
3069
  }
3303
- const localFetch = this.fetch || specifiedFetch || fetch;
3304
- const response = await localFetch(`${this.address}/api/action`, {
3305
- ...this.fetchOptions,
3306
- body,
3307
- method: "POST",
3308
- headers
3309
- });
3310
- if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3311
- throw new Error(await response.text());
3070
+ get json() {
3071
+ return {
3072
+ type: this.kind,
3073
+ value: convexToJson(this.value)
3074
+ };
3312
3075
  }
3313
- const respJSON = await response.json();
3314
- if (this.debug) {
3315
- for (const line of respJSON.logLines ?? []) {
3316
- logForFunction(this.logger, "info", "action", name, line);
3317
- }
3076
+ asOptional() {
3077
+ return new VLiteral({
3078
+ isOptional: "optional",
3079
+ value: this.value
3080
+ });
3318
3081
  }
3319
- switch (respJSON.status) {
3320
- case "success":
3321
- return jsonToConvex(respJSON.value);
3322
- case "error":
3323
- if (respJSON.errorData !== undefined) {
3324
- throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3325
- }
3326
- throw new Error(respJSON.errorMessage);
3327
- default:
3328
- throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3082
+ };
3083
+ VArray = class VArray extends BaseValidator {
3084
+ constructor({
3085
+ isOptional,
3086
+ element
3087
+ }) {
3088
+ super({ isOptional });
3089
+ __publicField(this, "element");
3090
+ __publicField(this, "kind", "array");
3091
+ if (element === undefined) {
3092
+ throwUndefinedValidatorError("v.array()");
3093
+ }
3094
+ this.element = element;
3329
3095
  }
3330
- }
3331
- async function(anyFunction, componentPath, ...args) {
3332
- const functionArgs = parseArgs2(args[0]);
3333
- const name = typeof anyFunction === "string" ? anyFunction : getFunctionName(anyFunction);
3334
- const body = JSON.stringify({
3335
- componentPath,
3336
- path: name,
3337
- format: "convex_encoded_json",
3338
- args: convexToJson(functionArgs)
3339
- });
3340
- const headers = {
3341
- "Content-Type": "application/json",
3342
- "Convex-Client": `npm-${version}`
3343
- };
3344
- if (this.adminAuth) {
3345
- headers["Authorization"] = `Convex ${this.adminAuth}`;
3346
- } else if (this.auth) {
3347
- headers["Authorization"] = `Bearer ${this.auth}`;
3096
+ get json() {
3097
+ return {
3098
+ type: this.kind,
3099
+ value: this.element.json
3100
+ };
3348
3101
  }
3349
- const localFetch = this.fetch || specifiedFetch || fetch;
3350
- const response = await localFetch(`${this.address}/api/function`, {
3351
- ...this.fetchOptions,
3352
- body,
3353
- method: "POST",
3354
- headers
3355
- });
3356
- if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3357
- throw new Error(await response.text());
3102
+ asOptional() {
3103
+ return new VArray({
3104
+ isOptional: "optional",
3105
+ element: this.element
3106
+ });
3358
3107
  }
3359
- const respJSON = await response.json();
3360
- if (this.debug) {
3361
- for (const line of respJSON.logLines ?? []) {
3362
- logForFunction(this.logger, "info", "any", name, line);
3108
+ };
3109
+ VRecord = class VRecord extends BaseValidator {
3110
+ constructor({
3111
+ isOptional,
3112
+ key,
3113
+ value
3114
+ }) {
3115
+ super({ isOptional });
3116
+ __publicField(this, "key");
3117
+ __publicField(this, "value");
3118
+ __publicField(this, "kind", "record");
3119
+ if (key === undefined) {
3120
+ throwUndefinedValidatorError("v.record()", "key");
3121
+ }
3122
+ if (value === undefined) {
3123
+ throwUndefinedValidatorError("v.record()", "value");
3363
3124
  }
3125
+ if (key.isOptional === "optional") {
3126
+ throw new Error("Record validator cannot have optional keys");
3127
+ }
3128
+ if (value.isOptional === "optional") {
3129
+ throw new Error("Record validator cannot have optional values");
3130
+ }
3131
+ if (!key.isConvexValidator || !value.isConvexValidator) {
3132
+ throw new Error("Key and value of v.record() but be validators");
3133
+ }
3134
+ this.key = key;
3135
+ this.value = value;
3364
3136
  }
3365
- switch (respJSON.status) {
3366
- case "success":
3367
- return jsonToConvex(respJSON.value);
3368
- case "error":
3369
- if (respJSON.errorData !== undefined) {
3370
- throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3137
+ get json() {
3138
+ return {
3139
+ type: this.kind,
3140
+ keys: this.key.json,
3141
+ values: {
3142
+ fieldType: this.value.json,
3143
+ optional: false
3371
3144
  }
3372
- throw new Error(respJSON.errorMessage);
3373
- default:
3374
- throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3145
+ };
3375
3146
  }
3376
- }
3377
- }
3378
- function forwardErrorData(errorData, error) {
3379
- error.data = jsonToConvex(errorData);
3380
- return error;
3381
- }
3382
- var __defProp5, __defNormalProp3 = (obj, key, value) => (key in obj) ? __defProp5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField3 = (obj, key, value) => __defNormalProp3(obj, typeof key !== "symbol" ? key + "" : key, value), STATUS_CODE_UDF_FAILED = 560, specifiedFetch = undefined;
3383
- var init_http_client = __esm(() => {
3384
- init_api();
3385
- init_values();
3386
- init_logging();
3387
- __defProp5 = Object.defineProperty;
3388
- });
3389
-
3390
- // ../../node_modules/.bun/convex@1.31.7+b1ab299f0a400331/node_modules/convex/dist/esm/browser/index-node.js
3391
- var init_index_node = __esm(() => {
3392
- init_http_client();
3147
+ asOptional() {
3148
+ return new VRecord({
3149
+ isOptional: "optional",
3150
+ key: this.key,
3151
+ value: this.value
3152
+ });
3153
+ }
3154
+ };
3155
+ VUnion = class VUnion extends BaseValidator {
3156
+ constructor({ isOptional, members }) {
3157
+ super({ isOptional });
3158
+ __publicField(this, "members");
3159
+ __publicField(this, "kind", "union");
3160
+ members.forEach((member, index) => {
3161
+ if (member === undefined) {
3162
+ throwUndefinedValidatorError("v.union()", `member at index ${index}`);
3163
+ }
3164
+ if (!member.isConvexValidator) {
3165
+ throw new Error("All members of v.union() must be validators");
3166
+ }
3167
+ });
3168
+ this.members = members;
3169
+ }
3170
+ get json() {
3171
+ return {
3172
+ type: this.kind,
3173
+ value: this.members.map((v2) => v2.json)
3174
+ };
3175
+ }
3176
+ asOptional() {
3177
+ return new VUnion({
3178
+ isOptional: "optional",
3179
+ members: this.members
3180
+ });
3181
+ }
3182
+ };
3393
3183
  });
3394
3184
 
3395
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/values/base64.js
3396
- function getLens2(b64) {
3397
- var len3 = b64.length;
3398
- if (len3 % 4 > 0) {
3399
- throw new Error("Invalid string. Length must be a multiple of 4");
3400
- }
3401
- var validLen = b64.indexOf("=");
3402
- if (validLen === -1)
3403
- validLen = len3;
3404
- var placeHoldersLen = validLen === len3 ? 0 : 4 - validLen % 4;
3405
- return [validLen, placeHoldersLen];
3406
- }
3407
- function _byteLength2(_b64, validLen, placeHoldersLen) {
3408
- return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen;
3409
- }
3410
- function toByteArray2(b64) {
3411
- var tmp;
3412
- var lens = getLens2(b64);
3413
- var validLen = lens[0];
3414
- var placeHoldersLen = lens[1];
3415
- var arr = new Arr2(_byteLength2(b64, validLen, placeHoldersLen));
3416
- var curByte = 0;
3417
- var len3 = placeHoldersLen > 0 ? validLen - 4 : validLen;
3418
- var i4;
3419
- for (i4 = 0;i4 < len3; i4 += 4) {
3420
- tmp = revLookup2[b64.charCodeAt(i4)] << 18 | revLookup2[b64.charCodeAt(i4 + 1)] << 12 | revLookup2[b64.charCodeAt(i4 + 2)] << 6 | revLookup2[b64.charCodeAt(i4 + 3)];
3421
- arr[curByte++] = tmp >> 16 & 255;
3422
- arr[curByte++] = tmp >> 8 & 255;
3423
- arr[curByte++] = tmp & 255;
3424
- }
3425
- if (placeHoldersLen === 2) {
3426
- tmp = revLookup2[b64.charCodeAt(i4)] << 2 | revLookup2[b64.charCodeAt(i4 + 1)] >> 4;
3427
- arr[curByte++] = tmp & 255;
3428
- }
3429
- if (placeHoldersLen === 1) {
3430
- tmp = revLookup2[b64.charCodeAt(i4)] << 10 | revLookup2[b64.charCodeAt(i4 + 1)] << 4 | revLookup2[b64.charCodeAt(i4 + 2)] >> 2;
3431
- arr[curByte++] = tmp >> 8 & 255;
3432
- arr[curByte++] = tmp & 255;
3433
- }
3434
- return arr;
3435
- }
3436
- function tripletToBase642(num) {
3437
- return lookup2[num >> 18 & 63] + lookup2[num >> 12 & 63] + lookup2[num >> 6 & 63] + lookup2[num & 63];
3438
- }
3439
- function encodeChunk2(uint8, start, end) {
3440
- var tmp;
3441
- var output = [];
3442
- for (var i4 = start;i4 < end; i4 += 3) {
3443
- tmp = (uint8[i4] << 16 & 16711680) + (uint8[i4 + 1] << 8 & 65280) + (uint8[i4 + 2] & 255);
3444
- output.push(tripletToBase642(tmp));
3445
- }
3446
- return output.join("");
3447
- }
3448
- function fromByteArray2(uint8) {
3449
- var tmp;
3450
- var len3 = uint8.length;
3451
- var extraBytes = len3 % 3;
3452
- var parts = [];
3453
- var maxChunkLength = 16383;
3454
- for (var i4 = 0, len22 = len3 - extraBytes;i4 < len22; i4 += maxChunkLength) {
3455
- parts.push(encodeChunk2(uint8, i4, i4 + maxChunkLength > len22 ? len22 : i4 + maxChunkLength));
3456
- }
3457
- if (extraBytes === 1) {
3458
- tmp = uint8[len3 - 1];
3459
- parts.push(lookup2[tmp >> 2] + lookup2[tmp << 4 & 63] + "==");
3460
- } else if (extraBytes === 2) {
3461
- tmp = (uint8[len3 - 2] << 8) + uint8[len3 - 1];
3462
- parts.push(lookup2[tmp >> 10] + lookup2[tmp >> 4 & 63] + lookup2[tmp << 2 & 63] + "=");
3463
- }
3464
- return parts.join("");
3465
- }
3466
- var lookup2, revLookup2, Arr2, code2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", i3, len2;
3467
- var init_base642 = __esm(() => {
3468
- lookup2 = [];
3469
- revLookup2 = [];
3470
- Arr2 = Uint8Array;
3471
- for (i3 = 0, len2 = code2.length;i3 < len2; ++i3) {
3472
- lookup2[i3] = code2[i3];
3473
- revLookup2[code2.charCodeAt(i3)] = i3;
3474
- }
3475
- revLookup2[45] = 62;
3476
- revLookup2[95] = 63;
3185
+ // ../../node_modules/convex/dist/esm/values/validator.js
3186
+ var v2;
3187
+ var init_validator = __esm(() => {
3188
+ init_validators();
3189
+ v2 = {
3190
+ id: (tableName) => {
3191
+ return new VId({
3192
+ isOptional: "required",
3193
+ tableName
3194
+ });
3195
+ },
3196
+ null: () => {
3197
+ return new VNull({ isOptional: "required" });
3198
+ },
3199
+ number: () => {
3200
+ return new VFloat64({ isOptional: "required" });
3201
+ },
3202
+ float64: () => {
3203
+ return new VFloat64({ isOptional: "required" });
3204
+ },
3205
+ bigint: () => {
3206
+ return new VInt64({ isOptional: "required" });
3207
+ },
3208
+ int64: () => {
3209
+ return new VInt64({ isOptional: "required" });
3210
+ },
3211
+ boolean: () => {
3212
+ return new VBoolean({ isOptional: "required" });
3213
+ },
3214
+ string: () => {
3215
+ return new VString({ isOptional: "required" });
3216
+ },
3217
+ bytes: () => {
3218
+ return new VBytes({ isOptional: "required" });
3219
+ },
3220
+ literal: (literal) => {
3221
+ return new VLiteral({ isOptional: "required", value: literal });
3222
+ },
3223
+ array: (element) => {
3224
+ return new VArray({ isOptional: "required", element });
3225
+ },
3226
+ object: (fields) => {
3227
+ return new VObject({ isOptional: "required", fields });
3228
+ },
3229
+ record: (keys, values) => {
3230
+ return new VRecord({
3231
+ isOptional: "required",
3232
+ key: keys,
3233
+ value: values
3234
+ });
3235
+ },
3236
+ union: (...members) => {
3237
+ return new VUnion({
3238
+ isOptional: "required",
3239
+ members
3240
+ });
3241
+ },
3242
+ any: () => {
3243
+ return new VAny({ isOptional: "required" });
3244
+ },
3245
+ optional: (value) => {
3246
+ return value.asOptional();
3247
+ },
3248
+ nullable: (value) => {
3249
+ return v2.union(value, v2.null());
3250
+ }
3251
+ };
3477
3252
  });
3478
3253
 
3479
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/common/index.js
3480
- function isSimpleObject2(value) {
3481
- const isObject = typeof value === "object";
3482
- const prototype = Object.getPrototypeOf(value);
3483
- const isSimple = prototype === null || prototype === Object.prototype || prototype?.constructor?.name === "Object";
3484
- return isObject && isSimple;
3485
- }
3254
+ // ../../node_modules/convex/dist/esm/values/errors.js
3255
+ var __defProp4, __defNormalProp2 = (obj, key, value) => (key in obj) ? __defProp4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value), _a2, _b, IDENTIFYING_FIELD, ConvexError;
3256
+ var init_errors = __esm(() => {
3257
+ init_value();
3258
+ __defProp4 = Object.defineProperty;
3259
+ IDENTIFYING_FIELD = Symbol.for("ConvexError");
3260
+ ConvexError = class ConvexError extends (_b = Error, _a2 = IDENTIFYING_FIELD, _b) {
3261
+ constructor(data) {
3262
+ super(typeof data === "string" ? data : stringifyValueForError(data));
3263
+ __publicField2(this, "name", "ConvexError");
3264
+ __publicField2(this, "data");
3265
+ __publicField2(this, _a2, true);
3266
+ this.data = data;
3267
+ }
3268
+ };
3269
+ });
3486
3270
 
3487
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/values/value.js
3488
- function isSpecial2(n2) {
3489
- return Number.isNaN(n2) || !Number.isFinite(n2) || Object.is(n2, -0);
3490
- }
3491
- function slowBigIntToBase642(value) {
3492
- if (value < ZERO2) {
3493
- value -= MIN_INT642 + MIN_INT642;
3494
- }
3495
- let hex = value.toString(16);
3496
- if (hex.length % 2 === 1)
3497
- hex = "0" + hex;
3498
- const bytes = new Uint8Array(new ArrayBuffer(8));
3499
- let i4 = 0;
3500
- for (const hexByte of hex.match(/.{2}/g).reverse()) {
3501
- bytes.set([parseInt(hexByte, 16)], i4++);
3502
- value >>= EIGHT2;
3271
+ // ../../node_modules/convex/dist/esm/values/index.js
3272
+ var init_values = __esm(() => {
3273
+ init_value();
3274
+ init_errors();
3275
+ });
3276
+
3277
+ // ../../node_modules/convex/dist/esm/browser/logging.js
3278
+ function prefix_for_source(source) {
3279
+ switch (source) {
3280
+ case "query":
3281
+ return "Q";
3282
+ case "mutation":
3283
+ return "M";
3284
+ case "action":
3285
+ return "A";
3286
+ case "any":
3287
+ return "?";
3503
3288
  }
3504
- return fromByteArray2(bytes);
3505
3289
  }
3506
- function slowBase64ToBigInt2(encoded) {
3507
- const integerBytes = toByteArray2(encoded);
3508
- if (integerBytes.byteLength !== 8) {
3509
- throw new Error(`Received ${integerBytes.byteLength} bytes, expected 8 for $integer`);
3510
- }
3511
- let value = ZERO2;
3512
- let power = ZERO2;
3513
- for (const byte of integerBytes) {
3514
- value += BigInt(byte) * TWOFIFTYSIX2 ** power;
3515
- power++;
3516
- }
3517
- if (value > MAX_INT642) {
3518
- value += MIN_INT642 + MIN_INT642;
3290
+
3291
+ class DefaultLogger {
3292
+ constructor(options) {
3293
+ __publicField3(this, "_onLogLineFuncs");
3294
+ __publicField3(this, "_verbose");
3295
+ this._onLogLineFuncs = {};
3296
+ this._verbose = options.verbose;
3519
3297
  }
3520
- return value;
3521
- }
3522
- function modernBigIntToBase642(value) {
3523
- if (value < MIN_INT642 || MAX_INT642 < value) {
3524
- throw new Error(`BigInt ${value} does not fit into a 64-bit signed integer.`);
3298
+ addLogLineListener(func) {
3299
+ let id = Math.random().toString(36).substring(2, 15);
3300
+ for (let i3 = 0;i3 < 10; i3++) {
3301
+ if (this._onLogLineFuncs[id] === undefined) {
3302
+ break;
3303
+ }
3304
+ id = Math.random().toString(36).substring(2, 15);
3305
+ }
3306
+ this._onLogLineFuncs[id] = func;
3307
+ return () => {
3308
+ delete this._onLogLineFuncs[id];
3309
+ };
3525
3310
  }
3526
- const buffer = new ArrayBuffer(8);
3527
- new DataView(buffer).setBigInt64(0, value, true);
3528
- return fromByteArray2(new Uint8Array(buffer));
3529
- }
3530
- function modernBase64ToBigInt2(encoded) {
3531
- const integerBytes = toByteArray2(encoded);
3532
- if (integerBytes.byteLength !== 8) {
3533
- throw new Error(`Received ${integerBytes.byteLength} bytes, expected 8 for $integer`);
3311
+ logVerbose(...args) {
3312
+ if (this._verbose) {
3313
+ for (const func of Object.values(this._onLogLineFuncs)) {
3314
+ func("debug", `${(/* @__PURE__ */ new Date()).toISOString()}`, ...args);
3315
+ }
3316
+ }
3534
3317
  }
3535
- const intBytesView = new DataView(integerBytes.buffer);
3536
- return intBytesView.getBigInt64(0, true);
3537
- }
3538
- function validateObjectField2(k2) {
3539
- if (k2.length > MAX_IDENTIFIER_LEN2) {
3540
- throw new Error(`Field name ${k2} exceeds maximum field name length ${MAX_IDENTIFIER_LEN2}.`);
3318
+ log(...args) {
3319
+ for (const func of Object.values(this._onLogLineFuncs)) {
3320
+ func("info", ...args);
3321
+ }
3541
3322
  }
3542
- if (k2.startsWith("$")) {
3543
- throw new Error(`Field name ${k2} starts with a '$', which is reserved.`);
3323
+ warn(...args) {
3324
+ for (const func of Object.values(this._onLogLineFuncs)) {
3325
+ func("warn", ...args);
3326
+ }
3544
3327
  }
3545
- for (let i4 = 0;i4 < k2.length; i4 += 1) {
3546
- const charCode = k2.charCodeAt(i4);
3547
- if (charCode < 32 || charCode >= 127) {
3548
- throw new Error(`Field name ${k2} has invalid character '${k2[i4]}': Field names can only contain non-control ASCII characters`);
3328
+ error(...args) {
3329
+ for (const func of Object.values(this._onLogLineFuncs)) {
3330
+ func("error", ...args);
3549
3331
  }
3550
3332
  }
3551
3333
  }
3552
- function stringifyValueForError2(value) {
3553
- const str = JSON.stringify(value, (_key, value2) => {
3554
- if (value2 === undefined) {
3555
- return "undefined";
3556
- }
3557
- if (typeof value2 === "bigint") {
3558
- return `${value2.toString()}n`;
3334
+ function instantiateDefaultLogger(options) {
3335
+ const logger = new DefaultLogger(options);
3336
+ logger.addLogLineListener((level, ...args) => {
3337
+ switch (level) {
3338
+ case "debug":
3339
+ console.debug(...args);
3340
+ break;
3341
+ case "info":
3342
+ console.log(...args);
3343
+ break;
3344
+ case "warn":
3345
+ console.warn(...args);
3346
+ break;
3347
+ case "error":
3348
+ console.error(...args);
3349
+ break;
3350
+ default: {
3351
+ console.log(...args);
3352
+ }
3559
3353
  }
3560
- return value2;
3561
3354
  });
3562
- if (str.length > MAX_VALUE_FOR_ERROR_LEN2) {
3563
- const rest = "[...truncated]";
3564
- let truncateAt = MAX_VALUE_FOR_ERROR_LEN2 - rest.length;
3565
- const codePoint = str.codePointAt(truncateAt - 1);
3566
- if (codePoint !== undefined && codePoint > 65535) {
3567
- truncateAt -= 1;
3568
- }
3569
- return str.substring(0, truncateAt) + rest;
3570
- }
3571
- return str;
3355
+ return logger;
3572
3356
  }
3573
- function convexToJsonInternal2(value, originalValue, context, includeTopLevelUndefined) {
3574
- if (value === undefined) {
3575
- const contextText = context && ` (present at path ${context} in original object ${stringifyValueForError2(originalValue)})`;
3576
- throw new Error(`undefined is not a valid Convex value${contextText}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`);
3577
- }
3578
- if (value === null) {
3579
- return value;
3357
+ function instantiateNoopLogger(options) {
3358
+ return new DefaultLogger(options);
3359
+ }
3360
+ function logForFunction(logger, type, source, udfPath, message) {
3361
+ const prefix = prefix_for_source(source);
3362
+ if (typeof message === "object") {
3363
+ message = `ConvexError ${JSON.stringify(message.errorData, null, 2)}`;
3580
3364
  }
3581
- if (typeof value === "bigint") {
3582
- if (value < MIN_INT642 || MAX_INT642 < value) {
3583
- throw new Error(`BigInt ${value} does not fit into a 64-bit signed integer.`);
3365
+ if (type === "info") {
3366
+ const match = message.match(/^\[.*?\] /);
3367
+ if (match === null) {
3368
+ logger.error(`[CONVEX ${prefix}(${udfPath})] Could not parse console.log`);
3369
+ return;
3584
3370
  }
3585
- return { $integer: bigIntToBase642(value) };
3371
+ const level = message.slice(1, match[0].length - 2);
3372
+ const args = message.slice(match[0].length);
3373
+ logger.log(`%c[CONVEX ${prefix}(${udfPath})] [${level}]`, INFO_COLOR, args);
3374
+ } else {
3375
+ logger.error(`[CONVEX ${prefix}(${udfPath})] ${message}`);
3586
3376
  }
3587
- if (typeof value === "number") {
3588
- if (isSpecial2(value)) {
3589
- const buffer = new ArrayBuffer(8);
3590
- new DataView(buffer).setFloat64(0, value, LITTLE_ENDIAN2);
3591
- return { $float: fromByteArray2(new Uint8Array(buffer)) };
3377
+ }
3378
+ var __defProp5, __defNormalProp3 = (obj, key, value) => (key in obj) ? __defProp5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField3 = (obj, key, value) => __defNormalProp3(obj, typeof key !== "symbol" ? key + "" : key, value), INFO_COLOR = "color:rgb(0, 145, 255)";
3379
+ var init_logging = __esm(() => {
3380
+ __defProp5 = Object.defineProperty;
3381
+ });
3382
+
3383
+ // ../../node_modules/convex/dist/esm/server/functionName.js
3384
+ var functionName;
3385
+ var init_functionName = __esm(() => {
3386
+ functionName = Symbol.for("functionName");
3387
+ });
3388
+
3389
+ // ../../node_modules/convex/dist/esm/server/components/paths.js
3390
+ function extractReferencePath(reference) {
3391
+ return reference[toReferencePath] ?? null;
3392
+ }
3393
+ function isFunctionHandle(s2) {
3394
+ return s2.startsWith("function://");
3395
+ }
3396
+ function getFunctionAddress(functionReference) {
3397
+ let functionAddress;
3398
+ if (typeof functionReference === "string") {
3399
+ if (isFunctionHandle(functionReference)) {
3400
+ functionAddress = { functionHandle: functionReference };
3592
3401
  } else {
3593
- return value;
3402
+ functionAddress = { name: functionReference };
3594
3403
  }
3595
- }
3596
- if (typeof value === "boolean") {
3597
- return value;
3598
- }
3599
- if (typeof value === "string") {
3600
- return value;
3601
- }
3602
- if (value instanceof ArrayBuffer) {
3603
- return { $bytes: fromByteArray2(new Uint8Array(value)) };
3604
- }
3605
- if (Array.isArray(value)) {
3606
- return value.map((value2, i4) => convexToJsonInternal2(value2, originalValue, context + `[${i4}]`, false));
3607
- }
3608
- if (value instanceof Set) {
3609
- throw new Error(errorMessageForUnsupportedType2(context, "Set", [...value], originalValue));
3610
- }
3611
- if (value instanceof Map) {
3612
- throw new Error(errorMessageForUnsupportedType2(context, "Map", [...value], originalValue));
3613
- }
3614
- if (!isSimpleObject2(value)) {
3615
- const theType = value?.constructor?.name;
3616
- const typeName = theType ? `${theType} ` : "";
3617
- throw new Error(errorMessageForUnsupportedType2(context, typeName, value, originalValue));
3618
- }
3619
- const out = {};
3620
- const entries = Object.entries(value);
3621
- entries.sort(([k1, _v1], [k2, _v2]) => k1 === k2 ? 0 : k1 < k2 ? -1 : 1);
3622
- for (const [k2, v2] of entries) {
3623
- if (v2 !== undefined) {
3624
- validateObjectField2(k2);
3625
- out[k2] = convexToJsonInternal2(v2, originalValue, context + `.${k2}`, false);
3626
- } else if (includeTopLevelUndefined) {
3627
- validateObjectField2(k2);
3628
- out[k2] = convexOrUndefinedToJsonInternal2(v2, originalValue, context + `.${k2}`);
3629
- }
3630
- }
3631
- return out;
3632
- }
3633
- function errorMessageForUnsupportedType2(context, typeName, value, originalValue) {
3634
- if (context) {
3635
- return `${typeName}${stringifyValueForError2(value)} is not a supported Convex type (present at path ${context} in original object ${stringifyValueForError2(originalValue)}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`;
3636
- } else {
3637
- return `${typeName}${stringifyValueForError2(value)} is not a supported Convex type.`;
3638
- }
3639
- }
3640
- function convexOrUndefinedToJsonInternal2(value, originalValue, context) {
3641
- if (value === undefined) {
3642
- return { $undefined: null };
3404
+ } else if (functionReference[functionName]) {
3405
+ functionAddress = { name: functionReference[functionName] };
3643
3406
  } else {
3644
- if (originalValue === undefined) {
3645
- throw new Error(`Programming error. Current value is ${stringifyValueForError2(value)} but original value is undefined`);
3407
+ const referencePath = extractReferencePath(functionReference);
3408
+ if (!referencePath) {
3409
+ throw new Error(`${functionReference} is not a functionReference`);
3646
3410
  }
3647
- return convexToJsonInternal2(value, originalValue, context, false);
3411
+ functionAddress = { reference: referencePath };
3648
3412
  }
3413
+ return functionAddress;
3649
3414
  }
3650
- function convexToJson2(value) {
3651
- return convexToJsonInternal2(value, value, "", false);
3652
- }
3653
- var LITTLE_ENDIAN2 = true, MIN_INT642, MAX_INT642, ZERO2, EIGHT2, TWOFIFTYSIX2, bigIntToBase642, base64ToBigInt2, MAX_IDENTIFIER_LEN2 = 1024, MAX_VALUE_FOR_ERROR_LEN2 = 16384;
3654
- var init_value2 = __esm(() => {
3655
- init_base642();
3656
- MIN_INT642 = BigInt("-9223372036854775808");
3657
- MAX_INT642 = BigInt("9223372036854775807");
3658
- ZERO2 = BigInt("0");
3659
- EIGHT2 = BigInt("8");
3660
- TWOFIFTYSIX2 = BigInt("256");
3661
- bigIntToBase642 = DataView.prototype.setBigInt64 ? modernBigIntToBase642 : slowBigIntToBase642;
3662
- base64ToBigInt2 = DataView.prototype.getBigInt64 ? modernBase64ToBigInt2 : slowBase64ToBigInt2;
3415
+ var toReferencePath;
3416
+ var init_paths = __esm(() => {
3417
+ init_functionName();
3418
+ toReferencePath = Symbol.for("toReferencePath");
3663
3419
  });
3664
3420
 
3665
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/values/validators.js
3666
- function throwUndefinedValidatorError(context, fieldName) {
3667
- const fieldInfo = fieldName !== undefined ? ` for field "${fieldName}"` : "";
3668
- throw new Error(`A validator is undefined${fieldInfo} in ${context}. This is often caused by circular imports. See ${UNDEFINED_VALIDATOR_ERROR_URL} for details.`);
3669
- }
3670
-
3671
- class BaseValidator {
3672
- constructor({ isOptional }) {
3673
- __publicField4(this, "type");
3674
- __publicField4(this, "fieldPaths");
3675
- __publicField4(this, "isOptional");
3676
- __publicField4(this, "isConvexValidator");
3677
- this.isOptional = isOptional;
3678
- this.isConvexValidator = true;
3421
+ // ../../node_modules/convex/dist/esm/server/api.js
3422
+ function getFunctionName(functionReference) {
3423
+ const address = getFunctionAddress(functionReference);
3424
+ if (address.name === undefined) {
3425
+ if (address.functionHandle !== undefined) {
3426
+ throw new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received function handle ${address.functionHandle}`);
3427
+ } else if (address.reference !== undefined) {
3428
+ throw new Error(`Expected function reference in the current component like "api.file.func" or "internal.file.func", but received reference ${address.reference}`);
3429
+ }
3430
+ throw new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received ${JSON.stringify(address)}`);
3431
+ }
3432
+ if (typeof functionReference === "string")
3433
+ return functionReference;
3434
+ const name = functionReference[functionName];
3435
+ if (!name) {
3436
+ throw new Error(`${functionReference} is not a functionReference`);
3679
3437
  }
3438
+ return name;
3680
3439
  }
3681
- var __defProp6, __defNormalProp4 = (obj, key, value) => (key in obj) ? __defProp6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField4 = (obj, key, value) => __defNormalProp4(obj, typeof key !== "symbol" ? key + "" : key, value), UNDEFINED_VALIDATOR_ERROR_URL = "https://docs.convex.dev/error#undefined-validator", VId, VFloat64, VInt64, VBoolean, VBytes, VString, VNull, VAny, VObject, VLiteral, VArray, VRecord, VUnion;
3682
- var init_validators = __esm(() => {
3683
- init_value2();
3684
- __defProp6 = Object.defineProperty;
3685
- VId = class VId extends BaseValidator {
3686
- constructor({
3687
- isOptional,
3688
- tableName
3689
- }) {
3690
- super({ isOptional });
3691
- __publicField4(this, "tableName");
3692
- __publicField4(this, "kind", "id");
3693
- if (typeof tableName !== "string") {
3694
- throw new Error("v.id(tableName) requires a string");
3440
+ function createApi(pathParts = []) {
3441
+ const handler = {
3442
+ get(_3, prop) {
3443
+ if (typeof prop === "string") {
3444
+ const newParts = [...pathParts, prop];
3445
+ return createApi(newParts);
3446
+ } else if (prop === functionName) {
3447
+ if (pathParts.length < 2) {
3448
+ const found = ["api", ...pathParts].join(".");
3449
+ throw new Error(`API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`${found}\``);
3450
+ }
3451
+ const path = pathParts.slice(0, -1).join("/");
3452
+ const exportName = pathParts[pathParts.length - 1];
3453
+ if (exportName === "default") {
3454
+ return path;
3455
+ } else {
3456
+ return path + ":" + exportName;
3457
+ }
3458
+ } else if (prop === Symbol.toStringTag) {
3459
+ return "FunctionReference";
3460
+ } else {
3461
+ return;
3695
3462
  }
3696
- this.tableName = tableName;
3697
- }
3698
- get json() {
3699
- return { type: "id", tableName: this.tableName };
3700
- }
3701
- asOptional() {
3702
- return new VId({
3703
- isOptional: "optional",
3704
- tableName: this.tableName
3705
- });
3706
3463
  }
3707
3464
  };
3708
- VFloat64 = class VFloat64 extends BaseValidator {
3709
- constructor() {
3710
- super(...arguments);
3711
- __publicField4(this, "kind", "float64");
3712
- }
3713
- get json() {
3714
- return { type: "number" };
3465
+ return new Proxy({}, handler);
3466
+ }
3467
+ var anyApi;
3468
+ var init_api = __esm(() => {
3469
+ init_functionName();
3470
+ init_paths();
3471
+ anyApi = createApi();
3472
+ });
3473
+
3474
+ // ../../node_modules/convex/dist/esm/browser/http_client.js
3475
+ class ConvexHttpClient {
3476
+ constructor(address, options) {
3477
+ __publicField4(this, "address");
3478
+ __publicField4(this, "auth");
3479
+ __publicField4(this, "adminAuth");
3480
+ __publicField4(this, "encodedTsPromise");
3481
+ __publicField4(this, "debug");
3482
+ __publicField4(this, "fetchOptions");
3483
+ __publicField4(this, "fetch");
3484
+ __publicField4(this, "logger");
3485
+ __publicField4(this, "mutationQueue", []);
3486
+ __publicField4(this, "isProcessingQueue", false);
3487
+ if (typeof options === "boolean") {
3488
+ throw new Error("skipConvexDeploymentUrlCheck as the second argument is no longer supported. Please pass an options object, `{ skipConvexDeploymentUrlCheck: true }`.");
3715
3489
  }
3716
- asOptional() {
3717
- return new VFloat64({
3718
- isOptional: "optional"
3719
- });
3490
+ const opts = options ?? {};
3491
+ if (opts.skipConvexDeploymentUrlCheck !== true) {
3492
+ validateDeploymentUrl(address);
3720
3493
  }
3721
- };
3722
- VInt64 = class VInt64 extends BaseValidator {
3723
- constructor() {
3724
- super(...arguments);
3725
- __publicField4(this, "kind", "int64");
3494
+ this.logger = options?.logger === false ? instantiateNoopLogger({ verbose: false }) : options?.logger !== true && options?.logger ? options.logger : instantiateDefaultLogger({ verbose: false });
3495
+ this.address = address;
3496
+ this.debug = true;
3497
+ this.auth = undefined;
3498
+ this.adminAuth = undefined;
3499
+ this.fetch = options?.fetch;
3500
+ if (options?.auth) {
3501
+ this.setAuth(options.auth);
3726
3502
  }
3727
- get json() {
3728
- return { type: "bigint" };
3503
+ }
3504
+ backendUrl() {
3505
+ return `${this.address}/api`;
3506
+ }
3507
+ get url() {
3508
+ return this.address;
3509
+ }
3510
+ setAuth(value) {
3511
+ this.clearAuth();
3512
+ this.auth = value;
3513
+ }
3514
+ setAdminAuth(token, actingAsIdentity) {
3515
+ this.clearAuth();
3516
+ if (actingAsIdentity !== undefined) {
3517
+ const bytes = new TextEncoder().encode(JSON.stringify(actingAsIdentity));
3518
+ const actingAsIdentityEncoded = btoa(String.fromCodePoint(...bytes));
3519
+ this.adminAuth = `${token}:${actingAsIdentityEncoded}`;
3520
+ } else {
3521
+ this.adminAuth = token;
3729
3522
  }
3730
- asOptional() {
3731
- return new VInt64({ isOptional: "optional" });
3523
+ }
3524
+ clearAuth() {
3525
+ this.auth = undefined;
3526
+ this.adminAuth = undefined;
3527
+ }
3528
+ setDebug(debug2) {
3529
+ this.debug = debug2;
3530
+ }
3531
+ setFetchOptions(fetchOptions) {
3532
+ this.fetchOptions = fetchOptions;
3533
+ }
3534
+ async consistentQuery(query, ...args) {
3535
+ const queryArgs = parseArgs2(args[0]);
3536
+ const timestampPromise = this.getTimestamp();
3537
+ return await this.queryInner(query, queryArgs, { timestampPromise });
3538
+ }
3539
+ async getTimestamp() {
3540
+ if (this.encodedTsPromise) {
3541
+ return this.encodedTsPromise;
3732
3542
  }
3733
- };
3734
- VBoolean = class VBoolean extends BaseValidator {
3735
- constructor() {
3736
- super(...arguments);
3737
- __publicField4(this, "kind", "boolean");
3543
+ return this.encodedTsPromise = this.getTimestampInner();
3544
+ }
3545
+ async getTimestampInner() {
3546
+ const localFetch = this.fetch || specifiedFetch || fetch;
3547
+ const headers = {
3548
+ "Content-Type": "application/json",
3549
+ "Convex-Client": `npm-${version}`
3550
+ };
3551
+ const response = await localFetch(`${this.address}/api/query_ts`, {
3552
+ ...this.fetchOptions,
3553
+ method: "POST",
3554
+ headers
3555
+ });
3556
+ if (!response.ok) {
3557
+ throw new Error(await response.text());
3738
3558
  }
3739
- get json() {
3740
- return { type: this.kind };
3559
+ const { ts } = await response.json();
3560
+ return ts;
3561
+ }
3562
+ async query(query, ...args) {
3563
+ const queryArgs = parseArgs2(args[0]);
3564
+ return await this.queryInner(query, queryArgs, {});
3565
+ }
3566
+ async queryInner(query, queryArgs, options) {
3567
+ const name = getFunctionName(query);
3568
+ const args = [convexToJson(queryArgs)];
3569
+ const headers = {
3570
+ "Content-Type": "application/json",
3571
+ "Convex-Client": `npm-${version}`
3572
+ };
3573
+ if (this.adminAuth) {
3574
+ headers["Authorization"] = `Convex ${this.adminAuth}`;
3575
+ } else if (this.auth) {
3576
+ headers["Authorization"] = `Bearer ${this.auth}`;
3741
3577
  }
3742
- asOptional() {
3743
- return new VBoolean({
3744
- isOptional: "optional"
3745
- });
3578
+ const localFetch = this.fetch || specifiedFetch || fetch;
3579
+ const timestamp = options.timestampPromise ? await options.timestampPromise : undefined;
3580
+ const body = JSON.stringify({
3581
+ path: name,
3582
+ format: "convex_encoded_json",
3583
+ args,
3584
+ ...timestamp ? { ts: timestamp } : {}
3585
+ });
3586
+ const endpoint = timestamp ? `${this.address}/api/query_at_ts` : `${this.address}/api/query`;
3587
+ const response = await localFetch(endpoint, {
3588
+ ...this.fetchOptions,
3589
+ body,
3590
+ method: "POST",
3591
+ headers
3592
+ });
3593
+ if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3594
+ throw new Error(await response.text());
3746
3595
  }
3747
- };
3748
- VBytes = class VBytes extends BaseValidator {
3749
- constructor() {
3750
- super(...arguments);
3751
- __publicField4(this, "kind", "bytes");
3596
+ const respJSON = await response.json();
3597
+ if (this.debug) {
3598
+ for (const line of respJSON.logLines ?? []) {
3599
+ logForFunction(this.logger, "info", "query", name, line);
3600
+ }
3752
3601
  }
3753
- get json() {
3754
- return { type: this.kind };
3602
+ switch (respJSON.status) {
3603
+ case "success":
3604
+ return jsonToConvex(respJSON.value);
3605
+ case "error":
3606
+ if (respJSON.errorData !== undefined) {
3607
+ throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3608
+ }
3609
+ throw new Error(respJSON.errorMessage);
3610
+ default:
3611
+ throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3755
3612
  }
3756
- asOptional() {
3757
- return new VBytes({ isOptional: "optional" });
3613
+ }
3614
+ async mutationInner(mutation, mutationArgs) {
3615
+ const name = getFunctionName(mutation);
3616
+ const body = JSON.stringify({
3617
+ path: name,
3618
+ format: "convex_encoded_json",
3619
+ args: [convexToJson(mutationArgs)]
3620
+ });
3621
+ const headers = {
3622
+ "Content-Type": "application/json",
3623
+ "Convex-Client": `npm-${version}`
3624
+ };
3625
+ if (this.adminAuth) {
3626
+ headers["Authorization"] = `Convex ${this.adminAuth}`;
3627
+ } else if (this.auth) {
3628
+ headers["Authorization"] = `Bearer ${this.auth}`;
3758
3629
  }
3759
- };
3760
- VString = class VString extends BaseValidator {
3761
- constructor() {
3762
- super(...arguments);
3763
- __publicField4(this, "kind", "string");
3630
+ const localFetch = this.fetch || specifiedFetch || fetch;
3631
+ const response = await localFetch(`${this.address}/api/mutation`, {
3632
+ ...this.fetchOptions,
3633
+ body,
3634
+ method: "POST",
3635
+ headers
3636
+ });
3637
+ if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3638
+ throw new Error(await response.text());
3764
3639
  }
3765
- get json() {
3766
- return { type: this.kind };
3640
+ const respJSON = await response.json();
3641
+ if (this.debug) {
3642
+ for (const line of respJSON.logLines ?? []) {
3643
+ logForFunction(this.logger, "info", "mutation", name, line);
3644
+ }
3767
3645
  }
3768
- asOptional() {
3769
- return new VString({
3770
- isOptional: "optional"
3771
- });
3646
+ switch (respJSON.status) {
3647
+ case "success":
3648
+ return jsonToConvex(respJSON.value);
3649
+ case "error":
3650
+ if (respJSON.errorData !== undefined) {
3651
+ throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3652
+ }
3653
+ throw new Error(respJSON.errorMessage);
3654
+ default:
3655
+ throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3772
3656
  }
3773
- };
3774
- VNull = class VNull extends BaseValidator {
3775
- constructor() {
3776
- super(...arguments);
3777
- __publicField4(this, "kind", "null");
3657
+ }
3658
+ async processMutationQueue() {
3659
+ if (this.isProcessingQueue) {
3660
+ return;
3778
3661
  }
3779
- get json() {
3780
- return { type: this.kind };
3662
+ this.isProcessingQueue = true;
3663
+ while (this.mutationQueue.length > 0) {
3664
+ const { mutation, args, resolve, reject } = this.mutationQueue.shift();
3665
+ try {
3666
+ const result = await this.mutationInner(mutation, args);
3667
+ resolve(result);
3668
+ } catch (error) {
3669
+ reject(error);
3670
+ }
3781
3671
  }
3782
- asOptional() {
3783
- return new VNull({ isOptional: "optional" });
3672
+ this.isProcessingQueue = false;
3673
+ }
3674
+ enqueueMutation(mutation, args) {
3675
+ return new Promise((resolve, reject) => {
3676
+ this.mutationQueue.push({ mutation, args, resolve, reject });
3677
+ this.processMutationQueue();
3678
+ });
3679
+ }
3680
+ async mutation(mutation, ...args) {
3681
+ const [fnArgs, options] = args;
3682
+ const mutationArgs = parseArgs2(fnArgs);
3683
+ const queued = !options?.skipQueue;
3684
+ if (queued) {
3685
+ return await this.enqueueMutation(mutation, mutationArgs);
3686
+ } else {
3687
+ return await this.mutationInner(mutation, mutationArgs);
3784
3688
  }
3785
- };
3786
- VAny = class VAny extends BaseValidator {
3787
- constructor() {
3788
- super(...arguments);
3789
- __publicField4(this, "kind", "any");
3689
+ }
3690
+ async action(action, ...args) {
3691
+ const actionArgs = parseArgs2(args[0]);
3692
+ const name = getFunctionName(action);
3693
+ const body = JSON.stringify({
3694
+ path: name,
3695
+ format: "convex_encoded_json",
3696
+ args: [convexToJson(actionArgs)]
3697
+ });
3698
+ const headers = {
3699
+ "Content-Type": "application/json",
3700
+ "Convex-Client": `npm-${version}`
3701
+ };
3702
+ if (this.adminAuth) {
3703
+ headers["Authorization"] = `Convex ${this.adminAuth}`;
3704
+ } else if (this.auth) {
3705
+ headers["Authorization"] = `Bearer ${this.auth}`;
3790
3706
  }
3791
- get json() {
3792
- return {
3793
- type: this.kind
3794
- };
3707
+ const localFetch = this.fetch || specifiedFetch || fetch;
3708
+ const response = await localFetch(`${this.address}/api/action`, {
3709
+ ...this.fetchOptions,
3710
+ body,
3711
+ method: "POST",
3712
+ headers
3713
+ });
3714
+ if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3715
+ throw new Error(await response.text());
3795
3716
  }
3796
- asOptional() {
3797
- return new VAny({
3798
- isOptional: "optional"
3799
- });
3717
+ const respJSON = await response.json();
3718
+ if (this.debug) {
3719
+ for (const line of respJSON.logLines ?? []) {
3720
+ logForFunction(this.logger, "info", "action", name, line);
3721
+ }
3800
3722
  }
3801
- };
3802
- VObject = class VObject extends BaseValidator {
3803
- constructor({
3804
- isOptional,
3805
- fields
3806
- }) {
3807
- super({ isOptional });
3808
- __publicField4(this, "fields");
3809
- __publicField4(this, "kind", "object");
3810
- globalThis.Object.entries(fields).forEach(([fieldName, validator]) => {
3811
- if (validator === undefined) {
3812
- throwUndefinedValidatorError("v.object()", fieldName);
3813
- }
3814
- if (!validator.isConvexValidator) {
3815
- throw new Error("v.object() entries must be validators");
3723
+ switch (respJSON.status) {
3724
+ case "success":
3725
+ return jsonToConvex(respJSON.value);
3726
+ case "error":
3727
+ if (respJSON.errorData !== undefined) {
3728
+ throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3816
3729
  }
3817
- });
3818
- this.fields = fields;
3819
- }
3820
- get json() {
3821
- return {
3822
- type: this.kind,
3823
- value: globalThis.Object.fromEntries(globalThis.Object.entries(this.fields).map(([k2, v2]) => [
3824
- k2,
3825
- {
3826
- fieldType: v2.json,
3827
- optional: v2.isOptional === "optional" ? true : false
3828
- }
3829
- ]))
3830
- };
3730
+ throw new Error(respJSON.errorMessage);
3731
+ default:
3732
+ throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3831
3733
  }
3832
- asOptional() {
3833
- return new VObject({
3834
- isOptional: "optional",
3835
- fields: this.fields
3836
- });
3734
+ }
3735
+ async function(anyFunction, componentPath, ...args) {
3736
+ const functionArgs = parseArgs2(args[0]);
3737
+ const name = typeof anyFunction === "string" ? anyFunction : getFunctionName(anyFunction);
3738
+ const body = JSON.stringify({
3739
+ componentPath,
3740
+ path: name,
3741
+ format: "convex_encoded_json",
3742
+ args: convexToJson(functionArgs)
3743
+ });
3744
+ const headers = {
3745
+ "Content-Type": "application/json",
3746
+ "Convex-Client": `npm-${version}`
3747
+ };
3748
+ if (this.adminAuth) {
3749
+ headers["Authorization"] = `Convex ${this.adminAuth}`;
3750
+ } else if (this.auth) {
3751
+ headers["Authorization"] = `Bearer ${this.auth}`;
3837
3752
  }
3838
- omit(...fields) {
3839
- const newFields = { ...this.fields };
3840
- for (const field of fields) {
3841
- delete newFields[field];
3842
- }
3843
- return new VObject({
3844
- isOptional: this.isOptional,
3845
- fields: newFields
3846
- });
3753
+ const localFetch = this.fetch || specifiedFetch || fetch;
3754
+ const response = await localFetch(`${this.address}/api/function`, {
3755
+ ...this.fetchOptions,
3756
+ body,
3757
+ method: "POST",
3758
+ headers
3759
+ });
3760
+ if (!response.ok && response.status !== STATUS_CODE_UDF_FAILED) {
3761
+ throw new Error(await response.text());
3847
3762
  }
3848
- pick(...fields) {
3849
- const newFields = {};
3850
- for (const field of fields) {
3851
- newFields[field] = this.fields[field];
3763
+ const respJSON = await response.json();
3764
+ if (this.debug) {
3765
+ for (const line of respJSON.logLines ?? []) {
3766
+ logForFunction(this.logger, "info", "any", name, line);
3852
3767
  }
3853
- return new VObject({
3854
- isOptional: this.isOptional,
3855
- fields: newFields
3856
- });
3857
3768
  }
3858
- partial() {
3859
- const newFields = {};
3860
- for (const [key, validator] of globalThis.Object.entries(this.fields)) {
3861
- newFields[key] = validator.asOptional();
3862
- }
3863
- return new VObject({
3864
- isOptional: this.isOptional,
3865
- fields: newFields
3866
- });
3769
+ switch (respJSON.status) {
3770
+ case "success":
3771
+ return jsonToConvex(respJSON.value);
3772
+ case "error":
3773
+ if (respJSON.errorData !== undefined) {
3774
+ throw forwardErrorData(respJSON.errorData, new ConvexError(respJSON.errorMessage));
3775
+ }
3776
+ throw new Error(respJSON.errorMessage);
3777
+ default:
3778
+ throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
3867
3779
  }
3868
- extend(fields) {
3869
- return new VObject({
3870
- isOptional: this.isOptional,
3871
- fields: { ...this.fields, ...fields }
3872
- });
3873
- }
3874
- };
3875
- VLiteral = class VLiteral extends BaseValidator {
3876
- constructor({ isOptional, value }) {
3877
- super({ isOptional });
3878
- __publicField4(this, "value");
3879
- __publicField4(this, "kind", "literal");
3880
- if (typeof value !== "string" && typeof value !== "boolean" && typeof value !== "number" && typeof value !== "bigint") {
3881
- throw new Error("v.literal(value) must be a string, number, or boolean");
3882
- }
3883
- this.value = value;
3884
- }
3885
- get json() {
3886
- return {
3887
- type: this.kind,
3888
- value: convexToJson2(this.value)
3889
- };
3890
- }
3891
- asOptional() {
3892
- return new VLiteral({
3893
- isOptional: "optional",
3894
- value: this.value
3895
- });
3896
- }
3897
- };
3898
- VArray = class VArray extends BaseValidator {
3899
- constructor({
3900
- isOptional,
3901
- element
3902
- }) {
3903
- super({ isOptional });
3904
- __publicField4(this, "element");
3905
- __publicField4(this, "kind", "array");
3906
- if (element === undefined) {
3907
- throwUndefinedValidatorError("v.array()");
3908
- }
3909
- this.element = element;
3910
- }
3911
- get json() {
3912
- return {
3913
- type: this.kind,
3914
- value: this.element.json
3915
- };
3916
- }
3917
- asOptional() {
3918
- return new VArray({
3919
- isOptional: "optional",
3920
- element: this.element
3921
- });
3922
- }
3923
- };
3924
- VRecord = class VRecord extends BaseValidator {
3925
- constructor({
3926
- isOptional,
3927
- key,
3928
- value
3929
- }) {
3930
- super({ isOptional });
3931
- __publicField4(this, "key");
3932
- __publicField4(this, "value");
3933
- __publicField4(this, "kind", "record");
3934
- if (key === undefined) {
3935
- throwUndefinedValidatorError("v.record()", "key");
3936
- }
3937
- if (value === undefined) {
3938
- throwUndefinedValidatorError("v.record()", "value");
3939
- }
3940
- if (key.isOptional === "optional") {
3941
- throw new Error("Record validator cannot have optional keys");
3942
- }
3943
- if (value.isOptional === "optional") {
3944
- throw new Error("Record validator cannot have optional values");
3945
- }
3946
- if (!key.isConvexValidator || !value.isConvexValidator) {
3947
- throw new Error("Key and value of v.record() but be validators");
3948
- }
3949
- this.key = key;
3950
- this.value = value;
3951
- }
3952
- get json() {
3953
- return {
3954
- type: this.kind,
3955
- keys: this.key.json,
3956
- values: {
3957
- fieldType: this.value.json,
3958
- optional: false
3959
- }
3960
- };
3961
- }
3962
- asOptional() {
3963
- return new VRecord({
3964
- isOptional: "optional",
3965
- key: this.key,
3966
- value: this.value
3967
- });
3968
- }
3969
- };
3970
- VUnion = class VUnion extends BaseValidator {
3971
- constructor({ isOptional, members }) {
3972
- super({ isOptional });
3973
- __publicField4(this, "members");
3974
- __publicField4(this, "kind", "union");
3975
- members.forEach((member, index) => {
3976
- if (member === undefined) {
3977
- throwUndefinedValidatorError("v.union()", `member at index ${index}`);
3978
- }
3979
- if (!member.isConvexValidator) {
3980
- throw new Error("All members of v.union() must be validators");
3981
- }
3982
- });
3983
- this.members = members;
3984
- }
3985
- get json() {
3986
- return {
3987
- type: this.kind,
3988
- value: this.members.map((v2) => v2.json)
3989
- };
3990
- }
3991
- asOptional() {
3992
- return new VUnion({
3993
- isOptional: "optional",
3994
- members: this.members
3995
- });
3996
- }
3997
- };
3998
- });
3999
-
4000
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/values/validator.js
4001
- var v2;
4002
- var init_validator = __esm(() => {
4003
- init_validators();
4004
- v2 = {
4005
- id: (tableName) => {
4006
- return new VId({
4007
- isOptional: "required",
4008
- tableName
4009
- });
4010
- },
4011
- null: () => {
4012
- return new VNull({ isOptional: "required" });
4013
- },
4014
- number: () => {
4015
- return new VFloat64({ isOptional: "required" });
4016
- },
4017
- float64: () => {
4018
- return new VFloat64({ isOptional: "required" });
4019
- },
4020
- bigint: () => {
4021
- return new VInt64({ isOptional: "required" });
4022
- },
4023
- int64: () => {
4024
- return new VInt64({ isOptional: "required" });
4025
- },
4026
- boolean: () => {
4027
- return new VBoolean({ isOptional: "required" });
4028
- },
4029
- string: () => {
4030
- return new VString({ isOptional: "required" });
4031
- },
4032
- bytes: () => {
4033
- return new VBytes({ isOptional: "required" });
4034
- },
4035
- literal: (literal) => {
4036
- return new VLiteral({ isOptional: "required", value: literal });
4037
- },
4038
- array: (element) => {
4039
- return new VArray({ isOptional: "required", element });
4040
- },
4041
- object: (fields) => {
4042
- return new VObject({ isOptional: "required", fields });
4043
- },
4044
- record: (keys, values) => {
4045
- return new VRecord({
4046
- isOptional: "required",
4047
- key: keys,
4048
- value: values
4049
- });
4050
- },
4051
- union: (...members) => {
4052
- return new VUnion({
4053
- isOptional: "required",
4054
- members
4055
- });
4056
- },
4057
- any: () => {
4058
- return new VAny({ isOptional: "required" });
4059
- },
4060
- optional: (value) => {
4061
- return value.asOptional();
4062
- },
4063
- nullable: (value) => {
4064
- return v2.union(value, v2.null());
4065
- }
4066
- };
4067
- });
4068
-
4069
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/functionName.js
4070
- var functionName2;
4071
- var init_functionName2 = __esm(() => {
4072
- functionName2 = Symbol.for("functionName");
3780
+ }
3781
+ }
3782
+ function forwardErrorData(errorData, error) {
3783
+ error.data = jsonToConvex(errorData);
3784
+ return error;
3785
+ }
3786
+ var __defProp6, __defNormalProp4 = (obj, key, value) => (key in obj) ? __defProp6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value, __publicField4 = (obj, key, value) => __defNormalProp4(obj, typeof key !== "symbol" ? key + "" : key, value), STATUS_CODE_UDF_FAILED = 560, specifiedFetch = undefined;
3787
+ var init_http_client = __esm(() => {
3788
+ init_api();
3789
+ init_values();
3790
+ init_logging();
3791
+ __defProp6 = Object.defineProperty;
4073
3792
  });
4074
3793
 
4075
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/components/paths.js
4076
- var toReferencePath2;
4077
- var init_paths2 = __esm(() => {
4078
- toReferencePath2 = Symbol.for("toReferencePath");
3794
+ // ../../node_modules/convex/dist/esm/browser/index-node.js
3795
+ var init_index_node = __esm(() => {
3796
+ init_http_client();
4079
3797
  });
4080
3798
 
4081
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/search_filter_builder.js
3799
+ // ../../node_modules/convex/dist/esm/server/search_filter_builder.js
4082
3800
  var init_search_filter_builder = () => {};
4083
3801
 
4084
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/pagination.js
3802
+ // ../../node_modules/convex/dist/esm/server/pagination.js
4085
3803
  var paginationOptsValidator;
4086
3804
  var init_pagination = __esm(() => {
4087
3805
  init_validator();
@@ -4095,48 +3813,14 @@ var init_pagination = __esm(() => {
4095
3813
  });
4096
3814
  });
4097
3815
 
4098
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/api.js
4099
- function createApi2(pathParts = []) {
4100
- const handler = {
4101
- get(_3, prop) {
4102
- if (typeof prop === "string") {
4103
- const newParts = [...pathParts, prop];
4104
- return createApi2(newParts);
4105
- } else if (prop === functionName2) {
4106
- if (pathParts.length < 2) {
4107
- const found = ["api", ...pathParts].join(".");
4108
- throw new Error(`API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`${found}\``);
4109
- }
4110
- const path = pathParts.slice(0, -1).join("/");
4111
- const exportName = pathParts[pathParts.length - 1];
4112
- if (exportName === "default") {
4113
- return path;
4114
- } else {
4115
- return path + ":" + exportName;
4116
- }
4117
- } else if (prop === Symbol.toStringTag) {
4118
- return "FunctionReference";
4119
- } else {
4120
- return;
4121
- }
4122
- }
4123
- };
4124
- return new Proxy({}, handler);
4125
- }
4126
- var anyApi2;
4127
- var init_api2 = __esm(() => {
4128
- init_functionName2();
4129
- anyApi2 = createApi2();
4130
- });
4131
-
4132
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/components/index.js
3816
+ // ../../node_modules/convex/dist/esm/server/components/index.js
4133
3817
  function createChildComponents(root, pathParts) {
4134
3818
  const handler = {
4135
3819
  get(_3, prop) {
4136
3820
  if (typeof prop === "string") {
4137
3821
  const newParts = [...pathParts, prop];
4138
3822
  return createChildComponents(root, newParts);
4139
- } else if (prop === toReferencePath2) {
3823
+ } else if (prop === toReferencePath) {
4140
3824
  if (pathParts.length < 1) {
4141
3825
  const found = [root, ...pathParts].join(".");
4142
3826
  throw new Error(`API path is expected to be of the form \`${root}.childComponent.functionName\`. Found: \`${found}\``);
@@ -4151,12 +3835,12 @@ function createChildComponents(root, pathParts) {
4151
3835
  }
4152
3836
  var componentsGeneric = () => createChildComponents("components", []);
4153
3837
  var init_components = __esm(() => {
4154
- init_paths2();
3838
+ init_paths();
4155
3839
  });
4156
3840
 
4157
- // ../../node_modules/.bun/convex@1.31.7/node_modules/convex/dist/esm/server/index.js
3841
+ // ../../node_modules/convex/dist/esm/server/index.js
4158
3842
  var init_server = __esm(() => {
4159
- init_api2();
3843
+ init_api();
4160
3844
  init_components();
4161
3845
  init_pagination();
4162
3846
  init_search_filter_builder();
@@ -4164,9 +3848,9 @@ var init_server = __esm(() => {
4164
3848
 
4165
3849
  // ../../convex/_generated/api.js
4166
3850
  var api, components;
4167
- var init_api3 = __esm(() => {
3851
+ var init_api2 = __esm(() => {
4168
3852
  init_server();
4169
- api = anyApi2;
3853
+ api = anyApi;
4170
3854
  components = componentsGeneric();
4171
3855
  });
4172
3856
 
@@ -4243,7 +3927,7 @@ function requireGitHub() {
4243
3927
  var PRODUCTION_CONVEX_URL = "https://steady-bass-841.convex.cloud", CONFIG_DIR, CONFIG_FILE, getClerkId, requireClerkId;
4244
3928
  var init_client = __esm(() => {
4245
3929
  init_index_node();
4246
- init_api3();
3930
+ init_api2();
4247
3931
  init_dist();
4248
3932
  CONFIG_DIR = join3(homedir2(), ".nairon-bench");
4249
3933
  CONFIG_FILE = join3(CONFIG_DIR, "config.json");
@@ -4251,7 +3935,7 @@ var init_client = __esm(() => {
4251
3935
  requireClerkId = requireGitHub;
4252
3936
  });
4253
3937
 
4254
- // ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
3938
+ // ../../node_modules/picocolors/picocolors.js
4255
3939
  var require_picocolors = __commonJS((exports, module) => {
4256
3940
  var p = process || {};
4257
3941
  var argv2 = p.argv || [];
@@ -4321,14 +4005,14 @@ var require_picocolors = __commonJS((exports, module) => {
4321
4005
  module.exports.createColors = createColors2;
4322
4006
  });
4323
4007
 
4324
- // ../../node_modules/.bun/citty@0.1.6/node_modules/citty/dist/index.mjs
4008
+ // ../../node_modules/citty/dist/index.mjs
4325
4009
  init_dist();
4326
4010
 
4327
- // ../../node_modules/.bun/consola@3.4.2/node_modules/consola/dist/utils.mjs
4011
+ // ../../node_modules/consola/dist/utils.mjs
4328
4012
  init_consola_DXBYu_KD();
4329
4013
  init_consola_DXBYu_KD();
4330
4014
 
4331
- // ../../node_modules/.bun/citty@0.1.6/node_modules/citty/dist/index.mjs
4015
+ // ../../node_modules/citty/dist/index.mjs
4332
4016
  function toArray(val) {
4333
4017
  if (Array.isArray(val)) {
4334
4018
  return val;
@@ -4755,7 +4439,7 @@ async function runMain(cmd, opts = {}) {
4755
4439
  }
4756
4440
  }
4757
4441
 
4758
- // ../../node_modules/.bun/citty@0.1.6/node_modules/citty/dist/index.mjs
4442
+ // ../../node_modules/citty/dist/index.mjs
4759
4443
  init_dist();
4760
4444
  function defineCommand2(def) {
4761
4445
  return def;
@@ -4765,7 +4449,7 @@ function defineCommand2(def) {
4765
4449
  import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
4766
4450
  import { join as join5 } from "node:path";
4767
4451
 
4768
- // ../../node_modules/.bun/simple-git@3.30.0/node_modules/simple-git/dist/esm/index.js
4452
+ // ../../node_modules/simple-git/dist/esm/index.js
4769
4453
  var import_file_exists = __toESM(require_dist(), 1);
4770
4454
  var import_debug = __toESM(require_src(), 1);
4771
4455
  var import_promise_deferred = __toESM(require_dist2(), 1);
@@ -4781,7 +4465,7 @@ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
4781
4465
  var __esm2 = (fn, res) => function __init() {
4782
4466
  return fn && (res = (0, fn[__getOwnPropNames2(fn)[0]])(fn = 0)), res;
4783
4467
  };
4784
- var __commonJS2 = (cb, mod) => function __require() {
4468
+ var __commonJS2 = (cb, mod) => function __require2() {
4785
4469
  return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
4786
4470
  };
4787
4471
  var __export2 = (target, all) => {
@@ -9129,6 +8813,42 @@ async function collectAgentSessions(since) {
9129
8813
  const openCodeSessions = collectOpenCodeSessions(openCodeDir, since);
9130
8814
  sessions.push(...openCodeSessions);
9131
8815
  }
8816
+ const cursorDirs = [
8817
+ join(homedir(), ".cursor", "sessions"),
8818
+ join(homedir(), "Library", "Application Support", "Cursor", "sessions"),
8819
+ join(homedir(), ".config", "cursor", "sessions")
8820
+ ];
8821
+ for (const cursorDir of cursorDirs) {
8822
+ if (existsSync(cursorDir)) {
8823
+ const cursorSessions = collectCursorSessions(cursorDir, since);
8824
+ sessions.push(...cursorSessions);
8825
+ break;
8826
+ }
8827
+ }
8828
+ const windsurfDirs = [
8829
+ join(homedir(), ".codeium", "chat_history"),
8830
+ join(homedir(), ".windsurf", "sessions"),
8831
+ join(homedir(), "Library", "Application Support", "Windsurf", "sessions")
8832
+ ];
8833
+ for (const windsurfDir of windsurfDirs) {
8834
+ if (existsSync(windsurfDir)) {
8835
+ const windsurfSessions = collectWindsurfSessions(windsurfDir, since);
8836
+ sessions.push(...windsurfSessions);
8837
+ break;
8838
+ }
8839
+ }
8840
+ const copilotDirs = [
8841
+ join(homedir(), ".config", "github-copilot"),
8842
+ join(homedir(), "Library", "Application Support", "Code", "User", "globalStorage", "github.copilot"),
8843
+ join(homedir(), ".vscode", "extensions")
8844
+ ];
8845
+ for (const copilotDir of copilotDirs) {
8846
+ if (existsSync(copilotDir)) {
8847
+ const copilotSessions = collectCopilotSessions(copilotDir, since);
8848
+ sessions.push(...copilotSessions);
8849
+ break;
8850
+ }
8851
+ }
9132
8852
  if (sessions.length === 0)
9133
8853
  return null;
9134
8854
  let totalTokens = 0;
@@ -9659,19 +9379,222 @@ function detectOpenCodePatterns(messages, partStorageDir) {
9659
9379
  }
9660
9380
  return patterns;
9661
9381
  }
9662
-
9663
- // src/collectors/tests.ts
9664
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
9665
- import { join as join2 } from "node:path";
9666
- async function collectTestResults(projectDir) {
9667
- const vitestResult = tryVitestReport(projectDir);
9668
- if (vitestResult)
9669
- return vitestResult;
9670
- const jestResult = tryJestReport(projectDir);
9671
- if (jestResult)
9672
- return jestResult;
9673
- const playwrightResult = tryPlaywrightReport(projectDir);
9674
- if (playwrightResult)
9382
+ function collectCursorSessions(sessionsDir, since) {
9383
+ const sessions = [];
9384
+ try {
9385
+ const files = readdirSync(sessionsDir).filter((f3) => f3.endsWith(".json") || f3.endsWith(".jsonl"));
9386
+ for (const file of files) {
9387
+ const filePath = join(sessionsDir, file);
9388
+ try {
9389
+ const content = readFileSync(filePath, "utf-8");
9390
+ let data;
9391
+ if (content.startsWith("[")) {
9392
+ data = JSON.parse(content);
9393
+ } else {
9394
+ data = content.trim().split(`
9395
+ `).map((line) => {
9396
+ try {
9397
+ return JSON.parse(line);
9398
+ } catch {
9399
+ return null;
9400
+ }
9401
+ }).filter(Boolean);
9402
+ }
9403
+ if (data.length === 0)
9404
+ continue;
9405
+ const firstEntry = data[0];
9406
+ const lastEntry = data[data.length - 1];
9407
+ const startTime = firstEntry?.timestamp ? new Date(firstEntry.timestamp) : new Date;
9408
+ if (startTime < since)
9409
+ continue;
9410
+ let totalTokens = 0;
9411
+ let inputTokens = 0;
9412
+ let outputTokens = 0;
9413
+ let messageCount = 0;
9414
+ for (const entry of data) {
9415
+ if (entry?.usage) {
9416
+ inputTokens += entry.usage.input_tokens || entry.usage.prompt_tokens || 0;
9417
+ outputTokens += entry.usage.output_tokens || entry.usage.completion_tokens || 0;
9418
+ }
9419
+ if (entry?.role)
9420
+ messageCount++;
9421
+ }
9422
+ totalTokens = inputTokens + outputTokens;
9423
+ const durationMinutes = lastEntry?.timestamp && firstEntry?.timestamp ? Math.round((new Date(lastEntry.timestamp).getTime() - new Date(firstEntry.timestamp).getTime()) / 60000) : 1;
9424
+ sessions.push({
9425
+ agent: "cursor",
9426
+ sessionId: basename(file, ".json").slice(0, 8),
9427
+ startedAt: startTime.toISOString(),
9428
+ endedAt: lastEntry?.timestamp || startTime.toISOString(),
9429
+ durationMinutes: Math.max(1, durationMinutes),
9430
+ inputTokens,
9431
+ outputTokens,
9432
+ cachedTokens: 0,
9433
+ totalTokens,
9434
+ costUsd: calculateTokenCost(inputTokens, outputTokens, "gpt-4"),
9435
+ model: firstEntry?.model || "gpt-4",
9436
+ toolCalls: 0,
9437
+ messageCount,
9438
+ toolNames: [],
9439
+ patterns: [{ type: "smooth_flow", count: 1, estimatedWastedTokens: 0, messageIndices: [] }]
9440
+ });
9441
+ } catch {}
9442
+ }
9443
+ } catch {}
9444
+ return sessions;
9445
+ }
9446
+ function collectWindsurfSessions(sessionsDir, since) {
9447
+ const sessions = [];
9448
+ try {
9449
+ const files = readdirSync(sessionsDir).filter((f3) => f3.endsWith(".json") || f3.endsWith(".jsonl"));
9450
+ for (const file of files) {
9451
+ const filePath = join(sessionsDir, file);
9452
+ try {
9453
+ const content = readFileSync(filePath, "utf-8");
9454
+ let data;
9455
+ if (content.startsWith("[")) {
9456
+ data = JSON.parse(content);
9457
+ } else {
9458
+ data = content.trim().split(`
9459
+ `).map((line) => {
9460
+ try {
9461
+ return JSON.parse(line);
9462
+ } catch {
9463
+ return null;
9464
+ }
9465
+ }).filter(Boolean);
9466
+ }
9467
+ if (data.length === 0)
9468
+ continue;
9469
+ const firstEntry = data[0];
9470
+ const lastEntry = data[data.length - 1];
9471
+ const startTime = firstEntry?.timestamp ? new Date(firstEntry.timestamp) : new Date;
9472
+ if (startTime < since)
9473
+ continue;
9474
+ let inputTokens = 0;
9475
+ let outputTokens = 0;
9476
+ let messageCount = 0;
9477
+ for (const entry of data) {
9478
+ if (entry?.tokens || entry?.usage) {
9479
+ const tokens = entry.tokens || entry.usage;
9480
+ inputTokens += tokens.input || tokens.prompt_tokens || 0;
9481
+ outputTokens += tokens.output || tokens.completion_tokens || 0;
9482
+ }
9483
+ messageCount++;
9484
+ }
9485
+ const totalTokens = inputTokens + outputTokens;
9486
+ const durationMinutes = Math.max(1, Math.round((new Date(lastEntry?.timestamp || startTime).getTime() - startTime.getTime()) / 60000));
9487
+ sessions.push({
9488
+ agent: "windsurf",
9489
+ sessionId: basename(file, ".json").slice(0, 8),
9490
+ startedAt: startTime.toISOString(),
9491
+ endedAt: lastEntry?.timestamp || startTime.toISOString(),
9492
+ durationMinutes,
9493
+ inputTokens,
9494
+ outputTokens,
9495
+ cachedTokens: 0,
9496
+ totalTokens,
9497
+ costUsd: calculateTokenCost(inputTokens, outputTokens, "gpt-4"),
9498
+ model: firstEntry?.model || "codeium",
9499
+ toolCalls: 0,
9500
+ messageCount,
9501
+ toolNames: [],
9502
+ patterns: [{ type: "smooth_flow", count: 1, estimatedWastedTokens: 0, messageIndices: [] }]
9503
+ });
9504
+ } catch {}
9505
+ }
9506
+ } catch {}
9507
+ return sessions;
9508
+ }
9509
+ function collectCopilotSessions(copilotDir, since) {
9510
+ const sessions = [];
9511
+ try {
9512
+ const searchPaths = [
9513
+ join(copilotDir, "usage"),
9514
+ join(copilotDir, "telemetry"),
9515
+ join(copilotDir, "chat"),
9516
+ copilotDir
9517
+ ];
9518
+ for (const searchPath of searchPaths) {
9519
+ if (!existsSync(searchPath))
9520
+ continue;
9521
+ const files = readdirSync(searchPath).filter((f3) => f3.endsWith(".json") || f3.endsWith(".jsonl") || f3.endsWith(".log"));
9522
+ for (const file of files) {
9523
+ const filePath = join(searchPath, file);
9524
+ try {
9525
+ const content = readFileSync(filePath, "utf-8");
9526
+ let entries = [];
9527
+ try {
9528
+ if (content.startsWith("[")) {
9529
+ entries = JSON.parse(content);
9530
+ } else {
9531
+ entries = content.trim().split(`
9532
+ `).map((line) => {
9533
+ try {
9534
+ return JSON.parse(line);
9535
+ } catch {
9536
+ return null;
9537
+ }
9538
+ }).filter(Boolean);
9539
+ }
9540
+ } catch {
9541
+ continue;
9542
+ }
9543
+ if (entries.length === 0)
9544
+ continue;
9545
+ const firstEntry = entries[0];
9546
+ const lastEntry = entries[entries.length - 1];
9547
+ const startTime = firstEntry?.timestamp ? new Date(firstEntry.timestamp) : firstEntry?.time ? new Date(firstEntry.time) : new Date;
9548
+ if (startTime < since)
9549
+ continue;
9550
+ let completionCount = 0;
9551
+ let totalChars = 0;
9552
+ for (const entry of entries) {
9553
+ if (entry?.completion || entry?.suggestion || entry?.accepted) {
9554
+ completionCount++;
9555
+ const text = entry.completion || entry.suggestion || entry.text || "";
9556
+ totalChars += typeof text === "string" ? text.length : 0;
9557
+ }
9558
+ }
9559
+ const estimatedTokens = Math.round(totalChars / 4);
9560
+ if (completionCount > 0) {
9561
+ sessions.push({
9562
+ agent: "copilot",
9563
+ sessionId: basename(file).slice(0, 8),
9564
+ startedAt: startTime.toISOString(),
9565
+ endedAt: lastEntry?.timestamp || lastEntry?.time || startTime.toISOString(),
9566
+ durationMinutes: 1,
9567
+ inputTokens: 0,
9568
+ outputTokens: estimatedTokens,
9569
+ cachedTokens: 0,
9570
+ totalTokens: estimatedTokens,
9571
+ costUsd: 0,
9572
+ model: "copilot",
9573
+ toolCalls: 0,
9574
+ messageCount: completionCount,
9575
+ toolNames: [],
9576
+ patterns: [{ type: "smooth_flow", count: 1, estimatedWastedTokens: 0, messageIndices: [] }]
9577
+ });
9578
+ }
9579
+ } catch {}
9580
+ }
9581
+ }
9582
+ } catch {}
9583
+ return sessions;
9584
+ }
9585
+
9586
+ // src/collectors/tests.ts
9587
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
9588
+ import { join as join2 } from "node:path";
9589
+ async function collectTestResults(projectDir) {
9590
+ const vitestResult = tryVitestReport(projectDir);
9591
+ if (vitestResult)
9592
+ return vitestResult;
9593
+ const jestResult = tryJestReport(projectDir);
9594
+ if (jestResult)
9595
+ return jestResult;
9596
+ const playwrightResult = tryPlaywrightReport(projectDir);
9597
+ if (playwrightResult)
9675
9598
  return playwrightResult;
9676
9599
  return null;
9677
9600
  }
@@ -10541,12 +10464,12 @@ function analyzeParallelization(agents) {
10541
10464
  if (agents && agents.sessions.length > 0) {
10542
10465
  const sortedSessions = [...agents.sessions].sort((a2, b2) => new Date(a2.startedAt).getTime() - new Date(b2.startedAt).getTime());
10543
10466
  let maxConcurrent = 1;
10544
- for (let i4 = 0;i4 < sortedSessions.length; i4++) {
10545
- const session = sortedSessions[i4];
10467
+ for (let i3 = 0;i3 < sortedSessions.length; i3++) {
10468
+ const session = sortedSessions[i3];
10546
10469
  const sessionStart = new Date(session.startedAt).getTime();
10547
10470
  const sessionEnd = session.endedAt ? new Date(session.endedAt).getTime() : sessionStart + session.durationMinutes * 60000;
10548
10471
  let concurrent = 1;
10549
- for (let j = i4 + 1;j < sortedSessions.length; j++) {
10472
+ for (let j = i3 + 1;j < sortedSessions.length; j++) {
10550
10473
  const other = sortedSessions[j];
10551
10474
  const otherStart = new Date(other.startedAt).getTime();
10552
10475
  if (otherStart < sessionEnd) {
@@ -10647,14 +10570,14 @@ function calculateScanCost(agents, git) {
10647
10570
  };
10648
10571
  }
10649
10572
 
10650
- // ../../node_modules/.bun/ora@9.3.0/node_modules/ora/index.js
10573
+ // ../../node_modules/ora/index.js
10651
10574
  import process8 from "node:process";
10652
10575
  import { stripVTControlCharacters } from "node:util";
10653
10576
 
10654
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
10577
+ // ../../node_modules/chalk/source/vendor/ansi-styles/index.js
10655
10578
  var ANSI_BACKGROUND_OFFSET = 10;
10656
- var wrapAnsi16 = (offset = 0) => (code3) => `\x1B[${code3 + offset}m`;
10657
- var wrapAnsi256 = (offset = 0) => (code3) => `\x1B[${38 + offset};5;${code3}m`;
10579
+ var wrapAnsi16 = (offset = 0) => (code2) => `\x1B[${code2 + offset}m`;
10580
+ var wrapAnsi256 = (offset = 0) => (code2) => `\x1B[${38 + offset};5;${code2}m`;
10658
10581
  var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
10659
10582
  var styles = {
10660
10583
  modifier: {
@@ -10781,24 +10704,24 @@ function assembleStyles() {
10781
10704
  enumerable: false
10782
10705
  },
10783
10706
  ansi256ToAnsi: {
10784
- value(code3) {
10785
- if (code3 < 8) {
10786
- return 30 + code3;
10707
+ value(code2) {
10708
+ if (code2 < 8) {
10709
+ return 30 + code2;
10787
10710
  }
10788
- if (code3 < 16) {
10789
- return 90 + (code3 - 8);
10711
+ if (code2 < 16) {
10712
+ return 90 + (code2 - 8);
10790
10713
  }
10791
10714
  let red;
10792
10715
  let green;
10793
10716
  let blue;
10794
- if (code3 >= 232) {
10795
- red = ((code3 - 232) * 10 + 8) / 255;
10717
+ if (code2 >= 232) {
10718
+ red = ((code2 - 232) * 10 + 8) / 255;
10796
10719
  green = red;
10797
10720
  blue = red;
10798
10721
  } else {
10799
- code3 -= 16;
10800
- const remainder = code3 % 36;
10801
- red = Math.floor(code3 / 36) / 5;
10722
+ code2 -= 16;
10723
+ const remainder = code2 % 36;
10724
+ red = Math.floor(code2 / 36) / 5;
10802
10725
  green = Math.floor(remainder / 6) / 5;
10803
10726
  blue = remainder % 6 / 5;
10804
10727
  }
@@ -10828,7 +10751,7 @@ function assembleStyles() {
10828
10751
  var ansiStyles = assembleStyles();
10829
10752
  var ansi_styles_default = ansiStyles;
10830
10753
 
10831
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
10754
+ // ../../node_modules/chalk/source/vendor/supports-color/index.js
10832
10755
  import process2 from "node:process";
10833
10756
  import os from "node:os";
10834
10757
  import tty2 from "node:tty";
@@ -10960,7 +10883,7 @@ var supportsColor = {
10960
10883
  };
10961
10884
  var supports_color_default = supportsColor;
10962
10885
 
10963
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/utilities.js
10886
+ // ../../node_modules/chalk/source/utilities.js
10964
10887
  function stringReplaceAll(string, substring, replacer) {
10965
10888
  let index = string.indexOf(substring);
10966
10889
  if (index === -1) {
@@ -10993,7 +10916,7 @@ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
10993
10916
  return returnValue;
10994
10917
  }
10995
10918
 
10996
- // ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/index.js
10919
+ // ../../node_modules/chalk/source/index.js
10997
10920
  var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
10998
10921
  var GENERATOR = Symbol("GENERATOR");
10999
10922
  var STYLER = Symbol("STYLER");
@@ -11140,13 +11063,13 @@ var chalk = createChalk();
11140
11063
  var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
11141
11064
  var source_default = chalk;
11142
11065
 
11143
- // ../../node_modules/.bun/cli-cursor@5.0.0/node_modules/cli-cursor/index.js
11066
+ // ../../node_modules/cli-cursor/index.js
11144
11067
  import process5 from "node:process";
11145
11068
 
11146
- // ../../node_modules/.bun/restore-cursor@5.1.0/node_modules/restore-cursor/index.js
11069
+ // ../../node_modules/restore-cursor/index.js
11147
11070
  import process4 from "node:process";
11148
11071
 
11149
- // ../../node_modules/.bun/mimic-function@5.0.1/node_modules/mimic-function/index.js
11072
+ // ../../node_modules/mimic-function/index.js
11150
11073
  var copyProperty = (to, from, property, ignoreNonConfigurable) => {
11151
11074
  if (property === "length" || property === "prototype") {
11152
11075
  return;
@@ -11192,7 +11115,7 @@ function mimicFunction(to, from, { ignoreNonConfigurable = false } = {}) {
11192
11115
  return to;
11193
11116
  }
11194
11117
 
11195
- // ../../node_modules/.bun/onetime@7.0.0/node_modules/onetime/index.js
11118
+ // ../../node_modules/onetime/index.js
11196
11119
  var calledFunctions = new WeakMap;
11197
11120
  var onetime = (function_, options = {}) => {
11198
11121
  if (typeof function_ !== "function") {
@@ -11200,14 +11123,14 @@ var onetime = (function_, options = {}) => {
11200
11123
  }
11201
11124
  let returnValue;
11202
11125
  let callCount = 0;
11203
- const functionName3 = function_.displayName || function_.name || "<anonymous>";
11126
+ const functionName2 = function_.displayName || function_.name || "<anonymous>";
11204
11127
  const onetime2 = function(...arguments_) {
11205
11128
  calledFunctions.set(onetime2, ++callCount);
11206
11129
  if (callCount === 1) {
11207
11130
  returnValue = function_.apply(this, arguments_);
11208
11131
  function_ = undefined;
11209
11132
  } else if (options.throw === true) {
11210
- throw new Error(`Function \`${functionName3}\` can only be called once`);
11133
+ throw new Error(`Function \`${functionName2}\` can only be called once`);
11211
11134
  }
11212
11135
  return returnValue;
11213
11136
  };
@@ -11223,7 +11146,7 @@ onetime.callCount = (function_) => {
11223
11146
  };
11224
11147
  var onetime_default = onetime;
11225
11148
 
11226
- // ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
11149
+ // ../../node_modules/signal-exit/dist/mjs/signals.js
11227
11150
  var signals = [];
11228
11151
  signals.push("SIGHUP", "SIGINT", "SIGTERM");
11229
11152
  if (process.platform !== "win32") {
@@ -11233,7 +11156,7 @@ if (process.platform === "linux") {
11233
11156
  signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
11234
11157
  }
11235
11158
 
11236
- // ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
11159
+ // ../../node_modules/signal-exit/dist/mjs/index.js
11237
11160
  var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
11238
11161
  var kExitEmitter = Symbol.for("signal-exit emitter");
11239
11162
  var global = globalThis;
@@ -11266,27 +11189,27 @@ class Emitter {
11266
11189
  }
11267
11190
  removeListener(ev, fn) {
11268
11191
  const list = this.listeners[ev];
11269
- const i4 = list.indexOf(fn);
11270
- if (i4 === -1) {
11192
+ const i3 = list.indexOf(fn);
11193
+ if (i3 === -1) {
11271
11194
  return;
11272
11195
  }
11273
- if (i4 === 0 && list.length === 1) {
11196
+ if (i3 === 0 && list.length === 1) {
11274
11197
  list.length = 0;
11275
11198
  } else {
11276
- list.splice(i4, 1);
11199
+ list.splice(i3, 1);
11277
11200
  }
11278
11201
  }
11279
- emit(ev, code3, signal) {
11202
+ emit(ev, code2, signal) {
11280
11203
  if (this.emitted[ev]) {
11281
11204
  return false;
11282
11205
  }
11283
11206
  this.emitted[ev] = true;
11284
11207
  let ret = false;
11285
11208
  for (const fn of this.listeners[ev]) {
11286
- ret = fn(code3, signal) === true || ret;
11209
+ ret = fn(code2, signal) === true || ret;
11287
11210
  }
11288
11211
  if (ev === "exit") {
11289
- ret = this.emit("afterExit", code3, signal) || ret;
11212
+ ret = this.emit("afterExit", code2, signal) || ret;
11290
11213
  }
11291
11214
  return ret;
11292
11215
  }
@@ -11380,8 +11303,8 @@ class SignalExit extends SignalExitBase {
11380
11303
  this.#process.emit = (ev, ...a2) => {
11381
11304
  return this.#processEmit(ev, ...a2);
11382
11305
  };
11383
- this.#process.reallyExit = (code3) => {
11384
- return this.#processReallyExit(code3);
11306
+ this.#process.reallyExit = (code2) => {
11307
+ return this.#processReallyExit(code2);
11385
11308
  };
11386
11309
  }
11387
11310
  unload() {
@@ -11402,11 +11325,11 @@ class SignalExit extends SignalExitBase {
11402
11325
  this.#process.reallyExit = this.#originalProcessReallyExit;
11403
11326
  this.#emitter.count -= 1;
11404
11327
  }
11405
- #processReallyExit(code3) {
11328
+ #processReallyExit(code2) {
11406
11329
  if (!processOk(this.#process)) {
11407
11330
  return 0;
11408
11331
  }
11409
- this.#process.exitCode = code3 || 0;
11332
+ this.#process.exitCode = code2 || 0;
11410
11333
  this.#emitter.emit("exit", this.#process.exitCode, null);
11411
11334
  return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
11412
11335
  }
@@ -11431,7 +11354,7 @@ var {
11431
11354
  unload
11432
11355
  } = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
11433
11356
 
11434
- // ../../node_modules/.bun/restore-cursor@5.1.0/node_modules/restore-cursor/index.js
11357
+ // ../../node_modules/restore-cursor/index.js
11435
11358
  var terminal = process4.stderr.isTTY ? process4.stderr : process4.stdout.isTTY ? process4.stdout : undefined;
11436
11359
  var restoreCursor = terminal ? onetime_default(() => {
11437
11360
  onExit(() => {
@@ -11440,7 +11363,7 @@ var restoreCursor = terminal ? onetime_default(() => {
11440
11363
  }) : () => {};
11441
11364
  var restore_cursor_default = restoreCursor;
11442
11365
 
11443
- // ../../node_modules/.bun/cli-cursor@5.0.0/node_modules/cli-cursor/index.js
11366
+ // ../../node_modules/cli-cursor/index.js
11444
11367
  var isHidden = false;
11445
11368
  var cliCursor = {};
11446
11369
  cliCursor.show = (writableStream = process5.stderr) => {
@@ -11469,7 +11392,7 @@ cliCursor.toggle = (force, writableStream) => {
11469
11392
  }
11470
11393
  };
11471
11394
  var cli_cursor_default = cliCursor;
11472
- // ../../node_modules/.bun/cli-spinners@3.4.0/node_modules/cli-spinners/spinners.json
11395
+ // ../../node_modules/cli-spinners/spinners.json
11473
11396
  var spinners_default = {
11474
11397
  dots: {
11475
11398
  interval: 80,
@@ -13168,11 +13091,11 @@ var spinners_default = {
13168
13091
  }
13169
13092
  };
13170
13093
 
13171
- // ../../node_modules/.bun/cli-spinners@3.4.0/node_modules/cli-spinners/index.js
13094
+ // ../../node_modules/cli-spinners/index.js
13172
13095
  var cli_spinners_default = spinners_default;
13173
13096
  var spinnersList = Object.keys(spinners_default);
13174
13097
 
13175
- // ../../node_modules/.bun/log-symbols@7.0.1/node_modules/log-symbols/symbols.js
13098
+ // ../../node_modules/log-symbols/symbols.js
13176
13099
  var exports_symbols = {};
13177
13100
  __export(exports_symbols, {
13178
13101
  warning: () => warning,
@@ -13181,7 +13104,7 @@ __export(exports_symbols, {
13181
13104
  error: () => error
13182
13105
  });
13183
13106
 
13184
- // ../../node_modules/.bun/yoctocolors@2.1.2/node_modules/yoctocolors/base.js
13107
+ // ../../node_modules/yoctocolors/base.js
13185
13108
  import tty3 from "node:tty";
13186
13109
  var hasColors = tty3?.WriteStream?.prototype?.hasColors?.() ?? false;
13187
13110
  var format = (open, close) => {
@@ -13251,7 +13174,7 @@ var bgMagentaBright = format(105, 49);
13251
13174
  var bgCyanBright = format(106, 49);
13252
13175
  var bgWhiteBright = format(107, 49);
13253
13176
 
13254
- // ../../node_modules/.bun/is-unicode-supported@2.1.0/node_modules/is-unicode-supported/index.js
13177
+ // ../../node_modules/is-unicode-supported/index.js
13255
13178
  import process6 from "node:process";
13256
13179
  function isUnicodeSupported2() {
13257
13180
  const { env: env3 } = process6;
@@ -13262,13 +13185,13 @@ function isUnicodeSupported2() {
13262
13185
  return Boolean(env3.WT_SESSION) || Boolean(env3.TERMINUS_SUBLIME) || env3.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env3.TERMINAL_EMULATOR === "JetBrains-JediTerm";
13263
13186
  }
13264
13187
 
13265
- // ../../node_modules/.bun/log-symbols@7.0.1/node_modules/log-symbols/symbols.js
13188
+ // ../../node_modules/log-symbols/symbols.js
13266
13189
  var _isUnicodeSupported = isUnicodeSupported2();
13267
13190
  var info = blue(_isUnicodeSupported ? "ℹ" : "i");
13268
13191
  var success = green(_isUnicodeSupported ? "✔" : "√");
13269
13192
  var warning = yellow(_isUnicodeSupported ? "⚠" : "‼");
13270
13193
  var error = red(_isUnicodeSupported ? "✖" : "×");
13271
- // ../../node_modules/.bun/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
13194
+ // ../../node_modules/ansi-regex/index.js
13272
13195
  function ansiRegex3({ onlyFirst = false } = {}) {
13273
13196
  const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
13274
13197
  const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
@@ -13277,7 +13200,7 @@ function ansiRegex3({ onlyFirst = false } = {}) {
13277
13200
  return new RegExp(pattern, onlyFirst ? undefined : "g");
13278
13201
  }
13279
13202
 
13280
- // ../../node_modules/.bun/strip-ansi@7.1.2/node_modules/strip-ansi/index.js
13203
+ // ../../node_modules/strip-ansi/index.js
13281
13204
  var regex2 = ansiRegex3();
13282
13205
  function stripAnsi3(string) {
13283
13206
  if (typeof string !== "string") {
@@ -13286,7 +13209,7 @@ function stripAnsi3(string) {
13286
13209
  return string.replace(regex2, "");
13287
13210
  }
13288
13211
 
13289
- // ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js
13212
+ // ../../node_modules/get-east-asian-width/lookup.js
13290
13213
  function isAmbiguous2(x2) {
13291
13214
  return x2 === 161 || x2 === 164 || x2 === 167 || x2 === 168 || x2 === 170 || x2 === 173 || x2 === 174 || x2 >= 176 && x2 <= 180 || x2 >= 182 && x2 <= 186 || x2 >= 188 && x2 <= 191 || x2 === 198 || x2 === 208 || x2 === 215 || x2 === 216 || x2 >= 222 && x2 <= 225 || x2 === 230 || x2 >= 232 && x2 <= 234 || x2 === 236 || x2 === 237 || x2 === 240 || x2 === 242 || x2 === 243 || x2 >= 247 && x2 <= 250 || x2 === 252 || x2 === 254 || x2 === 257 || x2 === 273 || x2 === 275 || x2 === 283 || x2 === 294 || x2 === 295 || x2 === 299 || x2 >= 305 && x2 <= 307 || x2 === 312 || x2 >= 319 && x2 <= 322 || x2 === 324 || x2 >= 328 && x2 <= 331 || x2 === 333 || x2 === 338 || x2 === 339 || x2 === 358 || x2 === 359 || x2 === 363 || x2 === 462 || x2 === 464 || x2 === 466 || x2 === 468 || x2 === 470 || x2 === 472 || x2 === 474 || x2 === 476 || x2 === 593 || x2 === 609 || x2 === 708 || x2 === 711 || x2 >= 713 && x2 <= 715 || x2 === 717 || x2 === 720 || x2 >= 728 && x2 <= 731 || x2 === 733 || x2 === 735 || x2 >= 768 && x2 <= 879 || x2 >= 913 && x2 <= 929 || x2 >= 931 && x2 <= 937 || x2 >= 945 && x2 <= 961 || x2 >= 963 && x2 <= 969 || x2 === 1025 || x2 >= 1040 && x2 <= 1103 || x2 === 1105 || x2 === 8208 || x2 >= 8211 && x2 <= 8214 || x2 === 8216 || x2 === 8217 || x2 === 8220 || x2 === 8221 || x2 >= 8224 && x2 <= 8226 || x2 >= 8228 && x2 <= 8231 || x2 === 8240 || x2 === 8242 || x2 === 8243 || x2 === 8245 || x2 === 8251 || x2 === 8254 || x2 === 8308 || x2 === 8319 || x2 >= 8321 && x2 <= 8324 || x2 === 8364 || x2 === 8451 || x2 === 8453 || x2 === 8457 || x2 === 8467 || x2 === 8470 || x2 === 8481 || x2 === 8482 || x2 === 8486 || x2 === 8491 || x2 === 8531 || x2 === 8532 || x2 >= 8539 && x2 <= 8542 || x2 >= 8544 && x2 <= 8555 || x2 >= 8560 && x2 <= 8569 || x2 === 8585 || x2 >= 8592 && x2 <= 8601 || x2 === 8632 || x2 === 8633 || x2 === 8658 || x2 === 8660 || x2 === 8679 || x2 === 8704 || x2 === 8706 || x2 === 8707 || x2 === 8711 || x2 === 8712 || x2 === 8715 || x2 === 8719 || x2 === 8721 || x2 === 8725 || x2 === 8730 || x2 >= 8733 && x2 <= 8736 || x2 === 8739 || x2 === 8741 || x2 >= 8743 && x2 <= 8748 || x2 === 8750 || x2 >= 8756 && x2 <= 8759 || x2 === 8764 || x2 === 8765 || x2 === 8776 || x2 === 8780 || x2 === 8786 || x2 === 8800 || x2 === 8801 || x2 >= 8804 && x2 <= 8807 || x2 === 8810 || x2 === 8811 || x2 === 8814 || x2 === 8815 || x2 === 8834 || x2 === 8835 || x2 === 8838 || x2 === 8839 || x2 === 8853 || x2 === 8857 || x2 === 8869 || x2 === 8895 || x2 === 8978 || x2 >= 9312 && x2 <= 9449 || x2 >= 9451 && x2 <= 9547 || x2 >= 9552 && x2 <= 9587 || x2 >= 9600 && x2 <= 9615 || x2 >= 9618 && x2 <= 9621 || x2 === 9632 || x2 === 9633 || x2 >= 9635 && x2 <= 9641 || x2 === 9650 || x2 === 9651 || x2 === 9654 || x2 === 9655 || x2 === 9660 || x2 === 9661 || x2 === 9664 || x2 === 9665 || x2 >= 9670 && x2 <= 9672 || x2 === 9675 || x2 >= 9678 && x2 <= 9681 || x2 >= 9698 && x2 <= 9701 || x2 === 9711 || x2 === 9733 || x2 === 9734 || x2 === 9737 || x2 === 9742 || x2 === 9743 || x2 === 9756 || x2 === 9758 || x2 === 9792 || x2 === 9794 || x2 === 9824 || x2 === 9825 || x2 >= 9827 && x2 <= 9829 || x2 >= 9831 && x2 <= 9834 || x2 === 9836 || x2 === 9837 || x2 === 9839 || x2 === 9886 || x2 === 9887 || x2 === 9919 || x2 >= 9926 && x2 <= 9933 || x2 >= 9935 && x2 <= 9939 || x2 >= 9941 && x2 <= 9953 || x2 === 9955 || x2 === 9960 || x2 === 9961 || x2 >= 9963 && x2 <= 9969 || x2 === 9972 || x2 >= 9974 && x2 <= 9977 || x2 === 9979 || x2 === 9980 || x2 === 9982 || x2 === 9983 || x2 === 10045 || x2 >= 10102 && x2 <= 10111 || x2 >= 11094 && x2 <= 11097 || x2 >= 12872 && x2 <= 12879 || x2 >= 57344 && x2 <= 63743 || x2 >= 65024 && x2 <= 65039 || x2 === 65533 || x2 >= 127232 && x2 <= 127242 || x2 >= 127248 && x2 <= 127277 || x2 >= 127280 && x2 <= 127337 || x2 >= 127344 && x2 <= 127373 || x2 === 127375 || x2 === 127376 || x2 >= 127387 && x2 <= 127404 || x2 >= 917760 && x2 <= 917999 || x2 >= 983040 && x2 <= 1048573 || x2 >= 1048576 && x2 <= 1114109;
13292
13215
  }
@@ -13297,7 +13220,7 @@ function isWide2(x2) {
13297
13220
  return x2 >= 4352 && x2 <= 4447 || x2 === 8986 || x2 === 8987 || x2 === 9001 || x2 === 9002 || x2 >= 9193 && x2 <= 9196 || x2 === 9200 || x2 === 9203 || x2 === 9725 || x2 === 9726 || x2 === 9748 || x2 === 9749 || x2 >= 9776 && x2 <= 9783 || x2 >= 9800 && x2 <= 9811 || x2 === 9855 || x2 >= 9866 && x2 <= 9871 || x2 === 9875 || x2 === 9889 || x2 === 9898 || x2 === 9899 || x2 === 9917 || x2 === 9918 || x2 === 9924 || x2 === 9925 || x2 === 9934 || x2 === 9940 || x2 === 9962 || x2 === 9970 || x2 === 9971 || x2 === 9973 || x2 === 9978 || x2 === 9981 || x2 === 9989 || x2 === 9994 || x2 === 9995 || x2 === 10024 || x2 === 10060 || x2 === 10062 || x2 >= 10067 && x2 <= 10069 || x2 === 10071 || x2 >= 10133 && x2 <= 10135 || x2 === 10160 || x2 === 10175 || x2 === 11035 || x2 === 11036 || x2 === 11088 || x2 === 11093 || x2 >= 11904 && x2 <= 11929 || x2 >= 11931 && x2 <= 12019 || x2 >= 12032 && x2 <= 12245 || x2 >= 12272 && x2 <= 12287 || x2 >= 12289 && x2 <= 12350 || x2 >= 12353 && x2 <= 12438 || x2 >= 12441 && x2 <= 12543 || x2 >= 12549 && x2 <= 12591 || x2 >= 12593 && x2 <= 12686 || x2 >= 12688 && x2 <= 12773 || x2 >= 12783 && x2 <= 12830 || x2 >= 12832 && x2 <= 12871 || x2 >= 12880 && x2 <= 42124 || x2 >= 42128 && x2 <= 42182 || x2 >= 43360 && x2 <= 43388 || x2 >= 44032 && x2 <= 55203 || x2 >= 63744 && x2 <= 64255 || x2 >= 65040 && x2 <= 65049 || x2 >= 65072 && x2 <= 65106 || x2 >= 65108 && x2 <= 65126 || x2 >= 65128 && x2 <= 65131 || x2 >= 94176 && x2 <= 94180 || x2 >= 94192 && x2 <= 94198 || x2 >= 94208 && x2 <= 101589 || x2 >= 101631 && x2 <= 101662 || x2 >= 101760 && x2 <= 101874 || x2 >= 110576 && x2 <= 110579 || x2 >= 110581 && x2 <= 110587 || x2 === 110589 || x2 === 110590 || x2 >= 110592 && x2 <= 110882 || x2 === 110898 || x2 >= 110928 && x2 <= 110930 || x2 === 110933 || x2 >= 110948 && x2 <= 110951 || x2 >= 110960 && x2 <= 111355 || x2 >= 119552 && x2 <= 119638 || x2 >= 119648 && x2 <= 119670 || x2 === 126980 || x2 === 127183 || x2 === 127374 || x2 >= 127377 && x2 <= 127386 || x2 >= 127488 && x2 <= 127490 || x2 >= 127504 && x2 <= 127547 || x2 >= 127552 && x2 <= 127560 || x2 === 127568 || x2 === 127569 || x2 >= 127584 && x2 <= 127589 || x2 >= 127744 && x2 <= 127776 || x2 >= 127789 && x2 <= 127797 || x2 >= 127799 && x2 <= 127868 || x2 >= 127870 && x2 <= 127891 || x2 >= 127904 && x2 <= 127946 || x2 >= 127951 && x2 <= 127955 || x2 >= 127968 && x2 <= 127984 || x2 === 127988 || x2 >= 127992 && x2 <= 128062 || x2 === 128064 || x2 >= 128066 && x2 <= 128252 || x2 >= 128255 && x2 <= 128317 || x2 >= 128331 && x2 <= 128334 || x2 >= 128336 && x2 <= 128359 || x2 === 128378 || x2 === 128405 || x2 === 128406 || x2 === 128420 || x2 >= 128507 && x2 <= 128591 || x2 >= 128640 && x2 <= 128709 || x2 === 128716 || x2 >= 128720 && x2 <= 128722 || x2 >= 128725 && x2 <= 128728 || x2 >= 128732 && x2 <= 128735 || x2 === 128747 || x2 === 128748 || x2 >= 128756 && x2 <= 128764 || x2 >= 128992 && x2 <= 129003 || x2 === 129008 || x2 >= 129292 && x2 <= 129338 || x2 >= 129340 && x2 <= 129349 || x2 >= 129351 && x2 <= 129535 || x2 >= 129648 && x2 <= 129660 || x2 >= 129664 && x2 <= 129674 || x2 >= 129678 && x2 <= 129734 || x2 === 129736 || x2 >= 129741 && x2 <= 129756 || x2 >= 129759 && x2 <= 129770 || x2 >= 129775 && x2 <= 129784 || x2 >= 131072 && x2 <= 196605 || x2 >= 196608 && x2 <= 262141;
13298
13221
  }
13299
13222
 
13300
- // ../../node_modules/.bun/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js
13223
+ // ../../node_modules/get-east-asian-width/index.js
13301
13224
  function validate2(codePoint) {
13302
13225
  if (!Number.isSafeInteger(codePoint)) {
13303
13226
  throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
@@ -13311,7 +13234,7 @@ function eastAsianWidth2(codePoint, { ambiguousAsWide = false } = {}) {
13311
13234
  return 1;
13312
13235
  }
13313
13236
 
13314
- // ../../node_modules/.bun/string-width@8.1.1/node_modules/string-width/index.js
13237
+ // ../../node_modules/string-width/index.js
13315
13238
  var segmenter2 = new Intl.Segmenter;
13316
13239
  var zeroWidthClusterRegex = /^(?:\p{Default_Ignorable_Code_Point}|\p{Control}|\p{Format}|\p{Mark}|\p{Surrogate})+$/v;
13317
13240
  var leadingNonPrintingRegex = /^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Mark}\p{Surrogate}]+/v;
@@ -13365,12 +13288,12 @@ function stringWidth2(input, options = {}) {
13365
13288
  return width;
13366
13289
  }
13367
13290
 
13368
- // ../../node_modules/.bun/is-interactive@2.0.0/node_modules/is-interactive/index.js
13291
+ // ../../node_modules/is-interactive/index.js
13369
13292
  function isInteractive({ stream = process.stdout } = {}) {
13370
13293
  return Boolean(stream && stream.isTTY && process.env.TERM !== "dumb" && !("CI" in process.env));
13371
13294
  }
13372
13295
 
13373
- // ../../node_modules/.bun/stdin-discarder@0.3.1/node_modules/stdin-discarder/index.js
13296
+ // ../../node_modules/stdin-discarder/index.js
13374
13297
  import process7 from "node:process";
13375
13298
  var ASCII_ETX_CODE = 3;
13376
13299
 
@@ -13383,8 +13306,8 @@ class StdinDiscarder {
13383
13306
  if (!chunk?.length) {
13384
13307
  return;
13385
13308
  }
13386
- const code3 = typeof chunk === "string" ? chunk.codePointAt(0) : chunk[0];
13387
- if (code3 === ASCII_ETX_CODE) {
13309
+ const code2 = typeof chunk === "string" ? chunk.codePointAt(0) : chunk[0];
13310
+ if (code2 === ASCII_ETX_CODE) {
13388
13311
  if (process7.listenerCount("SIGINT") > 0) {
13389
13312
  process7.emit("SIGINT");
13390
13313
  } else {
@@ -13441,7 +13364,7 @@ class StdinDiscarder {
13441
13364
  var stdinDiscarder = new StdinDiscarder;
13442
13365
  var stdin_discarder_default = Object.freeze(stdinDiscarder);
13443
13366
 
13444
- // ../../node_modules/.bun/ora@9.3.0/node_modules/ora/index.js
13367
+ // ../../node_modules/ora/index.js
13445
13368
  var RENDER_DEFERRAL_TIMEOUT = 200;
13446
13369
  var SYNCHRONIZED_OUTPUT_ENABLE = "\x1B[?2026h";
13447
13370
  var SYNCHRONIZED_OUTPUT_DISABLE = "\x1B[?2026l";
@@ -13977,8 +13900,8 @@ async function animateProgressBar(label, score, options = {}) {
13977
13900
  const paddedLabel = label.padEnd(labelWidth);
13978
13901
  const scoreStr = `${score}/100`.padStart(7);
13979
13902
  write(` ${colors2.dim(paddedLabel)} ${colors2.dim(scoreStr)} `);
13980
- for (let i4 = 0;i4 < width; i4++) {
13981
- if (i4 < filled) {
13903
+ for (let i3 = 0;i3 < width; i3++) {
13904
+ if (i3 < filled) {
13982
13905
  write(barColor("█"));
13983
13906
  } else {
13984
13907
  write(colors2.dim("░"));
@@ -14011,8 +13934,8 @@ async function animateScoreReveal(score, tier, options = {}) {
14011
13934
  console.log();
14012
13935
  const steps = 30;
14013
13936
  const stepDuration = countDuration / steps;
14014
- for (let i4 = 1;i4 <= steps; i4++) {
14015
- const current = Math.round(i4 / steps * score);
13937
+ for (let i3 = 1;i3 <= steps; i3++) {
13938
+ const current = Math.round(i3 / steps * score);
14016
13939
  clearLine2();
14017
13940
  write(` ${colors2.bold("Your Score:")} ${scoreColor(colors2.bold(current.toString()))}/100`);
14018
13941
  await sleep(stepDuration);
@@ -14023,8 +13946,8 @@ async function animateScoreReveal(score, tier, options = {}) {
14023
13946
  const barWidth = 30;
14024
13947
  const filled = Math.round(score / 100 * barWidth);
14025
13948
  write(" ");
14026
- for (let i4 = 0;i4 < barWidth; i4++) {
14027
- if (i4 < filled) {
13949
+ for (let i3 = 0;i3 < barWidth; i3++) {
13950
+ if (i3 < filled) {
14028
13951
  write(scoreColor("█"));
14029
13952
  } else {
14030
13953
  write(colors2.dim("░"));
@@ -14089,127 +14012,194 @@ var scanCommand = defineCommand2({
14089
14012
  type: "boolean",
14090
14013
  description: "Show brief output (skip detailed analysis)",
14091
14014
  default: false
14015
+ },
14016
+ json: {
14017
+ type: "boolean",
14018
+ description: "Output results as JSON (for CI/scripts)",
14019
+ default: false
14020
+ },
14021
+ quiet: {
14022
+ type: "boolean",
14023
+ alias: "q",
14024
+ description: "Quiet mode - only output the score number",
14025
+ default: false
14092
14026
  }
14093
14027
  },
14094
14028
  async run({ args }) {
14095
14029
  const projectDir = args.project ?? process.cwd();
14096
14030
  const since = parseSince(args.since);
14097
- console.log();
14098
- console.log(colors2.bold(colors2.primary(" NaironAI Workflow Scanner")));
14099
- console.log(colors2.dim(" " + "─".repeat(40)));
14100
- await sleep(300);
14101
- await showPhaseHeader(1, 3, "Data Collection", 200);
14102
- await thinkingStep("Connecting to git repository...", 400);
14031
+ const jsonOutput = args.json;
14032
+ const quietMode = args.quiet;
14033
+ const silent = jsonOutput || quietMode;
14034
+ if (!silent) {
14035
+ console.log();
14036
+ console.log(colors2.bold(colors2.primary(" NaironAI Workflow Scanner")));
14037
+ console.log(colors2.dim(" " + "─".repeat(40)));
14038
+ await sleep(300);
14039
+ }
14040
+ if (!silent)
14041
+ await showPhaseHeader(1, 3, "Data Collection", 200);
14042
+ if (!silent)
14043
+ await thinkingStep("Connecting to git repository...", 400);
14103
14044
  const git = await collectGit(projectDir, since);
14104
- if (git) {
14045
+ if (git && !silent) {
14105
14046
  await revealDiscovery(icons.success, `Git: ${colors2.primary(git.commitCount.toString())} commits found`, 200);
14106
14047
  }
14107
- await thinkingStep("Scanning AI session logs...", 600);
14048
+ if (!silent)
14049
+ await thinkingStep("Scanning AI session logs...", 600);
14108
14050
  const agents = await collectAgentSessions(since);
14109
- if (agents) {
14051
+ if (agents && !silent) {
14110
14052
  await revealDiscovery(icons.success, `Sessions: ${colors2.primary(agents.totalSessions.toString())} sessions loaded`, 200);
14111
14053
  }
14112
- await thinkingStep("Checking test results...", 400);
14054
+ if (!silent)
14055
+ await thinkingStep("Checking test results...", 400);
14113
14056
  const tests = await collectTestResults(projectDir);
14114
- if (tests) {
14057
+ if (tests && !silent) {
14115
14058
  await revealDiscovery(icons.success, `Tests: ${colors2.primary(tests.totalTests.toString())} tests found`, 200);
14116
14059
  }
14117
- await showPhaseHeader(2, 3, "Pattern Analysis", 400);
14118
- await thinkingStep("Analyzing commit patterns...", 500);
14119
- await thinkingStep("Detecting workflow inefficiencies...", 600);
14060
+ if (!silent) {
14061
+ await showPhaseHeader(2, 3, "Pattern Analysis", 400);
14062
+ await thinkingStep("Analyzing commit patterns...", 500);
14063
+ await thinkingStep("Detecting workflow inefficiencies...", 600);
14064
+ }
14120
14065
  const analysis = analyzeWorkflow(agents, projectDir);
14121
14066
  const sdlcAnalysis = analyzeSDLCPhases(agents, git, tests, projectDir);
14122
- if (analysis.sessionPatterns.memoryLossCount > 0) {
14123
- await showFinding("warning", "Memory loss events", analysis.sessionPatterns.memoryLossCount, " times/week", 300);
14124
- }
14125
- if (analysis.sessionPatterns.undoLoops > 0) {
14126
- await showFinding("warning", "Undo loop occurrences", analysis.sessionPatterns.undoLoops, "", 300);
14127
- }
14128
- if (analysis.sessionPatterns.frustrationCount > 0) {
14129
- await showFinding("error", "High frustration sessions", analysis.sessionPatterns.frustrationCount, "", 300);
14067
+ if (!silent) {
14068
+ if (analysis.sessionPatterns.memoryLossCount > 0) {
14069
+ await showFinding("warning", "Memory loss events", analysis.sessionPatterns.memoryLossCount, " times/week", 300);
14070
+ }
14071
+ if (analysis.sessionPatterns.undoLoops > 0) {
14072
+ await showFinding("warning", "Undo loop occurrences", analysis.sessionPatterns.undoLoops, "", 300);
14073
+ }
14074
+ if (analysis.sessionPatterns.frustrationCount > 0) {
14075
+ await showFinding("error", "High frustration sessions", analysis.sessionPatterns.frustrationCount, "", 300);
14076
+ }
14077
+ if (analysis.sessionPatterns.memoryLossCount === 0 && analysis.sessionPatterns.undoLoops === 0 && analysis.sessionPatterns.frustrationCount === 0) {
14078
+ await revealDiscovery(icons.success, colors2.success("No significant issues detected"), 300);
14079
+ }
14130
14080
  }
14131
- if (analysis.sessionPatterns.memoryLossCount === 0 && analysis.sessionPatterns.undoLoops === 0 && analysis.sessionPatterns.frustrationCount === 0) {
14132
- await revealDiscovery(icons.success, colors2.success("No significant issues detected"), 300);
14081
+ if (!silent) {
14082
+ await showPhaseHeader(3, 3, "Computing Score", 400);
14083
+ await thinkingStep("Evaluating SDLC phases...", 500);
14084
+ await thinkingStep("Calculating token efficiency...", 400);
14085
+ await thinkingStep("Computing final score...", 600);
14133
14086
  }
14134
- await showPhaseHeader(3, 3, "Computing Score", 400);
14135
- await thinkingStep("Evaluating SDLC phases...", 500);
14136
- await thinkingStep("Calculating token efficiency...", 400);
14137
- await thinkingStep("Computing final score...", 600);
14138
14087
  const score = computeNaironScore(git ?? undefined, agents ?? undefined, tests ?? undefined);
14139
14088
  const scanCost = calculateScanCost(agents, git);
14140
- await animateScoreReveal(score.overall, score.tier, {
14141
- countDuration: 1200,
14142
- barDelay: 35
14143
- });
14144
- console.log();
14145
- console.log(` ${colors2.bold("Phase Breakdown")}`);
14146
- console.log();
14147
- for (const phase of score.phases) {
14148
- await animateProgressBar(phase.phase, phase.score, {
14149
- width: 20,
14150
- charDelay: 25,
14151
- labelWidth: 18
14089
+ if (!silent) {
14090
+ await animateScoreReveal(score.overall, score.tier, {
14091
+ countDuration: 1200,
14092
+ barDelay: 35
14152
14093
  });
14153
- await sleep(150);
14154
- }
14155
- console.log();
14156
- const wasteColor = score.tokenEfficiency.wastePercentage <= 5 ? colors2.success : score.tokenEfficiency.wastePercentage <= 15 ? colors2.warning : colors2.error;
14157
- console.log(` ${colors2.dim("Token Efficiency:")} ${colors2.primary(score.tokenEfficiency.modifier.toString())}x ${colors2.dim("(")}${wasteColor(score.tokenEfficiency.wastePercentage.toString())}% waste${colors2.dim(")")}`);
14158
- if (!args.brief && analysis.recommendations.length > 0) {
14159
14094
  console.log();
14160
- console.log(` ${colors2.bold("Recommendations")}`);
14161
- console.log(colors2.dim(" " + "─".repeat(40)));
14162
- const topRecs = analysis.recommendations.slice(0, 3);
14163
- for (let i4 = 0;i4 < topRecs.length; i4++) {
14164
- const rec = topRecs[i4];
14165
- await sleep(400);
14095
+ console.log(` ${colors2.bold("Phase Breakdown")}`);
14096
+ console.log();
14097
+ for (const phase of score.phases) {
14098
+ await animateProgressBar(phase.phase, phase.score, {
14099
+ width: 20,
14100
+ charDelay: 25,
14101
+ labelWidth: 18
14102
+ });
14103
+ await sleep(150);
14104
+ }
14105
+ console.log();
14106
+ const wasteColor = score.tokenEfficiency.wastePercentage <= 5 ? colors2.success : score.tokenEfficiency.wastePercentage <= 15 ? colors2.warning : colors2.error;
14107
+ console.log(` ${colors2.dim("Token Efficiency:")} ${colors2.primary(score.tokenEfficiency.modifier.toString())}x ${colors2.dim("(")}${wasteColor(score.tokenEfficiency.wastePercentage.toString())}% waste${colors2.dim(")")}`);
14108
+ if (!args.brief && analysis.recommendations.length > 0) {
14109
+ console.log();
14110
+ console.log(` ${colors2.bold("Recommendations")}`);
14111
+ console.log(colors2.dim(" " + "─".repeat(40)));
14112
+ const topRecs = analysis.recommendations.slice(0, 3);
14113
+ for (let i3 = 0;i3 < topRecs.length; i3++) {
14114
+ const rec = topRecs[i3];
14115
+ await sleep(400);
14116
+ console.log();
14117
+ console.log(` ${colors2.success(`${i3 + 1}.`)} ${colors2.bold(rec.title)}`);
14118
+ await sleep(150);
14119
+ console.log(` ${colors2.dim(rec.description)}`);
14120
+ }
14166
14121
  console.log();
14167
- console.log(` ${colors2.success(`${i4 + 1}.`)} ${colors2.bold(rec.title)}`);
14122
+ await sleep(300);
14123
+ console.log(` ${colors2.dim("Estimated impact:")}`);
14124
+ await sleep(200);
14125
+ console.log(` ${icons.arrow} Score: ${colors2.success(`+${analysis.estimatedImpact.scoreImprovement}`)} points`);
14168
14126
  await sleep(150);
14169
- console.log(` ${colors2.dim(rec.description)}`);
14127
+ console.log(` ${icons.arrow} Tokens: ${colors2.success(`-${formatTokens2(analysis.estimatedImpact.tokenssSavedWeekly)}`)}/week`);
14170
14128
  }
14171
14129
  console.log();
14130
+ console.log(colors2.dim(" " + "═".repeat(45)));
14172
14131
  await sleep(300);
14173
- console.log(` ${colors2.dim("Estimated impact:")}`);
14132
+ const wastedPct = scanCost.sessionsCostUsd > 0 ? Math.round(scanCost.wastedCostUsd / scanCost.sessionsCostUsd * 100) : 0;
14133
+ console.log(` ${icons.money} ${colors2.bold("Cost Summary")}`);
14174
14134
  await sleep(200);
14175
- console.log(` ${icons.arrow} Score: ${colors2.success(`+${analysis.estimatedImpact.scoreImprovement}`)} points`);
14176
- await sleep(150);
14177
- console.log(` ${icons.arrow} Tokens: ${colors2.success(`-${formatTokens2(analysis.estimatedImpact.tokenssSavedWeekly)}`)}/week`);
14178
- }
14179
- console.log();
14180
- console.log(colors2.dim(" " + "═".repeat(45)));
14181
- await sleep(300);
14182
- const wastedPct = scanCost.sessionsCostUsd > 0 ? Math.round(scanCost.wastedCostUsd / scanCost.sessionsCostUsd * 100) : 0;
14183
- console.log(` ${icons.money} ${colors2.bold("Cost Summary")}`);
14184
- await sleep(200);
14185
- console.log(` Period cost: ${colors2.bold(colors2.success(`$${scanCost.sessionsCostUsd.toFixed(2)}`))}`);
14186
- if (scanCost.wastedCostUsd > 0) {
14135
+ console.log(` Period cost: ${colors2.bold(colors2.success(`$${scanCost.sessionsCostUsd.toFixed(2)}`))}`);
14136
+ if (scanCost.wastedCostUsd > 0) {
14137
+ await sleep(150);
14138
+ console.log(` Wasted: ${colors2.error(`$${scanCost.wastedCostUsd.toFixed(2)}`)} ${colors2.dim(`(${wastedPct}%)`)}`);
14139
+ }
14187
14140
  await sleep(150);
14188
- console.log(` Wasted: ${colors2.error(`$${scanCost.wastedCostUsd.toFixed(2)}`)} ${colors2.dim(`(${wastedPct}%)`)}`);
14189
- }
14190
- await sleep(150);
14191
- console.log(` Projected monthly: ${colors2.primary(`$${scanCost.projectedMonthlyCostUsd.toFixed(2)}`)}`);
14192
- console.log(colors2.dim(" " + "".repeat(45)));
14193
- console.log();
14194
- if (!args["no-report"]) {
14195
- const reportDir = join5(projectDir, args["report-dir"]);
14196
- const reportPath = generateReport(reportDir, score, git, agents, tests, args.since, sdlcAnalysis, scanCost, analysis);
14197
- console.log(` ${icons.success} Report saved: ${colors2.dim(reportPath)}`);
14141
+ console.log(` Projected monthly: ${colors2.primary(`$${scanCost.projectedMonthlyCostUsd.toFixed(2)}`)}`);
14142
+ console.log(colors2.dim(" " + "═".repeat(45)));
14143
+ console.log();
14144
+ if (!args["no-report"]) {
14145
+ const reportDir = join5(projectDir, args["report-dir"]);
14146
+ const reportPath = generateReport(reportDir, score, git, agents, tests, args.since, sdlcAnalysis, scanCost, analysis);
14147
+ console.log(` ${icons.success} Report saved: ${colors2.dim(reportPath)}`);
14148
+ }
14198
14149
  }
14199
14150
  if (args.offline) {
14200
- console.log(` ${icons.info} Offline mode - skipping cloud sync`);
14201
- console.log();
14151
+ if (!silent) {
14152
+ console.log(` ${icons.info} Offline mode - skipping cloud sync`);
14153
+ console.log();
14154
+ }
14155
+ if (jsonOutput) {
14156
+ const output = {
14157
+ score: score.overall,
14158
+ tier: score.tier,
14159
+ baseScore: score.baseScore,
14160
+ tokenEfficiency: score.tokenEfficiency,
14161
+ phases: score.phases,
14162
+ cost: scanCost,
14163
+ git: git ? { commitCount: git.commitCount, authors: git.authors.length } : null,
14164
+ agents: agents ? { sessions: agents.totalSessions, tokens: agents.totalTokens } : null,
14165
+ tests: tests ? { total: tests.totalTests, passRate: tests.passRate } : null,
14166
+ scannedAt: score.scannedAt
14167
+ };
14168
+ console.log(JSON.stringify(output, null, 2));
14169
+ } else if (quietMode) {
14170
+ console.log(score.overall);
14171
+ }
14202
14172
  return;
14203
14173
  }
14204
14174
  const client = getClient();
14205
14175
  const clerkId = getClerkId();
14206
14176
  if (!client || !clerkId) {
14207
- console.log(` ${icons.info} Run ${colors2.primary("nb init")} to enable cloud sync`);
14208
- console.log();
14177
+ if (!silent) {
14178
+ console.log(` ${icons.info} Run ${colors2.primary("nb init")} to enable cloud sync`);
14179
+ console.log();
14180
+ }
14181
+ if (jsonOutput) {
14182
+ const output = {
14183
+ score: score.overall,
14184
+ tier: score.tier,
14185
+ baseScore: score.baseScore,
14186
+ tokenEfficiency: score.tokenEfficiency,
14187
+ phases: score.phases,
14188
+ cost: scanCost,
14189
+ git: git ? { commitCount: git.commitCount, authors: git.authors.length } : null,
14190
+ agents: agents ? { sessions: agents.totalSessions, tokens: agents.totalTokens } : null,
14191
+ tests: tests ? { total: tests.totalTests, passRate: tests.passRate } : null,
14192
+ scannedAt: score.scannedAt
14193
+ };
14194
+ console.log(JSON.stringify(output, null, 2));
14195
+ } else if (quietMode) {
14196
+ console.log(score.overall);
14197
+ }
14209
14198
  return;
14210
14199
  }
14211
- const uploadSpinner = createSpinner("Syncing to cloud...");
14212
- uploadSpinner.start();
14200
+ const uploadSpinner = silent ? null : createSpinner("Syncing to cloud...");
14201
+ if (uploadSpinner)
14202
+ uploadSpinner.start();
14213
14203
  try {
14214
14204
  const result = await client.mutation(api.scans.ingestScan, {
14215
14205
  clerkId,
@@ -14254,12 +14244,51 @@ var scanCommand = defineCommand2({
14254
14244
  coveragePercent: tests.coveragePercent
14255
14245
  } : undefined
14256
14246
  });
14257
- uploadSpinner.succeed(`Synced to cloud`);
14247
+ if (uploadSpinner)
14248
+ uploadSpinner.succeed(`Synced to cloud`);
14258
14249
  } catch (err) {
14259
- uploadSpinner.fail("Cloud sync failed");
14260
- console.log(` ${colors2.dim(err instanceof Error ? err.message : String(err))}`);
14250
+ if (uploadSpinner)
14251
+ uploadSpinner.fail("Cloud sync failed");
14252
+ if (!silent)
14253
+ console.log(` ${colors2.dim(err instanceof Error ? err.message : String(err))}`);
14254
+ }
14255
+ if (!silent)
14256
+ console.log();
14257
+ if (jsonOutput) {
14258
+ const output = {
14259
+ score: score.overall,
14260
+ tier: score.tier,
14261
+ baseScore: score.baseScore,
14262
+ tokenEfficiency: score.tokenEfficiency,
14263
+ phases: score.phases,
14264
+ cost: scanCost,
14265
+ git: git ? {
14266
+ commitCount: git.commitCount,
14267
+ authors: git.authors.length,
14268
+ insertions: git.totalInsertions,
14269
+ deletions: git.totalDeletions
14270
+ } : null,
14271
+ agents: agents ? {
14272
+ sessions: agents.totalSessions,
14273
+ tokens: agents.totalTokens,
14274
+ costUsd: agents.totalCostUsd
14275
+ } : null,
14276
+ tests: tests ? {
14277
+ total: tests.totalTests,
14278
+ passRate: tests.passRate,
14279
+ coverage: tests.coveragePercent
14280
+ } : null,
14281
+ recommendations: analysis.recommendations.slice(0, 5).map((r3) => ({
14282
+ title: r3.title,
14283
+ action: r3.action
14284
+ })),
14285
+ scannedAt: score.scannedAt
14286
+ };
14287
+ console.log(JSON.stringify(output, null, 2));
14288
+ }
14289
+ if (quietMode) {
14290
+ console.log(score.overall);
14261
14291
  }
14262
- console.log();
14263
14292
  }
14264
14293
  });
14265
14294
  function parseSince(since) {
@@ -14375,9 +14404,9 @@ function generateReport(reportDir, score, git, agents, tests, since, sdlcAnalysi
14375
14404
  if (analysis && analysis.recommendations.length > 0) {
14376
14405
  lines.push("## Recommendations");
14377
14406
  lines.push("");
14378
- for (let i4 = 0;i4 < Math.min(5, analysis.recommendations.length); i4++) {
14379
- const rec = analysis.recommendations[i4];
14380
- lines.push(`### ${i4 + 1}. ${rec.title}`);
14407
+ for (let i3 = 0;i3 < Math.min(5, analysis.recommendations.length); i3++) {
14408
+ const rec = analysis.recommendations[i3];
14409
+ lines.push(`### ${i3 + 1}. ${rec.title}`);
14381
14410
  lines.push("");
14382
14411
  lines.push(rec.description);
14383
14412
  lines.push("");
@@ -15210,12 +15239,12 @@ function renderLocalInsights(score, phaseFilter) {
15210
15239
  consola.log("");
15211
15240
  consola.box({
15212
15241
  title: `Insights (${score.overall}/100 - ${getTierLabel(score.tier)})`,
15213
- message: insights.map((i4) => {
15214
- const icon = i4.severity === "critical" ? "[!!]" : i4.severity === "warning" ? "[!]" : "[i]";
15242
+ message: insights.map((i3) => {
15243
+ const icon = i3.severity === "critical" ? "[!!]" : i3.severity === "warning" ? "[!]" : "[i]";
15215
15244
  return [
15216
- `${icon} ${i4.title} (+${i4.estimatedImpact} pts potential)`,
15217
- ` ${i4.description}`,
15218
- ` Action: ${i4.action}`
15245
+ `${icon} ${i3.title} (+${i3.estimatedImpact} pts potential)`,
15246
+ ` ${i3.description}`,
15247
+ ` Action: ${i3.action}`
15219
15248
  ].join(`
15220
15249
  `);
15221
15250
  }).join(`
@@ -15788,324 +15817,1140 @@ var dashboardCommand = defineCommand2({
15788
15817
  if (strongest) {
15789
15818
  consola.log(` Strongest: ${strongest.phase} (${strongest.score}/100)`);
15790
15819
  }
15791
- if (latestScan.tokenEfficiency.wastePercentage > 15) {
15792
- consola.log(` [!] High token waste: ${latestScan.tokenEfficiency.wastePercentage}% - review your prompting patterns`);
15820
+ if (latestScan.tokenEfficiency.wastePercentage > 15) {
15821
+ consola.log(` [!] High token waste: ${latestScan.tokenEfficiency.wastePercentage}% - review your prompting patterns`);
15822
+ }
15823
+ if (weeklyReport) {
15824
+ const reportDelta = weeklyReport.scoreAfter - weeklyReport.scoreBefore;
15825
+ consola.log("");
15826
+ consola.log(" Weekly Report:");
15827
+ consola.log(" " + "─".repeat(56));
15828
+ consola.log(` Score: ${weeklyReport.scoreBefore} -> ${weeklyReport.scoreAfter} (${reportDelta > 0 ? "+" : ""}${reportDelta})`);
15829
+ const frustrations = weeklyReport.frustrations;
15830
+ if (frustrations.length > 0) {
15831
+ consola.log(` Top frustration: ${frustrations[0].topic}`);
15832
+ }
15833
+ consola.log(` Run \`nb report --weekly\` for full details`);
15834
+ }
15835
+ consola.log("");
15836
+ consola.log(" Actions:");
15837
+ consola.log(" " + "─".repeat(56));
15838
+ consola.log(" nb scan Re-run benchmark");
15839
+ consola.log(" nb insights Detailed coaching");
15840
+ consola.log(" nb report --weekly Weekly improvement report");
15841
+ consola.log(" nb tools discover Find tools for weak phases");
15842
+ consola.log("");
15843
+ }
15844
+ });
15845
+ function renderBar2(value, width) {
15846
+ const filled = Math.round(value / 100 * width);
15847
+ const empty = width - filled;
15848
+ return "█".repeat(filled) + "░".repeat(empty);
15849
+ }
15850
+
15851
+ // src/commands/publish.ts
15852
+ init_dist();
15853
+ init_client();
15854
+ import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
15855
+ import { join as join8 } from "node:path";
15856
+ import { homedir as homedir6 } from "node:os";
15857
+ var publishCommand = defineCommand2({
15858
+ meta: {
15859
+ name: "publish",
15860
+ description: "Generate and publish your AI Nativeness report to nairon.ai"
15861
+ },
15862
+ args: {
15863
+ preview: {
15864
+ type: "boolean",
15865
+ description: "Preview report without uploading",
15866
+ default: false
15867
+ },
15868
+ project: {
15869
+ type: "string",
15870
+ description: "Project directory (defaults to cwd)"
15871
+ },
15872
+ "report-dir": {
15873
+ type: "string",
15874
+ description: "Directory containing scan reports",
15875
+ default: ".nairon/reports"
15876
+ }
15877
+ },
15878
+ async run({ args }) {
15879
+ const projectDir = args.project ?? process.cwd();
15880
+ const reportDir = join8(projectDir, args["report-dir"]);
15881
+ consola.start(`Analyzing your AI workflow...
15882
+ `);
15883
+ consola.info("Reading scan reports...");
15884
+ const reports = readReports(reportDir);
15885
+ if (reports.length === 0) {
15886
+ consola.error(`No reports found in ${reportDir}`);
15887
+ consola.info("Run `nb scan` first to generate reports.");
15888
+ process.exit(1);
15889
+ }
15890
+ consola.success(`Found ${reports.length} scan reports`);
15891
+ consola.info("Detecting AI development concepts...");
15892
+ const concepts = detectConcepts(projectDir);
15893
+ const conceptCount = Object.values(concepts).filter(Boolean).length;
15894
+ consola.success(`${conceptCount}/5 AI concepts adopted`);
15895
+ const aggregated = aggregateReports(reports);
15896
+ const conceptsScore = computeConceptsScore(concepts);
15897
+ const toolsDetected = detectTools(projectDir);
15898
+ const toolsActivelyUsed = toolsDetected.slice(0, 5);
15899
+ const aiNativenessScore = computeAINativenessScore(aggregated, conceptsScore, toolsDetected.length);
15900
+ const tier = getTier(aiNativenessScore);
15901
+ consola.log("");
15902
+ consola.box({
15903
+ title: "AI Nativeness Report",
15904
+ message: formatPreview({
15905
+ score: aiNativenessScore,
15906
+ tier,
15907
+ toolsCount: toolsDetected.length,
15908
+ conceptsScore,
15909
+ concepts,
15910
+ avgEfficiency: aggregated.avgTokenEfficiency,
15911
+ improvementRate: aggregated.weekOverWeekImprovement,
15912
+ scansAnalyzed: reports.length
15913
+ })
15914
+ });
15915
+ if (args.preview) {
15916
+ consola.info("Preview mode - not uploading to Convex");
15917
+ return;
15918
+ }
15919
+ const client = getClient();
15920
+ const clerkId = getClerkId();
15921
+ if (!client || !clerkId) {
15922
+ consola.error("Not connected. Run `nb init` first.");
15923
+ process.exit(1);
15924
+ }
15925
+ consola.info("Publishing to nairon.ai...");
15926
+ try {
15927
+ const result = await client.mutation(api.publicReports.publish, {
15928
+ clerkId,
15929
+ aiNativenessScore,
15930
+ tier,
15931
+ toolsDetected,
15932
+ toolsActivelyUsed,
15933
+ modelPreferences: aggregated.modelPreferences,
15934
+ tokenEfficiencyAvg: aggregated.avgTokenEfficiency,
15935
+ wasteReductionRate: aggregated.wasteReductionRate,
15936
+ sdlcCoverage: aggregated.sdlcCoverage,
15937
+ improvementTrend: aggregated.improvementTrend,
15938
+ weekOverWeekImprovement: aggregated.weekOverWeekImprovement,
15939
+ conceptsAdopted: concepts,
15940
+ conceptsScore,
15941
+ patternCorrectionRate: aggregated.patternCorrectionRate,
15942
+ scansAnalyzed: reports.length,
15943
+ periodStart: reports[0]?.date ?? new Date().toISOString(),
15944
+ periodEnd: reports[reports.length - 1]?.date ?? new Date().toISOString()
15945
+ });
15946
+ consola.success(`Published! Your report is live.`);
15947
+ consola.log("");
15948
+ consola.log(` URL: https://nairon.ai/u/${result.slug}`);
15949
+ consola.log("");
15950
+ consola.log(" Share badge:");
15951
+ consola.log(` ![AI Nativeness](https://nairon.ai/badge/${result.slug}.svg)`);
15952
+ consola.log("");
15953
+ } catch (err) {
15954
+ consola.error(`Failed to publish: ${err instanceof Error ? err.message : String(err)}`);
15955
+ process.exit(1);
15956
+ }
15957
+ }
15958
+ });
15959
+ function readReports(reportDir) {
15960
+ if (!existsSync8(reportDir)) {
15961
+ return [];
15962
+ }
15963
+ const files = readdirSync3(reportDir).filter((f3) => f3.endsWith(".md") && f3.startsWith("scan-")).sort();
15964
+ return files.map((file) => {
15965
+ const content = readFileSync5(join8(reportDir, file), "utf-8");
15966
+ return parseReport(content, file);
15967
+ });
15968
+ }
15969
+ function parseReport(content, filename) {
15970
+ const dateMatch = filename.match(/scan-(\d{4}-\d{2}-\d{2})/);
15971
+ const date = dateMatch ? dateMatch[1] : new Date().toISOString().slice(0, 10);
15972
+ const overallMatch = content.match(/\*\*Overall\*\*\s*\|\s*(\d+)\/100/);
15973
+ const overall = overallMatch ? parseInt(overallMatch[1], 10) : 0;
15974
+ const tierMatch = content.match(/\*\*Tier:\*\*\s*(\w+)/);
15975
+ const tier = tierMatch ? tierMatch[1] : "Unknown";
15976
+ const efficiencyMatch = content.match(/Token Efficiency\s*\|\s*([\d.]+)x/);
15977
+ const tokenEfficiency = efficiencyMatch ? parseFloat(efficiencyMatch[1]) : 1;
15978
+ const wasteMatch = content.match(/Token Waste\s*\|\s*(\d+)%/);
15979
+ const tokenWaste = wasteMatch ? parseInt(wasteMatch[1], 10) : 0;
15980
+ const phases = {};
15981
+ const phaseRegex = /\| (Requirements|Planning|Implementation|Testing|Review)\s*\|\s*(\d+)\/100/gi;
15982
+ let match;
15983
+ while ((match = phaseRegex.exec(content)) !== null) {
15984
+ phases[match[1].toLowerCase()] = parseInt(match[2], 10);
15985
+ }
15986
+ const models = {};
15987
+ const modelRegex = /\| (claude-[\w-]+|gpt-[\w-]+|sonnet|opus|haiku)\s*\|\s*(\d+)/gi;
15988
+ while ((match = modelRegex.exec(content)) !== null) {
15989
+ models[match[1]] = parseInt(match[2], 10);
15990
+ }
15991
+ return { date, overall, tier, tokenEfficiency, tokenWaste, phases, models };
15992
+ }
15993
+ function detectConcepts(projectDir) {
15994
+ const home = homedir6();
15995
+ return {
15996
+ skills: existsSync8(join8(home, ".claude", "settings.json")) && readFileSync5(join8(home, ".claude", "settings.json"), "utf-8").includes("skill"),
15997
+ mcpServers: existsSync8(join8(home, ".config", "opencode", "config.json")) || existsSync8(join8(home, ".claude", "claude_desktop_config.json")) || existsSync8(join8(home, ".claude", "settings.json")) && readFileSync5(join8(home, ".claude", "settings.json"), "utf-8").includes("mcpServers"),
15998
+ customCommands: existsSync8(join8(home, ".claude", "commands")) || existsSync8(join8(projectDir, ".claude", "commands")),
15999
+ agentConfig: existsSync8(join8(projectDir, "AGENTS.md")) || existsSync8(join8(projectDir, ".cursorrules")) || existsSync8(join8(projectDir, ".github", "copilot-instructions.md")),
16000
+ contextManagement: existsSync8(join8(projectDir, "MEMORY.md")) || existsSync8(join8(projectDir, ".context")) || existsSync8(join8(projectDir, "docs", "architecture.md")) || existsSync8(join8(projectDir, ".beads"))
16001
+ };
16002
+ }
16003
+ function computeConceptsScore(concepts) {
16004
+ const weights = {
16005
+ skills: 25,
16006
+ mcpServers: 25,
16007
+ customCommands: 15,
16008
+ agentConfig: 20,
16009
+ contextManagement: 15
16010
+ };
16011
+ let score = 0;
16012
+ for (const [key, adopted] of Object.entries(concepts)) {
16013
+ if (adopted) {
16014
+ score += weights[key];
16015
+ }
16016
+ }
16017
+ return score;
16018
+ }
16019
+ function detectTools(projectDir) {
16020
+ const tools = [];
16021
+ const home = homedir6();
16022
+ const toolChecks = [
16023
+ { name: "Claude Code", check: () => existsSync8(join8(home, ".claude")) },
16024
+ { name: "Cursor", check: () => existsSync8(join8(projectDir, ".cursorrules")) },
16025
+ { name: "GitHub Copilot", check: () => existsSync8(join8(projectDir, ".github", "copilot-instructions.md")) },
16026
+ { name: "OpenCode", check: () => existsSync8(join8(home, ".config", "opencode")) },
16027
+ { name: "Windsurf", check: () => existsSync8(join8(home, ".windsurf")) },
16028
+ { name: "Aider", check: () => existsSync8(join8(projectDir, ".aider.conf.yml")) },
16029
+ { name: "Codeium", check: () => existsSync8(join8(home, ".codeium")) },
16030
+ { name: "Beads", check: () => existsSync8(join8(projectDir, ".beads")) },
16031
+ { name: "Convex", check: () => existsSync8(join8(projectDir, "convex")) },
16032
+ { name: "Supabase", check: () => existsSync8(join8(projectDir, "supabase")) }
16033
+ ];
16034
+ for (const { name, check } of toolChecks) {
16035
+ try {
16036
+ if (check()) {
16037
+ tools.push(name);
16038
+ }
16039
+ } catch {}
16040
+ }
16041
+ return tools;
16042
+ }
16043
+ function aggregateReports(reports) {
16044
+ if (reports.length === 0) {
16045
+ return {
16046
+ avgTokenEfficiency: 1,
16047
+ wasteReductionRate: 0,
16048
+ sdlcCoverage: {},
16049
+ modelPreferences: {},
16050
+ improvementTrend: [],
16051
+ weekOverWeekImprovement: 0,
16052
+ patternCorrectionRate: 0
16053
+ };
16054
+ }
16055
+ const avgTokenEfficiency = reports.reduce((acc, r3) => acc + r3.tokenEfficiency, 0) / reports.length;
16056
+ const firstWaste = reports[0]?.tokenWaste ?? 0;
16057
+ const lastWaste = reports[reports.length - 1]?.tokenWaste ?? 0;
16058
+ const wasteReductionRate = firstWaste > 0 ? (firstWaste - lastWaste) / firstWaste * 100 : 0;
16059
+ const sdlcCoverage = {};
16060
+ const phases = ["requirements", "planning", "implementation", "testing", "review"];
16061
+ for (const phase of phases) {
16062
+ const scores = reports.map((r3) => r3.phases[phase] ?? 0).filter((s2) => s2 > 0);
16063
+ if (scores.length > 0) {
16064
+ const avg = scores.reduce((a2, b2) => a2 + b2, 0) / scores.length;
16065
+ const trend = scores.length > 1 ? scores[scores.length - 1] - scores[0] : 0;
16066
+ sdlcCoverage[phase] = { score: Math.round(avg), trend };
16067
+ }
16068
+ }
16069
+ const modelPreferences = {};
16070
+ for (const report of reports) {
16071
+ for (const [model, count] of Object.entries(report.models)) {
16072
+ modelPreferences[model] = (modelPreferences[model] ?? 0) + count;
16073
+ }
16074
+ }
16075
+ const improvementTrend = reports.map((r3) => ({
16076
+ date: r3.date,
16077
+ score: r3.overall
16078
+ }));
16079
+ let weekOverWeekImprovement = 0;
16080
+ if (reports.length >= 2) {
16081
+ const recentScore = reports[reports.length - 1].overall;
16082
+ const olderScore = reports[Math.max(0, reports.length - 8)].overall;
16083
+ weekOverWeekImprovement = recentScore - olderScore;
16084
+ }
16085
+ const patternCorrectionRate = Math.max(0, wasteReductionRate);
16086
+ return {
16087
+ avgTokenEfficiency,
16088
+ wasteReductionRate,
16089
+ sdlcCoverage,
16090
+ modelPreferences,
16091
+ improvementTrend,
16092
+ weekOverWeekImprovement,
16093
+ patternCorrectionRate
16094
+ };
16095
+ }
16096
+ function computeAINativenessScore(aggregated, conceptsScore, toolCount) {
16097
+ const toolingScore = Math.min(100, toolCount * 10);
16098
+ const phaseScores = Object.values(aggregated.sdlcCoverage).map((p) => p.score);
16099
+ const workflowScore = phaseScores.length > 0 ? phaseScores.reduce((a2, b2) => a2 + b2, 0) / phaseScores.length : 0;
16100
+ const improvementBonus = Math.min(50, Math.max(0, aggregated.weekOverWeekImprovement * 2));
16101
+ const efficiencyBonus = Math.min(50, aggregated.avgTokenEfficiency * 25);
16102
+ const velocityScore = improvementBonus + efficiencyBonus;
16103
+ const score = toolingScore * 0.25 + workflowScore * 0.25 + conceptsScore * 0.25 + velocityScore * 0.25;
16104
+ return Math.round(Math.min(100, Math.max(0, score)));
16105
+ }
16106
+ function getTier(score) {
16107
+ if (score >= 90)
16108
+ return "Elite";
16109
+ if (score >= 75)
16110
+ return "Expert";
16111
+ if (score >= 60)
16112
+ return "Advanced";
16113
+ if (score >= 40)
16114
+ return "Intermediate";
16115
+ if (score >= 20)
16116
+ return "Beginner";
16117
+ return "Novice";
16118
+ }
16119
+ function formatPreview(data) {
16120
+ const lines = [];
16121
+ lines.push(`Score: ${data.score}/100 | Tier: ${data.tier}`);
16122
+ lines.push("");
16123
+ lines.push("Breakdown:");
16124
+ lines.push(` Tooling: ${Math.min(100, data.toolsCount * 10)}/100 (${data.toolsCount} tools detected)`);
16125
+ lines.push(` Concepts: ${data.conceptsScore}/100`);
16126
+ lines.push(` Efficiency: ${data.avgEfficiency.toFixed(2)}x`);
16127
+ lines.push(` Improvement: ${data.improvementRate >= 0 ? "+" : ""}${data.improvementRate.toFixed(1)} pts/week`);
16128
+ lines.push("");
16129
+ lines.push("AI Concepts:");
16130
+ lines.push(` ${data.concepts.skills ? "[x]" : "[ ]"} Skills configured`);
16131
+ lines.push(` ${data.concepts.mcpServers ? "[x]" : "[ ]"} MCP servers active`);
16132
+ lines.push(` ${data.concepts.customCommands ? "[x]" : "[ ]"} Custom commands`);
16133
+ lines.push(` ${data.concepts.agentConfig ? "[x]" : "[ ]"} Agent configuration`);
16134
+ lines.push(` ${data.concepts.contextManagement ? "[x]" : "[ ]"} Context management`);
16135
+ lines.push("");
16136
+ lines.push(`Based on ${data.scansAnalyzed} scans`);
16137
+ return lines.join(`
16138
+ `);
16139
+ }
16140
+
16141
+ // src/commands/history.ts
16142
+ init_client();
16143
+ var historyCommand = defineCommand2({
16144
+ meta: {
16145
+ name: "history",
16146
+ description: "Show your score history and trends over time"
16147
+ },
16148
+ args: {
16149
+ days: {
16150
+ type: "string",
16151
+ description: "Number of days to show (default: 30)",
16152
+ default: "30"
16153
+ },
16154
+ limit: {
16155
+ type: "string",
16156
+ description: "Maximum number of scans to show",
16157
+ default: "10"
16158
+ }
16159
+ },
16160
+ async run({ args }) {
16161
+ const client = getClient();
16162
+ const clerkId = getClerkId();
16163
+ if (!client || !clerkId) {
16164
+ console.log(` ${icons.error} Not connected. Run ${colors2.primary("nb init")} first.`);
16165
+ return;
15793
16166
  }
15794
- if (weeklyReport) {
15795
- const reportDelta = weeklyReport.scoreAfter - weeklyReport.scoreBefore;
15796
- consola.log("");
15797
- consola.log(" Weekly Report:");
15798
- consola.log(" " + "─".repeat(56));
15799
- consola.log(` Score: ${weeklyReport.scoreBefore} -> ${weeklyReport.scoreAfter} (${reportDelta > 0 ? "+" : ""}${reportDelta})`);
15800
- const frustrations = weeklyReport.frustrations;
15801
- if (frustrations.length > 0) {
15802
- consola.log(` Top frustration: ${frustrations[0].topic}`);
16167
+ console.log();
16168
+ console.log(colors2.bold(colors2.primary(" Score History")));
16169
+ console.log(colors2.dim(" " + "─".repeat(40)));
16170
+ const spinner = createSpinner("Loading history...");
16171
+ spinner.start();
16172
+ try {
16173
+ const [history, trend] = await Promise.all([
16174
+ client.query(api.scans.getScanHistory, {
16175
+ clerkId,
16176
+ limit: parseInt(args.limit, 10)
16177
+ }),
16178
+ client.query(api.scans.getScoreTrend, {
16179
+ clerkId,
16180
+ days: parseInt(args.days, 10)
16181
+ })
16182
+ ]);
16183
+ spinner.succeed("History loaded");
16184
+ console.log();
16185
+ if (!history || history.length === 0) {
16186
+ console.log(` ${icons.info} No scan history found.`);
16187
+ console.log(` Run ${colors2.primary("nb scan")} to create your first scan.`);
16188
+ return;
15803
16189
  }
15804
- consola.log(` Run \`nb report --weekly\` for full details`);
16190
+ if (trend && trend.length >= 2) {
16191
+ const first2 = trend[0];
16192
+ const last2 = trend[trend.length - 1];
16193
+ const delta = last2.overall - first2.overall;
16194
+ const deltaColor = delta >= 0 ? colors2.success : colors2.error;
16195
+ const deltaIcon = delta >= 0 ? "↑" : "↓";
16196
+ console.log(` ${colors2.bold("Trend")} (last ${args.days} days)`);
16197
+ console.log(` ${colors2.dim("Start:")} ${first2.overall}/100 → ${colors2.dim("Now:")} ${last2.overall}/100`);
16198
+ console.log(` ${colors2.dim("Change:")} ${deltaColor(`${deltaIcon} ${Math.abs(delta)} points`)}`);
16199
+ console.log();
16200
+ console.log(` ${colors2.bold("Score Chart")}`);
16201
+ renderMiniChart(trend.map((t2) => t2.overall));
16202
+ console.log();
16203
+ }
16204
+ console.log(` ${colors2.bold("Recent Scans")}`);
16205
+ console.log();
16206
+ for (const scan of history) {
16207
+ const date = new Date(scan.scannedAt);
16208
+ const dateStr = date.toLocaleDateString("en-US", {
16209
+ month: "short",
16210
+ day: "numeric",
16211
+ year: date.getFullYear() !== new Date().getFullYear() ? "numeric" : undefined
16212
+ });
16213
+ const timeStr = date.toLocaleTimeString("en-US", {
16214
+ hour: "2-digit",
16215
+ minute: "2-digit"
16216
+ });
16217
+ const scoreColor = scan.overall >= 80 ? colors2.success : scan.overall >= 60 ? colors2.primary : scan.overall >= 40 ? colors2.warning : colors2.error;
16218
+ const phasesWithDelta = scan.phases;
16219
+ const avgDelta = phasesWithDelta.filter((p) => p.delta !== undefined).reduce((sum, p) => sum + (p.delta ?? 0), 0) / phasesWithDelta.length;
16220
+ const deltaStr = !isNaN(avgDelta) && avgDelta !== 0 ? avgDelta > 0 ? colors2.success(` +${Math.round(avgDelta)}`) : colors2.error(` ${Math.round(avgDelta)}`) : "";
16221
+ console.log(` ${colors2.dim(dateStr)} ${colors2.dim(timeStr)} ${scoreColor(scan.overall.toString().padStart(3))}/100${deltaStr} ${formatTier(scan.tier)}`);
16222
+ const phases = phasesWithDelta.map((p) => {
16223
+ const short = p.phase.slice(0, 3);
16224
+ const color = p.score >= 70 ? colors2.success : p.score >= 50 ? colors2.warning : colors2.error;
16225
+ return `${short}:${color(p.score.toString())}`;
16226
+ }).join(" ");
16227
+ console.log(` ${colors2.dim(phases)}`);
16228
+ }
16229
+ console.log();
16230
+ console.log(colors2.dim(` Showing ${history.length} most recent scans`));
16231
+ } catch (error2) {
16232
+ spinner.fail("Failed to load history");
16233
+ console.log(` ${colors2.dim(error2 instanceof Error ? error2.message : String(error2))}`);
15805
16234
  }
15806
- consola.log("");
15807
- consola.log(" Actions:");
15808
- consola.log(" " + "─".repeat(56));
15809
- consola.log(" nb scan Re-run benchmark");
15810
- consola.log(" nb insights Detailed coaching");
15811
- consola.log(" nb report --weekly Weekly improvement report");
15812
- consola.log(" nb tools discover Find tools for weak phases");
15813
- consola.log("");
16235
+ console.log();
15814
16236
  }
15815
16237
  });
15816
- function renderBar2(value, width) {
15817
- const filled = Math.round(value / 100 * width);
15818
- const empty = width - filled;
15819
- return "█".repeat(filled) + "░".repeat(empty);
16238
+ function renderMiniChart(scores) {
16239
+ if (scores.length === 0)
16240
+ return;
16241
+ const height = 5;
16242
+ const width = Math.min(scores.length, 30);
16243
+ const step = Math.max(1, Math.floor(scores.length / width));
16244
+ const sampled = [];
16245
+ for (let i3 = 0;i3 < scores.length; i3 += step) {
16246
+ sampled.push(scores[i3]);
16247
+ }
16248
+ const min = Math.min(...sampled);
16249
+ const max = Math.max(...sampled);
16250
+ const range = max - min || 1;
16251
+ const chart = [];
16252
+ for (let row = 0;row < height; row++) {
16253
+ chart.push([]);
16254
+ }
16255
+ for (const score of sampled) {
16256
+ const normalized = (score - min) / range;
16257
+ const barHeight = Math.round(normalized * (height - 1));
16258
+ for (let row = 0;row < height; row++) {
16259
+ const rowFromBottom = height - 1 - row;
16260
+ if (rowFromBottom <= barHeight) {
16261
+ const color = score >= 80 ? colors2.success : score >= 60 ? colors2.primary : score >= 40 ? colors2.warning : colors2.error;
16262
+ chart[row].push(color("█"));
16263
+ } else {
16264
+ chart[row].push(colors2.dim("░"));
16265
+ }
16266
+ }
16267
+ }
16268
+ for (const row of chart) {
16269
+ console.log(" " + row.join(""));
16270
+ }
16271
+ const startLabel = "oldest";
16272
+ const endLabel = "newest";
16273
+ const padding = sampled.length - startLabel.length - endLabel.length;
16274
+ console.log(` ${colors2.dim(startLabel)}${" ".repeat(Math.max(0, padding))}${colors2.dim(endLabel)}`);
15820
16275
  }
15821
16276
 
15822
- // src/commands/publish.ts
15823
- init_dist();
15824
- init_client();
15825
- import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
15826
- import { join as join8 } from "node:path";
15827
- import { homedir as homedir6 } from "node:os";
15828
- var publishCommand = defineCommand2({
16277
+ // src/commands/cost.ts
16278
+ var costCommand = defineCommand2({
15829
16279
  meta: {
15830
- name: "publish",
15831
- description: "Generate and publish your AI Nativeness report to nairon.ai"
16280
+ name: "cost",
16281
+ description: "Analyze AI usage costs by model, day, and project"
15832
16282
  },
15833
16283
  args: {
15834
- preview: {
15835
- type: "boolean",
15836
- description: "Preview report without uploading",
15837
- default: false
15838
- },
15839
- project: {
16284
+ since: {
15840
16285
  type: "string",
15841
- description: "Project directory (defaults to cwd)"
16286
+ description: 'Time range (e.g., "7 days", "30 days")',
16287
+ default: "7 days"
15842
16288
  },
15843
- "report-dir": {
15844
- type: "string",
15845
- description: "Directory containing scan reports",
15846
- default: ".nairon/reports"
16289
+ breakdown: {
16290
+ type: "boolean",
16291
+ description: "Show detailed daily breakdown",
16292
+ default: false
15847
16293
  }
15848
16294
  },
15849
16295
  async run({ args }) {
15850
- const projectDir = args.project ?? process.cwd();
15851
- const reportDir = join8(projectDir, args["report-dir"]);
15852
- consola.start(`Analyzing your AI workflow...
15853
- `);
15854
- consola.info("Reading scan reports...");
15855
- const reports = readReports(reportDir);
15856
- if (reports.length === 0) {
15857
- consola.error(`No reports found in ${reportDir}`);
15858
- consola.info("Run `nb scan` first to generate reports.");
15859
- process.exit(1);
15860
- }
15861
- consola.success(`Found ${reports.length} scan reports`);
15862
- consola.info("Detecting AI development concepts...");
15863
- const concepts = detectConcepts(projectDir);
15864
- const conceptCount = Object.values(concepts).filter(Boolean).length;
15865
- consola.success(`${conceptCount}/5 AI concepts adopted`);
15866
- const aggregated = aggregateReports(reports);
15867
- const conceptsScore = computeConceptsScore(concepts);
15868
- const toolsDetected = detectTools(projectDir);
15869
- const toolsActivelyUsed = toolsDetected.slice(0, 5);
15870
- const aiNativenessScore = computeAINativenessScore(aggregated, conceptsScore, toolsDetected.length);
15871
- const tier = getTier(aiNativenessScore);
15872
- consola.log("");
15873
- consola.box({
15874
- title: "AI Nativeness Report",
15875
- message: formatPreview({
15876
- score: aiNativenessScore,
15877
- tier,
15878
- toolsCount: toolsDetected.length,
15879
- conceptsScore,
15880
- concepts,
15881
- avgEfficiency: aggregated.avgTokenEfficiency,
15882
- improvementRate: aggregated.weekOverWeekImprovement,
15883
- scansAnalyzed: reports.length
15884
- })
15885
- });
15886
- if (args.preview) {
15887
- consola.info("Preview mode - not uploading to Convex");
16296
+ const since = parseSince3(args.since);
16297
+ console.log();
16298
+ console.log(colors2.bold(colors2.primary(" AI Cost Analysis")));
16299
+ console.log(colors2.dim(` Last ${args.since}`));
16300
+ console.log(colors2.dim(" " + "─".repeat(40)));
16301
+ console.log();
16302
+ const spinner = createSpinner("Analyzing session costs...");
16303
+ spinner.start();
16304
+ const agents = await collectAgentSessions(since);
16305
+ if (!agents || agents.sessions.length === 0) {
16306
+ spinner.fail("No session data found");
16307
+ console.log(` ${icons.info} No AI sessions found in this period.`);
15888
16308
  return;
15889
16309
  }
15890
- const client = getClient();
15891
- const clerkId = getClerkId();
15892
- if (!client || !clerkId) {
15893
- consola.error("Not connected. Run `nb init` first.");
15894
- process.exit(1);
16310
+ spinner.succeed(`Analyzed ${agents.totalSessions} sessions`);
16311
+ console.log();
16312
+ const totalCost = agents.totalCostUsd;
16313
+ const costByModel = agents.costByModel;
16314
+ const costByDay = calculateCostByDay(agents.sessions);
16315
+ const avgCostPerSession = totalCost / agents.totalSessions;
16316
+ const avgCostPerDay = totalCost / getDaysInRange(args.since);
16317
+ const projectedMonthly = avgCostPerDay * 30;
16318
+ let wastedTokens = 0;
16319
+ for (const session of agents.sessions) {
16320
+ for (const pattern of session.patterns) {
16321
+ wastedTokens += pattern.estimatedWastedTokens;
16322
+ }
15895
16323
  }
15896
- consola.info("Publishing to nairon.ai...");
15897
- try {
15898
- const result = await client.mutation(api.publicReports.publish, {
15899
- clerkId,
15900
- aiNativenessScore,
15901
- tier,
15902
- toolsDetected,
15903
- toolsActivelyUsed,
15904
- modelPreferences: aggregated.modelPreferences,
15905
- tokenEfficiencyAvg: aggregated.avgTokenEfficiency,
15906
- wasteReductionRate: aggregated.wasteReductionRate,
15907
- sdlcCoverage: aggregated.sdlcCoverage,
15908
- improvementTrend: aggregated.improvementTrend,
15909
- weekOverWeekImprovement: aggregated.weekOverWeekImprovement,
15910
- conceptsAdopted: concepts,
15911
- conceptsScore,
15912
- patternCorrectionRate: aggregated.patternCorrectionRate,
15913
- scansAnalyzed: reports.length,
15914
- periodStart: reports[0]?.date ?? new Date().toISOString(),
15915
- periodEnd: reports[reports.length - 1]?.date ?? new Date().toISOString()
16324
+ const wasteRatio = agents.totalTokens > 0 ? wastedTokens / agents.totalTokens : 0;
16325
+ const wastedCost = totalCost * wasteRatio;
16326
+ console.log(` ${icons.money} ${colors2.bold("Total Cost")}`);
16327
+ console.log(` ${colors2.bold(colors2.success(`$${totalCost.toFixed(2)}`))}`);
16328
+ console.log();
16329
+ console.log(` ${colors2.dim("Avg per session:")} $${avgCostPerSession.toFixed(2)}`);
16330
+ console.log(` ${colors2.dim("Avg per day:")} $${avgCostPerDay.toFixed(2)}`);
16331
+ console.log(` ${colors2.dim("Projected monthly:")} ${colors2.primary(`$${projectedMonthly.toFixed(2)}`)}`);
16332
+ console.log();
16333
+ if (wastedCost > 0) {
16334
+ const wastePercent = Math.round(wasteRatio * 100);
16335
+ console.log(` ${icons.warning} ${colors2.bold("Wasted Cost")}`);
16336
+ console.log(` ${colors2.error(`$${wastedCost.toFixed(2)}`)} ${colors2.dim(`(${wastePercent}% of total)`)}`);
16337
+ console.log(` ${colors2.dim("From: undo loops, context reloading, rephrasing")}`);
16338
+ console.log();
16339
+ }
16340
+ console.log(colors2.dim(" " + "─".repeat(40)));
16341
+ console.log();
16342
+ console.log(` ${colors2.bold("Cost by Model")}`);
16343
+ console.log();
16344
+ const sortedModels = Object.entries(costByModel).sort((a2, b2) => b2[1] - a2[1]);
16345
+ for (const [model, cost] of sortedModels) {
16346
+ const percent = Math.round(cost / totalCost * 100);
16347
+ const shortModel = model.length > 25 ? model.slice(0, 22) + "..." : model;
16348
+ await animateProgressBar(shortModel, percent, {
16349
+ width: 15,
16350
+ charDelay: 15,
16351
+ labelWidth: 25
15916
16352
  });
15917
- consola.success(`Published! Your report is live.`);
15918
- consola.log("");
15919
- consola.log(` URL: https://nairon.ai/u/${result.slug}`);
15920
- consola.log("");
15921
- consola.log(" Share badge:");
15922
- consola.log(` ![AI Nativeness](https://nairon.ai/badge/${result.slug}.svg)`);
15923
- consola.log("");
15924
- } catch (err) {
15925
- consola.error(`Failed to publish: ${err instanceof Error ? err.message : String(err)}`);
15926
- process.exit(1);
16353
+ console.log(` ${colors2.dim(`$${cost.toFixed(2)}`)}`);
16354
+ }
16355
+ if (args.breakdown && Object.keys(costByDay).length > 1) {
16356
+ console.log();
16357
+ console.log(colors2.dim(" " + "─".repeat(40)));
16358
+ console.log();
16359
+ console.log(` ${colors2.bold("Daily Breakdown")}`);
16360
+ console.log();
16361
+ const sortedDays = Object.entries(costByDay).sort((a2, b2) => a2[0].localeCompare(b2[0]));
16362
+ const maxCost = Math.max(...Object.values(costByDay));
16363
+ for (const [day, cost] of sortedDays) {
16364
+ const date = new Date(day);
16365
+ const dayStr = date.toLocaleDateString("en-US", {
16366
+ weekday: "short",
16367
+ month: "short",
16368
+ day: "numeric"
16369
+ });
16370
+ const barWidth = Math.round(cost / maxCost * 20);
16371
+ const bar = colors2.primary("█".repeat(barWidth)) + colors2.dim("░".repeat(20 - barWidth));
16372
+ console.log(` ${colors2.dim(dayStr.padEnd(12))} ${bar} $${cost.toFixed(2)}`);
16373
+ }
16374
+ }
16375
+ console.log();
16376
+ console.log(colors2.dim(" " + "─".repeat(40)));
16377
+ console.log();
16378
+ console.log(` ${colors2.bold("Token Usage")}`);
16379
+ console.log();
16380
+ console.log(` ${colors2.dim("Total tokens:")} ${formatTokens3(agents.totalTokens)}`);
16381
+ console.log(` ${colors2.dim("Wasted tokens:")} ${colors2.error(formatTokens3(wastedTokens))}`);
16382
+ console.log(` ${colors2.dim("Cost per 1M tokens:")} $${(totalCost / agents.totalTokens * 1e6).toFixed(2)}`);
16383
+ console.log();
16384
+ console.log(colors2.dim(" " + "─".repeat(40)));
16385
+ console.log();
16386
+ console.log(` ${colors2.bold("Tips to Reduce Costs")}`);
16387
+ console.log();
16388
+ if (costByModel["claude-3-opus-20240229"] && costByModel["claude-3-opus-20240229"] > totalCost * 0.3) {
16389
+ console.log(` ${icons.arrow} Use Claude Sonnet for simpler tasks (Opus is 15x more expensive)`);
16390
+ }
16391
+ if (wasteRatio > 0.1) {
16392
+ console.log(` ${icons.arrow} Reduce undo loops with better initial prompts`);
15927
16393
  }
16394
+ if (avgCostPerSession > 5) {
16395
+ console.log(` ${icons.arrow} Break long sessions into smaller, focused tasks`);
16396
+ }
16397
+ console.log(` ${icons.arrow} Use context caching for repeated operations`);
16398
+ console.log();
16399
+ }
16400
+ });
16401
+ function parseSince3(since) {
16402
+ const match = since.match(/^(\d+)\s*(day|days|week|weeks|month|months)$/i);
16403
+ if (!match) {
16404
+ return new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
16405
+ }
16406
+ const num = parseInt(match[1], 10);
16407
+ const unit = match[2].toLowerCase();
16408
+ const ms = unit.startsWith("day") ? num * 24 * 60 * 60 * 1000 : unit.startsWith("week") ? num * 7 * 24 * 60 * 60 * 1000 : num * 30 * 24 * 60 * 60 * 1000;
16409
+ return new Date(Date.now() - ms);
16410
+ }
16411
+ function getDaysInRange(since) {
16412
+ const match = since.match(/^(\d+)\s*(day|days|week|weeks|month|months)$/i);
16413
+ if (!match)
16414
+ return 7;
16415
+ const num = parseInt(match[1], 10);
16416
+ const unit = match[2].toLowerCase();
16417
+ if (unit.startsWith("day"))
16418
+ return num;
16419
+ if (unit.startsWith("week"))
16420
+ return num * 7;
16421
+ return num * 30;
16422
+ }
16423
+ function calculateCostByDay(sessions) {
16424
+ const byDay = {};
16425
+ for (const session of sessions) {
16426
+ const day = session.startedAt.split("T")[0];
16427
+ byDay[day] = (byDay[day] ?? 0) + session.costUsd;
16428
+ }
16429
+ return byDay;
16430
+ }
16431
+ function formatTokens3(tokens) {
16432
+ if (tokens >= 1e6) {
16433
+ return `${(tokens / 1e6).toFixed(1)}M`;
16434
+ }
16435
+ if (tokens >= 1000) {
16436
+ return `${Math.round(tokens / 1000)}K`;
16437
+ }
16438
+ return tokens.toString();
16439
+ }
16440
+
16441
+ // src/commands/session.ts
16442
+ import { existsSync as existsSync9, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync } from "node:fs";
16443
+ import { homedir as homedir7 } from "node:os";
16444
+ import { join as join9, basename as basename2 } from "node:path";
16445
+ var sessionCommand = defineCommand2({
16446
+ meta: {
16447
+ name: "session",
16448
+ description: "Analyze specific AI coding sessions"
16449
+ },
16450
+ subCommands: {
16451
+ list: defineCommand2({
16452
+ meta: {
16453
+ name: "list",
16454
+ description: "List recent sessions"
16455
+ },
16456
+ args: {
16457
+ limit: {
16458
+ type: "string",
16459
+ description: "Number of sessions to show",
16460
+ default: "10"
16461
+ },
16462
+ project: {
16463
+ type: "string",
16464
+ description: "Filter by project name"
16465
+ }
16466
+ },
16467
+ async run({ args }) {
16468
+ console.log();
16469
+ console.log(colors2.bold(colors2.primary(" Recent AI Sessions")));
16470
+ console.log(colors2.dim(" " + "─".repeat(50)));
16471
+ console.log();
16472
+ const spinner = createSpinner("Scanning sessions...");
16473
+ spinner.start();
16474
+ const sessions = await collectSessionList();
16475
+ spinner.succeed(`Found ${sessions.length} sessions`);
16476
+ if (sessions.length === 0) {
16477
+ console.log(` ${icons.info} No sessions found`);
16478
+ console.log();
16479
+ return;
16480
+ }
16481
+ let filtered = sessions;
16482
+ const projectFilter = typeof args.project === "string" ? args.project : undefined;
16483
+ if (projectFilter) {
16484
+ filtered = sessions.filter((s2) => s2.project.toLowerCase().includes(projectFilter.toLowerCase()));
16485
+ }
16486
+ const limitStr = typeof args.limit === "string" ? args.limit : "10";
16487
+ const limit = parseInt(limitStr, 10) || 10;
16488
+ const toShow = filtered.sort((a2, b2) => b2.startedAt.getTime() - a2.startedAt.getTime()).slice(0, limit);
16489
+ console.log();
16490
+ console.log(` ${colors2.dim("ID".padEnd(12))} ${colors2.dim("Project".padEnd(25))} ${colors2.dim("Date".padEnd(12))} ${colors2.dim("Tokens".padEnd(10))} ${colors2.dim("Cost")}`);
16491
+ console.log(colors2.dim(" " + "─".repeat(70)));
16492
+ for (const session of toShow) {
16493
+ const dateStr = session.startedAt.toLocaleDateString("en-US", {
16494
+ month: "short",
16495
+ day: "numeric"
16496
+ });
16497
+ const projectShort = session.project.length > 22 ? session.project.slice(0, 19) + "..." : session.project;
16498
+ console.log(` ${colors2.primary(session.id.padEnd(12))} ` + `${projectShort.padEnd(25)} ` + `${colors2.dim(dateStr.padEnd(12))} ` + `${formatTokens2(session.tokens).padEnd(10)} ` + `${colors2.success(`$${session.cost.toFixed(2)}`)}`);
16499
+ }
16500
+ console.log();
16501
+ console.log(colors2.dim(` Run ${colors2.primary("nb session show <id>")} to view details`));
16502
+ console.log();
16503
+ }
16504
+ }),
16505
+ show: defineCommand2({
16506
+ meta: {
16507
+ name: "show",
16508
+ description: "Show detailed session analysis"
16509
+ },
16510
+ args: {
16511
+ id: {
16512
+ type: "positional",
16513
+ description: "Session ID to analyze",
16514
+ required: true
16515
+ }
16516
+ },
16517
+ async run({ args }) {
16518
+ const sessionId = args.id;
16519
+ console.log();
16520
+ console.log(colors2.bold(colors2.primary(" Session Analysis")));
16521
+ console.log(colors2.dim(" " + "─".repeat(40)));
16522
+ console.log();
16523
+ const spinner = createSpinner("Loading session...");
16524
+ spinner.start();
16525
+ const sessions = await collectSessionList();
16526
+ const session = sessions.find((s2) => s2.id === sessionId || s2.id.startsWith(sessionId));
16527
+ if (!session) {
16528
+ spinner.fail("Session not found");
16529
+ console.log(` ${icons.error} No session found with ID: ${sessionId}`);
16530
+ console.log(` ${colors2.dim("Run")} ${colors2.primary("nb session list")} ${colors2.dim("to see available sessions")}`);
16531
+ console.log();
16532
+ return;
16533
+ }
16534
+ spinner.succeed(`Loaded session ${session.id}`);
16535
+ console.log();
16536
+ const details = await parseSessionDetails(session.filePath);
16537
+ console.log(` ${colors2.bold("Session Info")}`);
16538
+ console.log(colors2.dim(" " + "─".repeat(40)));
16539
+ console.log(` ${colors2.dim("ID:")} ${colors2.primary(session.id)}`);
16540
+ console.log(` ${colors2.dim("Project:")} ${session.project}`);
16541
+ console.log(` ${colors2.dim("Started:")} ${session.startedAt.toLocaleString()}`);
16542
+ console.log(` ${colors2.dim("Model:")} ${session.model || "Unknown"}`);
16543
+ console.log(` ${colors2.dim("Duration:")} ${session.duration} minutes`);
16544
+ console.log();
16545
+ console.log(` ${colors2.bold("Token Usage")}`);
16546
+ console.log(colors2.dim(" " + "─".repeat(40)));
16547
+ console.log(` ${colors2.dim("Total:")} ${formatTokens2(details.totalTokens)}`);
16548
+ console.log(` ${colors2.dim("Input:")} ${formatTokens2(details.inputTokens)}`);
16549
+ console.log(` ${colors2.dim("Output:")} ${formatTokens2(details.outputTokens)}`);
16550
+ if (details.cachedTokens > 0) {
16551
+ console.log(` ${colors2.dim("Cached:")} ${formatTokens2(details.cachedTokens)} ${colors2.success("(saved)")}`);
16552
+ }
16553
+ console.log(` ${colors2.dim("Cost:")} ${colors2.success(`$${session.cost.toFixed(2)}`)}`);
16554
+ console.log();
16555
+ console.log(` ${colors2.bold("Activity")}`);
16556
+ console.log(colors2.dim(" " + "─".repeat(40)));
16557
+ console.log(` ${colors2.dim("Messages:")} ${details.messageCount}`);
16558
+ console.log(` ${colors2.dim("Tool calls:")} ${details.toolCalls}`);
16559
+ console.log(` ${colors2.dim("Files touched:")} ${details.filesModified.length}`);
16560
+ console.log();
16561
+ if (Object.keys(details.toolUsage).length > 0) {
16562
+ console.log(` ${colors2.bold("Tools Used")}`);
16563
+ console.log(colors2.dim(" " + "─".repeat(40)));
16564
+ const sortedTools = Object.entries(details.toolUsage).sort((a2, b2) => b2[1] - a2[1]).slice(0, 8);
16565
+ const maxCount = Math.max(...sortedTools.map((t2) => t2[1]));
16566
+ for (const [tool, count] of sortedTools) {
16567
+ const barWidth = Math.round(count / maxCount * 15);
16568
+ const bar = colors2.primary("█".repeat(barWidth)) + colors2.dim("░".repeat(15 - barWidth));
16569
+ const toolName = tool.length > 20 ? tool.slice(0, 17) + "..." : tool;
16570
+ console.log(` ${toolName.padEnd(20)} ${bar} ${count}`);
16571
+ }
16572
+ console.log();
16573
+ }
16574
+ if (details.filesModified.length > 0) {
16575
+ console.log(` ${colors2.bold("Files Modified")}`);
16576
+ console.log(colors2.dim(" " + "─".repeat(40)));
16577
+ const filesToShow = details.filesModified.slice(0, 10);
16578
+ for (const file of filesToShow) {
16579
+ const shortFile = file.length > 50 ? "..." + file.slice(-47) : file;
16580
+ console.log(` ${icons.arrow} ${colors2.dim(shortFile)}`);
16581
+ }
16582
+ if (details.filesModified.length > 10) {
16583
+ console.log(` ${colors2.dim(`... and ${details.filesModified.length - 10} more`)}`);
16584
+ }
16585
+ console.log();
16586
+ }
16587
+ if (details.patterns.length > 0) {
16588
+ console.log(` ${colors2.bold("Patterns Detected")}`);
16589
+ console.log(colors2.dim(" " + "─".repeat(40)));
16590
+ for (const pattern of details.patterns) {
16591
+ const icon = pattern.type === "good" ? icons.success : pattern.type === "warning" ? icons.warning : icons.error;
16592
+ const color = pattern.type === "good" ? colors2.success : pattern.type === "warning" ? colors2.warning : colors2.error;
16593
+ console.log(` ${icon} ${color(pattern.message)}`);
16594
+ }
16595
+ console.log();
16596
+ }
16597
+ }
16598
+ })
15928
16599
  }
15929
16600
  });
15930
- function readReports(reportDir) {
15931
- if (!existsSync8(reportDir)) {
15932
- return [];
15933
- }
15934
- const files = readdirSync3(reportDir).filter((f3) => f3.endsWith(".md") && f3.startsWith("scan-")).sort();
15935
- return files.map((file) => {
15936
- const content = readFileSync5(join8(reportDir, file), "utf-8");
15937
- return parseReport(content, file);
15938
- });
15939
- }
15940
- function parseReport(content, filename) {
15941
- const dateMatch = filename.match(/scan-(\d{4}-\d{2}-\d{2})/);
15942
- const date = dateMatch ? dateMatch[1] : new Date().toISOString().slice(0, 10);
15943
- const overallMatch = content.match(/\*\*Overall\*\*\s*\|\s*(\d+)\/100/);
15944
- const overall = overallMatch ? parseInt(overallMatch[1], 10) : 0;
15945
- const tierMatch = content.match(/\*\*Tier:\*\*\s*(\w+)/);
15946
- const tier = tierMatch ? tierMatch[1] : "Unknown";
15947
- const efficiencyMatch = content.match(/Token Efficiency\s*\|\s*([\d.]+)x/);
15948
- const tokenEfficiency = efficiencyMatch ? parseFloat(efficiencyMatch[1]) : 1;
15949
- const wasteMatch = content.match(/Token Waste\s*\|\s*(\d+)%/);
15950
- const tokenWaste = wasteMatch ? parseInt(wasteMatch[1], 10) : 0;
15951
- const phases = {};
15952
- const phaseRegex = /\| (Requirements|Planning|Implementation|Testing|Review)\s*\|\s*(\d+)\/100/gi;
15953
- let match;
15954
- while ((match = phaseRegex.exec(content)) !== null) {
15955
- phases[match[1].toLowerCase()] = parseInt(match[2], 10);
16601
+ async function collectSessionList() {
16602
+ const sessions = [];
16603
+ const claudeProjectsDir = join9(homedir7(), ".claude", "projects");
16604
+ if (!existsSync9(claudeProjectsDir)) {
16605
+ return sessions;
15956
16606
  }
15957
- const models = {};
15958
- const modelRegex = /\| (claude-[\w-]+|gpt-[\w-]+|sonnet|opus|haiku)\s*\|\s*(\d+)/gi;
15959
- while ((match = modelRegex.exec(content)) !== null) {
15960
- models[match[1]] = parseInt(match[2], 10);
16607
+ const projectDirs = readdirSync4(claudeProjectsDir);
16608
+ for (const projectDir of projectDirs) {
16609
+ const projectPath = join9(claudeProjectsDir, projectDir);
16610
+ const stat = statSync(projectPath);
16611
+ if (!stat.isDirectory())
16612
+ continue;
16613
+ const projectName = decodeProjectName(projectDir);
16614
+ const files = readdirSync4(projectPath).filter((f3) => f3.endsWith(".jsonl"));
16615
+ for (const file of files) {
16616
+ const filePath = join9(projectPath, file);
16617
+ const sessionId = basename2(file, ".jsonl").slice(0, 8);
16618
+ try {
16619
+ const content = readFileSync6(filePath, "utf-8");
16620
+ const lines = content.trim().split(`
16621
+ `).filter(Boolean);
16622
+ if (lines.length === 0)
16623
+ continue;
16624
+ let startedAt = new Date;
16625
+ let model = "";
16626
+ let totalTokens = 0;
16627
+ let cost = 0;
16628
+ let messageCount = 0;
16629
+ let toolCalls = 0;
16630
+ for (const line of lines) {
16631
+ try {
16632
+ const msg = JSON.parse(line);
16633
+ if (msg.timestamp && messageCount === 0) {
16634
+ startedAt = new Date(msg.timestamp);
16635
+ }
16636
+ if (msg.message?.model && !model) {
16637
+ model = msg.message.model;
16638
+ }
16639
+ if (msg.type === "user" || msg.type === "assistant") {
16640
+ messageCount++;
16641
+ }
16642
+ if (msg.message?.content) {
16643
+ for (const block of msg.message.content) {
16644
+ if (block.type === "tool_use") {
16645
+ toolCalls++;
16646
+ }
16647
+ }
16648
+ }
16649
+ const usage = msg.message?.usage || msg.usage;
16650
+ if (usage) {
16651
+ totalTokens += (usage.input_tokens || 0) + (usage.output_tokens || 0);
16652
+ }
16653
+ if (msg.costUsd) {
16654
+ cost += msg.costUsd;
16655
+ }
16656
+ } catch {}
16657
+ }
16658
+ if (cost === 0 && totalTokens > 0) {
16659
+ cost = totalTokens / 1e6 * 3;
16660
+ }
16661
+ const fileStat = statSync(filePath);
16662
+ const duration = Math.round((fileStat.mtimeMs - startedAt.getTime()) / 60000);
16663
+ sessions.push({
16664
+ id: sessionId,
16665
+ project: projectName,
16666
+ startedAt,
16667
+ model,
16668
+ tokens: totalTokens,
16669
+ cost: Math.round(cost * 100) / 100,
16670
+ duration: Math.max(1, duration),
16671
+ messageCount,
16672
+ toolCalls,
16673
+ filePath
16674
+ });
16675
+ } catch {}
16676
+ }
15961
16677
  }
15962
- return { date, overall, tier, tokenEfficiency, tokenWaste, phases, models };
15963
- }
15964
- function detectConcepts(projectDir) {
15965
- const home = homedir6();
15966
- return {
15967
- skills: existsSync8(join8(home, ".claude", "settings.json")) && readFileSync5(join8(home, ".claude", "settings.json"), "utf-8").includes("skill"),
15968
- mcpServers: existsSync8(join8(home, ".config", "opencode", "config.json")) || existsSync8(join8(home, ".claude", "claude_desktop_config.json")) || existsSync8(join8(home, ".claude", "settings.json")) && readFileSync5(join8(home, ".claude", "settings.json"), "utf-8").includes("mcpServers"),
15969
- customCommands: existsSync8(join8(home, ".claude", "commands")) || existsSync8(join8(projectDir, ".claude", "commands")),
15970
- agentConfig: existsSync8(join8(projectDir, "AGENTS.md")) || existsSync8(join8(projectDir, ".cursorrules")) || existsSync8(join8(projectDir, ".github", "copilot-instructions.md")),
15971
- contextManagement: existsSync8(join8(projectDir, "MEMORY.md")) || existsSync8(join8(projectDir, ".context")) || existsSync8(join8(projectDir, "docs", "architecture.md")) || existsSync8(join8(projectDir, ".beads"))
15972
- };
16678
+ return sessions;
15973
16679
  }
15974
- function computeConceptsScore(concepts) {
15975
- const weights = {
15976
- skills: 25,
15977
- mcpServers: 25,
15978
- customCommands: 15,
15979
- agentConfig: 20,
15980
- contextManagement: 15
16680
+ async function parseSessionDetails(filePath) {
16681
+ const details = {
16682
+ totalTokens: 0,
16683
+ inputTokens: 0,
16684
+ outputTokens: 0,
16685
+ cachedTokens: 0,
16686
+ messageCount: 0,
16687
+ toolCalls: 0,
16688
+ toolUsage: {},
16689
+ filesModified: [],
16690
+ patterns: []
15981
16691
  };
15982
- let score = 0;
15983
- for (const [key, adopted] of Object.entries(concepts)) {
15984
- if (adopted) {
15985
- score += weights[key];
16692
+ try {
16693
+ const content = readFileSync6(filePath, "utf-8");
16694
+ const lines = content.trim().split(`
16695
+ `).filter(Boolean);
16696
+ const filesSet = new Set;
16697
+ let undoCount = 0;
16698
+ let errorCount = 0;
16699
+ for (const line of lines) {
16700
+ try {
16701
+ const msg = JSON.parse(line);
16702
+ if (msg.type === "user" || msg.type === "assistant") {
16703
+ details.messageCount++;
16704
+ }
16705
+ const usage = msg.message?.usage || msg.usage;
16706
+ if (usage) {
16707
+ details.inputTokens += usage.input_tokens || 0;
16708
+ details.outputTokens += usage.output_tokens || 0;
16709
+ details.cachedTokens += usage.cache_read_input_tokens || 0;
16710
+ }
16711
+ if (msg.message?.content) {
16712
+ for (const block of msg.message.content) {
16713
+ if (block.type === "tool_use" && block.name) {
16714
+ details.toolCalls++;
16715
+ details.toolUsage[block.name] = (details.toolUsage[block.name] || 0) + 1;
16716
+ if (block.name === "Write" || block.name === "Edit") {
16717
+ const input = block.input || {};
16718
+ if (input.filePath) {
16719
+ filesSet.add(input.filePath);
16720
+ }
16721
+ }
16722
+ }
16723
+ if (block.type === "text" && typeof block.text === "string") {
16724
+ if (block.text.includes("undo") || block.text.includes("revert")) {
16725
+ undoCount++;
16726
+ }
16727
+ if (block.text.includes("error") || block.text.includes("Error")) {
16728
+ errorCount++;
16729
+ }
16730
+ }
16731
+ }
16732
+ }
16733
+ if (msg.type === "user" && typeof msg.content === "string") {
16734
+ if (msg.content.toLowerCase().includes("undo") || msg.content.toLowerCase().includes("revert")) {
16735
+ undoCount++;
16736
+ }
16737
+ }
16738
+ } catch {}
15986
16739
  }
15987
- }
15988
- return score;
16740
+ details.totalTokens = details.inputTokens + details.outputTokens;
16741
+ details.filesModified = Array.from(filesSet);
16742
+ if (undoCount === 0) {
16743
+ details.patterns.push({ type: "good", message: "No undo/revert patterns detected" });
16744
+ } else if (undoCount < 3) {
16745
+ details.patterns.push({ type: "warning", message: `${undoCount} undo/revert operations` });
16746
+ } else {
16747
+ details.patterns.push({ type: "error", message: `High undo frequency: ${undoCount} operations` });
16748
+ }
16749
+ if (details.cachedTokens > details.inputTokens * 0.3) {
16750
+ details.patterns.push({ type: "good", message: "Good cache utilization" });
16751
+ }
16752
+ if (details.toolCalls > 50) {
16753
+ details.patterns.push({ type: "good", message: "High tool usage - efficient workflow" });
16754
+ }
16755
+ if (errorCount > 5) {
16756
+ details.patterns.push({ type: "warning", message: `${errorCount} error mentions in session` });
16757
+ }
16758
+ } catch {}
16759
+ return details;
15989
16760
  }
15990
- function detectTools(projectDir) {
15991
- const tools = [];
15992
- const home = homedir6();
15993
- const toolChecks = [
15994
- { name: "Claude Code", check: () => existsSync8(join8(home, ".claude")) },
15995
- { name: "Cursor", check: () => existsSync8(join8(projectDir, ".cursorrules")) },
15996
- { name: "GitHub Copilot", check: () => existsSync8(join8(projectDir, ".github", "copilot-instructions.md")) },
15997
- { name: "OpenCode", check: () => existsSync8(join8(home, ".config", "opencode")) },
15998
- { name: "Windsurf", check: () => existsSync8(join8(home, ".windsurf")) },
15999
- { name: "Aider", check: () => existsSync8(join8(projectDir, ".aider.conf.yml")) },
16000
- { name: "Codeium", check: () => existsSync8(join8(home, ".codeium")) },
16001
- { name: "Beads", check: () => existsSync8(join8(projectDir, ".beads")) },
16002
- { name: "Convex", check: () => existsSync8(join8(projectDir, "convex")) },
16003
- { name: "Supabase", check: () => existsSync8(join8(projectDir, "supabase")) }
16004
- ];
16005
- for (const { name, check } of toolChecks) {
16006
- try {
16007
- if (check()) {
16008
- tools.push(name);
16009
- }
16010
- } catch {}
16761
+ function decodeProjectName(encoded) {
16762
+ try {
16763
+ let decoded = encoded;
16764
+ if (decoded.includes("-")) {
16765
+ decoded = decoded.split("-").slice(-1)[0] || decoded;
16766
+ }
16767
+ decoded = decoded.replace(/%2F/g, "/").replace(/%20/g, " ");
16768
+ return decoded || encoded;
16769
+ } catch {
16770
+ return encoded;
16011
16771
  }
16012
- return tools;
16013
16772
  }
16014
- function aggregateReports(reports) {
16015
- if (reports.length === 0) {
16016
- return {
16017
- avgTokenEfficiency: 1,
16018
- wasteReductionRate: 0,
16019
- sdlcCoverage: {},
16020
- modelPreferences: {},
16021
- improvementTrend: [],
16022
- weekOverWeekImprovement: 0,
16023
- patternCorrectionRate: 0
16024
- };
16025
- }
16026
- const avgTokenEfficiency = reports.reduce((acc, r3) => acc + r3.tokenEfficiency, 0) / reports.length;
16027
- const firstWaste = reports[0]?.tokenWaste ?? 0;
16028
- const lastWaste = reports[reports.length - 1]?.tokenWaste ?? 0;
16029
- const wasteReductionRate = firstWaste > 0 ? (firstWaste - lastWaste) / firstWaste * 100 : 0;
16030
- const sdlcCoverage = {};
16031
- const phases = ["requirements", "planning", "implementation", "testing", "review"];
16032
- for (const phase of phases) {
16033
- const scores = reports.map((r3) => r3.phases[phase] ?? 0).filter((s2) => s2 > 0);
16034
- if (scores.length > 0) {
16035
- const avg = scores.reduce((a2, b2) => a2 + b2, 0) / scores.length;
16036
- const trend = scores.length > 1 ? scores[scores.length - 1] - scores[0] : 0;
16037
- sdlcCoverage[phase] = { score: Math.round(avg), trend };
16773
+
16774
+ // src/commands/export.ts
16775
+ import { writeFileSync as writeFileSync3 } from "node:fs";
16776
+ var exportCommand = defineCommand2({
16777
+ meta: {
16778
+ name: "export",
16779
+ description: "Export scan data in JSON or CSV format for custom analysis"
16780
+ },
16781
+ args: {
16782
+ format: {
16783
+ type: "string",
16784
+ description: "Output format: json, csv, or both",
16785
+ default: "json"
16786
+ },
16787
+ output: {
16788
+ type: "string",
16789
+ description: "Output file path (without extension)",
16790
+ alias: "o"
16791
+ },
16792
+ since: {
16793
+ type: "string",
16794
+ description: 'Time range (e.g., "7 days", "30 days")',
16795
+ default: "30 days"
16796
+ },
16797
+ detailed: {
16798
+ type: "boolean",
16799
+ description: "Include detailed session-level data",
16800
+ default: false
16038
16801
  }
16039
- }
16040
- const modelPreferences = {};
16041
- for (const report of reports) {
16042
- for (const [model, count] of Object.entries(report.models)) {
16043
- modelPreferences[model] = (modelPreferences[model] ?? 0) + count;
16802
+ },
16803
+ async run({ args }) {
16804
+ console.log();
16805
+ console.log(colors2.bold(colors2.primary(" Export Scan Data")));
16806
+ console.log(colors2.dim(" " + "─".repeat(40)));
16807
+ console.log();
16808
+ const spinner = createSpinner("Collecting data...");
16809
+ spinner.start();
16810
+ const since = parseSince4(args.since);
16811
+ const projectDir = process.cwd();
16812
+ const git = await collectGit(projectDir, since);
16813
+ const agents = await collectAgentSessions(since);
16814
+ const tests = await collectTestResults(projectDir);
16815
+ const score = computeNaironScore(git ?? undefined, agents ?? undefined, tests ?? undefined);
16816
+ const analysis = analyzeWorkflow(agents, projectDir);
16817
+ const cost = calculateScanCost(agents, git);
16818
+ spinner.succeed("Data collected");
16819
+ const exportData = {
16820
+ meta: {
16821
+ exportedAt: new Date().toISOString(),
16822
+ period: args.since,
16823
+ projectDir
16824
+ },
16825
+ score: {
16826
+ overall: score.overall,
16827
+ tier: score.tier,
16828
+ baseScore: score.baseScore,
16829
+ phases: score.phases,
16830
+ tokenEfficiency: score.tokenEfficiency
16831
+ },
16832
+ cost: {
16833
+ total: cost.sessionsCostUsd,
16834
+ wasted: cost.wastedCostUsd,
16835
+ perSession: cost.costPerSession,
16836
+ perCommit: cost.costPerCommit,
16837
+ projectedMonthly: cost.projectedMonthlyCostUsd
16838
+ },
16839
+ git: git ? {
16840
+ commits: git.commitCount,
16841
+ insertions: git.totalInsertions,
16842
+ deletions: git.totalDeletions,
16843
+ avgCommitSize: git.avgCommitSize,
16844
+ commitsPerDay: git.commitsPerDay,
16845
+ authors: git.authors
16846
+ } : null,
16847
+ agents: agents ? {
16848
+ totalSessions: agents.totalSessions,
16849
+ totalTokens: agents.totalTokens,
16850
+ totalCost: agents.totalCostUsd,
16851
+ durationMinutes: agents.totalDurationMinutes,
16852
+ agentBreakdown: agents.agentBreakdown,
16853
+ modelBreakdown: agents.modelBreakdown,
16854
+ costByModel: agents.costByModel
16855
+ } : null,
16856
+ tests: tests ? {
16857
+ framework: tests.framework,
16858
+ total: tests.totalTests,
16859
+ passed: tests.passed,
16860
+ failed: tests.failed,
16861
+ passRate: tests.passRate,
16862
+ coverage: tests.coveragePercent
16863
+ } : null,
16864
+ patterns: {
16865
+ memoryLoss: analysis.sessionPatterns.memoryLossCount,
16866
+ undoLoops: analysis.sessionPatterns.undoLoops,
16867
+ frustration: analysis.sessionPatterns.frustrationCount
16868
+ },
16869
+ recommendations: analysis.recommendations.map((r3) => ({
16870
+ title: r3.title,
16871
+ description: r3.description,
16872
+ action: r3.action,
16873
+ phase: r3.phase,
16874
+ impact: r3.estimatedImpact
16875
+ })),
16876
+ sessions: args.detailed && agents ? agents.sessions.map((s2) => ({
16877
+ id: s2.sessionId,
16878
+ agent: s2.agent,
16879
+ model: s2.model,
16880
+ startedAt: s2.startedAt,
16881
+ durationMinutes: s2.durationMinutes,
16882
+ tokens: s2.totalTokens,
16883
+ cost: s2.costUsd,
16884
+ patterns: s2.patterns
16885
+ })) : undefined
16886
+ };
16887
+ const formatArg = typeof args.format === "string" ? args.format : "json";
16888
+ const formats = formatArg === "both" ? ["json", "csv"] : [formatArg];
16889
+ const basePath = typeof args.output === "string" ? args.output : `nairon-export-${Date.now()}`;
16890
+ for (const fmt of formats) {
16891
+ if (fmt === "json") {
16892
+ const jsonPath = `${basePath}.json`;
16893
+ writeFileSync3(jsonPath, JSON.stringify(exportData, null, 2));
16894
+ console.log(` ${icons.success} Exported: ${colors2.primary(jsonPath)}`);
16895
+ } else if (fmt === "csv") {
16896
+ const csvPath = `${basePath}.csv`;
16897
+ const csv = generateCSV(exportData);
16898
+ writeFileSync3(csvPath, csv);
16899
+ console.log(` ${icons.success} Exported: ${colors2.primary(csvPath)}`);
16900
+ }
16044
16901
  }
16902
+ console.log();
16903
+ console.log(colors2.dim(" Use the exported data for custom dashboards, reports, or analysis."));
16904
+ console.log();
16045
16905
  }
16046
- const improvementTrend = reports.map((r3) => ({
16047
- date: r3.date,
16048
- score: r3.overall
16049
- }));
16050
- let weekOverWeekImprovement = 0;
16051
- if (reports.length >= 2) {
16052
- const recentScore = reports[reports.length - 1].overall;
16053
- const olderScore = reports[Math.max(0, reports.length - 8)].overall;
16054
- weekOverWeekImprovement = recentScore - olderScore;
16055
- }
16056
- const patternCorrectionRate = Math.max(0, wasteReductionRate);
16057
- return {
16058
- avgTokenEfficiency,
16059
- wasteReductionRate,
16060
- sdlcCoverage,
16061
- modelPreferences,
16062
- improvementTrend,
16063
- weekOverWeekImprovement,
16064
- patternCorrectionRate
16065
- };
16066
- }
16067
- function computeAINativenessScore(aggregated, conceptsScore, toolCount) {
16068
- const toolingScore = Math.min(100, toolCount * 10);
16069
- const phaseScores = Object.values(aggregated.sdlcCoverage).map((p) => p.score);
16070
- const workflowScore = phaseScores.length > 0 ? phaseScores.reduce((a2, b2) => a2 + b2, 0) / phaseScores.length : 0;
16071
- const improvementBonus = Math.min(50, Math.max(0, aggregated.weekOverWeekImprovement * 2));
16072
- const efficiencyBonus = Math.min(50, aggregated.avgTokenEfficiency * 25);
16073
- const velocityScore = improvementBonus + efficiencyBonus;
16074
- const score = toolingScore * 0.25 + workflowScore * 0.25 + conceptsScore * 0.25 + velocityScore * 0.25;
16075
- return Math.round(Math.min(100, Math.max(0, score)));
16076
- }
16077
- function getTier(score) {
16078
- if (score >= 90)
16079
- return "Elite";
16080
- if (score >= 75)
16081
- return "Expert";
16082
- if (score >= 60)
16083
- return "Advanced";
16084
- if (score >= 40)
16085
- return "Intermediate";
16086
- if (score >= 20)
16087
- return "Beginner";
16088
- return "Novice";
16906
+ });
16907
+ function parseSince4(since) {
16908
+ const match = since.match(/^(\d+)\s*(day|days|week|weeks|month|months)$/i);
16909
+ if (!match)
16910
+ return new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
16911
+ const num = parseInt(match[1], 10);
16912
+ const unit = match[2].toLowerCase();
16913
+ const ms = unit.startsWith("day") ? num * 24 * 60 * 60 * 1000 : unit.startsWith("week") ? num * 7 * 24 * 60 * 60 * 1000 : num * 30 * 24 * 60 * 60 * 1000;
16914
+ return new Date(Date.now() - ms);
16089
16915
  }
16090
- function formatPreview(data) {
16091
- const lines = [];
16092
- lines.push(`Score: ${data.score}/100 | Tier: ${data.tier}`);
16093
- lines.push("");
16094
- lines.push("Breakdown:");
16095
- lines.push(` Tooling: ${Math.min(100, data.toolsCount * 10)}/100 (${data.toolsCount} tools detected)`);
16096
- lines.push(` Concepts: ${data.conceptsScore}/100`);
16097
- lines.push(` Efficiency: ${data.avgEfficiency.toFixed(2)}x`);
16098
- lines.push(` Improvement: ${data.improvementRate >= 0 ? "+" : ""}${data.improvementRate.toFixed(1)} pts/week`);
16099
- lines.push("");
16100
- lines.push("AI Concepts:");
16101
- lines.push(` ${data.concepts.skills ? "[x]" : "[ ]"} Skills configured`);
16102
- lines.push(` ${data.concepts.mcpServers ? "[x]" : "[ ]"} MCP servers active`);
16103
- lines.push(` ${data.concepts.customCommands ? "[x]" : "[ ]"} Custom commands`);
16104
- lines.push(` ${data.concepts.agentConfig ? "[x]" : "[ ]"} Agent configuration`);
16105
- lines.push(` ${data.concepts.contextManagement ? "[x]" : "[ ]"} Context management`);
16106
- lines.push("");
16107
- lines.push(`Based on ${data.scansAnalyzed} scans`);
16108
- return lines.join(`
16916
+ function generateCSV(data) {
16917
+ const rows = [];
16918
+ rows.push([
16919
+ "Metric",
16920
+ "Category",
16921
+ "Value",
16922
+ "Details"
16923
+ ]);
16924
+ rows.push(["Overall Score", "Score", String(data.score.overall), `Tier: ${data.score.tier}`]);
16925
+ rows.push(["Base Score", "Score", String(data.score.baseScore), ""]);
16926
+ rows.push(["Token Efficiency", "Score", String(data.score.tokenEfficiency.modifier), `${data.score.tokenEfficiency.wastePercentage}% waste`]);
16927
+ for (const phase of data.score.phases) {
16928
+ rows.push([`${phase.phase} Score`, "Phase", String(phase.score), ""]);
16929
+ }
16930
+ rows.push(["Total Cost", "Cost", `$${data.cost.total.toFixed(2)}`, ""]);
16931
+ rows.push(["Wasted Cost", "Cost", `$${data.cost.wasted.toFixed(2)}`, ""]);
16932
+ rows.push(["Projected Monthly", "Cost", `$${data.cost.projectedMonthly.toFixed(2)}`, ""]);
16933
+ if (data.git) {
16934
+ rows.push(["Commits", "Git", String(data.git.commits), `${data.git.commitsPerDay.toFixed(1)}/day`]);
16935
+ rows.push(["Insertions", "Git", String(data.git.insertions), ""]);
16936
+ rows.push(["Deletions", "Git", String(data.git.deletions), ""]);
16937
+ }
16938
+ if (data.agents) {
16939
+ rows.push(["Sessions", "Agent", String(data.agents.totalSessions), ""]);
16940
+ rows.push(["Total Tokens", "Agent", String(data.agents.totalTokens), ""]);
16941
+ rows.push(["Duration (min)", "Agent", String(data.agents.durationMinutes), ""]);
16942
+ }
16943
+ if (data.tests) {
16944
+ rows.push(["Total Tests", "Testing", String(data.tests.total), data.tests.framework]);
16945
+ rows.push(["Pass Rate", "Testing", `${(data.tests.passRate * 100).toFixed(1)}%`, ""]);
16946
+ if (data.tests.coverage !== undefined) {
16947
+ rows.push(["Coverage", "Testing", `${data.tests.coverage}%`, ""]);
16948
+ }
16949
+ }
16950
+ rows.push(["Memory Loss Events", "Patterns", String(data.patterns.memoryLoss), ""]);
16951
+ rows.push(["Undo Loops", "Patterns", String(data.patterns.undoLoops), ""]);
16952
+ rows.push(["Frustration Events", "Patterns", String(data.patterns.frustration), ""]);
16953
+ return rows.map((row) => row.map((cell) => `"${cell.replace(/"/g, '""')}"`).join(",")).join(`
16109
16954
  `);
16110
16955
  }
16111
16956
 
@@ -16139,7 +16984,7 @@ function showBanner() {
16139
16984
  log("");
16140
16985
  }
16141
16986
  var args = process.argv.slice(2);
16142
- var subcommands = ["init", "scan", "report", "dashboard", "insights", "tools", "doctor", "publish"];
16987
+ var subcommands = ["init", "scan", "report", "dashboard", "insights", "tools", "doctor", "publish", "history", "cost", "session", "export"];
16143
16988
  var hasSubcommand = args.some((arg) => subcommands.includes(arg));
16144
16989
  var hasHelp = args.includes("--help") || args.includes("-h");
16145
16990
  var hasVersion = args.includes("--version");
@@ -16160,7 +17005,11 @@ if (!hasSubcommand && !hasHelp && !hasVersion && args.length === 0) {
16160
17005
  insights: insightsCommand,
16161
17006
  tools: toolsCommand,
16162
17007
  doctor: doctorCommand,
16163
- publish: publishCommand
17008
+ publish: publishCommand,
17009
+ history: historyCommand,
17010
+ cost: costCommand,
17011
+ session: sessionCommand,
17012
+ export: exportCommand
16164
17013
  }
16165
17014
  });
16166
17015
  runMain(main);