@sinoia/hubdoc-tools 1.10.0 → 1.12.0
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/cli.js +297 -71
- package/docs/llm-usage.md +79 -11
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -42589,9 +42589,9 @@ var require_follow_redirects = __commonJS({
|
|
|
42589
42589
|
"search",
|
|
42590
42590
|
"hash"
|
|
42591
42591
|
];
|
|
42592
|
-
var
|
|
42592
|
+
var events2 = ["abort", "aborted", "connect", "error", "socket", "timeout"];
|
|
42593
42593
|
var eventHandlers = /* @__PURE__ */ Object.create(null);
|
|
42594
|
-
|
|
42594
|
+
events2.forEach(function(event) {
|
|
42595
42595
|
eventHandlers[event] = function(arg1, arg2, arg3) {
|
|
42596
42596
|
this._redirectable.emit(event, arg1, arg2, arg3);
|
|
42597
42597
|
};
|
|
@@ -42805,7 +42805,7 @@ var require_follow_redirects = __commonJS({
|
|
|
42805
42805
|
}
|
|
42806
42806
|
var request = this._currentRequest = nativeProtocol.request(this._options, this._onNativeResponse);
|
|
42807
42807
|
request._redirectable = this;
|
|
42808
|
-
for (var event of
|
|
42808
|
+
for (var event of events2) {
|
|
42809
42809
|
request.on(event, eventHandlers[event]);
|
|
42810
42810
|
}
|
|
42811
42811
|
this._currentUrl = /^\//.test(this._options.path) ? url3.format(this._options) : (
|
|
@@ -43020,7 +43020,7 @@ var require_follow_redirects = __commonJS({
|
|
|
43020
43020
|
return CustomError;
|
|
43021
43021
|
}
|
|
43022
43022
|
function destroyRequest(request, error2) {
|
|
43023
|
-
for (var event of
|
|
43023
|
+
for (var event of events2) {
|
|
43024
43024
|
request.removeListener(event, eventHandlers[event]);
|
|
43025
43025
|
}
|
|
43026
43026
|
request.on("error", noop2);
|
|
@@ -50043,7 +50043,7 @@ var require_parser = __commonJS({
|
|
|
50043
50043
|
"node_modules/xml2js/lib/parser.js"(exports2) {
|
|
50044
50044
|
(function() {
|
|
50045
50045
|
"use strict";
|
|
50046
|
-
var bom, defaults3, defineProperty,
|
|
50046
|
+
var bom, defaults3, defineProperty, events2, isEmpty, processItem, processors, sax, setImmediate2, bind2 = function(fn, me) {
|
|
50047
50047
|
return function() {
|
|
50048
50048
|
return fn.apply(me, arguments);
|
|
50049
50049
|
};
|
|
@@ -50060,7 +50060,7 @@ var require_parser = __commonJS({
|
|
|
50060
50060
|
return child;
|
|
50061
50061
|
}, hasProp = {}.hasOwnProperty;
|
|
50062
50062
|
sax = require_sax();
|
|
50063
|
-
|
|
50063
|
+
events2 = require("events");
|
|
50064
50064
|
bom = require_bom();
|
|
50065
50065
|
processors = require_processors();
|
|
50066
50066
|
setImmediate2 = require("timers").setImmediate;
|
|
@@ -50398,7 +50398,7 @@ var require_parser = __commonJS({
|
|
|
50398
50398
|
})(this));
|
|
50399
50399
|
};
|
|
50400
50400
|
return Parser;
|
|
50401
|
-
})(
|
|
50401
|
+
})(events2);
|
|
50402
50402
|
exports2.parseString = function(str, a3, b3) {
|
|
50403
50403
|
var cb, options, parser;
|
|
50404
50404
|
if (b3 != null) {
|
|
@@ -73349,7 +73349,7 @@ var require_dist_cjs69 = __commonJS({
|
|
|
73349
73349
|
return value2;
|
|
73350
73350
|
};
|
|
73351
73351
|
};
|
|
73352
|
-
var
|
|
73352
|
+
var sleep2 = (seconds) => {
|
|
73353
73353
|
return new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
|
|
73354
73354
|
};
|
|
73355
73355
|
var waiterServiceDefaults = {
|
|
@@ -73416,7 +73416,7 @@ var require_dist_cjs69 = __commonJS({
|
|
|
73416
73416
|
if (Date.now() + delay5 * 1e3 > waitUntil) {
|
|
73417
73417
|
return { state: exports2.WaiterState.TIMEOUT, observedResponses };
|
|
73418
73418
|
}
|
|
73419
|
-
await
|
|
73419
|
+
await sleep2(delay5);
|
|
73420
73420
|
const { state: state5, reason: reason2 } = await acceptorChecks(client, input);
|
|
73421
73421
|
if (reason2) {
|
|
73422
73422
|
const message = createMessageFromResponse(reason2);
|
|
@@ -86010,7 +86010,7 @@ var require_dist_cjs72 = __commonJS({
|
|
|
86010
86010
|
var abortController = require_dist_cjs71();
|
|
86011
86011
|
var middlewareEndpoint = require_dist_cjs42();
|
|
86012
86012
|
var smithyClient = require_dist_cjs20();
|
|
86013
|
-
var
|
|
86013
|
+
var events2 = require("events");
|
|
86014
86014
|
var buffer2 = require("buffer");
|
|
86015
86015
|
var runtimeConfig = require_runtimeConfig3();
|
|
86016
86016
|
var stream5 = require("stream");
|
|
@@ -86166,7 +86166,7 @@ var require_dist_cjs72 = __commonJS({
|
|
|
86166
86166
|
}
|
|
86167
86167
|
throw new Error("Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;.");
|
|
86168
86168
|
};
|
|
86169
|
-
var Upload2 = class _Upload extends
|
|
86169
|
+
var Upload2 = class _Upload extends events2.EventEmitter {
|
|
86170
86170
|
static MIN_PART_SIZE = 1024 * 1024 * 5;
|
|
86171
86171
|
MAX_PARTS = 1e4;
|
|
86172
86172
|
queueSize = 4;
|
|
@@ -86229,7 +86229,7 @@ var require_dist_cjs72 = __commonJS({
|
|
|
86229
86229
|
const params = { ...this.params, Body: dataPart.data };
|
|
86230
86230
|
const clientConfig = this.client.config;
|
|
86231
86231
|
const requestHandler = clientConfig.requestHandler;
|
|
86232
|
-
const eventEmitter = requestHandler instanceof
|
|
86232
|
+
const eventEmitter = requestHandler instanceof events2.EventEmitter ? requestHandler : null;
|
|
86233
86233
|
const uploadEventListener = (event) => {
|
|
86234
86234
|
this.bytesUploadedSoFar = event.loaded;
|
|
86235
86235
|
this.totalBytes = event.total;
|
|
@@ -86325,7 +86325,7 @@ var require_dist_cjs72 = __commonJS({
|
|
|
86325
86325
|
}
|
|
86326
86326
|
const partSize = byteLength(dataPart.data) || 0;
|
|
86327
86327
|
const requestHandler = this.client.config.requestHandler;
|
|
86328
|
-
const eventEmitter = requestHandler instanceof
|
|
86328
|
+
const eventEmitter = requestHandler instanceof events2.EventEmitter ? requestHandler : null;
|
|
86329
86329
|
let lastSeenBytes = 0;
|
|
86330
86330
|
const uploadEventListener = (event, request) => {
|
|
86331
86331
|
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
|
@@ -95034,7 +95034,7 @@ var require_bignumber = __commonJS({
|
|
|
95034
95034
|
"node_modules/bignumber.js/bignumber.js"(exports2, module2) {
|
|
95035
95035
|
(function(globalObject) {
|
|
95036
95036
|
"use strict";
|
|
95037
|
-
var BigNumber, isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor = Math.floor, bignumberError = "[BigNumber Error] ", tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ",
|
|
95037
|
+
var BigNumber, isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i, mathceil = Math.ceil, mathfloor = Math.floor, bignumberError = "[BigNumber Error] ", tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ", BASE6 = 1e14, LOG_BASE = 14, MAX_SAFE_INTEGER = 9007199254740991, POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13], SQRT_BASE = 1e7, MAX = 1e9;
|
|
95038
95038
|
function clone(configObject) {
|
|
95039
95039
|
var div, convertBase, parseNumeric, P = BigNumber2.prototype = { constructor: BigNumber2, toString: null, valueOf: null }, ONE = new BigNumber2(1), DECIMAL_PLACES = 20, ROUNDING_MODE = 4, TO_EXP_NEG = -7, TO_EXP_POS = 21, MIN_EXP = -1e7, MAX_EXP = 1e7, CRYPTO = false, MODULO_MODE = 1, POW_PRECISION = 0, FORMAT = {
|
|
95040
95040
|
prefix: "",
|
|
@@ -95286,7 +95286,7 @@ var require_bignumber = __commonJS({
|
|
|
95286
95286
|
if (String(c3[0]).length == i3) {
|
|
95287
95287
|
for (i3 = 0; i3 < c3.length; i3++) {
|
|
95288
95288
|
n3 = c3[i3];
|
|
95289
|
-
if (n3 < 0 || n3 >=
|
|
95289
|
+
if (n3 < 0 || n3 >= BASE6 || n3 !== mathfloor(n3)) break out;
|
|
95290
95290
|
}
|
|
95291
95291
|
if (n3 !== 0) return true;
|
|
95292
95292
|
}
|
|
@@ -95503,7 +95503,7 @@ var require_bignumber = __commonJS({
|
|
|
95503
95503
|
e3 = x3.e - y2.e;
|
|
95504
95504
|
s3 = dp + e3 + 1;
|
|
95505
95505
|
if (!base) {
|
|
95506
|
-
base =
|
|
95506
|
+
base = BASE6;
|
|
95507
95507
|
e3 = bitFloor(x3.e / LOG_BASE) - bitFloor(y2.e / LOG_BASE);
|
|
95508
95508
|
s3 = s3 / LOG_BASE | 0;
|
|
95509
95509
|
}
|
|
@@ -95582,7 +95582,7 @@ var require_bignumber = __commonJS({
|
|
|
95582
95582
|
more = rem[0] != null;
|
|
95583
95583
|
if (!qc[0]) qc.splice(0, 1);
|
|
95584
95584
|
}
|
|
95585
|
-
if (base ==
|
|
95585
|
+
if (base == BASE6) {
|
|
95586
95586
|
for (i3 = 1, s3 = qc[0]; s3 >= 10; s3 /= 10, i3++) ;
|
|
95587
95587
|
round(q3, dp + (q3.e = i3 + e3 * LOG_BASE - 1) + 1, rm, more);
|
|
95588
95588
|
} else {
|
|
@@ -95741,12 +95741,12 @@ var require_bignumber = __commonJS({
|
|
|
95741
95741
|
for (k3 = 1; j3 >= 10; j3 /= 10, k3++) ;
|
|
95742
95742
|
if (i3 != k3) {
|
|
95743
95743
|
x3.e++;
|
|
95744
|
-
if (xc[0] ==
|
|
95744
|
+
if (xc[0] == BASE6) xc[0] = 1;
|
|
95745
95745
|
}
|
|
95746
95746
|
break;
|
|
95747
95747
|
} else {
|
|
95748
95748
|
xc[ni] += k3;
|
|
95749
|
-
if (xc[ni] !=
|
|
95749
|
+
if (xc[ni] != BASE6) break;
|
|
95750
95750
|
xc[ni--] = 0;
|
|
95751
95751
|
k3 = 1;
|
|
95752
95752
|
}
|
|
@@ -95955,12 +95955,12 @@ var require_bignumber = __commonJS({
|
|
|
95955
95955
|
}
|
|
95956
95956
|
b3 = (j3 = yc.length) - (i3 = xc.length);
|
|
95957
95957
|
if (b3 > 0) for (; b3--; xc[i3++] = 0) ;
|
|
95958
|
-
b3 =
|
|
95958
|
+
b3 = BASE6 - 1;
|
|
95959
95959
|
for (; j3 > a3; ) {
|
|
95960
95960
|
if (xc[--j3] < yc[j3]) {
|
|
95961
95961
|
for (i3 = j3; i3 && !xc[--i3]; xc[i3] = b3) ;
|
|
95962
95962
|
--xc[i3];
|
|
95963
|
-
xc[j3] +=
|
|
95963
|
+
xc[j3] += BASE6;
|
|
95964
95964
|
}
|
|
95965
95965
|
xc[j3] -= yc[j3];
|
|
95966
95966
|
}
|
|
@@ -96022,7 +96022,7 @@ var require_bignumber = __commonJS({
|
|
|
96022
96022
|
ycL = i3;
|
|
96023
96023
|
}
|
|
96024
96024
|
for (i3 = xcL + ycL, zc = []; i3--; zc.push(0)) ;
|
|
96025
|
-
base =
|
|
96025
|
+
base = BASE6;
|
|
96026
96026
|
sqrtBase = SQRT_BASE;
|
|
96027
96027
|
for (i3 = ycL; --i3 >= 0; ) {
|
|
96028
96028
|
c3 = 0;
|
|
@@ -96088,8 +96088,8 @@ var require_bignumber = __commonJS({
|
|
|
96088
96088
|
b3 = a3;
|
|
96089
96089
|
}
|
|
96090
96090
|
for (a3 = 0; b3; ) {
|
|
96091
|
-
a3 = (xc[--b3] = xc[b3] + yc[b3] + a3) /
|
|
96092
|
-
xc[b3] =
|
|
96091
|
+
a3 = (xc[--b3] = xc[b3] + yc[b3] + a3) / BASE6 | 0;
|
|
96092
|
+
xc[b3] = BASE6 === xc[b3] ? 0 : xc[b3] % BASE6;
|
|
96093
96093
|
}
|
|
96094
96094
|
if (a3) {
|
|
96095
96095
|
xc = [a3].concat(xc);
|
|
@@ -672699,11 +672699,11 @@ var ListPrompt = class extends Prompt {
|
|
|
672699
672699
|
*/
|
|
672700
672700
|
_run(cb) {
|
|
672701
672701
|
this.done = cb;
|
|
672702
|
-
const
|
|
672703
|
-
|
|
672704
|
-
|
|
672705
|
-
|
|
672706
|
-
|
|
672702
|
+
const events2 = observe(this.rl);
|
|
672703
|
+
events2.normalizedUpKey.pipe((0, import_rxjs3.takeUntil)(events2.line)).forEach(this.onUpKey.bind(this));
|
|
672704
|
+
events2.normalizedDownKey.pipe((0, import_rxjs3.takeUntil)(events2.line)).forEach(this.onDownKey.bind(this));
|
|
672705
|
+
events2.numberKey.pipe((0, import_rxjs3.takeUntil)(events2.line)).forEach(this.onNumberKey.bind(this));
|
|
672706
|
+
events2.line.pipe(
|
|
672707
672707
|
(0, import_rxjs3.take)(1),
|
|
672708
672708
|
(0, import_rxjs3.map)(this.getCurrentValue.bind(this)),
|
|
672709
672709
|
(0, import_rxjs3.flatMap)(
|
|
@@ -672816,12 +672816,12 @@ var InputPrompt = class extends Prompt {
|
|
|
672816
672816
|
*/
|
|
672817
672817
|
_run(cb) {
|
|
672818
672818
|
this.done = cb;
|
|
672819
|
-
const
|
|
672820
|
-
const submit =
|
|
672819
|
+
const events2 = observe(this.rl);
|
|
672820
|
+
const submit = events2.line.pipe((0, import_rxjs4.map)(this.filterInput.bind(this)));
|
|
672821
672821
|
const validation = this.handleSubmitEvents(submit);
|
|
672822
672822
|
validation.success.forEach(this.onEnd.bind(this));
|
|
672823
672823
|
validation.error.forEach(this.onError.bind(this));
|
|
672824
|
-
|
|
672824
|
+
events2.keypress.pipe((0, import_rxjs4.takeUntil)(validation.success)).forEach(this.onKeypress.bind(this));
|
|
672825
672825
|
this.render();
|
|
672826
672826
|
return this;
|
|
672827
672827
|
}
|
|
@@ -672918,9 +672918,9 @@ var ConfirmPrompt = class extends Prompt {
|
|
|
672918
672918
|
*/
|
|
672919
672919
|
_run(cb) {
|
|
672920
672920
|
this.done = cb;
|
|
672921
|
-
const
|
|
672922
|
-
|
|
672923
|
-
|
|
672921
|
+
const events2 = observe(this.rl);
|
|
672922
|
+
events2.keypress.pipe((0, import_rxjs5.takeUntil)(events2.line)).forEach(this.onKeypress.bind(this));
|
|
672923
|
+
events2.line.pipe((0, import_rxjs5.take)(1)).forEach(this.onEnd.bind(this));
|
|
672924
672924
|
this.render();
|
|
672925
672925
|
return this;
|
|
672926
672926
|
}
|
|
@@ -673001,14 +673001,14 @@ var RawListPrompt = class extends Prompt {
|
|
|
673001
673001
|
*/
|
|
673002
673002
|
_run(cb) {
|
|
673003
673003
|
this.done = cb;
|
|
673004
|
-
const
|
|
673005
|
-
const submit =
|
|
673004
|
+
const events2 = observe(this.rl);
|
|
673005
|
+
const submit = events2.line.pipe((0, import_rxjs6.map)(this.getCurrentValue.bind(this)));
|
|
673006
673006
|
const validation = this.handleSubmitEvents(submit);
|
|
673007
673007
|
validation.success.forEach(this.onEnd.bind(this));
|
|
673008
673008
|
validation.error.forEach(this.onError.bind(this));
|
|
673009
|
-
|
|
673010
|
-
|
|
673011
|
-
|
|
673009
|
+
events2.normalizedUpKey.pipe((0, import_rxjs6.takeUntil)(validation.success)).forEach(this.onUpKey.bind(this));
|
|
673010
|
+
events2.normalizedDownKey.pipe((0, import_rxjs6.takeUntil)(validation.success)).forEach(this.onDownKey.bind(this));
|
|
673011
|
+
events2.keypress.pipe((0, import_rxjs6.takeUntil)(validation.success)).forEach(this.onKeypress.bind(this));
|
|
673012
673012
|
this.render();
|
|
673013
673013
|
return this;
|
|
673014
673014
|
}
|
|
@@ -673145,13 +673145,13 @@ var ExpandPrompt = class extends Prompt {
|
|
|
673145
673145
|
*/
|
|
673146
673146
|
_run(cb) {
|
|
673147
673147
|
this.done = cb;
|
|
673148
|
-
const
|
|
673148
|
+
const events2 = observe(this.rl);
|
|
673149
673149
|
const validation = this.handleSubmitEvents(
|
|
673150
|
-
|
|
673150
|
+
events2.line.pipe((0, import_rxjs7.map)(this.getCurrentValue.bind(this)))
|
|
673151
673151
|
);
|
|
673152
673152
|
validation.success.forEach(this.onSubmit.bind(this));
|
|
673153
673153
|
validation.error.forEach(this.onError.bind(this));
|
|
673154
|
-
this.keypressObs =
|
|
673154
|
+
this.keypressObs = events2.keypress.pipe((0, import_rxjs7.takeUntil)(validation.success)).forEach(this.onKeypress.bind(this));
|
|
673155
673155
|
this.render();
|
|
673156
673156
|
return this;
|
|
673157
673157
|
}
|
|
@@ -673338,18 +673338,18 @@ var CheckboxPrompt = class extends Prompt {
|
|
|
673338
673338
|
*/
|
|
673339
673339
|
_run(cb) {
|
|
673340
673340
|
this.done = cb;
|
|
673341
|
-
const
|
|
673341
|
+
const events2 = observe(this.rl);
|
|
673342
673342
|
const validation = this.handleSubmitEvents(
|
|
673343
|
-
|
|
673343
|
+
events2.line.pipe((0, import_rxjs8.map)(this.getCurrentValue.bind(this)))
|
|
673344
673344
|
);
|
|
673345
673345
|
validation.success.forEach(this.onEnd.bind(this));
|
|
673346
673346
|
validation.error.forEach(this.onError.bind(this));
|
|
673347
|
-
|
|
673348
|
-
|
|
673349
|
-
|
|
673350
|
-
|
|
673351
|
-
|
|
673352
|
-
|
|
673347
|
+
events2.normalizedUpKey.pipe((0, import_rxjs8.takeUntil)(validation.success)).forEach(this.onUpKey.bind(this));
|
|
673348
|
+
events2.normalizedDownKey.pipe((0, import_rxjs8.takeUntil)(validation.success)).forEach(this.onDownKey.bind(this));
|
|
673349
|
+
events2.numberKey.pipe((0, import_rxjs8.takeUntil)(validation.success)).forEach(this.onNumberKey.bind(this));
|
|
673350
|
+
events2.spaceKey.pipe((0, import_rxjs8.takeUntil)(validation.success)).forEach(this.onSpaceKey.bind(this));
|
|
673351
|
+
events2.aKey.pipe((0, import_rxjs8.takeUntil)(validation.success)).forEach(this.onAllKey.bind(this));
|
|
673352
|
+
events2.iKey.pipe((0, import_rxjs8.takeUntil)(validation.success)).forEach(this.onInverseKey.bind(this));
|
|
673353
673353
|
this.render();
|
|
673354
673354
|
this.firstRender = false;
|
|
673355
673355
|
return this;
|
|
@@ -673502,12 +673502,12 @@ var PasswordPrompt = class extends Prompt {
|
|
|
673502
673502
|
*/
|
|
673503
673503
|
_run(cb) {
|
|
673504
673504
|
this.done = cb;
|
|
673505
|
-
const
|
|
673506
|
-
const submit =
|
|
673505
|
+
const events2 = observe(this.rl);
|
|
673506
|
+
const submit = events2.line.pipe((0, import_rxjs9.map)(this.filterInput.bind(this)));
|
|
673507
673507
|
const validation = this.handleSubmitEvents(submit);
|
|
673508
673508
|
validation.success.forEach(this.onEnd.bind(this));
|
|
673509
673509
|
validation.error.forEach(this.onError.bind(this));
|
|
673510
|
-
|
|
673510
|
+
events2.keypress.pipe((0, import_rxjs9.takeUntil)(validation.success)).forEach(this.onKeypress.bind(this));
|
|
673511
673511
|
this.render();
|
|
673512
673512
|
return this;
|
|
673513
673513
|
}
|
|
@@ -673774,8 +673774,8 @@ var EditorPrompt = class extends Prompt {
|
|
|
673774
673774
|
_run(cb) {
|
|
673775
673775
|
this.done = cb;
|
|
673776
673776
|
this.editorResult = new import_rxjs10.Subject();
|
|
673777
|
-
const
|
|
673778
|
-
this.lineSubscription =
|
|
673777
|
+
const events2 = observe(this.rl);
|
|
673778
|
+
this.lineSubscription = events2.line.subscribe(this.startExternalEditor.bind(this));
|
|
673779
673779
|
const waitUserInput = this.opt.waitUserInput === void 0 ? true : this.opt.waitUserInput;
|
|
673780
673780
|
const validation = this.handleSubmitEvents(this.editorResult);
|
|
673781
673781
|
validation.success.forEach(this.onEnd.bind(this));
|
|
@@ -730850,7 +730850,7 @@ var DeviceAuthService = class {
|
|
|
730850
730850
|
* Honors `slow_down` by widening the interval (RFC 8628 §3.5).
|
|
730851
730851
|
*/
|
|
730852
730852
|
async pollUntilDone(deviceCode, opts) {
|
|
730853
|
-
const
|
|
730853
|
+
const sleep2 = opts.sleep || defaultSleep;
|
|
730854
730854
|
let intervalMs = Math.max(1, opts.interval) * 1e3;
|
|
730855
730855
|
const caps = [Date.now() + opts.expiresIn * 1e3];
|
|
730856
730856
|
if (opts.timeoutMs != null) caps.push(Date.now() + opts.timeoutMs);
|
|
@@ -730880,7 +730880,7 @@ var DeviceAuthService = class {
|
|
|
730880
730880
|
"Timed out waiting for device approval. Run `hubdoc login --start` again."
|
|
730881
730881
|
);
|
|
730882
730882
|
}
|
|
730883
|
-
await
|
|
730883
|
+
await sleep2(intervalMs);
|
|
730884
730884
|
}
|
|
730885
730885
|
}
|
|
730886
730886
|
};
|
|
@@ -733822,7 +733822,7 @@ var PERM_COLUMNS = [
|
|
|
733822
733822
|
{ header: "ID", key: "id" },
|
|
733823
733823
|
{ header: "Actor", key: "actor_type", format: (v6, row) => `${v6}:${row.actor?.display_name ?? row.actor_id?.substring(0, 8)}` },
|
|
733824
733824
|
{ header: "Level", key: "level" },
|
|
733825
|
-
{ header: "On", key: "permissible_type", format: (v6) => v6?.replace(/^Documents::/, "") ?? "" },
|
|
733825
|
+
{ header: "On", key: "permissible_type", format: (v6) => v6?.replace(/^(Documents|Projects)::/, "") ?? "" },
|
|
733826
733826
|
{ header: "Resource ID", key: "permissible_id" },
|
|
733827
733827
|
{ header: "Updated", key: "updated_at" }
|
|
733828
733828
|
];
|
|
@@ -733831,7 +733831,8 @@ var PERMISSIBLE_ALIASES = {
|
|
|
733831
733831
|
workspace: "Documents::Workspace",
|
|
733832
733832
|
folder: "Documents::Folder",
|
|
733833
733833
|
file: "Documents::File",
|
|
733834
|
-
share_link: "Documents::ShareLink"
|
|
733834
|
+
share_link: "Documents::ShareLink",
|
|
733835
|
+
project: "Projects::Project"
|
|
733835
733836
|
};
|
|
733836
733837
|
var ACTOR_ALIASES = {
|
|
733837
733838
|
user: "User",
|
|
@@ -733841,10 +733842,10 @@ var ACTOR_ALIASES = {
|
|
|
733841
733842
|
function normalizePermissibleType(input, out) {
|
|
733842
733843
|
const lower = input.toLowerCase();
|
|
733843
733844
|
if (PERMISSIBLE_ALIASES[lower]) return PERMISSIBLE_ALIASES[lower];
|
|
733844
|
-
if (input.startsWith("Documents::")) return input;
|
|
733845
|
+
if (input.startsWith("Documents::") || input.startsWith("Projects::")) return input;
|
|
733845
733846
|
out.fail(
|
|
733846
733847
|
new Error(
|
|
733847
|
-
`Invalid --on-type: '${input}'. Use workspace/folder/file/share_link or a fully-qualified Documents::\u2026 class name.`
|
|
733848
|
+
`Invalid --on-type: '${input}'. Use workspace/folder/file/share_link/project or a fully-qualified Documents::\u2026 / Projects::\u2026 class name.`
|
|
733848
733849
|
)
|
|
733849
733850
|
);
|
|
733850
733851
|
return "";
|
|
@@ -734334,7 +734335,7 @@ async function handleTicketsShow(id, opts) {
|
|
|
734334
734335
|
out.fail(err);
|
|
734335
734336
|
}
|
|
734336
734337
|
}
|
|
734337
|
-
function ticketBodyFromOpts(opts,
|
|
734338
|
+
function ticketBodyFromOpts(opts, out) {
|
|
734338
734339
|
const body2 = {};
|
|
734339
734340
|
if (opts.title !== void 0) body2.title = opts.title;
|
|
734340
734341
|
if (opts.description !== void 0) body2.description = opts.description;
|
|
@@ -734355,14 +734356,21 @@ function ticketBodyFromOpts(opts, includeAll) {
|
|
|
734355
734356
|
const labels = parseLabels(opts.labels);
|
|
734356
734357
|
if (labels !== void 0) body2.labels = labels;
|
|
734357
734358
|
if (opts.column !== void 0) body2.column_status = opts.column;
|
|
734358
|
-
|
|
734359
|
+
if (opts.agentConfig !== void 0) {
|
|
734360
|
+
try {
|
|
734361
|
+
body2.agent_config = JSON.parse(opts.agentConfig);
|
|
734362
|
+
} catch (err) {
|
|
734363
|
+
out.fail(new Error(`Invalid JSON for --agent-config: ${err.message}`));
|
|
734364
|
+
}
|
|
734365
|
+
}
|
|
734366
|
+
return body2;
|
|
734359
734367
|
}
|
|
734360
734368
|
async function handleTicketsCreate(opts) {
|
|
734361
734369
|
const out = output(opts);
|
|
734362
734370
|
requireProject2(opts, out);
|
|
734363
734371
|
const ctx = await buildApiContext(out);
|
|
734364
734372
|
if (!opts.title) out.fail(new Error("--title is required"));
|
|
734365
|
-
const body2 = ticketBodyFromOpts(opts,
|
|
734373
|
+
const body2 = ticketBodyFromOpts(opts, out);
|
|
734366
734374
|
try {
|
|
734367
734375
|
const res = await ctx.axios.post(ticketsBase(opts.project), body2);
|
|
734368
734376
|
const ticket = res.data?.ticket ?? res.data;
|
|
@@ -734375,7 +734383,7 @@ async function handleTicketsUpdate(id, opts) {
|
|
|
734375
734383
|
const out = output(opts);
|
|
734376
734384
|
requireProject2(opts, out);
|
|
734377
734385
|
const ctx = await buildApiContext(out);
|
|
734378
|
-
const body2 = ticketBodyFromOpts(opts,
|
|
734386
|
+
const body2 = ticketBodyFromOpts(opts, out);
|
|
734379
734387
|
if (Object.keys(body2).length === 0) out.fail(new Error("No fields to update"));
|
|
734380
734388
|
try {
|
|
734381
734389
|
const res = await ctx.axios.patch(
|
|
@@ -734414,6 +734422,34 @@ async function handleTicketsDelete(id, opts) {
|
|
|
734414
734422
|
out.fail(err);
|
|
734415
734423
|
}
|
|
734416
734424
|
}
|
|
734425
|
+
async function handleTicketsSetAgent(id, opts) {
|
|
734426
|
+
const out = output(opts);
|
|
734427
|
+
requireProject2(opts, out);
|
|
734428
|
+
const ctx = await buildApiContext(out);
|
|
734429
|
+
if (opts.agent === void 0) out.fail(new Error("--agent <agent-id|null> is required"));
|
|
734430
|
+
const body2 = {
|
|
734431
|
+
assignee_id: opts.agent === "null" ? null : opts.agent
|
|
734432
|
+
};
|
|
734433
|
+
if (opts.agentConfig !== void 0) {
|
|
734434
|
+
try {
|
|
734435
|
+
body2.agent_config = JSON.parse(opts.agentConfig);
|
|
734436
|
+
} catch (err) {
|
|
734437
|
+
out.fail(new Error(`Invalid JSON for --agent-config: ${err.message}`));
|
|
734438
|
+
}
|
|
734439
|
+
}
|
|
734440
|
+
try {
|
|
734441
|
+
const res = await ctx.axios.patch(
|
|
734442
|
+
`${ticketsBase(opts.project)}/${encodeURIComponent(id)}`,
|
|
734443
|
+
body2
|
|
734444
|
+
);
|
|
734445
|
+
out.ok(
|
|
734446
|
+
body2.assignee_id === null ? `Ticket ${id} agent cleared` : `Ticket ${id} agent set to ${body2.assignee_id}`,
|
|
734447
|
+
res.data?.ticket ?? res.data
|
|
734448
|
+
);
|
|
734449
|
+
} catch (err) {
|
|
734450
|
+
out.fail(err);
|
|
734451
|
+
}
|
|
734452
|
+
}
|
|
734417
734453
|
async function handleTicketsAssign(id, opts) {
|
|
734418
734454
|
const out = output(opts);
|
|
734419
734455
|
requireProject2(opts, out);
|
|
@@ -734604,6 +734640,179 @@ async function handleTicketsDispatch(id, opts) {
|
|
|
734604
734640
|
}
|
|
734605
734641
|
}
|
|
734606
734642
|
|
|
734643
|
+
// apps/cli/cli/handlers/agent-handlers.ts
|
|
734644
|
+
var BASE4 = "/api/v1/agents";
|
|
734645
|
+
var AGENT_COLUMNS = [
|
|
734646
|
+
{ header: "ID", key: "id" },
|
|
734647
|
+
{ header: "Key", key: "key" },
|
|
734648
|
+
{ header: "Name", key: "name", maxWidth: 30 },
|
|
734649
|
+
{ header: "Type", key: "type", format: (v6) => v6?.replace(/^Agents::/, "") ?? "" },
|
|
734650
|
+
{ header: "Active", key: "active", format: (v6) => v6 ? "\u2714" : "" }
|
|
734651
|
+
];
|
|
734652
|
+
async function handleAgentsList(opts) {
|
|
734653
|
+
const out = output(opts);
|
|
734654
|
+
const ctx = await buildApiContext(out);
|
|
734655
|
+
const params = {};
|
|
734656
|
+
if (opts.active !== void 0) params.active = opts.active;
|
|
734657
|
+
if (opts.page) params.page = Number(opts.page);
|
|
734658
|
+
if (opts.perPage) params.per_page = Number(opts.perPage);
|
|
734659
|
+
try {
|
|
734660
|
+
const res = await ctx.axios.get(BASE4, { params });
|
|
734661
|
+
const items = Array.isArray(res.data) ? res.data : [];
|
|
734662
|
+
const pagination = extractPagination(res.headers, items.length);
|
|
734663
|
+
if (opts.json) {
|
|
734664
|
+
out.show({ items, pagination });
|
|
734665
|
+
return;
|
|
734666
|
+
}
|
|
734667
|
+
out.list(items, AGENT_COLUMNS);
|
|
734668
|
+
if (pagination.pages > 1) {
|
|
734669
|
+
out.note(`page ${pagination.page}/${pagination.pages} (${pagination.count} total)`);
|
|
734670
|
+
}
|
|
734671
|
+
} catch (err) {
|
|
734672
|
+
out.fail(err);
|
|
734673
|
+
}
|
|
734674
|
+
}
|
|
734675
|
+
async function handleAgentsShow(id, opts) {
|
|
734676
|
+
const out = output(opts);
|
|
734677
|
+
const ctx = await buildApiContext(out);
|
|
734678
|
+
try {
|
|
734679
|
+
const res = await ctx.axios.get(`${BASE4}/${encodeURIComponent(id)}`);
|
|
734680
|
+
out.show(res.data?.agent ?? res.data, { title: `Agent ${id}` });
|
|
734681
|
+
} catch (err) {
|
|
734682
|
+
out.fail(err);
|
|
734683
|
+
}
|
|
734684
|
+
}
|
|
734685
|
+
|
|
734686
|
+
// apps/cli/cli/handlers/event-handlers.ts
|
|
734687
|
+
var BASE5 = "/api/v1/events";
|
|
734688
|
+
var EVENT_COLUMNS = [
|
|
734689
|
+
{ header: "Event ID", key: "event_id" },
|
|
734690
|
+
{ header: "Type", key: "type", format: (v6) => shortType(v6) },
|
|
734691
|
+
{ header: "At", key: "timestamp" }
|
|
734692
|
+
];
|
|
734693
|
+
var TYPE_ALIASES = {
|
|
734694
|
+
// Projects
|
|
734695
|
+
"project.created": "Projects::Projects::ProjectCreated",
|
|
734696
|
+
"project.updated": "Projects::Projects::ProjectUpdated",
|
|
734697
|
+
"project.started": "Projects::Projects::ProjectStarted",
|
|
734698
|
+
"project.completed": "Projects::Projects::ProjectCompleted",
|
|
734699
|
+
"project.archived": "Projects::Projects::ProjectArchived",
|
|
734700
|
+
"project.deleted": "Projects::Projects::ProjectDeleted",
|
|
734701
|
+
// Sprints
|
|
734702
|
+
"sprint.created": "Projects::Sprints::SprintCreated",
|
|
734703
|
+
"sprint.updated": "Projects::Sprints::SprintUpdated",
|
|
734704
|
+
"sprint.started": "Projects::Sprints::SprintStarted",
|
|
734705
|
+
"sprint.completed": "Projects::Sprints::SprintCompleted",
|
|
734706
|
+
"sprint.deleted": "Projects::Sprints::SprintDeleted",
|
|
734707
|
+
// Tickets
|
|
734708
|
+
"ticket.created": "Projects::Tickets::TicketCreated",
|
|
734709
|
+
"ticket.updated": "Projects::Tickets::TicketUpdated",
|
|
734710
|
+
"ticket.assigned": "Projects::Tickets::TicketAssigned",
|
|
734711
|
+
"ticket.blocked": "Projects::Tickets::TicketBlocked",
|
|
734712
|
+
"ticket.escalated": "Projects::Tickets::TicketEscalated",
|
|
734713
|
+
"ticket.failed": "Projects::Tickets::TicketFailed",
|
|
734714
|
+
"ticket.moved": "Projects::Tickets::TicketMoved",
|
|
734715
|
+
"ticket.status_changed": "Projects::Tickets::TicketStatusChanged",
|
|
734716
|
+
"ticket.deleted": "Projects::Tickets::TicketDeleted",
|
|
734717
|
+
"ticket.comment": "Projects::Tickets::ChannelMessagePosted",
|
|
734718
|
+
"ticket.deliverable": "Projects::Tickets::DeliverableAttached",
|
|
734719
|
+
// Tasks
|
|
734720
|
+
"task.created": "Projects::Tasks::TaskCreated",
|
|
734721
|
+
"task.updated": "Projects::Tasks::TaskUpdated",
|
|
734722
|
+
"task.completed": "Projects::Tasks::TaskCompleted",
|
|
734723
|
+
"task.deleted": "Projects::Tasks::TaskDeleted"
|
|
734724
|
+
};
|
|
734725
|
+
function expandTypes(raw) {
|
|
734726
|
+
if (raw == null) return void 0;
|
|
734727
|
+
const items = raw.split(",").map((s3) => s3.trim()).filter(Boolean).map((s3) => TYPE_ALIASES[s3] ?? s3);
|
|
734728
|
+
return items.length > 0 ? items.join(",") : void 0;
|
|
734729
|
+
}
|
|
734730
|
+
function shortType(fq) {
|
|
734731
|
+
if (!fq) return "";
|
|
734732
|
+
const inverted = Object.entries(TYPE_ALIASES).find(([, v6]) => v6 === fq)?.[0];
|
|
734733
|
+
if (inverted) return inverted;
|
|
734734
|
+
return fq.split("::").pop() ?? fq;
|
|
734735
|
+
}
|
|
734736
|
+
async function fetchEventsPage(ctx, opts) {
|
|
734737
|
+
const params = {};
|
|
734738
|
+
if (opts.project) params.project_id = opts.project;
|
|
734739
|
+
if (opts.ticket) params.ticket_id = opts.ticket;
|
|
734740
|
+
const expanded = expandTypes(opts.type);
|
|
734741
|
+
if (expanded) params.type = expanded;
|
|
734742
|
+
if (opts.since) params.since = opts.since;
|
|
734743
|
+
if (opts.limit) params.limit = Number(opts.limit);
|
|
734744
|
+
const res = await ctx.axios.get(BASE5, { params });
|
|
734745
|
+
const items = Array.isArray(res.data) ? res.data : [];
|
|
734746
|
+
const headers = res.headers ?? {};
|
|
734747
|
+
const nextCursor = headers["x-next-cursor"] ?? headers["X-Next-Cursor"] ?? null;
|
|
734748
|
+
return { items, nextCursor };
|
|
734749
|
+
}
|
|
734750
|
+
async function handleEventsList(opts) {
|
|
734751
|
+
const out = output(opts);
|
|
734752
|
+
const ctx = await buildApiContext(out);
|
|
734753
|
+
try {
|
|
734754
|
+
const { items, nextCursor } = await fetchEventsPage(ctx, opts);
|
|
734755
|
+
if (opts.json) {
|
|
734756
|
+
out.show({ items, next_cursor: nextCursor });
|
|
734757
|
+
return;
|
|
734758
|
+
}
|
|
734759
|
+
out.list(items, EVENT_COLUMNS);
|
|
734760
|
+
if (nextCursor) {
|
|
734761
|
+
out.note(`next_cursor: ${nextCursor} (pass to --since to continue)`);
|
|
734762
|
+
}
|
|
734763
|
+
} catch (err) {
|
|
734764
|
+
out.fail(err);
|
|
734765
|
+
}
|
|
734766
|
+
}
|
|
734767
|
+
async function handleEventsWatch(opts) {
|
|
734768
|
+
const out = output(opts);
|
|
734769
|
+
const ctx = await buildApiContext(out);
|
|
734770
|
+
const timeoutMs = Math.max(1e3, Number(opts.timeout ?? "60") * 1e3);
|
|
734771
|
+
const intervalMs = Math.max(100, Number(opts.pollIntervalMs ?? "1000"));
|
|
734772
|
+
const startedAt = Date.now();
|
|
734773
|
+
let cursor2 = opts.since;
|
|
734774
|
+
try {
|
|
734775
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
734776
|
+
const page = await fetchEventsPage(ctx, { ...opts, since: cursor2 });
|
|
734777
|
+
if (page.items.length > 0) {
|
|
734778
|
+
if (opts.json) {
|
|
734779
|
+
out.show({
|
|
734780
|
+
items: page.items,
|
|
734781
|
+
next_cursor: page.nextCursor,
|
|
734782
|
+
waited_ms: Date.now() - startedAt
|
|
734783
|
+
});
|
|
734784
|
+
} else {
|
|
734785
|
+
out.list(page.items, EVENT_COLUMNS);
|
|
734786
|
+
if (page.nextCursor) {
|
|
734787
|
+
out.note(`next_cursor: ${page.nextCursor}`);
|
|
734788
|
+
}
|
|
734789
|
+
}
|
|
734790
|
+
return;
|
|
734791
|
+
}
|
|
734792
|
+
await sleep(intervalMs);
|
|
734793
|
+
}
|
|
734794
|
+
} catch (err) {
|
|
734795
|
+
out.fail(err);
|
|
734796
|
+
}
|
|
734797
|
+
const waited = Date.now() - startedAt;
|
|
734798
|
+
const payload2 = {
|
|
734799
|
+
ok: false,
|
|
734800
|
+
reason: "timeout",
|
|
734801
|
+
waited_ms: waited,
|
|
734802
|
+
since: cursor2 ?? null
|
|
734803
|
+
};
|
|
734804
|
+
if (opts.json) {
|
|
734805
|
+
process.stderr.write(JSON.stringify(payload2, null, 2) + "\n");
|
|
734806
|
+
} else {
|
|
734807
|
+
process.stderr.write(`Timed out after ${waited}ms with no matching event.
|
|
734808
|
+
`);
|
|
734809
|
+
}
|
|
734810
|
+
process.exit(2);
|
|
734811
|
+
}
|
|
734812
|
+
function sleep(ms) {
|
|
734813
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
734814
|
+
}
|
|
734815
|
+
|
|
734607
734816
|
// apps/cli/cli/handlers/task-handlers.ts
|
|
734608
734817
|
var tasksBase = (pid, tid) => `/api/v1/projects/${encodeURIComponent(pid)}/tickets/${encodeURIComponent(tid)}/tasks`;
|
|
734609
734818
|
var TASK_COLUMNS = [
|
|
@@ -734778,7 +734987,7 @@ async function handleTasksReorder(opts) {
|
|
|
734778
734987
|
// apps/cli/cli.ts
|
|
734779
734988
|
var getVersion = () => {
|
|
734780
734989
|
try {
|
|
734781
|
-
if (true) return "1.
|
|
734990
|
+
if (true) return "1.12.0";
|
|
734782
734991
|
} catch {
|
|
734783
734992
|
}
|
|
734784
734993
|
for (const candidate of [
|
|
@@ -735060,13 +735269,13 @@ members.command("remove <membership-id>").description("Remove a membership by it
|
|
|
735060
735269
|
await handleGroupMembersRemove(id, withGlobals(options));
|
|
735061
735270
|
});
|
|
735062
735271
|
var permissions = program2.command("permissions").description("Manage ACL: grant / list / revoke permissions on documents resources");
|
|
735063
|
-
permissions.command("ls").description("List permissions on a specific resource").requiredOption("--on <resource-id>", "Permissible resource UUID").option("--on-type <type>", "workspace | folder | file | share_link", "workspace").option("--to <actor-id>", "Filter by actor id (client-side)").option("--to-type <type>", "Filter by actor type (user | group | contact)").option("--level <level>", "Filter by level (read|write|admin|owner|forbidden)").action(async (options) => {
|
|
735272
|
+
permissions.command("ls").description("List permissions on a specific resource").requiredOption("--on <resource-id>", "Permissible resource UUID").option("--on-type <type>", "workspace | folder | file | share_link | project", "workspace").option("--to <actor-id>", "Filter by actor id (client-side)").option("--to-type <type>", "Filter by actor type (user | group | contact)").option("--level <level>", "Filter by level (read|write|admin|owner|forbidden)").action(async (options) => {
|
|
735064
735273
|
await handlePermissionsList(withGlobals(options));
|
|
735065
735274
|
});
|
|
735066
735275
|
permissions.command("show <id>").description("Show a permission by id").action(async (id, options) => {
|
|
735067
735276
|
await handlePermissionsShow(id, withGlobals(options));
|
|
735068
735277
|
});
|
|
735069
|
-
permissions.command("grant").description("Grant a permission on a resource to a user or group").requiredOption("--to <actor-id>", "Actor UUID (user/group/contact)").requiredOption("--to-type <type>", "user | group | contact").requiredOption("--on <resource-id>", "Permissible resource UUID").requiredOption("--on-type <type>", "workspace | folder | file | share_link").requiredOption("--level <level>", "read | write | admin | owner | forbidden").option("--temporary", "Mark as temporary (auto-expiring per server policy)").action(async (options) => {
|
|
735278
|
+
permissions.command("grant").description("Grant a permission on a resource to a user or group").requiredOption("--to <actor-id>", "Actor UUID (user/group/contact)").requiredOption("--to-type <type>", "user | group | contact").requiredOption("--on <resource-id>", "Permissible resource UUID").requiredOption("--on-type <type>", "workspace | folder | file | share_link | project").requiredOption("--level <level>", "read | write | admin | owner | forbidden").option("--temporary", "Mark as temporary (auto-expiring per server policy)").action(async (options) => {
|
|
735070
735279
|
await handlePermissionsGrant(withGlobals(options));
|
|
735071
735280
|
});
|
|
735072
735281
|
permissions.command("revoke <id>").description("Revoke a permission by id").option("--yes", "Skip the interactive confirmation").action(async (id, options) => {
|
|
@@ -735123,10 +735332,10 @@ tickets.command("ls").alias("list").description("List tickets").requiredOption("
|
|
|
735123
735332
|
tickets.command("show <id>").description("Show a ticket (with tasks, subtasks, deliverables)").requiredOption("--project <id>", "Parent project id").action(async (id, options) => {
|
|
735124
735333
|
await handleTicketsShow(id, withGlobals(options));
|
|
735125
735334
|
});
|
|
735126
|
-
tickets.command("create").description("Create a ticket").requiredOption("--project <id>", "Parent project id").requiredOption("--title <text>").option("--description <text>").option("--type <ticket_type>", "task (default) | bug | story | epic | \u2026").option("--sprint <id>", "Attach to a sprint; omit to leave in backlog").option("--assignee <id>", "Assign to a user id").option("--priority <priority>", "lowest | low | medium | high | highest").option("--status <status>").option("--parent <id>", "Parent ticket id (for subtasks)").option("--due <YYYY-MM-DD>").option("--story-points <n>").option("--labels <a,b,c>", "Comma-separated labels").option("--column <column_status>").action(async (options) => {
|
|
735335
|
+
tickets.command("create").description("Create a ticket").requiredOption("--project <id>", "Parent project id").requiredOption("--title <text>").option("--description <text>").option("--type <ticket_type>", "task (default) | bug | story | epic | \u2026").option("--sprint <id>", "Attach to a sprint; omit to leave in backlog").option("--assignee <id>", "Assign to a user id").option("--priority <priority>", "lowest | low | medium | high | highest").option("--status <status>").option("--parent <id>", "Parent ticket id (for subtasks)").option("--due <YYYY-MM-DD>").option("--story-points <n>").option("--labels <a,b,c>", "Comma-separated labels").option("--column <column_status>").option("--agent-config <json>", "JSON payload written to the ticket agent_config (corex#591)").action(async (options) => {
|
|
735127
735336
|
await handleTicketsCreate(withGlobals(options));
|
|
735128
735337
|
});
|
|
735129
|
-
tickets.command("update <id>").description("Update a ticket").requiredOption("--project <id>", "Parent project id").option("--title <text>").option("--description <text>").option("--type <ticket_type>").option("--sprint <id>", 'Move to a sprint; use "null" for backlog').option("--assignee <id>", 'Reassign; use "null" to unassign').option("--priority <priority>").option("--status <status>").option("--parent <id>").option("--due <YYYY-MM-DD>").option("--story-points <n>").option("--labels <a,b,c>").option("--column <column_status>").action(async (id, options) => {
|
|
735338
|
+
tickets.command("update <id>").description("Update a ticket").requiredOption("--project <id>", "Parent project id").option("--title <text>").option("--description <text>").option("--type <ticket_type>").option("--sprint <id>", 'Move to a sprint; use "null" for backlog').option("--assignee <id>", 'Reassign; use "null" to unassign').option("--priority <priority>").option("--status <status>").option("--parent <id>").option("--due <YYYY-MM-DD>").option("--story-points <n>").option("--labels <a,b,c>").option("--column <column_status>").option("--agent-config <json>", "JSON payload written to the ticket agent_config (corex#591)").action(async (id, options) => {
|
|
735130
735339
|
await handleTicketsUpdate(id, withGlobals(options));
|
|
735131
735340
|
});
|
|
735132
735341
|
tickets.command("delete <id>").description("Delete a ticket (drops its tasks, deliverables, activities)").requiredOption("--project <id>", "Parent project id").option("--yes", "Skip the interactive confirmation").action(async (id, options) => {
|
|
@@ -735135,6 +735344,9 @@ tickets.command("delete <id>").description("Delete a ticket (drops its tasks, de
|
|
|
735135
735344
|
tickets.command("assign <id>").description("Assign a ticket to a user; --to null to unassign").requiredOption("--project <id>", "Parent project id").requiredOption("--to <user-id|null>").action(async (id, options) => {
|
|
735136
735345
|
await handleTicketsAssign(id, withGlobals(options));
|
|
735137
735346
|
});
|
|
735347
|
+
tickets.command("set-agent <id>").description("Configure the ticket with an agent (assignee + agent_config in one PATCH) \u2014 needed before `dispatch` (corex#591)").requiredOption("--project <id>", "Parent project id").requiredOption("--agent <agent-id|null>", 'Agents::Agent UUID (use "null" to clear)').option("--agent-config <json>", "Optional JSON payload merged into agent_config").action(async (id, options) => {
|
|
735348
|
+
await handleTicketsSetAgent(id, withGlobals(options));
|
|
735349
|
+
});
|
|
735138
735350
|
tickets.command("status <id>").description("Change a ticket status (optionally pin the kanban column with --column)").requiredOption("--project <id>", "Parent project id").requiredOption("--to <status>", "open | in_progress | done | blocked | awaiting_human | cancelled | failed").option("--column <column_status>", "Optionally set the kanban column at the same time").action(async (id, options) => {
|
|
735139
735351
|
await handleTicketsStatus(id, withGlobals(options));
|
|
735140
735352
|
});
|
|
@@ -735178,6 +735390,20 @@ tasks.command("complete <id>").description("Mark a task as completed (or re-open
|
|
|
735178
735390
|
tasks.command("reorder").description("Reorder tasks under a ticket").requiredOption("--project <id>", "Parent project id").requiredOption("--ticket <id>", "Parent ticket id").requiredOption("--order <ids>", "Comma-separated task ids in the desired order").action(async (options) => {
|
|
735179
735391
|
await handleTasksReorder(withGlobals(options));
|
|
735180
735392
|
});
|
|
735393
|
+
var agents = program2.command("agents").description("List agents dispatchable on tickets (corex#591)");
|
|
735394
|
+
agents.command("ls").alias("list").description("List agents").option("--active", "Only agents whose config is active").option("--page <n>").option("--per-page <n>").action(async (options) => {
|
|
735395
|
+
await handleAgentsList(withGlobals(options));
|
|
735396
|
+
});
|
|
735397
|
+
agents.command("show <id>").description("Show an agent").action(async (id, options) => {
|
|
735398
|
+
await handleAgentsShow(id, withGlobals(options));
|
|
735399
|
+
});
|
|
735400
|
+
var events = program2.command("events").description("Read the Rails Event Store stream (corex#593)");
|
|
735401
|
+
events.command("ls").alias("list").description("One-shot cursor-paginated read of the event stream").option("--project <id>", "Filter to events touching a specific project").option("--ticket <id>", "Filter to events on a specific ticket").option("--type <a,b,c>", "Comma-separated event types (aliases like ticket.status_changed OR full RES class names)").option("--since <cursor>", "Read events strictly after this event_id").option("--limit <n>", "Max events (default 100, server-side max 1000)").action(async (options) => {
|
|
735402
|
+
await handleEventsList(withGlobals(options));
|
|
735403
|
+
});
|
|
735404
|
+
events.command("watch").description("Block until a matching event arrives or the timeout expires (client-side long-poll)").option("--project <id>", "Filter to events touching a specific project").option("--ticket <id>", "Filter to events on a specific ticket").option("--type <a,b,c>", "Comma-separated event types (aliases or full class names)").option("--since <cursor>", "Start watching from this event_id (exclusive)").option("--limit <n>", "Max events per poll (default 100)").option("--timeout <s>", "Give up after this many seconds (default 60, exit 2 on timeout)").option("--poll-interval-ms <ms>", "Delay between polls (default 1000, min 100)").action(async (options) => {
|
|
735405
|
+
await handleEventsWatch(withGlobals(options));
|
|
735406
|
+
});
|
|
735181
735407
|
program2.parse();
|
|
735182
735408
|
/*! Bundled license information:
|
|
735183
735409
|
|
package/docs/llm-usage.md
CHANGED
|
@@ -377,16 +377,78 @@ themselves. All commands support `--json` for machine parsing.
|
|
|
377
377
|
| start | complete`.
|
|
378
378
|
|
|
379
379
|
`hubdoc tickets --project=<pid>` — `ls | show | create | update | delete
|
|
380
|
-
| assign | status | move | activities | deliverable |
|
|
381
|
-
comment | comments`. Every verb requires `--project=<pid>`.
|
|
382
|
-
--backlog` (or `ls --sprint null`) lists the backlog. `assign --to
|
|
383
|
-
unassigns. `status --to <state> [--column <col>]` uses the
|
|
384
|
-
statuses: `open | in_progress | done | blocked |
|
|
385
|
-
cancelled | failed` and optionally pins the kanban
|
|
386
|
-
time. `comment <id> --body <text>` (or `--body-file
|
|
387
|
-
message on the ticket's discussion thread (visible in
|
|
388
|
-
attributed to the token holder); `comments <id>` reads
|
|
389
|
-
oldest-first (paginated like `activities`).
|
|
380
|
+
| assign | set-agent | status | move | activities | deliverable |
|
|
381
|
+
dispatch | comment | comments`. Every verb requires `--project=<pid>`.
|
|
382
|
+
`ls --backlog` (or `ls --sprint null`) lists the backlog. `assign --to
|
|
383
|
+
null` unassigns. `status --to <state> [--column <col>]` uses the
|
|
384
|
+
canonical statuses: `open | in_progress | done | blocked |
|
|
385
|
+
awaiting_human | cancelled | failed` and optionally pins the kanban
|
|
386
|
+
column at the same time. `comment <id> --body <text>` (or `--body-file
|
|
387
|
+
<path>`) posts a message on the ticket's discussion thread (visible in
|
|
388
|
+
Corex / Agoria, attributed to the token holder); `comments <id>` reads
|
|
389
|
+
the thread oldest-first (paginated like `activities`).
|
|
390
|
+
|
|
391
|
+
**Agent configuration on tickets** (corex#591) : `create` and `update`
|
|
392
|
+
both accept `--agent-config <json>` — free-form jsonb persisted on the
|
|
393
|
+
ticket and read back by `dispatch_agent` / the agent runner (canonical
|
|
394
|
+
keys: `agent_role: planner|executor|…`, `instructions`). The convenience
|
|
395
|
+
verb `tickets set-agent <id> --project <pid> --agent <agent-id>
|
|
396
|
+
[--agent-config <json>]` PATCHes `assignee_id` and (optionally)
|
|
397
|
+
`agent_config` in one call — the shortest path from "empty ticket" to
|
|
398
|
+
"dispatchable". Use `hubdoc agents ls [--active]` to discover
|
|
399
|
+
dispatchable agent UUIDs (STI: `Agents::Planner`, `Agents::Executor`,
|
|
400
|
+
`Agents::Classifier`, `Agents::Conversational`, …).
|
|
401
|
+
|
|
402
|
+
**Project ACL** (hubdoc-tools#15) : the `permissions` verbs now accept
|
|
403
|
+
`--on-type project` (alias of `Projects::Project`) — the corex
|
|
404
|
+
`/api/v1/permissions` controller is polymorphic and `Projects::Project`
|
|
405
|
+
includes `HasPermissionsConcern`. This lets an agent share a **standalone
|
|
406
|
+
project** (no workspace attached) with a colleague or another agent
|
|
407
|
+
without going through a workspace-scoped ACL. Example:
|
|
408
|
+
`hubdoc permissions grant --to <user-id> --to-type user --on <project-id>
|
|
409
|
+
--on-type project --level admin`.
|
|
410
|
+
|
|
411
|
+
### Events — react to what's happening (corex#593)
|
|
412
|
+
|
|
413
|
+
`hubdoc events ls` and `hubdoc events watch` sit on top of the Rails
|
|
414
|
+
Event Store stream. Every mutation done by `projects/sprints/tickets/
|
|
415
|
+
tasks` (create, update, status_changed, moved, deliverable_attached,
|
|
416
|
+
channel_message_posted, …) is published as a typed event; the CLI lets
|
|
417
|
+
an agent either **poll** the stream once (`ls`) or **block** until
|
|
418
|
+
something happens (`watch`).
|
|
419
|
+
|
|
420
|
+
- **Type aliases** (agent-friendly): `ticket.created | ticket.updated |
|
|
421
|
+
ticket.status_changed | ticket.assigned | ticket.blocked |
|
|
422
|
+
ticket.escalated | ticket.failed | ticket.moved | ticket.comment |
|
|
423
|
+
ticket.deliverable | ticket.deleted | sprint.{created,started,updated,
|
|
424
|
+
completed,deleted} | project.{created,updated,started,completed,
|
|
425
|
+
archived,deleted} | task.{created,updated,completed,deleted}`. Full RES
|
|
426
|
+
class names (`Projects::Tickets::TicketStatusChanged`) are also
|
|
427
|
+
accepted verbatim.
|
|
428
|
+
- **Cursor**: each `ls` response includes `next_cursor` — pass it as
|
|
429
|
+
`--since` on the next call to resume. `watch` re-uses the same `since`
|
|
430
|
+
across empty polls (never skips an event that arrives mid-poll).
|
|
431
|
+
- **Timeout**: `watch --timeout <s>` (default 60) — exit code 2 with a
|
|
432
|
+
`{ ok:false, reason:"timeout", waited_ms, since }` envelope on stderr
|
|
433
|
+
when the window expires. This is distinct from network errors (exit 1).
|
|
434
|
+
- **Poll cadence**: `watch --poll-interval-ms <n>` (default 1000, min
|
|
435
|
+
100). Kept short so the perceived latency stays low; harmless because
|
|
436
|
+
each poll is a lightweight bare-array read.
|
|
437
|
+
|
|
438
|
+
Two typical patterns:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
# 1) Wait for the dispatched agent to finish before moving on.
|
|
442
|
+
hubdoc events watch --project "$PID" --ticket "$TID" \
|
|
443
|
+
--type ticket.status_changed --timeout 900 --json \
|
|
444
|
+
| jq -r '.items[-1].data.new_status' # → done / failed / blocked
|
|
445
|
+
# (returns as soon as the first matching event arrives)
|
|
446
|
+
|
|
447
|
+
# 2) Loop over the day's activity from a saved checkpoint.
|
|
448
|
+
CURSOR=$(cat .last-cursor 2>/dev/null || echo "")
|
|
449
|
+
hubdoc events ls --project "$PID" --since "$CURSOR" --limit 200 --json \
|
|
450
|
+
| tee day-batch.json | jq -r '.next_cursor' > .last-cursor
|
|
451
|
+
```
|
|
390
452
|
|
|
391
453
|
`hubdoc tasks --project=<pid> --ticket=<tid>` — `ls | show | create |
|
|
392
454
|
update | delete | complete | reorder`. Sub-tasks live under a ticket;
|
|
@@ -444,7 +506,13 @@ hubdoc tasks create --project "$PID" --ticket "$TID" \
|
|
|
444
506
|
hubdoc tasks create --project "$PID" --ticket "$TID" \
|
|
445
507
|
--title "Rédiger devis" --priority high --due 2026-07-16 --json
|
|
446
508
|
|
|
447
|
-
# 5.
|
|
509
|
+
# 5. Pick a dispatchable agent then set it on the ticket in one shot.
|
|
510
|
+
AGENT_ID=$(hubdoc agents ls --active --json | jq -r '.items[] | select(.key=="planner") | .id')
|
|
511
|
+
hubdoc tickets set-agent "$TID" --project "$PID" \
|
|
512
|
+
--agent "$AGENT_ID" \
|
|
513
|
+
--agent-config '{"agent_role":"planner","instructions":"Rédige un devis à partir des PJ."}' --json
|
|
514
|
+
|
|
515
|
+
# 5b. Now `dispatch` can actually fire (agent + agent_config both set).
|
|
448
516
|
hubdoc tickets dispatch "$TID" --project "$PID" --json
|
|
449
517
|
|
|
450
518
|
# 6. Later — post a follow-up on the ticket thread (visible to the human):
|