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.
- package/dist/index.js +2495 -1646
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2486
|
+
// ../../node_modules/convex/dist/esm/index.js
|
|
2487
2487
|
var version = "1.31.7";
|
|
2488
2488
|
|
|
2489
|
-
// ../../node_modules
|
|
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
|
|
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
|
|
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
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
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
|
|
2888
|
-
constructor(
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
this
|
|
2892
|
-
this
|
|
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
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
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
|
-
|
|
2881
|
+
this.tableName = tableName;
|
|
2901
2882
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
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
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2886
|
+
asOptional() {
|
|
2887
|
+
return new VId({
|
|
2888
|
+
isOptional: "optional",
|
|
2889
|
+
tableName: this.tableName
|
|
2890
|
+
});
|
|
2917
2891
|
}
|
|
2918
|
-
}
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2892
|
+
};
|
|
2893
|
+
VFloat64 = class VFloat64 extends BaseValidator {
|
|
2894
|
+
constructor() {
|
|
2895
|
+
super(...arguments);
|
|
2896
|
+
__publicField(this, "kind", "float64");
|
|
2922
2897
|
}
|
|
2923
|
-
|
|
2924
|
-
|
|
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
|
-
|
|
2931
|
-
|
|
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
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
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
|
-
|
|
2968
|
-
|
|
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
|
-
|
|
3001
|
-
|
|
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
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
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
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
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
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
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
|
-
|
|
3087
|
-
|
|
3088
|
-
validateDeploymentUrl(address);
|
|
2938
|
+
get json() {
|
|
2939
|
+
return { type: this.kind };
|
|
3089
2940
|
}
|
|
3090
|
-
|
|
3091
|
-
|
|
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
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
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
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
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
|
-
|
|
3175
|
-
|
|
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
|
-
|
|
3193
|
-
|
|
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
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
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
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
2999
|
+
if (!validator.isConvexValidator) {
|
|
3000
|
+
throw new Error("v.object() entries must be validators");
|
|
3001
|
+
}
|
|
3002
|
+
});
|
|
3003
|
+
this.fields = fields;
|
|
3208
3004
|
}
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
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
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
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
|
-
|
|
3237
|
-
|
|
3238
|
-
for (const
|
|
3239
|
-
|
|
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
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
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
|
-
|
|
3259
|
-
|
|
3260
|
-
const
|
|
3261
|
-
|
|
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
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
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
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
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
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
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
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
}
|
|
3076
|
+
asOptional() {
|
|
3077
|
+
return new VLiteral({
|
|
3078
|
+
isOptional: "optional",
|
|
3079
|
+
value: this.value
|
|
3080
|
+
});
|
|
3318
3081
|
}
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
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
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
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
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
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
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
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
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
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
|
-
|
|
3373
|
-
default:
|
|
3374
|
-
throw new Error(`Invalid response: ${JSON.stringify(respJSON)}`);
|
|
3145
|
+
};
|
|
3375
3146
|
}
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
}
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
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
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
}
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
}
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
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
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
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
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
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
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
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
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
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
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
}
|
|
3530
|
-
|
|
3531
|
-
|
|
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
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
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
|
-
|
|
3543
|
-
|
|
3323
|
+
warn(...args) {
|
|
3324
|
+
for (const func of Object.values(this._onLogLineFuncs)) {
|
|
3325
|
+
func("warn", ...args);
|
|
3326
|
+
}
|
|
3544
3327
|
}
|
|
3545
|
-
|
|
3546
|
-
const
|
|
3547
|
-
|
|
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
|
|
3553
|
-
const
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
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
|
-
|
|
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
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
if (
|
|
3579
|
-
|
|
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 (
|
|
3582
|
-
|
|
3583
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
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
|
-
|
|
3402
|
+
functionAddress = { name: functionReference };
|
|
3594
3403
|
}
|
|
3595
|
-
}
|
|
3596
|
-
|
|
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
|
-
|
|
3645
|
-
|
|
3407
|
+
const referencePath = extractReferencePath(functionReference);
|
|
3408
|
+
if (!referencePath) {
|
|
3409
|
+
throw new Error(`${functionReference} is not a functionReference`);
|
|
3646
3410
|
}
|
|
3647
|
-
|
|
3411
|
+
functionAddress = { reference: referencePath };
|
|
3648
3412
|
}
|
|
3413
|
+
return functionAddress;
|
|
3649
3414
|
}
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
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
|
|
3666
|
-
function
|
|
3667
|
-
const
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
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
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
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
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
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
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
});
|
|
3490
|
+
const opts = options ?? {};
|
|
3491
|
+
if (opts.skipConvexDeploymentUrlCheck !== true) {
|
|
3492
|
+
validateDeploymentUrl(address);
|
|
3720
3493
|
}
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
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
|
-
|
|
3728
|
-
|
|
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
|
-
|
|
3731
|
-
|
|
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
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
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
|
-
|
|
3740
|
-
|
|
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
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
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
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
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
|
-
|
|
3754
|
-
|
|
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
|
-
|
|
3757
|
-
|
|
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
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
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
|
-
|
|
3766
|
-
|
|
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
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
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
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
__publicField4(this, "kind", "null");
|
|
3657
|
+
}
|
|
3658
|
+
async processMutationQueue() {
|
|
3659
|
+
if (this.isProcessingQueue) {
|
|
3660
|
+
return;
|
|
3778
3661
|
}
|
|
3779
|
-
|
|
3780
|
-
|
|
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
|
-
|
|
3783
|
-
|
|
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
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
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
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
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
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
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
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
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
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
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
|
-
|
|
3849
|
-
|
|
3850
|
-
for (const
|
|
3851
|
-
|
|
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
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
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
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
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
|
|
4076
|
-
var
|
|
4077
|
-
|
|
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
|
|
3799
|
+
// ../../node_modules/convex/dist/esm/server/search_filter_builder.js
|
|
4082
3800
|
var init_search_filter_builder = () => {};
|
|
4083
3801
|
|
|
4084
|
-
// ../../node_modules
|
|
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
|
|
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 ===
|
|
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
|
-
|
|
3838
|
+
init_paths();
|
|
4155
3839
|
});
|
|
4156
3840
|
|
|
4157
|
-
// ../../node_modules
|
|
3841
|
+
// ../../node_modules/convex/dist/esm/server/index.js
|
|
4158
3842
|
var init_server = __esm(() => {
|
|
4159
|
-
|
|
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
|
|
3851
|
+
var init_api2 = __esm(() => {
|
|
4168
3852
|
init_server();
|
|
4169
|
-
api =
|
|
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
|
-
|
|
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
|
|
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
|
|
4008
|
+
// ../../node_modules/citty/dist/index.mjs
|
|
4325
4009
|
init_dist();
|
|
4326
4010
|
|
|
4327
|
-
// ../../node_modules
|
|
4011
|
+
// ../../node_modules/consola/dist/utils.mjs
|
|
4328
4012
|
init_consola_DXBYu_KD();
|
|
4329
4013
|
init_consola_DXBYu_KD();
|
|
4330
4014
|
|
|
4331
|
-
// ../../node_modules
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
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
|
|
10545
|
-
const session = sortedSessions[
|
|
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 =
|
|
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
|
|
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
|
|
10577
|
+
// ../../node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
10655
10578
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
10656
|
-
var wrapAnsi16 = (offset = 0) => (
|
|
10657
|
-
var wrapAnsi256 = (offset = 0) => (
|
|
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(
|
|
10785
|
-
if (
|
|
10786
|
-
return 30 +
|
|
10707
|
+
value(code2) {
|
|
10708
|
+
if (code2 < 8) {
|
|
10709
|
+
return 30 + code2;
|
|
10787
10710
|
}
|
|
10788
|
-
if (
|
|
10789
|
-
return 90 + (
|
|
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 (
|
|
10795
|
-
red = ((
|
|
10717
|
+
if (code2 >= 232) {
|
|
10718
|
+
red = ((code2 - 232) * 10 + 8) / 255;
|
|
10796
10719
|
green = red;
|
|
10797
10720
|
blue = red;
|
|
10798
10721
|
} else {
|
|
10799
|
-
|
|
10800
|
-
const remainder =
|
|
10801
|
-
red = Math.floor(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
11066
|
+
// ../../node_modules/cli-cursor/index.js
|
|
11144
11067
|
import process5 from "node:process";
|
|
11145
11068
|
|
|
11146
|
-
// ../../node_modules
|
|
11069
|
+
// ../../node_modules/restore-cursor/index.js
|
|
11147
11070
|
import process4 from "node:process";
|
|
11148
11071
|
|
|
11149
|
-
// ../../node_modules
|
|
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
|
|
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
|
|
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 \`${
|
|
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
|
|
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
|
|
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
|
|
11270
|
-
if (
|
|
11192
|
+
const i3 = list.indexOf(fn);
|
|
11193
|
+
if (i3 === -1) {
|
|
11271
11194
|
return;
|
|
11272
11195
|
}
|
|
11273
|
-
if (
|
|
11196
|
+
if (i3 === 0 && list.length === 1) {
|
|
11274
11197
|
list.length = 0;
|
|
11275
11198
|
} else {
|
|
11276
|
-
list.splice(
|
|
11199
|
+
list.splice(i3, 1);
|
|
11277
11200
|
}
|
|
11278
11201
|
}
|
|
11279
|
-
emit(ev,
|
|
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(
|
|
11209
|
+
ret = fn(code2, signal) === true || ret;
|
|
11287
11210
|
}
|
|
11288
11211
|
if (ev === "exit") {
|
|
11289
|
-
ret = this.emit("afterExit",
|
|
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 = (
|
|
11384
|
-
return this.#processReallyExit(
|
|
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(
|
|
11328
|
+
#processReallyExit(code2) {
|
|
11406
11329
|
if (!processOk(this.#process)) {
|
|
11407
11330
|
return 0;
|
|
11408
11331
|
}
|
|
11409
|
-
this.#process.exitCode =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
13387
|
-
if (
|
|
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
|
|
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
|
|
13981
|
-
if (
|
|
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
|
|
14015
|
-
const current = Math.round(
|
|
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
|
|
14027
|
-
if (
|
|
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
|
-
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14118
|
-
|
|
14119
|
-
|
|
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 (
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
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 (
|
|
14132
|
-
await
|
|
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
|
-
|
|
14141
|
-
|
|
14142
|
-
|
|
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("
|
|
14161
|
-
console.log(
|
|
14162
|
-
const
|
|
14163
|
-
|
|
14164
|
-
|
|
14165
|
-
|
|
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
|
-
|
|
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(`
|
|
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
|
-
|
|
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(`
|
|
14176
|
-
|
|
14177
|
-
|
|
14178
|
-
|
|
14179
|
-
|
|
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(`
|
|
14189
|
-
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
|
|
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
|
-
|
|
14201
|
-
|
|
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
|
-
|
|
14208
|
-
|
|
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
|
|
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
|
|
14247
|
+
if (uploadSpinner)
|
|
14248
|
+
uploadSpinner.succeed(`Synced to cloud`);
|
|
14258
14249
|
} catch (err) {
|
|
14259
|
-
uploadSpinner
|
|
14260
|
-
|
|
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
|
|
14379
|
-
const rec = analysis.recommendations[
|
|
14380
|
-
lines.push(`### ${
|
|
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((
|
|
15214
|
-
const icon =
|
|
15242
|
+
message: insights.map((i3) => {
|
|
15243
|
+
const icon = i3.severity === "critical" ? "[!!]" : i3.severity === "warning" ? "[!]" : "[i]";
|
|
15215
15244
|
return [
|
|
15216
|
-
`${icon} ${
|
|
15217
|
-
` ${
|
|
15218
|
-
` 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(` `);
|
|
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
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
const
|
|
15801
|
-
|
|
15802
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
15817
|
-
|
|
15818
|
-
|
|
15819
|
-
|
|
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/
|
|
15823
|
-
|
|
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: "
|
|
15831
|
-
description: "
|
|
16280
|
+
name: "cost",
|
|
16281
|
+
description: "Analyze AI usage costs by model, day, and project"
|
|
15832
16282
|
},
|
|
15833
16283
|
args: {
|
|
15834
|
-
|
|
15835
|
-
type: "boolean",
|
|
15836
|
-
description: "Preview report without uploading",
|
|
15837
|
-
default: false
|
|
15838
|
-
},
|
|
15839
|
-
project: {
|
|
16284
|
+
since: {
|
|
15840
16285
|
type: "string",
|
|
15841
|
-
description:
|
|
16286
|
+
description: 'Time range (e.g., "7 days", "30 days")',
|
|
16287
|
+
default: "7 days"
|
|
15842
16288
|
},
|
|
15843
|
-
|
|
15844
|
-
type: "
|
|
15845
|
-
description: "
|
|
15846
|
-
default:
|
|
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
|
|
15851
|
-
|
|
15852
|
-
|
|
15853
|
-
`);
|
|
15854
|
-
|
|
15855
|
-
|
|
15856
|
-
|
|
15857
|
-
|
|
15858
|
-
|
|
15859
|
-
|
|
15860
|
-
|
|
15861
|
-
|
|
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
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
|
|
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
|
-
|
|
15897
|
-
|
|
15898
|
-
|
|
15899
|
-
|
|
15900
|
-
|
|
15901
|
-
|
|
15902
|
-
|
|
15903
|
-
|
|
15904
|
-
|
|
15905
|
-
|
|
15906
|
-
|
|
15907
|
-
|
|
15908
|
-
|
|
15909
|
-
|
|
15910
|
-
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
15914
|
-
|
|
15915
|
-
|
|
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
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
|
|
15922
|
-
|
|
15923
|
-
|
|
15924
|
-
|
|
15925
|
-
|
|
15926
|
-
|
|
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
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
|
|
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
|
|
15958
|
-
const
|
|
15959
|
-
|
|
15960
|
-
|
|
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
|
|
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
|
|
15975
|
-
const
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
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
|
-
|
|
15983
|
-
|
|
15984
|
-
|
|
15985
|
-
|
|
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
|
-
|
|
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
|
|
15991
|
-
|
|
15992
|
-
|
|
15993
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
15996
|
-
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
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
|
-
|
|
16015
|
-
|
|
16016
|
-
|
|
16017
|
-
|
|
16018
|
-
|
|
16019
|
-
|
|
16020
|
-
|
|
16021
|
-
|
|
16022
|
-
|
|
16023
|
-
|
|
16024
|
-
|
|
16025
|
-
|
|
16026
|
-
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
|
|
16030
|
-
|
|
16031
|
-
|
|
16032
|
-
|
|
16033
|
-
|
|
16034
|
-
|
|
16035
|
-
|
|
16036
|
-
|
|
16037
|
-
|
|
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
|
-
|
|
16041
|
-
|
|
16042
|
-
|
|
16043
|
-
|
|
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
|
-
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16052
|
-
|
|
16053
|
-
|
|
16054
|
-
|
|
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
|
|
16091
|
-
const
|
|
16092
|
-
|
|
16093
|
-
|
|
16094
|
-
|
|
16095
|
-
|
|
16096
|
-
|
|
16097
|
-
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16102
|
-
|
|
16103
|
-
|
|
16104
|
-
|
|
16105
|
-
|
|
16106
|
-
|
|
16107
|
-
|
|
16108
|
-
|
|
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);
|