cruo-agent 0.1.3 → 0.1.4
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/VERSION +1 -1
- package/dist/cli.js +675 -163
- package/package.json +1 -1
package/dist/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.4
|
package/dist/cli.js
CHANGED
|
@@ -45,64 +45,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
45
45
|
));
|
|
46
46
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
47
47
|
|
|
48
|
-
// src/options.ts
|
|
49
|
-
function stripTokenFlag(argv2) {
|
|
50
|
-
const at = argv2.indexOf("--token");
|
|
51
|
-
if (at < 0) return [...argv2];
|
|
52
|
-
return [...argv2.slice(0, at), ...argv2.slice(at + 2)];
|
|
53
|
-
}
|
|
54
|
-
function numericIn(argv2, name, spec = {}) {
|
|
55
|
-
const i = argv2.indexOf(`--${name}`);
|
|
56
|
-
if (i < 0) return spec.fallback;
|
|
57
|
-
const raw = argv2[i + 1];
|
|
58
|
-
if (raw === void 0 || raw.startsWith("--")) {
|
|
59
|
-
throw new OptionError(
|
|
60
|
-
`--${name} expects a ${spec.integer ? "whole " : ""}number${spec.unit ? ` of ${spec.unit}` : ""}, but no value followed it.`
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
const value = raw.trim() === "" ? NaN : Number(raw);
|
|
64
|
-
const what = `--${name} ${JSON.stringify(raw)}`;
|
|
65
|
-
if (!Number.isFinite(value)) {
|
|
66
|
-
throw new OptionError(
|
|
67
|
-
`${what} is not a number.` + // Reached only by something like `-abc`. A plain `-5` is a finite
|
|
68
|
-
// negative and falls to the range check below, which is the accurate
|
|
69
|
-
// refusal for it — this hint is for the case where the leading dash is
|
|
70
|
-
// the reason it did not parse at all.
|
|
71
|
-
(raw.startsWith("-") ? " A leading `-` reads as a flag, not a sign." : "")
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
if (value <= 0) {
|
|
75
|
-
throw new OptionError(`${what} must be greater than zero${spec.unit ? ` ${spec.unit}` : ""}.`);
|
|
76
|
-
}
|
|
77
|
-
if (spec.integer && !Number.isInteger(value)) {
|
|
78
|
-
throw new OptionError(`${what} must be a whole number.`);
|
|
79
|
-
}
|
|
80
|
-
return value;
|
|
81
|
-
}
|
|
82
|
-
function requiredNumericIn(argv2, name, fallback, spec = {}) {
|
|
83
|
-
return numericIn(argv2, name, { ...spec, fallback });
|
|
84
|
-
}
|
|
85
|
-
function secondsIn(argv2, name, fallbackSeconds) {
|
|
86
|
-
return requiredNumericIn(argv2, name, fallbackSeconds, { unit: "seconds" }) * 1e3;
|
|
87
|
-
}
|
|
88
|
-
var OptionError, flagIn, optIn;
|
|
89
|
-
var init_options = __esm({
|
|
90
|
-
"src/options.ts"() {
|
|
91
|
-
"use strict";
|
|
92
|
-
OptionError = class extends Error {
|
|
93
|
-
constructor(message) {
|
|
94
|
-
super(message);
|
|
95
|
-
this.name = "OptionError";
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
flagIn = (argv2, name) => argv2.includes(`--${name}`);
|
|
99
|
-
optIn = (argv2, name, fallback) => {
|
|
100
|
-
const i = argv2.indexOf(`--${name}`);
|
|
101
|
-
return i >= 0 && argv2[i + 1] && !argv2[i + 1].startsWith("--") ? argv2[i + 1] : fallback;
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
48
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
|
|
107
49
|
// @__NO_SIDE_EFFECTS__
|
|
108
50
|
function $constructor(name, initializer3, params) {
|
|
@@ -14032,17 +13974,17 @@ var init_schemas2 = __esm({
|
|
|
14032
13974
|
inst._zod.processJSONSchema = (ctx, json2, params) => arrayProcessor(inst, ctx, json2, params);
|
|
14033
13975
|
inst.element = def.element;
|
|
14034
13976
|
_installLazyMethods(inst, "ZodArray", {
|
|
14035
|
-
min(
|
|
14036
|
-
return this.check(_minLength(
|
|
13977
|
+
min(n2, params) {
|
|
13978
|
+
return this.check(_minLength(n2, params));
|
|
14037
13979
|
},
|
|
14038
13980
|
nonempty(params) {
|
|
14039
13981
|
return this.check(_minLength(1, params));
|
|
14040
13982
|
},
|
|
14041
|
-
max(
|
|
14042
|
-
return this.check(_maxLength(
|
|
13983
|
+
max(n2, params) {
|
|
13984
|
+
return this.check(_maxLength(n2, params));
|
|
14043
13985
|
},
|
|
14044
|
-
length(
|
|
14045
|
-
return this.check(_length(
|
|
13986
|
+
length(n2, params) {
|
|
13987
|
+
return this.check(_length(n2, params));
|
|
14046
13988
|
},
|
|
14047
13989
|
unwrap() {
|
|
14048
13990
|
return this.element;
|
|
@@ -15360,8 +15302,8 @@ var init_dist = __esm({
|
|
|
15360
15302
|
|
|
15361
15303
|
// ../../packages/mcp-kit/dist/env.js
|
|
15362
15304
|
function pick2(...names) {
|
|
15363
|
-
for (const
|
|
15364
|
-
const v = process.env[
|
|
15305
|
+
for (const n2 of names) {
|
|
15306
|
+
const v = process.env[n2];
|
|
15365
15307
|
if (v && v.trim())
|
|
15366
15308
|
return v.trim();
|
|
15367
15309
|
}
|
|
@@ -15581,9 +15523,9 @@ function __generator(thisArg, body) {
|
|
|
15581
15523
|
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
15582
15524
|
return this;
|
|
15583
15525
|
}), g;
|
|
15584
|
-
function verb(
|
|
15526
|
+
function verb(n2) {
|
|
15585
15527
|
return function(v) {
|
|
15586
|
-
return step([
|
|
15528
|
+
return step([n2, v]);
|
|
15587
15529
|
};
|
|
15588
15530
|
}
|
|
15589
15531
|
function step(op) {
|
|
@@ -15656,12 +15598,12 @@ function __values(o) {
|
|
|
15656
15598
|
};
|
|
15657
15599
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
15658
15600
|
}
|
|
15659
|
-
function __read(o,
|
|
15601
|
+
function __read(o, n2) {
|
|
15660
15602
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
15661
15603
|
if (!m) return o;
|
|
15662
15604
|
var i = m.call(o), r, ar = [], e;
|
|
15663
15605
|
try {
|
|
15664
|
-
while ((
|
|
15606
|
+
while ((n2 === void 0 || n2-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
15665
15607
|
} catch (error51) {
|
|
15666
15608
|
e = { error: error51 };
|
|
15667
15609
|
} finally {
|
|
@@ -15708,19 +15650,19 @@ function __asyncGenerator(thisArg, _arguments, generator) {
|
|
|
15708
15650
|
return Promise.resolve(v).then(f, reject);
|
|
15709
15651
|
};
|
|
15710
15652
|
}
|
|
15711
|
-
function verb(
|
|
15712
|
-
if (g[
|
|
15713
|
-
i[
|
|
15653
|
+
function verb(n2, f) {
|
|
15654
|
+
if (g[n2]) {
|
|
15655
|
+
i[n2] = function(v) {
|
|
15714
15656
|
return new Promise(function(a, b) {
|
|
15715
|
-
q.push([
|
|
15657
|
+
q.push([n2, v, a, b]) > 1 || resume(n2, v);
|
|
15716
15658
|
});
|
|
15717
15659
|
};
|
|
15718
|
-
if (f) i[
|
|
15660
|
+
if (f) i[n2] = f(i[n2]);
|
|
15719
15661
|
}
|
|
15720
15662
|
}
|
|
15721
|
-
function resume(
|
|
15663
|
+
function resume(n2, v) {
|
|
15722
15664
|
try {
|
|
15723
|
-
step(g[
|
|
15665
|
+
step(g[n2](v));
|
|
15724
15666
|
} catch (e) {
|
|
15725
15667
|
settle(q[0][3], e);
|
|
15726
15668
|
}
|
|
@@ -15745,9 +15687,9 @@ function __asyncDelegator(o) {
|
|
|
15745
15687
|
}), verb("return"), i[Symbol.iterator] = function() {
|
|
15746
15688
|
return this;
|
|
15747
15689
|
}, i;
|
|
15748
|
-
function verb(
|
|
15749
|
-
i[
|
|
15750
|
-
return (p = !p) ? { value: __await(o[
|
|
15690
|
+
function verb(n2, f) {
|
|
15691
|
+
i[n2] = o[n2] ? function(v) {
|
|
15692
|
+
return (p = !p) ? { value: __await(o[n2](v)), done: false } : f ? f(v) : v;
|
|
15751
15693
|
} : f;
|
|
15752
15694
|
}
|
|
15753
15695
|
}
|
|
@@ -15757,10 +15699,10 @@ function __asyncValues(o) {
|
|
|
15757
15699
|
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
|
|
15758
15700
|
return this;
|
|
15759
15701
|
}, i);
|
|
15760
|
-
function verb(
|
|
15761
|
-
i[
|
|
15702
|
+
function verb(n2) {
|
|
15703
|
+
i[n2] = o[n2] && function(v) {
|
|
15762
15704
|
return new Promise(function(resolve2, reject) {
|
|
15763
|
-
v = o[
|
|
15705
|
+
v = o[n2](v), settle(resolve2, reject, v.done, v.value);
|
|
15764
15706
|
});
|
|
15765
15707
|
};
|
|
15766
15708
|
}
|
|
@@ -15879,7 +15821,7 @@ var init_tslib_es6 = __esm({
|
|
|
15879
15821
|
};
|
|
15880
15822
|
__assign = function() {
|
|
15881
15823
|
__assign = Object.assign || function __assign2(t) {
|
|
15882
|
-
for (var s, i = 1,
|
|
15824
|
+
for (var s, i = 1, n2 = arguments.length; i < n2; i++) {
|
|
15883
15825
|
s = arguments[i];
|
|
15884
15826
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
15885
15827
|
}
|
|
@@ -31064,8 +31006,8 @@ var require_GoTrueClient = __commonJS({
|
|
|
31064
31006
|
const result = await this.initializePromise;
|
|
31065
31007
|
const queue = (_a3 = this._pendingInitNotifications) !== null && _a3 !== void 0 ? _a3 : [];
|
|
31066
31008
|
this._pendingInitNotifications = null;
|
|
31067
|
-
for (const
|
|
31068
|
-
await this._notifyAllSubscribers(
|
|
31009
|
+
for (const n2 of queue) {
|
|
31010
|
+
await this._notifyAllSubscribers(n2.event, n2.session, n2.broadcast);
|
|
31069
31011
|
}
|
|
31070
31012
|
return result;
|
|
31071
31013
|
}
|
|
@@ -39415,17 +39357,17 @@ var require_codegen = __commonJS({
|
|
|
39415
39357
|
this.nodes = nodes;
|
|
39416
39358
|
}
|
|
39417
39359
|
render(opts) {
|
|
39418
|
-
return this.nodes.reduce((code,
|
|
39360
|
+
return this.nodes.reduce((code, n2) => code + n2.render(opts), "");
|
|
39419
39361
|
}
|
|
39420
39362
|
optimizeNodes() {
|
|
39421
39363
|
const { nodes } = this;
|
|
39422
39364
|
let i = nodes.length;
|
|
39423
39365
|
while (i--) {
|
|
39424
|
-
const
|
|
39425
|
-
if (Array.isArray(
|
|
39426
|
-
nodes.splice(i, 1, ...
|
|
39427
|
-
else if (
|
|
39428
|
-
nodes[i] =
|
|
39366
|
+
const n2 = nodes[i].optimizeNodes();
|
|
39367
|
+
if (Array.isArray(n2))
|
|
39368
|
+
nodes.splice(i, 1, ...n2);
|
|
39369
|
+
else if (n2)
|
|
39370
|
+
nodes[i] = n2;
|
|
39429
39371
|
else
|
|
39430
39372
|
nodes.splice(i, 1);
|
|
39431
39373
|
}
|
|
@@ -39435,16 +39377,16 @@ var require_codegen = __commonJS({
|
|
|
39435
39377
|
const { nodes } = this;
|
|
39436
39378
|
let i = nodes.length;
|
|
39437
39379
|
while (i--) {
|
|
39438
|
-
const
|
|
39439
|
-
if (
|
|
39380
|
+
const n2 = nodes[i];
|
|
39381
|
+
if (n2.optimizeNames(names, constants))
|
|
39440
39382
|
continue;
|
|
39441
|
-
subtractNames(names,
|
|
39383
|
+
subtractNames(names, n2.names);
|
|
39442
39384
|
nodes.splice(i, 1);
|
|
39443
39385
|
}
|
|
39444
39386
|
return nodes.length > 0 ? this : void 0;
|
|
39445
39387
|
}
|
|
39446
39388
|
get names() {
|
|
39447
|
-
return this.nodes.reduce((names,
|
|
39389
|
+
return this.nodes.reduce((names, n2) => addNames(names, n2.names), {});
|
|
39448
39390
|
}
|
|
39449
39391
|
};
|
|
39450
39392
|
var BlockNode = class extends ParentNode {
|
|
@@ -39855,8 +39797,8 @@ var require_codegen = __commonJS({
|
|
|
39855
39797
|
endFunc() {
|
|
39856
39798
|
return this._endBlockNode(Func);
|
|
39857
39799
|
}
|
|
39858
|
-
optimize(
|
|
39859
|
-
while (
|
|
39800
|
+
optimize(n2 = 1) {
|
|
39801
|
+
while (n2-- > 0) {
|
|
39860
39802
|
this._root.optimizeNodes();
|
|
39861
39803
|
this._root.optimizeNames(this._root.names, this._constants);
|
|
39862
39804
|
}
|
|
@@ -39870,19 +39812,19 @@ var require_codegen = __commonJS({
|
|
|
39870
39812
|
this._nodes.push(node);
|
|
39871
39813
|
}
|
|
39872
39814
|
_endBlockNode(N1, N2) {
|
|
39873
|
-
const
|
|
39874
|
-
if (
|
|
39815
|
+
const n2 = this._currNode;
|
|
39816
|
+
if (n2 instanceof N1 || N2 && n2 instanceof N2) {
|
|
39875
39817
|
this._nodes.pop();
|
|
39876
39818
|
return this;
|
|
39877
39819
|
}
|
|
39878
39820
|
throw new Error(`CodeGen: not in block "${N2 ? `${N1.kind}/${N2.kind}` : N1.kind}"`);
|
|
39879
39821
|
}
|
|
39880
39822
|
_elseNode(node) {
|
|
39881
|
-
const
|
|
39882
|
-
if (!(
|
|
39823
|
+
const n2 = this._currNode;
|
|
39824
|
+
if (!(n2 instanceof If)) {
|
|
39883
39825
|
throw new Error('CodeGen: "else" without "if"');
|
|
39884
39826
|
}
|
|
39885
|
-
this._currNode =
|
|
39827
|
+
this._currNode = n2.else = node;
|
|
39886
39828
|
return this;
|
|
39887
39829
|
}
|
|
39888
39830
|
get _root() {
|
|
@@ -39899,8 +39841,8 @@ var require_codegen = __commonJS({
|
|
|
39899
39841
|
};
|
|
39900
39842
|
exports.CodeGen = CodeGen;
|
|
39901
39843
|
function addNames(names, from) {
|
|
39902
|
-
for (const
|
|
39903
|
-
names[
|
|
39844
|
+
for (const n2 in from)
|
|
39845
|
+
names[n2] = (names[n2] || 0) + (from[n2] || 0);
|
|
39904
39846
|
return names;
|
|
39905
39847
|
}
|
|
39906
39848
|
function addExprNames(names, from) {
|
|
@@ -39920,11 +39862,11 @@ var require_codegen = __commonJS({
|
|
|
39920
39862
|
items.push(c);
|
|
39921
39863
|
return items;
|
|
39922
39864
|
}, []));
|
|
39923
|
-
function replaceName(
|
|
39924
|
-
const c = constants[
|
|
39925
|
-
if (c === void 0 || names[
|
|
39926
|
-
return
|
|
39927
|
-
delete names[
|
|
39865
|
+
function replaceName(n2) {
|
|
39866
|
+
const c = constants[n2.str];
|
|
39867
|
+
if (c === void 0 || names[n2.str] !== 1)
|
|
39868
|
+
return n2;
|
|
39869
|
+
delete names[n2.str];
|
|
39928
39870
|
return c;
|
|
39929
39871
|
}
|
|
39930
39872
|
function canOptimize(e) {
|
|
@@ -39932,8 +39874,8 @@ var require_codegen = __commonJS({
|
|
|
39932
39874
|
}
|
|
39933
39875
|
}
|
|
39934
39876
|
function subtractNames(names, from) {
|
|
39935
|
-
for (const
|
|
39936
|
-
names[
|
|
39877
|
+
for (const n2 in from)
|
|
39878
|
+
names[n2] = (names[n2] || 0) - (from[n2] || 0);
|
|
39937
39879
|
}
|
|
39938
39880
|
function not(x) {
|
|
39939
39881
|
return typeof x == "boolean" || typeof x == "number" || x === null ? !x : (0, code_1._)`!${par(x)}`;
|
|
@@ -45949,6 +45891,64 @@ var init_dist7 = __esm({
|
|
|
45949
45891
|
}
|
|
45950
45892
|
});
|
|
45951
45893
|
|
|
45894
|
+
// src/options.ts
|
|
45895
|
+
function stripTokenFlag(argv2) {
|
|
45896
|
+
const at = argv2.indexOf("--token");
|
|
45897
|
+
if (at < 0) return [...argv2];
|
|
45898
|
+
return [...argv2.slice(0, at), ...argv2.slice(at + 2)];
|
|
45899
|
+
}
|
|
45900
|
+
function numericIn(argv2, name, spec = {}) {
|
|
45901
|
+
const i = argv2.indexOf(`--${name}`);
|
|
45902
|
+
if (i < 0) return spec.fallback;
|
|
45903
|
+
const raw = argv2[i + 1];
|
|
45904
|
+
if (raw === void 0 || raw.startsWith("--")) {
|
|
45905
|
+
throw new OptionError(
|
|
45906
|
+
`--${name} expects a ${spec.integer ? "whole " : ""}number${spec.unit ? ` of ${spec.unit}` : ""}, but no value followed it.`
|
|
45907
|
+
);
|
|
45908
|
+
}
|
|
45909
|
+
const value = raw.trim() === "" ? NaN : Number(raw);
|
|
45910
|
+
const what = `--${name} ${JSON.stringify(raw)}`;
|
|
45911
|
+
if (!Number.isFinite(value)) {
|
|
45912
|
+
throw new OptionError(
|
|
45913
|
+
`${what} is not a number.` + // Reached only by something like `-abc`. A plain `-5` is a finite
|
|
45914
|
+
// negative and falls to the range check below, which is the accurate
|
|
45915
|
+
// refusal for it — this hint is for the case where the leading dash is
|
|
45916
|
+
// the reason it did not parse at all.
|
|
45917
|
+
(raw.startsWith("-") ? " A leading `-` reads as a flag, not a sign." : "")
|
|
45918
|
+
);
|
|
45919
|
+
}
|
|
45920
|
+
if (value <= 0) {
|
|
45921
|
+
throw new OptionError(`${what} must be greater than zero${spec.unit ? ` ${spec.unit}` : ""}.`);
|
|
45922
|
+
}
|
|
45923
|
+
if (spec.integer && !Number.isInteger(value)) {
|
|
45924
|
+
throw new OptionError(`${what} must be a whole number.`);
|
|
45925
|
+
}
|
|
45926
|
+
return value;
|
|
45927
|
+
}
|
|
45928
|
+
function requiredNumericIn(argv2, name, fallback, spec = {}) {
|
|
45929
|
+
return numericIn(argv2, name, { ...spec, fallback });
|
|
45930
|
+
}
|
|
45931
|
+
function secondsIn(argv2, name, fallbackSeconds) {
|
|
45932
|
+
return requiredNumericIn(argv2, name, fallbackSeconds, { unit: "seconds" }) * 1e3;
|
|
45933
|
+
}
|
|
45934
|
+
var OptionError, flagIn, optIn;
|
|
45935
|
+
var init_options = __esm({
|
|
45936
|
+
"src/options.ts"() {
|
|
45937
|
+
"use strict";
|
|
45938
|
+
OptionError = class extends Error {
|
|
45939
|
+
constructor(message) {
|
|
45940
|
+
super(message);
|
|
45941
|
+
this.name = "OptionError";
|
|
45942
|
+
}
|
|
45943
|
+
};
|
|
45944
|
+
flagIn = (argv2, name) => argv2.includes(`--${name}`);
|
|
45945
|
+
optIn = (argv2, name, fallback) => {
|
|
45946
|
+
const i = argv2.indexOf(`--${name}`);
|
|
45947
|
+
return i >= 0 && argv2[i + 1] && !argv2[i + 1].startsWith("--") ? argv2[i + 1] : fallback;
|
|
45948
|
+
};
|
|
45949
|
+
}
|
|
45950
|
+
});
|
|
45951
|
+
|
|
45952
45952
|
// src/env.ts
|
|
45953
45953
|
function applyCloudDefaults() {
|
|
45954
45954
|
const url3 = process.env.SUPABASE_URL ?? process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
@@ -46001,6 +46001,21 @@ function childSession() {
|
|
|
46001
46001
|
const endpoint = sessionEndpoint();
|
|
46002
46002
|
return endpoint ? fetchDelegatedSession(endpoint, token) : mintDelegatedSession({ config: config2, token, product: "projects", mintedAt: MINTED_AT });
|
|
46003
46003
|
}
|
|
46004
|
+
async function contextOrExplain() {
|
|
46005
|
+
try {
|
|
46006
|
+
return await getContext();
|
|
46007
|
+
} catch (error51) {
|
|
46008
|
+
const label = process.env.CRUO_IDENTITY?.trim();
|
|
46009
|
+
if (!label) throw error51;
|
|
46010
|
+
throw new Error(
|
|
46011
|
+
`${error51 instanceof Error ? error51.message : String(error51)}
|
|
46012
|
+
|
|
46013
|
+
That is the token stored for \`${label}\`.
|
|
46014
|
+
Replace it: Cruo \u2192 Settings \u2192 Members \u2192 ${label} \u2192 new token,
|
|
46015
|
+
then: cruo login <token> --as ${label}`
|
|
46016
|
+
);
|
|
46017
|
+
}
|
|
46018
|
+
}
|
|
46004
46019
|
var stdioResolver;
|
|
46005
46020
|
var init_auth = __esm({
|
|
46006
46021
|
"src/auth.ts"() {
|
|
@@ -46012,6 +46027,176 @@ var init_auth = __esm({
|
|
|
46012
46027
|
}
|
|
46013
46028
|
});
|
|
46014
46029
|
|
|
46030
|
+
// src/usage.ts
|
|
46031
|
+
var usage_exports = {};
|
|
46032
|
+
__export(usage_exports, {
|
|
46033
|
+
reportUsage: () => reportUsage
|
|
46034
|
+
});
|
|
46035
|
+
function compact(value) {
|
|
46036
|
+
if (value === 0) return "\u2014";
|
|
46037
|
+
if (value >= 1e6) return `${(value / 1e6).toFixed(2)}M`;
|
|
46038
|
+
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
|
|
46039
|
+
return String(value);
|
|
46040
|
+
}
|
|
46041
|
+
async function reportUsage(opts) {
|
|
46042
|
+
const ctx = await contextOrExplain();
|
|
46043
|
+
const since = new Date(Date.now() - opts.days * 864e5).toISOString();
|
|
46044
|
+
let query = ctx.client.from("harness_runs").select("*").gte("started_at", since).order("started_at", { ascending: false });
|
|
46045
|
+
let issueTitle = null;
|
|
46046
|
+
if (opts.issue) {
|
|
46047
|
+
const [key, num3] = opts.issue.split("-");
|
|
46048
|
+
const { data: project } = await ctx.client.from("projects").select("id").eq("key", (key ?? "").toUpperCase()).maybeSingle();
|
|
46049
|
+
const { data: issue2 } = project ? await ctx.client.from("issues").select("id, title").eq("project_id", project.id).eq("number", Number(num3)).maybeSingle() : { data: null };
|
|
46050
|
+
if (!issue2) {
|
|
46051
|
+
console.error(`
|
|
46052
|
+
No issue ${opts.issue} on this board.
|
|
46053
|
+
`);
|
|
46054
|
+
process.exit(2);
|
|
46055
|
+
}
|
|
46056
|
+
issueTitle = issue2.title;
|
|
46057
|
+
query = query.eq("issue_id", issue2.id);
|
|
46058
|
+
}
|
|
46059
|
+
const { data, error: error51 } = await query;
|
|
46060
|
+
if (error51) {
|
|
46061
|
+
console.error(`
|
|
46062
|
+
Could not read run costs: ${error51.message}
|
|
46063
|
+
`);
|
|
46064
|
+
process.exit(1);
|
|
46065
|
+
}
|
|
46066
|
+
const rows = data ?? [];
|
|
46067
|
+
console.log(
|
|
46068
|
+
`
|
|
46069
|
+
${opts.issue ? `${opts.issue} \u2014 ${issueTitle}` : ctx.workspaceName} \xB7 last ${opts.days} day${opts.days === 1 ? "" : "s"}`
|
|
46070
|
+
);
|
|
46071
|
+
if (rows.length === 0) {
|
|
46072
|
+
console.log(
|
|
46073
|
+
`
|
|
46074
|
+
No runs recorded. Either no agent has run in that window, or the runs
|
|
46075
|
+
predate cost recording (\`CRA-89\`, 2026-08-29).
|
|
46076
|
+
`
|
|
46077
|
+
);
|
|
46078
|
+
return;
|
|
46079
|
+
}
|
|
46080
|
+
const ids = [...new Set(rows.map((r) => r.agent_id))];
|
|
46081
|
+
const { data: people } = await ctx.client.schema("public").from("profiles").select("id, display_name, email").in("id", ids);
|
|
46082
|
+
const nameOf = (id) => {
|
|
46083
|
+
const p = (people ?? []).find((x) => x.id === id);
|
|
46084
|
+
return p?.display_name || p?.email || id.slice(0, 8);
|
|
46085
|
+
};
|
|
46086
|
+
const blank = () => ({
|
|
46087
|
+
runs: 0,
|
|
46088
|
+
productive: 0,
|
|
46089
|
+
neverRan: 0,
|
|
46090
|
+
ms: 0,
|
|
46091
|
+
bytes: 0,
|
|
46092
|
+
input: 0,
|
|
46093
|
+
output: 0,
|
|
46094
|
+
cacheRead: 0,
|
|
46095
|
+
cacheWrite: 0,
|
|
46096
|
+
cost: 0,
|
|
46097
|
+
measured: 0
|
|
46098
|
+
});
|
|
46099
|
+
const fold = (a, r) => {
|
|
46100
|
+
a.runs += 1;
|
|
46101
|
+
if (r.outcome === "productive") a.productive += 1;
|
|
46102
|
+
if (r.outcome === "never-ran") a.neverRan += 1;
|
|
46103
|
+
a.ms += r.duration_ms;
|
|
46104
|
+
a.bytes += n(r.stdout_bytes);
|
|
46105
|
+
a.input += n(r.input_tokens);
|
|
46106
|
+
a.output += n(r.output_tokens);
|
|
46107
|
+
a.cacheRead += n(r.cache_read_tokens);
|
|
46108
|
+
a.cacheWrite += n(r.cache_write_tokens);
|
|
46109
|
+
a.cost += n(r.cost_usd);
|
|
46110
|
+
if (r.input_tokens !== null || r.cost_usd !== null) a.measured += 1;
|
|
46111
|
+
};
|
|
46112
|
+
const byAgent = /* @__PURE__ */ new Map();
|
|
46113
|
+
const total = blank();
|
|
46114
|
+
for (const r of rows) {
|
|
46115
|
+
if (!byAgent.has(r.agent_id)) byAgent.set(r.agent_id, blank());
|
|
46116
|
+
fold(byAgent.get(r.agent_id), r);
|
|
46117
|
+
fold(total, r);
|
|
46118
|
+
}
|
|
46119
|
+
const w = Math.max(12, ...[...byAgent.keys()].map((id) => nameOf(id).length));
|
|
46120
|
+
console.log(
|
|
46121
|
+
`
|
|
46122
|
+
${pad("agent", w)} ${rpad("runs", 5)} ${rpad("useful", 7)} ${rpad("dead", 5)} ${rpad("time", 7)} ${rpad("in", 8)} ${rpad("out", 8)} ${rpad("cost", 9)}`
|
|
46123
|
+
);
|
|
46124
|
+
for (const [id, a] of [...byAgent].sort((x, y) => y[1].runs - x[1].runs)) {
|
|
46125
|
+
console.log(
|
|
46126
|
+
` ${pad(nameOf(id), w)} ${rpad(String(a.runs), 5)} ${rpad(String(a.productive), 7)} ${rpad(String(a.neverRan), 5)} ${rpad(duration3(a.ms), 7)} ${rpad(compact(a.input + a.cacheRead), 8)} ${rpad(compact(a.output), 8)} ${rpad(a.cost > 0 ? `$${a.cost.toFixed(2)}` : "\u2014", 9)}`
|
|
46127
|
+
);
|
|
46128
|
+
}
|
|
46129
|
+
if (!opts.issue) {
|
|
46130
|
+
const byIssue = /* @__PURE__ */ new Map();
|
|
46131
|
+
for (const r of rows) {
|
|
46132
|
+
if (!r.issue_id) continue;
|
|
46133
|
+
if (!byIssue.has(r.issue_id)) byIssue.set(r.issue_id, blank());
|
|
46134
|
+
fold(byIssue.get(r.issue_id), r);
|
|
46135
|
+
}
|
|
46136
|
+
const worst = [...byIssue].sort((x, y) => y[1].runs - x[1].runs).slice(0, 8);
|
|
46137
|
+
if (worst.length > 0) {
|
|
46138
|
+
const { data: issues } = await ctx.client.from("issues").select("id, number, title, project_id").in("id", worst.map(([id]) => id));
|
|
46139
|
+
const { data: projects } = await ctx.client.from("projects").select("id, key");
|
|
46140
|
+
const refOf = (id) => {
|
|
46141
|
+
const i = (issues ?? []).find((x) => x.id === id);
|
|
46142
|
+
if (!i) return id.slice(0, 8);
|
|
46143
|
+
const key = (projects ?? []).find((p) => p.id === i.project_id)?.key ?? "?";
|
|
46144
|
+
return `${key}-${i.number}`;
|
|
46145
|
+
};
|
|
46146
|
+
const titleOf = (id) => (issues ?? []).find((x) => x.id === id)?.title ?? "";
|
|
46147
|
+
console.log(`
|
|
46148
|
+
most-worked cards`);
|
|
46149
|
+
for (const [id, a] of worst) {
|
|
46150
|
+
console.log(
|
|
46151
|
+
` ${rpad(String(a.runs), 3)} run${a.runs === 1 ? " " : "s"} ${pad(refOf(id), 8)} ${rpad(duration3(a.ms), 6)} ${titleOf(id).slice(0, 52)}`
|
|
46152
|
+
);
|
|
46153
|
+
}
|
|
46154
|
+
}
|
|
46155
|
+
} else {
|
|
46156
|
+
console.log(`
|
|
46157
|
+
run by run`);
|
|
46158
|
+
for (const r of rows) {
|
|
46159
|
+
console.log(
|
|
46160
|
+
` ${r.started_at.slice(0, 16).replace("T", " ")} ${pad(r.outcome, 13)} ${rpad(duration3(r.duration_ms), 6)} ${rpad(compact(n(r.output_tokens)), 7)} out ${nameOf(r.agent_id)}`
|
|
46161
|
+
);
|
|
46162
|
+
}
|
|
46163
|
+
}
|
|
46164
|
+
console.log(
|
|
46165
|
+
`
|
|
46166
|
+
${total.runs} run(s), ${total.productive} productive, ${total.neverRan} never reached a model.
|
|
46167
|
+
${duration3(total.ms)} of wall clock, ${compact(total.bytes)} bytes of output.`
|
|
46168
|
+
);
|
|
46169
|
+
if (total.measured === 0) {
|
|
46170
|
+
console.log(
|
|
46171
|
+
`
|
|
46172
|
+
No token or cost figures: this harness does not report them. Runs, time and
|
|
46173
|
+
output are measured for any harness; tokens need one that says what it spent \u2014
|
|
46174
|
+
e.g. --harness "claude -p --output-format json".
|
|
46175
|
+
`
|
|
46176
|
+
);
|
|
46177
|
+
} else if (total.measured < total.runs) {
|
|
46178
|
+
console.log(
|
|
46179
|
+
`
|
|
46180
|
+
${total.measured} of ${total.runs} runs reported tokens; the rest did not, so the
|
|
46181
|
+
figures above are a floor rather than a total.
|
|
46182
|
+
`
|
|
46183
|
+
);
|
|
46184
|
+
} else {
|
|
46185
|
+
console.log("");
|
|
46186
|
+
}
|
|
46187
|
+
}
|
|
46188
|
+
var n, pad, rpad, duration3;
|
|
46189
|
+
var init_usage = __esm({
|
|
46190
|
+
"src/usage.ts"() {
|
|
46191
|
+
"use strict";
|
|
46192
|
+
init_auth();
|
|
46193
|
+
n = (v) => v === null || v === void 0 ? 0 : Number(v);
|
|
46194
|
+
pad = (s, w) => s.padEnd(w);
|
|
46195
|
+
rpad = (s, w) => s.padStart(w);
|
|
46196
|
+
duration3 = (ms2) => ms2 >= 36e5 ? `${(ms2 / 36e5).toFixed(1)}h` : ms2 >= 6e4 ? `${(ms2 / 6e4).toFixed(1)}m` : `${Math.round(ms2 / 1e3)}s`;
|
|
46197
|
+
}
|
|
46198
|
+
});
|
|
46199
|
+
|
|
46015
46200
|
// src/harness-signal.ts
|
|
46016
46201
|
function refusalIn(stdout) {
|
|
46017
46202
|
if (!stdout.trim()) return null;
|
|
@@ -46023,7 +46208,36 @@ function refusalIn(stdout) {
|
|
|
46023
46208
|
function neverRan(run) {
|
|
46024
46209
|
return run.refusal !== null || run.stdoutBytes === 0;
|
|
46025
46210
|
}
|
|
46026
|
-
|
|
46211
|
+
function usageIn(text) {
|
|
46212
|
+
const trimmed = text.trimEnd();
|
|
46213
|
+
if (!trimmed.endsWith("}")) return null;
|
|
46214
|
+
let parsed = null;
|
|
46215
|
+
for (let i = trimmed.length - 1; i >= 0; i -= 1) {
|
|
46216
|
+
if (trimmed[i] !== "{") continue;
|
|
46217
|
+
try {
|
|
46218
|
+
parsed = JSON.parse(trimmed.slice(i));
|
|
46219
|
+
break;
|
|
46220
|
+
} catch {
|
|
46221
|
+
}
|
|
46222
|
+
}
|
|
46223
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
46224
|
+
const root = parsed;
|
|
46225
|
+
const usage = root.usage ?? root;
|
|
46226
|
+
const out = {
|
|
46227
|
+
model: typeof root.model === "string" ? root.model : void 0,
|
|
46228
|
+
// Both spellings. The snake_case ones are the API's; a harness that passes
|
|
46229
|
+
// its response through unchanged emits those, and one that tidies them
|
|
46230
|
+
// emits camelCase.
|
|
46231
|
+
inputTokens: num(usage.input_tokens) ?? num(usage.inputTokens),
|
|
46232
|
+
outputTokens: num(usage.output_tokens) ?? num(usage.outputTokens),
|
|
46233
|
+
cacheReadTokens: num(usage.cache_read_input_tokens) ?? num(usage.cacheReadInputTokens),
|
|
46234
|
+
cacheWriteTokens: num(usage.cache_creation_input_tokens) ?? num(usage.cacheCreationInputTokens),
|
|
46235
|
+
costUsd: num(root.total_cost_usd) ?? num(root.totalCostUsd) ?? num(root.cost_usd)
|
|
46236
|
+
};
|
|
46237
|
+
const measured = Object.values(out).some((v) => v !== void 0);
|
|
46238
|
+
return measured ? out : null;
|
|
46239
|
+
}
|
|
46240
|
+
var REFUSALS, num;
|
|
46027
46241
|
var init_harness_signal = __esm({
|
|
46028
46242
|
"src/harness-signal.ts"() {
|
|
46029
46243
|
"use strict";
|
|
@@ -46034,6 +46248,47 @@ var init_harness_signal = __esm({
|
|
|
46034
46248
|
[/invalid api key|authentication[_ ]error|please run \/login/i, "the harness is not signed in"],
|
|
46035
46249
|
[/rate limit(ed| exceeded|s? reached)\b.*\btry again/i, "the account is rate limited"]
|
|
46036
46250
|
];
|
|
46251
|
+
num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
46252
|
+
}
|
|
46253
|
+
});
|
|
46254
|
+
|
|
46255
|
+
// src/pacing.ts
|
|
46256
|
+
function afterAttempt(p, attempt, limits, now) {
|
|
46257
|
+
const allDead = attempt.invoked > 0 && attempt.failedToRun === attempt.invoked;
|
|
46258
|
+
const deadTicks = allDead ? p.deadTicks + 1 : 0;
|
|
46259
|
+
if (deadTicks < 2) {
|
|
46260
|
+
return {
|
|
46261
|
+
next: { deadTicks, invokeAfter: 0, backedOff: false },
|
|
46262
|
+
event: p.backedOff ? "recovered" : null,
|
|
46263
|
+
cooldownMs: 0
|
|
46264
|
+
};
|
|
46265
|
+
}
|
|
46266
|
+
const cooldownMs = Math.min(
|
|
46267
|
+
limits.intervalMs * 2 ** (deadTicks - 1),
|
|
46268
|
+
limits.maxIntervalMs
|
|
46269
|
+
);
|
|
46270
|
+
return {
|
|
46271
|
+
next: { deadTicks, invokeAfter: now + cooldownMs, backedOff: true },
|
|
46272
|
+
// Said once per descent, not once per tick. The ceiling is reached in a few
|
|
46273
|
+
// ticks and held for hours; repeating the line there would bury the
|
|
46274
|
+
// `recovered` that matters.
|
|
46275
|
+
event: p.backedOff ? null : "backing-off",
|
|
46276
|
+
cooldownMs
|
|
46277
|
+
};
|
|
46278
|
+
}
|
|
46279
|
+
var freshPacing, allowanceAt;
|
|
46280
|
+
var init_pacing = __esm({
|
|
46281
|
+
"src/pacing.ts"() {
|
|
46282
|
+
"use strict";
|
|
46283
|
+
freshPacing = () => ({
|
|
46284
|
+
deadTicks: 0,
|
|
46285
|
+
invokeAfter: 0,
|
|
46286
|
+
backedOff: false
|
|
46287
|
+
});
|
|
46288
|
+
allowanceAt = (p, now) => {
|
|
46289
|
+
if (!p.backedOff) return "free";
|
|
46290
|
+
return now >= p.invokeAfter ? "probe" : "held";
|
|
46291
|
+
};
|
|
46037
46292
|
}
|
|
46038
46293
|
});
|
|
46039
46294
|
|
|
@@ -46264,10 +46519,10 @@ async function pollMentions(ctx, identity) {
|
|
|
46264
46519
|
if (error51) throw new Error(`Mention poll failed: ${error51.message}`);
|
|
46265
46520
|
if (!notes || notes.length === 0) return [];
|
|
46266
46521
|
const byIssue = /* @__PURE__ */ new Map();
|
|
46267
|
-
for (const
|
|
46268
|
-
const list = byIssue.get(
|
|
46269
|
-
list.push(
|
|
46270
|
-
byIssue.set(
|
|
46522
|
+
for (const n2 of notes) {
|
|
46523
|
+
const list = byIssue.get(n2.issue_id) ?? [];
|
|
46524
|
+
list.push(n2.id);
|
|
46525
|
+
byIssue.set(n2.issue_id, list);
|
|
46271
46526
|
}
|
|
46272
46527
|
const { data: issues, error: issueErr } = await ctx.client.from("issues").select("*").in("id", [...byIssue.keys()]);
|
|
46273
46528
|
if (issueErr) throw new Error(`Mention issue lookup failed: ${issueErr.message}`);
|
|
@@ -46551,11 +46806,14 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
46551
46806
|
cwd,
|
|
46552
46807
|
env: harnessEnv()
|
|
46553
46808
|
});
|
|
46809
|
+
const startedAtMs = Date.now();
|
|
46554
46810
|
let stdoutBytes = 0;
|
|
46811
|
+
let tail = "";
|
|
46555
46812
|
let head2 = "";
|
|
46556
46813
|
child.stdout?.on("data", (c) => {
|
|
46557
46814
|
stdoutBytes += c.length;
|
|
46558
46815
|
if (head2.length < 2048) head2 += c.toString("utf8").slice(0, 2048 - head2.length);
|
|
46816
|
+
tail = (tail + c.toString("utf8")).slice(-4096);
|
|
46559
46817
|
process.stdout.write(c);
|
|
46560
46818
|
});
|
|
46561
46819
|
child.stderr?.on("data", (c) => process.stderr.write(c));
|
|
@@ -46567,11 +46825,23 @@ async function invokeHarness(ctx, identity, hit, worktree) {
|
|
|
46567
46825
|
child.on("error", (e) => {
|
|
46568
46826
|
clearTimeout(timer);
|
|
46569
46827
|
log(` harness failed to start: ${e.message}`);
|
|
46570
|
-
resolve2({
|
|
46828
|
+
resolve2({
|
|
46829
|
+
code: 127,
|
|
46830
|
+
stdoutBytes,
|
|
46831
|
+
refusal: refusalIn(head2),
|
|
46832
|
+
durationMs: Date.now() - startedAtMs,
|
|
46833
|
+
usage: null
|
|
46834
|
+
});
|
|
46571
46835
|
});
|
|
46572
46836
|
child.on("close", (code) => {
|
|
46573
46837
|
clearTimeout(timer);
|
|
46574
|
-
resolve2({
|
|
46838
|
+
resolve2({
|
|
46839
|
+
code: code ?? 1,
|
|
46840
|
+
stdoutBytes,
|
|
46841
|
+
refusal: refusalIn(head2),
|
|
46842
|
+
durationMs: Date.now() - startedAtMs,
|
|
46843
|
+
usage: usageIn(tail)
|
|
46844
|
+
});
|
|
46575
46845
|
});
|
|
46576
46846
|
});
|
|
46577
46847
|
} finally {
|
|
@@ -46654,7 +46924,29 @@ async function beat(ctx, fields) {
|
|
|
46654
46924
|
);
|
|
46655
46925
|
if (error51) log(` could not record a heartbeat: ${error51.message}`);
|
|
46656
46926
|
}
|
|
46657
|
-
async function
|
|
46927
|
+
async function recordRun(ctx, hit, run, outcome) {
|
|
46928
|
+
const { error: error51 } = await ctx.client.from("harness_runs").insert({
|
|
46929
|
+
agent_id: ctx.userId,
|
|
46930
|
+
workspace_id: ctx.workspaceId,
|
|
46931
|
+
issue_id: hit.issue.id,
|
|
46932
|
+
reason: hit.reason,
|
|
46933
|
+
duration_ms: run.durationMs,
|
|
46934
|
+
exit_code: run.code,
|
|
46935
|
+
stdout_bytes: run.stdoutBytes,
|
|
46936
|
+
outcome,
|
|
46937
|
+
model: run.usage?.model ?? null,
|
|
46938
|
+
input_tokens: run.usage?.inputTokens ?? null,
|
|
46939
|
+
output_tokens: run.usage?.outputTokens ?? null,
|
|
46940
|
+
cache_read_tokens: run.usage?.cacheReadTokens ?? null,
|
|
46941
|
+
cache_write_tokens: run.usage?.cacheWriteTokens ?? null,
|
|
46942
|
+
cost_usd: run.usage?.costUsd ?? null
|
|
46943
|
+
});
|
|
46944
|
+
if (error51 && !warnedAboutSpendTable) {
|
|
46945
|
+
warnedAboutSpendTable = true;
|
|
46946
|
+
log(` (not recording run costs: ${error51.message})`);
|
|
46947
|
+
}
|
|
46948
|
+
}
|
|
46949
|
+
async function tick(ctx, identity, deadTicks, allowance) {
|
|
46658
46950
|
const mentions = await pollMentions(ctx, identity);
|
|
46659
46951
|
const [assigned, stateWork] = await Promise.all([pollAssigned(ctx), poll(ctx, identity)]);
|
|
46660
46952
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -46675,7 +46967,20 @@ async function tick(ctx, identity, deadTicks) {
|
|
|
46675
46967
|
if (free.length > 0) log(`${free.length} issue(s) waiting, all set aside`);
|
|
46676
46968
|
else if (heldByOthers.size > 0) log(`nothing free \u2014 everything waiting is claimed`);
|
|
46677
46969
|
await beat(ctx, { holding: 0, deadTicks, intervalMs: options.intervalMs });
|
|
46678
|
-
return { invoked: 0, failedToRun: 0 };
|
|
46970
|
+
return { invoked: 0, failedToRun: 0, suppressed: false, waiting: 0 };
|
|
46971
|
+
}
|
|
46972
|
+
if (allowance === "held") {
|
|
46973
|
+
await beat(ctx, {
|
|
46974
|
+
holding: actionable.length,
|
|
46975
|
+
deadTicks,
|
|
46976
|
+
intervalMs: options.intervalMs
|
|
46977
|
+
});
|
|
46978
|
+
return {
|
|
46979
|
+
invoked: 0,
|
|
46980
|
+
failedToRun: 0,
|
|
46981
|
+
suppressed: true,
|
|
46982
|
+
waiting: actionable.length
|
|
46983
|
+
};
|
|
46679
46984
|
}
|
|
46680
46985
|
await beat(ctx, {
|
|
46681
46986
|
holding: actionable.length,
|
|
@@ -46688,9 +46993,12 @@ async function tick(ctx, identity, deadTicks) {
|
|
|
46688
46993
|
log(
|
|
46689
46994
|
`${actionable.length} issue(s) for "${identity.jobFunction}"` + (mentionCount > 0 ? ` \u2014 ${mentionCount} from unread mentions` : "")
|
|
46690
46995
|
);
|
|
46691
|
-
const
|
|
46996
|
+
const cap = allowance === "probe" ? 1 : options.limit;
|
|
46997
|
+
const taking = cap ? actionable.slice(0, cap) : actionable;
|
|
46692
46998
|
if (taking.length < actionable.length) {
|
|
46693
|
-
log(
|
|
46999
|
+
log(
|
|
47000
|
+
allowance === "probe" ? ` probing with ${taking.length} of ${actionable.length} \u2014 one card is enough to learn whether the harness works again` : ` taking ${taking.length} this tick (--limit ${options.limit})`
|
|
47001
|
+
);
|
|
46694
47002
|
}
|
|
46695
47003
|
for (const hit of taking) {
|
|
46696
47004
|
const why = hit.reason === "mention" ? "mentioned" : hit.reason === "assigned" ? `assigned \xB7 ${hit.state.name}` : hit.state.name;
|
|
@@ -46730,6 +47038,7 @@ async function tick(ctx, identity, deadTicks) {
|
|
|
46730
47038
|
const code = run.code;
|
|
46731
47039
|
if (neverRan(run)) {
|
|
46732
47040
|
failedToRun += 1;
|
|
47041
|
+
await recordRun(ctx, hit, run, "never-ran");
|
|
46733
47042
|
if (run.refusal) {
|
|
46734
47043
|
if (run.refusal !== lastRefusal) {
|
|
46735
47044
|
log(`! the harness is refusing to work: ${run.refusal}`);
|
|
@@ -46746,6 +47055,7 @@ async function tick(ctx, identity, deadTicks) {
|
|
|
46746
47055
|
const { data: after } = await ctx.client.from("issues").select("status_id, assignee_id").eq("id", hit.issue.id).maybeSingle();
|
|
46747
47056
|
const moved = !after || after.status_id !== before.status || after.assignee_id !== before.assignee;
|
|
46748
47057
|
const productive = hit.reason === "mention" ? await repliedSince(ctx, hit, startedAt) || moved : moved || committed > 0;
|
|
47058
|
+
await recordRun(ctx, hit, run, productive ? "productive" : "unproductive");
|
|
46749
47059
|
if (productive) {
|
|
46750
47060
|
await clearAttempts(ctx, hit);
|
|
46751
47061
|
if (hit.reason === "mention") {
|
|
@@ -46761,9 +47071,9 @@ async function tick(ctx, identity, deadTicks) {
|
|
|
46761
47071
|
}
|
|
46762
47072
|
} else {
|
|
46763
47073
|
const what = hit.reason === "mention" ? "no reply written" : "unchanged";
|
|
46764
|
-
const
|
|
47074
|
+
const n2 = await recordAttempt(ctx, hit, `${what} (exit ${code})`, attemptsFor(hit));
|
|
46765
47075
|
log(
|
|
46766
|
-
` ${hit.ref} ${what} after the run (exit ${code}) \u2014 attempt ${
|
|
47076
|
+
` ${hit.ref} ${what} after the run (exit ${code}) \u2014 attempt ${n2}/${options.maxAttempts}` + (n2 >= options.maxAttempts ? "; setting it aside, a human should look" : "")
|
|
46767
47077
|
);
|
|
46768
47078
|
}
|
|
46769
47079
|
if (worktree) {
|
|
@@ -46788,7 +47098,7 @@ async function tick(ctx, identity, deadTicks) {
|
|
|
46788
47098
|
deadTicks: allDead ? deadTicks + 1 : 0,
|
|
46789
47099
|
intervalMs: options.intervalMs
|
|
46790
47100
|
});
|
|
46791
|
-
return { invoked, failedToRun };
|
|
47101
|
+
return { invoked, failedToRun, suppressed: false, waiting: actionable.length };
|
|
46792
47102
|
}
|
|
46793
47103
|
async function main() {
|
|
46794
47104
|
log(
|
|
@@ -46801,7 +47111,7 @@ async function main() {
|
|
|
46801
47111
|
if (staleConfigs > 0) {
|
|
46802
47112
|
log(` cleared ${staleConfigs} temp config(s) left by a killed run`);
|
|
46803
47113
|
}
|
|
46804
|
-
const ctx = await
|
|
47114
|
+
const ctx = await contextOrExplain();
|
|
46805
47115
|
const identity = await identify(ctx);
|
|
46806
47116
|
try {
|
|
46807
47117
|
await preflight();
|
|
@@ -46848,24 +47158,45 @@ async function main() {
|
|
|
46848
47158
|
log(
|
|
46849
47159
|
options.once ? "single pass" : `polling every ${options.intervalMs / 1e3}s \xB7 ctrl-c to stop`
|
|
46850
47160
|
);
|
|
46851
|
-
let
|
|
47161
|
+
let pacing = freshPacing();
|
|
47162
|
+
let lastHeldLog = 0;
|
|
46852
47163
|
for (; ; ) {
|
|
46853
47164
|
try {
|
|
46854
|
-
const result = await tick(
|
|
46855
|
-
|
|
46856
|
-
|
|
47165
|
+
const result = await tick(
|
|
47166
|
+
await getContext(),
|
|
47167
|
+
identity,
|
|
47168
|
+
pacing.deadTicks,
|
|
47169
|
+
allowanceAt(pacing, Date.now())
|
|
47170
|
+
);
|
|
47171
|
+
if (result.suppressed) {
|
|
47172
|
+
const now = Date.now();
|
|
47173
|
+
if (now - lastHeldLog >= 6e4) {
|
|
47174
|
+
lastHeldLog = now;
|
|
47175
|
+
const left = Math.max(0, Math.round((pacing.invokeAfter - now) / 1e3));
|
|
47176
|
+
log(
|
|
47177
|
+
`! ${result.waiting} issue(s) waiting \u2014 not invoking after ${pacing.deadTicks} dead ticks; next attempt in ${left}s`
|
|
47178
|
+
);
|
|
47179
|
+
}
|
|
47180
|
+
} else {
|
|
47181
|
+
const step = afterAttempt(pacing, result, options, Date.now());
|
|
47182
|
+
pacing = step.next;
|
|
47183
|
+
if (step.event === "backing-off") {
|
|
47184
|
+
lastHeldLog = Date.now();
|
|
47185
|
+
log(
|
|
47186
|
+
` backing off \u2014 ${pacing.deadTicks} ticks with nothing reaching a model; still polling every ${options.intervalMs / 1e3}s, next invocation in ${step.cooldownMs / 1e3}s`
|
|
47187
|
+
);
|
|
47188
|
+
} else if (step.event === "recovered") {
|
|
47189
|
+
log(` recovered \u2014 a run reached a model; invoking normally again`);
|
|
47190
|
+
}
|
|
47191
|
+
}
|
|
46857
47192
|
} catch (e) {
|
|
46858
47193
|
log(`poll error: ${e instanceof Error ? e.message : String(e)}`);
|
|
46859
47194
|
}
|
|
46860
47195
|
if (options.once) return;
|
|
46861
|
-
|
|
46862
|
-
if (wait !== options.intervalMs) {
|
|
46863
|
-
log(` backing off \u2014 ${deadTicks} ticks with nothing reaching a model; next in ${wait / 1e3}s`);
|
|
46864
|
-
}
|
|
46865
|
-
await new Promise((r) => setTimeout(r, wait));
|
|
47196
|
+
await new Promise((r) => setTimeout(r, options.intervalMs));
|
|
46866
47197
|
}
|
|
46867
47198
|
}
|
|
46868
|
-
var argv, flag, opt,
|
|
47199
|
+
var argv, flag, opt, num2, ms, readOptions, options, log, worktreeConfig, lastRefusal, PRIORITY_RANK, CONFIG_DIR_PREFIX, CRUO_OWNED_ENV, warnedAboutSpendTable;
|
|
46869
47200
|
var init_supervisor = __esm({
|
|
46870
47201
|
"src/supervisor.ts"() {
|
|
46871
47202
|
"use strict";
|
|
@@ -46875,11 +47206,12 @@ var init_supervisor = __esm({
|
|
|
46875
47206
|
init_auth();
|
|
46876
47207
|
init_options();
|
|
46877
47208
|
init_harness_signal();
|
|
47209
|
+
init_pacing();
|
|
46878
47210
|
init_worktree();
|
|
46879
47211
|
argv = process.argv.slice(2);
|
|
46880
47212
|
flag = (name) => flagIn(argv, name);
|
|
46881
47213
|
opt = (name, fallback) => optIn(argv, name, fallback);
|
|
46882
|
-
|
|
47214
|
+
num2 = (name, spec) => numericIn(argv, name, spec);
|
|
46883
47215
|
ms = (name, fallbackSeconds) => secondsIn(argv, name, fallbackSeconds);
|
|
46884
47216
|
readOptions = () => ({
|
|
46885
47217
|
/** Override the function to poll for. Defaults to this agent's own. */
|
|
@@ -46895,7 +47227,7 @@ var init_supervisor = __esm({
|
|
|
46895
47227
|
* moment they have the least reason to trust three. Unset means all of them,
|
|
46896
47228
|
* which is the right steady-state behaviour.
|
|
46897
47229
|
*/
|
|
46898
|
-
limit:
|
|
47230
|
+
limit: num2("limit", { integer: true }),
|
|
46899
47231
|
intervalMs: ms("interval", 20),
|
|
46900
47232
|
once: flag("once"),
|
|
46901
47233
|
dryRun: flag("dry-run"),
|
|
@@ -46925,11 +47257,15 @@ var init_supervisor = __esm({
|
|
|
46925
47257
|
* `pm.issue_attempts` since CRA-7 — it was in-memory, which meant a restart
|
|
46926
47258
|
* forgot every set-aside and nothing outside the process could see one.
|
|
46927
47259
|
*/
|
|
46928
|
-
maxAttempts:
|
|
47260
|
+
maxAttempts: num2("max-attempts", { fallback: 3, integer: true }),
|
|
46929
47261
|
/**
|
|
46930
|
-
* Ceiling
|
|
46931
|
-
*
|
|
46932
|
-
* the cause is noticed without restarting
|
|
47262
|
+
* Ceiling on how long invocation is held back after a run of dead ticks.
|
|
47263
|
+
* Ten minutes: long enough that a broken harness stops being spawned over and
|
|
47264
|
+
* over, short enough that fixing the cause is noticed without restarting
|
|
47265
|
+
* anything.
|
|
47266
|
+
*
|
|
47267
|
+
* It is not a poll ceiling. Polling stays at `--interval` throughout, so this
|
|
47268
|
+
* bounds spend, not how quickly a recovery is seen (`CRA-87`).
|
|
46933
47269
|
*/
|
|
46934
47270
|
maxIntervalMs: ms("max-interval", 600),
|
|
46935
47271
|
/**
|
|
@@ -47014,6 +47350,7 @@ cruo-supervisor: ${error51.message}
|
|
|
47014
47350
|
// stands in for. Cheap to list, and wrong to discover the hard way.
|
|
47015
47351
|
"CRUO_SESSION"
|
|
47016
47352
|
];
|
|
47353
|
+
warnedAboutSpendTable = false;
|
|
47017
47354
|
main().catch((e) => {
|
|
47018
47355
|
console.error(e instanceof Error ? e.message : e);
|
|
47019
47356
|
process.exit(1);
|
|
@@ -47022,17 +47359,26 @@ cruo-supervisor: ${error51.message}
|
|
|
47022
47359
|
});
|
|
47023
47360
|
|
|
47024
47361
|
// src/cli.ts
|
|
47362
|
+
init_dist();
|
|
47363
|
+
init_dist7();
|
|
47025
47364
|
init_options();
|
|
47026
47365
|
import { chmod, mkdir as mkdir2, readFile as readFile2, rm as rm3, writeFile as writeFile2 } from "node:fs/promises";
|
|
47027
47366
|
import { homedir as homedir2 } from "node:os";
|
|
47028
47367
|
import { join as join3 } from "node:path";
|
|
47029
47368
|
var CONFIG_DIR = join3(homedir2(), ".cruo");
|
|
47030
47369
|
var CONFIG_PATH = join3(CONFIG_DIR, "config.json");
|
|
47370
|
+
function nameFromEmail(email3) {
|
|
47371
|
+
const local = email3.split("@")[0]?.toLowerCase().replace(/[^a-z0-9._-]/g, "");
|
|
47372
|
+
return local && local.length > 0 ? local : null;
|
|
47373
|
+
}
|
|
47031
47374
|
var USAGE = `cruo \u2014 run a Cruo agent
|
|
47032
47375
|
|
|
47033
47376
|
cruo login <token> remember an agent's token on this machine
|
|
47034
|
-
cruo
|
|
47377
|
+
cruo agents list what is remembered (never the tokens)
|
|
47378
|
+
cruo usage [--days 7] what the agents have been spending
|
|
47379
|
+
cruo logout [name] forget one, or --all
|
|
47035
47380
|
cruo [options] run the agent's supervisor
|
|
47381
|
+
cruo --as <name> \u2026 run a particular one
|
|
47036
47382
|
|
|
47037
47383
|
Getting a token
|
|
47038
47384
|
Cruo \u2192 Settings \u2192 Members \u2192 Add an agent. It is shown once.
|
|
@@ -47048,52 +47394,188 @@ Common options
|
|
|
47048
47394
|
|
|
47049
47395
|
Full list and what each one is for: https://cruo.space/docs#agents
|
|
47050
47396
|
|
|
47397
|
+
More than one agent on one machine: \`login\` files each token under the name the
|
|
47398
|
+
board shows, so the chain is \`cruo --as jarvis\` and \`cruo --as luna\` rather than
|
|
47399
|
+
a CRUO_TOKEN export per terminal.
|
|
47400
|
+
|
|
47051
47401
|
The token comes from CRUO_TOKEN, then --token, then whatever \`login\` stored.
|
|
47052
47402
|
`;
|
|
47053
|
-
|
|
47403
|
+
var EMPTY = { version: 2, default: null, agents: {} };
|
|
47404
|
+
async function readConfig2() {
|
|
47405
|
+
let parsed;
|
|
47406
|
+
try {
|
|
47407
|
+
parsed = JSON.parse(await readFile2(CONFIG_PATH, "utf8"));
|
|
47408
|
+
} catch {
|
|
47409
|
+
return { ...EMPTY };
|
|
47410
|
+
}
|
|
47411
|
+
const raw = parsed;
|
|
47412
|
+
if (raw.agents && typeof raw.agents === "object") {
|
|
47413
|
+
return {
|
|
47414
|
+
version: 2,
|
|
47415
|
+
default: typeof raw.default === "string" ? raw.default : null,
|
|
47416
|
+
agents: raw.agents
|
|
47417
|
+
};
|
|
47418
|
+
}
|
|
47419
|
+
const legacy = raw.token?.trim();
|
|
47420
|
+
if (legacy) {
|
|
47421
|
+
return { version: 2, default: "default", agents: { default: { token: legacy } } };
|
|
47422
|
+
}
|
|
47423
|
+
return { ...EMPTY };
|
|
47424
|
+
}
|
|
47425
|
+
async function writeConfig(config3) {
|
|
47426
|
+
await mkdir2(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
47427
|
+
await writeFile2(CONFIG_PATH, JSON.stringify(config3, null, 2) + "\n", { mode: 384 });
|
|
47428
|
+
await chmod(CONFIG_PATH, 384);
|
|
47429
|
+
}
|
|
47430
|
+
async function identify2(token) {
|
|
47431
|
+
const endpoint = process.env.CRUO_SESSION_URL?.trim() || CRUO_CLOUD.sessionUrl;
|
|
47054
47432
|
try {
|
|
47055
|
-
const
|
|
47056
|
-
return
|
|
47433
|
+
const session = await fetchDelegatedSession(endpoint, token);
|
|
47434
|
+
return { email: session.email, workspace: session.workspaceName };
|
|
47057
47435
|
} catch {
|
|
47058
47436
|
return null;
|
|
47059
47437
|
}
|
|
47060
47438
|
}
|
|
47061
|
-
async function login(token) {
|
|
47439
|
+
async function login(token, as) {
|
|
47062
47440
|
if (!token.startsWith("cruo_pat_")) {
|
|
47063
47441
|
console.error(`
|
|
47064
47442
|
That does not look like a Cruo token \u2014 they begin "cruo_pat_".
|
|
47065
47443
|
`);
|
|
47066
47444
|
process.exit(2);
|
|
47067
47445
|
}
|
|
47068
|
-
|
|
47069
|
-
|
|
47070
|
-
|
|
47071
|
-
|
|
47072
|
-
|
|
47446
|
+
const who = as ? null : await identify2(token);
|
|
47447
|
+
const name = as ?? (who ? nameFromEmail(who.email) : null);
|
|
47448
|
+
if (!name) {
|
|
47449
|
+
console.error(
|
|
47450
|
+
`
|
|
47451
|
+
Could not work out whose token that is, so it needs a name:
|
|
47452
|
+
|
|
47453
|
+
cruo login <token> --as jarvis
|
|
47454
|
+
|
|
47455
|
+
That happens when the board cannot be reached \u2014 a local stack, or no
|
|
47456
|
+
network. The token is fine; only the lookup failed.
|
|
47457
|
+
`
|
|
47458
|
+
);
|
|
47459
|
+
process.exit(2);
|
|
47460
|
+
}
|
|
47461
|
+
const config3 = await readConfig2();
|
|
47462
|
+
const replacing = config3.agents[name];
|
|
47463
|
+
config3.agents[name] = {
|
|
47464
|
+
token,
|
|
47465
|
+
email: who?.email,
|
|
47466
|
+
workspace: who?.workspace,
|
|
47467
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
47468
|
+
};
|
|
47469
|
+
config3.default ??= name;
|
|
47470
|
+
await writeConfig(config3);
|
|
47471
|
+
const where = who ? ` (${who.email} in ${who.workspace})` : "";
|
|
47472
|
+
console.log(
|
|
47473
|
+
`
|
|
47474
|
+
${replacing ? "Replaced" : "Saved"} the token for \`${name}\`${where}.
|
|
47475
|
+
${CONFIG_PATH} is readable only by you.
|
|
47476
|
+
|
|
47477
|
+
` + (config3.default === name ? `Run \`cruo --dry-run\` to see what it would pick up.
|
|
47478
|
+
` : `Run \`cruo --as ${name} --dry-run\` to see what it would pick up.
|
|
47479
|
+
A bare \`cruo\` still runs \`${config3.default}\`.
|
|
47480
|
+
`)
|
|
47481
|
+
);
|
|
47482
|
+
}
|
|
47483
|
+
async function logout(which, all) {
|
|
47484
|
+
const config3 = await readConfig2();
|
|
47485
|
+
const names = Object.keys(config3.agents);
|
|
47486
|
+
if (all) {
|
|
47487
|
+
await rm3(CONFIG_PATH, { force: true });
|
|
47488
|
+
console.log(
|
|
47489
|
+
names.length === 0 ? `
|
|
47490
|
+
Nothing was stored.
|
|
47491
|
+
` : `
|
|
47492
|
+
Forgot ${names.length} token(s): ${names.join(", ")}. ${CONFIG_PATH} is gone.
|
|
47493
|
+
`
|
|
47494
|
+
);
|
|
47495
|
+
return;
|
|
47496
|
+
}
|
|
47497
|
+
if (!which) {
|
|
47498
|
+
if (names.length <= 1) {
|
|
47499
|
+
await rm3(CONFIG_PATH, { force: true });
|
|
47500
|
+
console.log(
|
|
47501
|
+
names.length === 0 ? `
|
|
47502
|
+
Nothing was stored.
|
|
47503
|
+
` : `
|
|
47504
|
+
Forgot the token for \`${names[0]}\`. ${CONFIG_PATH} is gone.
|
|
47505
|
+
`
|
|
47506
|
+
);
|
|
47507
|
+
return;
|
|
47508
|
+
}
|
|
47509
|
+
console.error(
|
|
47510
|
+
`
|
|
47511
|
+
${names.length} tokens are stored: ${names.join(", ")}
|
|
47073
47512
|
|
|
47074
|
-
|
|
47513
|
+
Say which: cruo logout <name>
|
|
47514
|
+
Or all: cruo logout --all
|
|
47515
|
+
`
|
|
47516
|
+
);
|
|
47517
|
+
process.exit(2);
|
|
47518
|
+
}
|
|
47519
|
+
if (!config3.agents[which]) {
|
|
47520
|
+
console.error(`
|
|
47521
|
+
Nothing stored for \`${which}\`. Stored: ${names.join(", ") || "(none)"}
|
|
47075
47522
|
`);
|
|
47523
|
+
process.exit(2);
|
|
47524
|
+
}
|
|
47525
|
+
delete config3.agents[which];
|
|
47526
|
+
if (config3.default === which) config3.default = Object.keys(config3.agents)[0] ?? null;
|
|
47527
|
+
await writeConfig(config3);
|
|
47528
|
+
console.log(
|
|
47529
|
+
`
|
|
47530
|
+
Forgot the token for \`${which}\`.` + (config3.default ? ` A bare \`cruo\` now runs \`${config3.default}\`.
|
|
47531
|
+
` : ` Nothing is stored now.
|
|
47532
|
+
`)
|
|
47533
|
+
);
|
|
47076
47534
|
}
|
|
47077
|
-
async function
|
|
47078
|
-
|
|
47535
|
+
async function listAgents() {
|
|
47536
|
+
const config3 = await readConfig2();
|
|
47537
|
+
const names = Object.keys(config3.agents);
|
|
47538
|
+
if (names.length === 0) {
|
|
47539
|
+
console.log(`
|
|
47540
|
+
No tokens stored. \`cruo login <token>\` to add one.
|
|
47541
|
+
`);
|
|
47542
|
+
return;
|
|
47543
|
+
}
|
|
47544
|
+
console.log("");
|
|
47545
|
+
for (const name of names) {
|
|
47546
|
+
const a = config3.agents[name];
|
|
47547
|
+
const mark = config3.default === name ? "*" : " ";
|
|
47548
|
+
const who = a.email ? ` \u2014 ${a.email}${a.workspace ? ` in ${a.workspace}` : ""}` : "";
|
|
47549
|
+
console.log(` ${mark} ${name}${who}`);
|
|
47550
|
+
}
|
|
47079
47551
|
console.log(`
|
|
47080
|
-
|
|
47552
|
+
* is what a bare \`cruo\` runs. Use \`--as <name>\` for another.
|
|
47081
47553
|
`);
|
|
47082
47554
|
}
|
|
47083
47555
|
async function main2() {
|
|
47084
47556
|
const argv2 = process.argv.slice(2);
|
|
47085
47557
|
const [first] = argv2;
|
|
47558
|
+
const flagValue = (name) => {
|
|
47559
|
+
const i = argv2.indexOf(name);
|
|
47560
|
+
return i >= 0 ? argv2[i + 1] ?? null : null;
|
|
47561
|
+
};
|
|
47086
47562
|
if (first === "login") {
|
|
47087
47563
|
const token2 = argv2[1];
|
|
47088
|
-
if (!token2) {
|
|
47564
|
+
if (!token2 || token2.startsWith("--")) {
|
|
47089
47565
|
console.error(`
|
|
47090
|
-
Usage: cruo login <token>
|
|
47566
|
+
Usage: cruo login <token> [--as <name>]
|
|
47091
47567
|
`);
|
|
47092
47568
|
process.exit(2);
|
|
47093
47569
|
}
|
|
47094
|
-
return login(token2);
|
|
47570
|
+
return login(token2, flagValue("--as"));
|
|
47571
|
+
}
|
|
47572
|
+
if (first === "logout") {
|
|
47573
|
+
const named = argv2[1] && !argv2[1].startsWith("--") ? argv2[1] : null;
|
|
47574
|
+
return logout(named, argv2.includes("--all"));
|
|
47575
|
+
}
|
|
47576
|
+
if (first === "agents" || first === "whoami") return listAgents();
|
|
47577
|
+
if (first === "usage") {
|
|
47095
47578
|
}
|
|
47096
|
-
if (first === "logout") return logout();
|
|
47097
47579
|
if (first === "help" || argv2.includes("--help") || argv2.includes("-h")) {
|
|
47098
47580
|
console.log(USAGE);
|
|
47099
47581
|
return;
|
|
@@ -47106,7 +47588,22 @@ Usage: cruo login <token>
|
|
|
47106
47588
|
Prefer CRUO_TOKEN in the environment, or \`cruo login\` once.`
|
|
47107
47589
|
);
|
|
47108
47590
|
}
|
|
47109
|
-
const
|
|
47591
|
+
const asName = flagValue("--as");
|
|
47592
|
+
const config3 = await readConfig2();
|
|
47593
|
+
const stored = asName ? config3.agents[asName] : config3.default ? config3.agents[config3.default] : void 0;
|
|
47594
|
+
if (asName && !stored) {
|
|
47595
|
+
const names = Object.keys(config3.agents);
|
|
47596
|
+
console.error(
|
|
47597
|
+
`
|
|
47598
|
+
Nothing stored for \`${asName}\`.
|
|
47599
|
+
|
|
47600
|
+
` + (names.length > 0 ? `Stored: ${names.join(", ")}
|
|
47601
|
+
` : `Nothing is stored at all \u2014 \`cruo login <token>\` first.
|
|
47602
|
+
`)
|
|
47603
|
+
);
|
|
47604
|
+
process.exit(2);
|
|
47605
|
+
}
|
|
47606
|
+
const token = process.env.CRUO_TOKEN?.trim() || fromFlag || stored?.token;
|
|
47110
47607
|
if (!token) {
|
|
47111
47608
|
console.error(
|
|
47112
47609
|
`
|
|
@@ -47117,9 +47614,24 @@ Get one from Cruo \u2192 Settings \u2192 Members \u2192 Add an agent.
|
|
|
47117
47614
|
);
|
|
47118
47615
|
process.exit(2);
|
|
47119
47616
|
}
|
|
47617
|
+
const usingStored = !process.env.CRUO_TOKEN?.trim() && !fromFlag && stored;
|
|
47618
|
+
if (usingStored) {
|
|
47619
|
+
process.env.CRUO_IDENTITY = asName ?? config3.default ?? "";
|
|
47620
|
+
}
|
|
47120
47621
|
process.env.CRUO_TOKEN = token;
|
|
47121
|
-
const passthrough = stripTokenFlag(argv2);
|
|
47622
|
+
const passthrough = stripTokenFlag(argv2).filter((a, i, all) => a !== "--as" && all[i - 1] !== "--as");
|
|
47122
47623
|
process.argv = [process.argv[0], process.argv[1], ...passthrough];
|
|
47624
|
+
if (first === "usage") {
|
|
47625
|
+
const { reportUsage: reportUsage2 } = await Promise.resolve().then(() => (init_usage(), usage_exports));
|
|
47626
|
+
const days = Number(flagValue("--days") ?? 7);
|
|
47627
|
+
if (!Number.isFinite(days) || days <= 0) {
|
|
47628
|
+
console.error(`
|
|
47629
|
+
--days must be a positive number.
|
|
47630
|
+
`);
|
|
47631
|
+
process.exit(2);
|
|
47632
|
+
}
|
|
47633
|
+
return reportUsage2({ days, issue: flagValue("--issue") });
|
|
47634
|
+
}
|
|
47123
47635
|
await Promise.resolve().then(() => (init_supervisor(), supervisor_exports));
|
|
47124
47636
|
}
|
|
47125
47637
|
main2().catch((error51) => {
|
package/package.json
CHANGED