@corenel/cli 0.3.0 → 0.3.2
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/README.md +28 -2
- package/dist/cli.js +913 -147
- package/package.json +15 -15
package/dist/cli.js
CHANGED
|
@@ -324,13 +324,13 @@ var require_directives = __commonJS({
|
|
|
324
324
|
onError(0, "%YAML directive should contain exactly one part");
|
|
325
325
|
return false;
|
|
326
326
|
}
|
|
327
|
-
const [
|
|
328
|
-
if (
|
|
329
|
-
this.yaml.version =
|
|
327
|
+
const [version2] = parts;
|
|
328
|
+
if (version2 === "1.1" || version2 === "1.2") {
|
|
329
|
+
this.yaml.version = version2;
|
|
330
330
|
return true;
|
|
331
331
|
} else {
|
|
332
|
-
const isValid = /^\d+\.\d+$/.test(
|
|
333
|
-
onError(6, `Unsupported YAML version ${
|
|
332
|
+
const isValid = /^\d+\.\d+$/.test(version2);
|
|
333
|
+
onError(6, `Unsupported YAML version ${version2}`, isValid);
|
|
334
334
|
return false;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
@@ -3430,14 +3430,14 @@ var require_Document = __commonJS({
|
|
|
3430
3430
|
version: "1.2"
|
|
3431
3431
|
}, options);
|
|
3432
3432
|
this.options = opt;
|
|
3433
|
-
let { version } = opt;
|
|
3433
|
+
let { version: version2 } = opt;
|
|
3434
3434
|
if (options?._directives) {
|
|
3435
3435
|
this.directives = options._directives.atDocument();
|
|
3436
3436
|
if (this.directives.yaml.explicit)
|
|
3437
|
-
|
|
3437
|
+
version2 = this.directives.yaml.version;
|
|
3438
3438
|
} else
|
|
3439
|
-
this.directives = new directives.Directives({ version });
|
|
3440
|
-
this.setSchema(
|
|
3439
|
+
this.directives = new directives.Directives({ version: version2 });
|
|
3440
|
+
this.setSchema(version2, options);
|
|
3441
3441
|
this.contents = value === void 0 ? null : this.createNode(value, _replacer, options);
|
|
3442
3442
|
}
|
|
3443
3443
|
/**
|
|
@@ -3617,11 +3617,11 @@ var require_Document = __commonJS({
|
|
|
3617
3617
|
*
|
|
3618
3618
|
* Overrides all previously set schema options.
|
|
3619
3619
|
*/
|
|
3620
|
-
setSchema(
|
|
3621
|
-
if (typeof
|
|
3622
|
-
|
|
3620
|
+
setSchema(version2, options = {}) {
|
|
3621
|
+
if (typeof version2 === "number")
|
|
3622
|
+
version2 = String(version2);
|
|
3623
3623
|
let opt;
|
|
3624
|
-
switch (
|
|
3624
|
+
switch (version2) {
|
|
3625
3625
|
case "1.1":
|
|
3626
3626
|
if (this.directives)
|
|
3627
3627
|
this.directives.yaml.version = "1.1";
|
|
@@ -3632,9 +3632,9 @@ var require_Document = __commonJS({
|
|
|
3632
3632
|
case "1.2":
|
|
3633
3633
|
case "next":
|
|
3634
3634
|
if (this.directives)
|
|
3635
|
-
this.directives.yaml.version =
|
|
3635
|
+
this.directives.yaml.version = version2;
|
|
3636
3636
|
else
|
|
3637
|
-
this.directives = new directives.Directives({ version });
|
|
3637
|
+
this.directives = new directives.Directives({ version: version2 });
|
|
3638
3638
|
opt = { resolveKnownTags: true, schema: "core" };
|
|
3639
3639
|
break;
|
|
3640
3640
|
case null:
|
|
@@ -3643,7 +3643,7 @@ var require_Document = __commonJS({
|
|
|
3643
3643
|
opt = null;
|
|
3644
3644
|
break;
|
|
3645
3645
|
default: {
|
|
3646
|
-
const sv = JSON.stringify(
|
|
3646
|
+
const sv = JSON.stringify(version2);
|
|
3647
3647
|
throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);
|
|
3648
3648
|
}
|
|
3649
3649
|
}
|
|
@@ -7541,31 +7541,31 @@ var require_semver = __commonJS({
|
|
|
7541
7541
|
return true;
|
|
7542
7542
|
};
|
|
7543
7543
|
var SemVer = class _SemVer {
|
|
7544
|
-
constructor(
|
|
7544
|
+
constructor(version2, options) {
|
|
7545
7545
|
options = parseOptions(options);
|
|
7546
|
-
if (
|
|
7547
|
-
if (
|
|
7548
|
-
return
|
|
7546
|
+
if (version2 instanceof _SemVer) {
|
|
7547
|
+
if (version2.loose === !!options.loose && version2.includePrerelease === !!options.includePrerelease) {
|
|
7548
|
+
return version2;
|
|
7549
7549
|
} else {
|
|
7550
|
-
|
|
7550
|
+
version2 = version2.version;
|
|
7551
7551
|
}
|
|
7552
|
-
} else if (typeof
|
|
7553
|
-
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof
|
|
7552
|
+
} else if (typeof version2 !== "string") {
|
|
7553
|
+
throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version2}".`);
|
|
7554
7554
|
}
|
|
7555
|
-
if (
|
|
7555
|
+
if (version2.length > MAX_LENGTH) {
|
|
7556
7556
|
throw new TypeError(
|
|
7557
7557
|
`version is longer than ${MAX_LENGTH} characters`
|
|
7558
7558
|
);
|
|
7559
7559
|
}
|
|
7560
|
-
debug("SemVer",
|
|
7560
|
+
debug("SemVer", version2, options);
|
|
7561
7561
|
this.options = options;
|
|
7562
7562
|
this.loose = !!options.loose;
|
|
7563
7563
|
this.includePrerelease = !!options.includePrerelease;
|
|
7564
|
-
const m =
|
|
7564
|
+
const m = version2.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]);
|
|
7565
7565
|
if (!m) {
|
|
7566
|
-
throw new TypeError(`Invalid Version: ${
|
|
7566
|
+
throw new TypeError(`Invalid Version: ${version2}`);
|
|
7567
7567
|
}
|
|
7568
|
-
this.raw =
|
|
7568
|
+
this.raw = version2;
|
|
7569
7569
|
this.major = +m[1];
|
|
7570
7570
|
this.minor = +m[2];
|
|
7571
7571
|
this.patch = +m[3];
|
|
@@ -7812,12 +7812,12 @@ var require_parse = __commonJS({
|
|
|
7812
7812
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/parse.js"(exports, module) {
|
|
7813
7813
|
"use strict";
|
|
7814
7814
|
var SemVer = require_semver();
|
|
7815
|
-
var parse3 = (
|
|
7816
|
-
if (
|
|
7817
|
-
return
|
|
7815
|
+
var parse3 = (version2, options, throwErrors = false) => {
|
|
7816
|
+
if (version2 instanceof SemVer) {
|
|
7817
|
+
return version2;
|
|
7818
7818
|
}
|
|
7819
7819
|
try {
|
|
7820
|
-
return new SemVer(
|
|
7820
|
+
return new SemVer(version2, options);
|
|
7821
7821
|
} catch (er) {
|
|
7822
7822
|
if (!throwErrors) {
|
|
7823
7823
|
return null;
|
|
@@ -7834,8 +7834,8 @@ var require_valid = __commonJS({
|
|
|
7834
7834
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/valid.js"(exports, module) {
|
|
7835
7835
|
"use strict";
|
|
7836
7836
|
var parse3 = require_parse();
|
|
7837
|
-
var valid = (
|
|
7838
|
-
const v = parse3(
|
|
7837
|
+
var valid = (version2, options) => {
|
|
7838
|
+
const v = parse3(version2, options);
|
|
7839
7839
|
return v ? v.version : null;
|
|
7840
7840
|
};
|
|
7841
7841
|
module.exports = valid;
|
|
@@ -7847,8 +7847,8 @@ var require_clean = __commonJS({
|
|
|
7847
7847
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/clean.js"(exports, module) {
|
|
7848
7848
|
"use strict";
|
|
7849
7849
|
var parse3 = require_parse();
|
|
7850
|
-
var clean = (
|
|
7851
|
-
const s = parse3(
|
|
7850
|
+
var clean = (version2, options) => {
|
|
7851
|
+
const s = parse3(version2.trim().replace(/^[=v]+/, ""), options);
|
|
7852
7852
|
return s ? s.version : null;
|
|
7853
7853
|
};
|
|
7854
7854
|
module.exports = clean;
|
|
@@ -7860,7 +7860,7 @@ var require_inc = __commonJS({
|
|
|
7860
7860
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/inc.js"(exports, module) {
|
|
7861
7861
|
"use strict";
|
|
7862
7862
|
var SemVer = require_semver();
|
|
7863
|
-
var inc = (
|
|
7863
|
+
var inc = (version2, release, options, identifier, identifierBase) => {
|
|
7864
7864
|
if (typeof options === "string") {
|
|
7865
7865
|
identifierBase = identifier;
|
|
7866
7866
|
identifier = options;
|
|
@@ -7868,7 +7868,7 @@ var require_inc = __commonJS({
|
|
|
7868
7868
|
}
|
|
7869
7869
|
try {
|
|
7870
7870
|
return new SemVer(
|
|
7871
|
-
|
|
7871
|
+
version2 instanceof SemVer ? version2.version : version2,
|
|
7872
7872
|
options
|
|
7873
7873
|
).inc(release, identifier, identifierBase).version;
|
|
7874
7874
|
} catch (er) {
|
|
@@ -7958,8 +7958,8 @@ var require_prerelease = __commonJS({
|
|
|
7958
7958
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/prerelease.js"(exports, module) {
|
|
7959
7959
|
"use strict";
|
|
7960
7960
|
var parse3 = require_parse();
|
|
7961
|
-
var prerelease = (
|
|
7962
|
-
const parsed = parse3(
|
|
7961
|
+
var prerelease = (version2, options) => {
|
|
7962
|
+
const parsed = parse3(version2, options);
|
|
7963
7963
|
return parsed && parsed.prerelease.length ? parsed.prerelease : null;
|
|
7964
7964
|
};
|
|
7965
7965
|
module.exports = prerelease;
|
|
@@ -8147,24 +8147,24 @@ var require_coerce = __commonJS({
|
|
|
8147
8147
|
var SemVer = require_semver();
|
|
8148
8148
|
var parse3 = require_parse();
|
|
8149
8149
|
var { safeRe: re, t } = require_re();
|
|
8150
|
-
var coerce = (
|
|
8151
|
-
if (
|
|
8152
|
-
return
|
|
8150
|
+
var coerce = (version2, options) => {
|
|
8151
|
+
if (version2 instanceof SemVer) {
|
|
8152
|
+
return version2;
|
|
8153
8153
|
}
|
|
8154
|
-
if (typeof
|
|
8155
|
-
|
|
8154
|
+
if (typeof version2 === "number") {
|
|
8155
|
+
version2 = String(version2);
|
|
8156
8156
|
}
|
|
8157
|
-
if (typeof
|
|
8157
|
+
if (typeof version2 !== "string") {
|
|
8158
8158
|
return null;
|
|
8159
8159
|
}
|
|
8160
8160
|
options = options || {};
|
|
8161
8161
|
let match = null;
|
|
8162
8162
|
if (!options.rtl) {
|
|
8163
|
-
match =
|
|
8163
|
+
match = version2.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]);
|
|
8164
8164
|
} else {
|
|
8165
8165
|
const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL];
|
|
8166
8166
|
let next;
|
|
8167
|
-
while ((next = coerceRtlRegex.exec(
|
|
8167
|
+
while ((next = coerceRtlRegex.exec(version2)) && (!match || match.index + match[0].length !== version2.length)) {
|
|
8168
8168
|
if (!match || next.index + next[0].length !== match.index + match[0].length) {
|
|
8169
8169
|
match = next;
|
|
8170
8170
|
}
|
|
@@ -8193,37 +8193,37 @@ var require_truncate = __commonJS({
|
|
|
8193
8193
|
var parse3 = require_parse();
|
|
8194
8194
|
var constants = require_constants();
|
|
8195
8195
|
var SemVer = require_semver();
|
|
8196
|
-
var
|
|
8196
|
+
var truncate2 = (version2, truncation, options) => {
|
|
8197
8197
|
if (!constants.RELEASE_TYPES.includes(truncation)) {
|
|
8198
8198
|
return null;
|
|
8199
8199
|
}
|
|
8200
|
-
const clonedVersion = cloneInputVersion(
|
|
8200
|
+
const clonedVersion = cloneInputVersion(version2, options);
|
|
8201
8201
|
return clonedVersion && doTruncation(clonedVersion, truncation);
|
|
8202
8202
|
};
|
|
8203
|
-
var cloneInputVersion = (
|
|
8204
|
-
const versionStringToParse =
|
|
8203
|
+
var cloneInputVersion = (version2, options) => {
|
|
8204
|
+
const versionStringToParse = version2 instanceof SemVer ? version2.version : version2;
|
|
8205
8205
|
return parse3(versionStringToParse, options);
|
|
8206
8206
|
};
|
|
8207
|
-
var doTruncation = (
|
|
8207
|
+
var doTruncation = (version2, truncation) => {
|
|
8208
8208
|
if (isPrerelease(truncation)) {
|
|
8209
|
-
return
|
|
8209
|
+
return version2.version;
|
|
8210
8210
|
}
|
|
8211
|
-
|
|
8211
|
+
version2.prerelease = [];
|
|
8212
8212
|
switch (truncation) {
|
|
8213
8213
|
case "major":
|
|
8214
|
-
|
|
8215
|
-
|
|
8214
|
+
version2.minor = 0;
|
|
8215
|
+
version2.patch = 0;
|
|
8216
8216
|
break;
|
|
8217
8217
|
case "minor":
|
|
8218
|
-
|
|
8218
|
+
version2.patch = 0;
|
|
8219
8219
|
break;
|
|
8220
8220
|
}
|
|
8221
|
-
return
|
|
8221
|
+
return version2.format();
|
|
8222
8222
|
};
|
|
8223
8223
|
var isPrerelease = (type) => {
|
|
8224
8224
|
return type.startsWith("pre");
|
|
8225
8225
|
};
|
|
8226
|
-
module.exports =
|
|
8226
|
+
module.exports = truncate2;
|
|
8227
8227
|
}
|
|
8228
8228
|
});
|
|
8229
8229
|
|
|
@@ -8390,19 +8390,19 @@ var require_range = __commonJS({
|
|
|
8390
8390
|
});
|
|
8391
8391
|
}
|
|
8392
8392
|
// if ANY of the sets match ALL of its comparators, then pass
|
|
8393
|
-
test(
|
|
8394
|
-
if (!
|
|
8393
|
+
test(version2) {
|
|
8394
|
+
if (!version2) {
|
|
8395
8395
|
return false;
|
|
8396
8396
|
}
|
|
8397
|
-
if (typeof
|
|
8397
|
+
if (typeof version2 === "string") {
|
|
8398
8398
|
try {
|
|
8399
|
-
|
|
8399
|
+
version2 = new SemVer(version2, this.options);
|
|
8400
8400
|
} catch (er) {
|
|
8401
8401
|
return false;
|
|
8402
8402
|
}
|
|
8403
8403
|
}
|
|
8404
8404
|
for (let i = 0; i < this.set.length; i++) {
|
|
8405
|
-
if (testSet(this.set[i],
|
|
8405
|
+
if (testSet(this.set[i], version2, this.options)) {
|
|
8406
8406
|
return true;
|
|
8407
8407
|
}
|
|
8408
8408
|
}
|
|
@@ -8624,13 +8624,13 @@ var require_range = __commonJS({
|
|
|
8624
8624
|
}
|
|
8625
8625
|
return `${from} ${to}`.trim();
|
|
8626
8626
|
};
|
|
8627
|
-
var testSet = (set,
|
|
8627
|
+
var testSet = (set, version2, options) => {
|
|
8628
8628
|
for (let i = 0; i < set.length; i++) {
|
|
8629
|
-
if (!set[i].test(
|
|
8629
|
+
if (!set[i].test(version2)) {
|
|
8630
8630
|
return false;
|
|
8631
8631
|
}
|
|
8632
8632
|
}
|
|
8633
|
-
if (
|
|
8633
|
+
if (version2.prerelease.length && !options.includePrerelease) {
|
|
8634
8634
|
for (let i = 0; i < set.length; i++) {
|
|
8635
8635
|
debug(set[i].semver);
|
|
8636
8636
|
if (set[i].semver === Comparator.ANY) {
|
|
@@ -8638,7 +8638,7 @@ var require_range = __commonJS({
|
|
|
8638
8638
|
}
|
|
8639
8639
|
if (set[i].semver.prerelease.length > 0) {
|
|
8640
8640
|
const allowed = set[i].semver;
|
|
8641
|
-
if (allowed.major ===
|
|
8641
|
+
if (allowed.major === version2.major && allowed.minor === version2.minor && allowed.patch === version2.patch) {
|
|
8642
8642
|
return true;
|
|
8643
8643
|
}
|
|
8644
8644
|
}
|
|
@@ -8699,19 +8699,19 @@ var require_comparator = __commonJS({
|
|
|
8699
8699
|
toString() {
|
|
8700
8700
|
return this.value;
|
|
8701
8701
|
}
|
|
8702
|
-
test(
|
|
8703
|
-
debug("Comparator.test",
|
|
8704
|
-
if (this.semver === ANY ||
|
|
8702
|
+
test(version2) {
|
|
8703
|
+
debug("Comparator.test", version2, this.options.loose);
|
|
8704
|
+
if (this.semver === ANY || version2 === ANY) {
|
|
8705
8705
|
return true;
|
|
8706
8706
|
}
|
|
8707
|
-
if (typeof
|
|
8707
|
+
if (typeof version2 === "string") {
|
|
8708
8708
|
try {
|
|
8709
|
-
|
|
8709
|
+
version2 = new SemVer(version2, this.options);
|
|
8710
8710
|
} catch (er) {
|
|
8711
8711
|
return false;
|
|
8712
8712
|
}
|
|
8713
8713
|
}
|
|
8714
|
-
return cmp(
|
|
8714
|
+
return cmp(version2, this.operator, this.semver, this.options);
|
|
8715
8715
|
}
|
|
8716
8716
|
intersects(comp, options) {
|
|
8717
8717
|
if (!(comp instanceof _Comparator)) {
|
|
@@ -8768,13 +8768,13 @@ var require_satisfies = __commonJS({
|
|
|
8768
8768
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/functions/satisfies.js"(exports, module) {
|
|
8769
8769
|
"use strict";
|
|
8770
8770
|
var Range = require_range();
|
|
8771
|
-
var satisfies = (
|
|
8771
|
+
var satisfies = (version2, range, options) => {
|
|
8772
8772
|
try {
|
|
8773
8773
|
range = new Range(range, options);
|
|
8774
8774
|
} catch (er) {
|
|
8775
8775
|
return false;
|
|
8776
8776
|
}
|
|
8777
|
-
return range.test(
|
|
8777
|
+
return range.test(version2);
|
|
8778
8778
|
};
|
|
8779
8779
|
module.exports = satisfies;
|
|
8780
8780
|
}
|
|
@@ -8934,8 +8934,8 @@ var require_outside = __commonJS({
|
|
|
8934
8934
|
var lt = require_lt();
|
|
8935
8935
|
var lte = require_lte();
|
|
8936
8936
|
var gte = require_gte();
|
|
8937
|
-
var outside = (
|
|
8938
|
-
|
|
8937
|
+
var outside = (version2, range, hilo, options) => {
|
|
8938
|
+
version2 = new SemVer(version2, options);
|
|
8939
8939
|
range = new Range(range, options);
|
|
8940
8940
|
let gtfn, ltefn, ltfn, comp, ecomp;
|
|
8941
8941
|
switch (hilo) {
|
|
@@ -8956,7 +8956,7 @@ var require_outside = __commonJS({
|
|
|
8956
8956
|
default:
|
|
8957
8957
|
throw new TypeError('Must provide a hilo val of "<" or ">"');
|
|
8958
8958
|
}
|
|
8959
|
-
if (satisfies(
|
|
8959
|
+
if (satisfies(version2, range, options)) {
|
|
8960
8960
|
return false;
|
|
8961
8961
|
}
|
|
8962
8962
|
for (let i = 0; i < range.set.length; ++i) {
|
|
@@ -8978,9 +8978,9 @@ var require_outside = __commonJS({
|
|
|
8978
8978
|
if (high.operator === comp || high.operator === ecomp) {
|
|
8979
8979
|
return false;
|
|
8980
8980
|
}
|
|
8981
|
-
if ((!low.operator || low.operator === comp) && ltefn(
|
|
8981
|
+
if ((!low.operator || low.operator === comp) && ltefn(version2, low.semver)) {
|
|
8982
8982
|
return false;
|
|
8983
|
-
} else if (low.operator === ecomp && ltfn(
|
|
8983
|
+
} else if (low.operator === ecomp && ltfn(version2, low.semver)) {
|
|
8984
8984
|
return false;
|
|
8985
8985
|
}
|
|
8986
8986
|
}
|
|
@@ -8995,7 +8995,7 @@ var require_gtr = __commonJS({
|
|
|
8995
8995
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/gtr.js"(exports, module) {
|
|
8996
8996
|
"use strict";
|
|
8997
8997
|
var outside = require_outside();
|
|
8998
|
-
var gtr = (
|
|
8998
|
+
var gtr = (version2, range, options) => outside(version2, range, ">", options);
|
|
8999
8999
|
module.exports = gtr;
|
|
9000
9000
|
}
|
|
9001
9001
|
});
|
|
@@ -9005,7 +9005,7 @@ var require_ltr = __commonJS({
|
|
|
9005
9005
|
"../../node_modules/.pnpm/semver@7.8.5/node_modules/semver/ranges/ltr.js"(exports, module) {
|
|
9006
9006
|
"use strict";
|
|
9007
9007
|
var outside = require_outside();
|
|
9008
|
-
var ltr = (
|
|
9008
|
+
var ltr = (version2, range, options) => outside(version2, range, "<", options);
|
|
9009
9009
|
module.exports = ltr;
|
|
9010
9010
|
}
|
|
9011
9011
|
});
|
|
@@ -9035,12 +9035,12 @@ var require_simplify = __commonJS({
|
|
|
9035
9035
|
let first = null;
|
|
9036
9036
|
let prev = null;
|
|
9037
9037
|
const v = versions.sort((a, b) => compare(a, b, options));
|
|
9038
|
-
for (const
|
|
9039
|
-
const included = satisfies(
|
|
9038
|
+
for (const version2 of v) {
|
|
9039
|
+
const included = satisfies(version2, range, options);
|
|
9040
9040
|
if (included) {
|
|
9041
|
-
prev =
|
|
9041
|
+
prev = version2;
|
|
9042
9042
|
if (!first) {
|
|
9043
|
-
first =
|
|
9043
|
+
first = version2;
|
|
9044
9044
|
}
|
|
9045
9045
|
} else {
|
|
9046
9046
|
if (prev) {
|
|
@@ -9267,7 +9267,7 @@ var require_semver2 = __commonJS({
|
|
|
9267
9267
|
var lte = require_lte();
|
|
9268
9268
|
var cmp = require_cmp();
|
|
9269
9269
|
var coerce = require_coerce();
|
|
9270
|
-
var
|
|
9270
|
+
var truncate2 = require_truncate();
|
|
9271
9271
|
var Comparator = require_comparator();
|
|
9272
9272
|
var Range = require_range();
|
|
9273
9273
|
var satisfies = require_satisfies();
|
|
@@ -9306,7 +9306,7 @@ var require_semver2 = __commonJS({
|
|
|
9306
9306
|
lte,
|
|
9307
9307
|
cmp,
|
|
9308
9308
|
coerce,
|
|
9309
|
-
truncate,
|
|
9309
|
+
truncate: truncate2,
|
|
9310
9310
|
Comparator,
|
|
9311
9311
|
Range,
|
|
9312
9312
|
satisfies,
|
|
@@ -13261,7 +13261,7 @@ var require_filters = __commonJS({
|
|
|
13261
13261
|
return r.copySafeness(str5, res);
|
|
13262
13262
|
}
|
|
13263
13263
|
_exports.indent = indent;
|
|
13264
|
-
function
|
|
13264
|
+
function join6(arr, del, attr) {
|
|
13265
13265
|
del = del || "";
|
|
13266
13266
|
if (attr) {
|
|
13267
13267
|
arr = lib.map(arr, function(v) {
|
|
@@ -13270,7 +13270,7 @@ var require_filters = __commonJS({
|
|
|
13270
13270
|
}
|
|
13271
13271
|
return arr.join(del);
|
|
13272
13272
|
}
|
|
13273
|
-
_exports.join =
|
|
13273
|
+
_exports.join = join6;
|
|
13274
13274
|
function last(arr) {
|
|
13275
13275
|
return arr[arr.length - 1];
|
|
13276
13276
|
}
|
|
@@ -13511,7 +13511,7 @@ var require_filters = __commonJS({
|
|
|
13511
13511
|
return r.copySafeness(str5, str5.replace(/^\s*|\s*$/g, ""));
|
|
13512
13512
|
}
|
|
13513
13513
|
_exports.trim = trim;
|
|
13514
|
-
function
|
|
13514
|
+
function truncate2(input, length, killwords, end) {
|
|
13515
13515
|
var orig = input;
|
|
13516
13516
|
input = normalize(input, "");
|
|
13517
13517
|
length = length || 255;
|
|
@@ -13530,7 +13530,7 @@ var require_filters = __commonJS({
|
|
|
13530
13530
|
input += end !== void 0 && end !== null ? end : "...";
|
|
13531
13531
|
return r.copySafeness(orig, input);
|
|
13532
13532
|
}
|
|
13533
|
-
_exports.truncate =
|
|
13533
|
+
_exports.truncate = truncate2;
|
|
13534
13534
|
function upper(str5) {
|
|
13535
13535
|
str5 = normalize(str5, "");
|
|
13536
13536
|
return str5.toUpperCase();
|
|
@@ -15039,7 +15039,7 @@ import OpenAI from "openai";
|
|
|
15039
15039
|
var enabled = true;
|
|
15040
15040
|
function setAgentLogging(on) {
|
|
15041
15041
|
enabled = on;
|
|
15042
|
-
console.log(
|
|
15042
|
+
if (on) console.log("[agent] logging enabled");
|
|
15043
15043
|
}
|
|
15044
15044
|
function alog(...args) {
|
|
15045
15045
|
if (enabled) console.debug("[agent]", ...args);
|
|
@@ -15708,7 +15708,7 @@ function reconcileDanglingToolCalls(messages) {
|
|
|
15708
15708
|
}
|
|
15709
15709
|
|
|
15710
15710
|
// src/cli.ts
|
|
15711
|
-
import { join as
|
|
15711
|
+
import { join as join5 } from "node:path";
|
|
15712
15712
|
|
|
15713
15713
|
// ../harness/tools/registry.ts
|
|
15714
15714
|
var registry = /* @__PURE__ */ new Map();
|
|
@@ -16436,14 +16436,14 @@ var spawnAgentsTool = {
|
|
|
16436
16436
|
},
|
|
16437
16437
|
async run(args, ctx) {
|
|
16438
16438
|
if (!ctx.spawn) return "Sub-agents are not available here (depth limit reached or unsupported context).";
|
|
16439
|
-
const
|
|
16439
|
+
const spawn3 = ctx.spawn;
|
|
16440
16440
|
const raw = Array.isArray(args.tasks) ? args.tasks : [];
|
|
16441
16441
|
const reqs = raw.map((t) => spawnReq(t && typeof t === "object" ? t : {})).filter((r) => r !== null);
|
|
16442
16442
|
if (!reqs.length) return "Error: `tasks` must contain at least one task with a non-empty `task` string.";
|
|
16443
16443
|
const results = await Promise.all(
|
|
16444
16444
|
reqs.map(async (req, i) => {
|
|
16445
16445
|
try {
|
|
16446
|
-
const r = await
|
|
16446
|
+
const r = await spawn3(req);
|
|
16447
16447
|
return `### Sub-agent ${i + 1}
|
|
16448
16448
|
${r.text}${spawnFooter(r)}`;
|
|
16449
16449
|
} catch (e) {
|
|
@@ -17297,6 +17297,12 @@ async function readAuthToken() {
|
|
|
17297
17297
|
return null;
|
|
17298
17298
|
}
|
|
17299
17299
|
}
|
|
17300
|
+
async function clearAuthToken() {
|
|
17301
|
+
try {
|
|
17302
|
+
await fs2.rm(authTokenPath(), { force: true });
|
|
17303
|
+
} catch {
|
|
17304
|
+
}
|
|
17305
|
+
}
|
|
17300
17306
|
function nodeAuthToken() {
|
|
17301
17307
|
return { getToken: async () => await readAuthToken() ?? process.env.CORENEL_TOKEN ?? null };
|
|
17302
17308
|
}
|
|
@@ -17429,9 +17435,9 @@ var PrompdParser = class {
|
|
|
17429
17435
|
}
|
|
17430
17436
|
return issues;
|
|
17431
17437
|
}
|
|
17432
|
-
isValidSemver(
|
|
17438
|
+
isValidSemver(version2) {
|
|
17433
17439
|
const semverRegex = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
17434
|
-
return semverRegex.test(
|
|
17440
|
+
return semverRegex.test(version2);
|
|
17435
17441
|
}
|
|
17436
17442
|
};
|
|
17437
17443
|
var PACKAGE_TYPE_DIRS = {
|
|
@@ -17613,17 +17619,17 @@ function parsePackageReference(packageRef) {
|
|
|
17613
17619
|
}
|
|
17614
17620
|
const name = match[1];
|
|
17615
17621
|
const rawVersion = match[2] || "latest";
|
|
17616
|
-
const
|
|
17622
|
+
const version2 = import_semver.default.valid(rawVersion) || rawVersion;
|
|
17617
17623
|
const scopeMatch = name.match(/^(@[\w.-]+)\//);
|
|
17618
17624
|
const scope = scopeMatch ? scopeMatch[1] : void 0;
|
|
17619
|
-
return { name, version, scope };
|
|
17625
|
+
return { name, version: version2, scope };
|
|
17620
17626
|
}
|
|
17621
17627
|
function parsePackageReferenceWithPath(packageRef) {
|
|
17622
|
-
const { name, version, scope } = parsePackageReference(packageRef);
|
|
17628
|
+
const { name, version: version2, scope } = parsePackageReference(packageRef);
|
|
17623
17629
|
const stripped = stripFilePath(packageRef);
|
|
17624
17630
|
const remainder = packageRef.slice(stripped.length);
|
|
17625
17631
|
const filePath = remainder.length > 1 ? remainder.slice(1) : void 0;
|
|
17626
|
-
return { name, version, scope, filePath };
|
|
17632
|
+
return { name, version: version2, scope, filePath };
|
|
17627
17633
|
}
|
|
17628
17634
|
function resolvePackageFile(packagePath, filePath) {
|
|
17629
17635
|
const normalized = posixNormalize(filePath.replace(/\\/g, "/"));
|
|
@@ -20123,8 +20129,8 @@ var MemoryFileSystem = class {
|
|
|
20123
20129
|
return joinPosix2(...pathSegments);
|
|
20124
20130
|
}
|
|
20125
20131
|
/** Get the virtual file system path for a package. */
|
|
20126
|
-
getPackagePath(packageName,
|
|
20127
|
-
return `/packages/${packageName}@${
|
|
20132
|
+
getPackagePath(packageName, version2) {
|
|
20133
|
+
return `/packages/${packageName}@${version2}`;
|
|
20128
20134
|
}
|
|
20129
20135
|
/** Get all files under an optional base path. */
|
|
20130
20136
|
getAllFiles(basePath) {
|
|
@@ -20350,6 +20356,7 @@ function nodeToolCtx(signal, opts = {}) {
|
|
|
20350
20356
|
kv: inMemoryKv(),
|
|
20351
20357
|
search: nullSearch,
|
|
20352
20358
|
confirm: async () => true,
|
|
20359
|
+
...opts.ask ? { ask: opts.ask } : {},
|
|
20353
20360
|
...opts.files ? { files: opts.files, fileMeta: { kind: opts.files.kind, label: opts.files.label, isLocalDisk: opts.files.isLocalDisk, writable: opts.files.writable } } : {}
|
|
20354
20361
|
};
|
|
20355
20362
|
}
|
|
@@ -20420,6 +20427,12 @@ async function deviceLogin(opts) {
|
|
|
20420
20427
|
}
|
|
20421
20428
|
}
|
|
20422
20429
|
|
|
20430
|
+
// src/apiBase.ts
|
|
20431
|
+
var DEFAULT_API_BASE = "https://api.corenel.ai/api";
|
|
20432
|
+
function apiBase2(explicit) {
|
|
20433
|
+
return explicit || process.env.CORENEL_API_BASE || DEFAULT_API_BASE;
|
|
20434
|
+
}
|
|
20435
|
+
|
|
20423
20436
|
// ../crew/frontmatter.ts
|
|
20424
20437
|
var import_yaml = __toESM(require_dist(), 1);
|
|
20425
20438
|
var FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
@@ -20605,6 +20618,90 @@ async function loadCrewAgentAtIfExists(files, root, name, scope = "workspace") {
|
|
|
20605
20618
|
}
|
|
20606
20619
|
}
|
|
20607
20620
|
|
|
20621
|
+
// ../harness/guardrail/permission-service.ts
|
|
20622
|
+
var LEVEL_RANK = { allow: 0, ask: 1, deny: 2 };
|
|
20623
|
+
function subjectMatches(tool, glob) {
|
|
20624
|
+
if (tool.address && matchesAnyGlob(tool.address, [glob])) return true;
|
|
20625
|
+
return matchesAnyGlob(tool.name, [glob]);
|
|
20626
|
+
}
|
|
20627
|
+
function specificity(glob) {
|
|
20628
|
+
const literal = glob.replace(/\*/g, "").length;
|
|
20629
|
+
return (glob.includes("*") ? 0 : 1e4) + literal;
|
|
20630
|
+
}
|
|
20631
|
+
function matchLevel(tool, rules) {
|
|
20632
|
+
let best;
|
|
20633
|
+
let bestScore = -1;
|
|
20634
|
+
for (const [glob, level] of Object.entries(rules)) {
|
|
20635
|
+
if (!subjectMatches(tool, glob)) continue;
|
|
20636
|
+
const score = specificity(glob);
|
|
20637
|
+
if (score > bestScore) {
|
|
20638
|
+
bestScore = score;
|
|
20639
|
+
best = level;
|
|
20640
|
+
}
|
|
20641
|
+
}
|
|
20642
|
+
return best;
|
|
20643
|
+
}
|
|
20644
|
+
function mostRestrictive(a, b) {
|
|
20645
|
+
return LEVEL_RANK[a] >= LEVEL_RANK[b] ? a : b;
|
|
20646
|
+
}
|
|
20647
|
+
var PermissionService = class {
|
|
20648
|
+
policy;
|
|
20649
|
+
prompt;
|
|
20650
|
+
defaultForReadOnly;
|
|
20651
|
+
defaultForMutating;
|
|
20652
|
+
ceiling;
|
|
20653
|
+
sessionAllow = /* @__PURE__ */ new Set();
|
|
20654
|
+
constructor(opts) {
|
|
20655
|
+
this.policy = opts.policy;
|
|
20656
|
+
if (opts.prompt) this.prompt = opts.prompt;
|
|
20657
|
+
this.defaultForReadOnly = opts.defaultForReadOnly ?? "allow";
|
|
20658
|
+
this.defaultForMutating = opts.defaultForMutating ?? "ask";
|
|
20659
|
+
if (opts.ceiling) this.ceiling = opts.ceiling;
|
|
20660
|
+
}
|
|
20661
|
+
/** Pre-approve a tool-name glob for the rest of the session (an "ask" becomes "allow"). */
|
|
20662
|
+
preApprove(toolGlob) {
|
|
20663
|
+
this.sessionAllow.add(toolGlob);
|
|
20664
|
+
}
|
|
20665
|
+
reset() {
|
|
20666
|
+
this.sessionAllow.clear();
|
|
20667
|
+
}
|
|
20668
|
+
async check(tool, input) {
|
|
20669
|
+
const level = this.resolveLevel(tool);
|
|
20670
|
+
return this.decide(level, tool.name, input);
|
|
20671
|
+
}
|
|
20672
|
+
/**
|
|
20673
|
+
* Resolve the effective level. Base precedence (highest first):
|
|
20674
|
+
* policy.permissions glob > tool.permission > mutates heuristic > policy.defaultPermission.
|
|
20675
|
+
* Then the ceiling clamps to the more restrictive of base and ceiling.
|
|
20676
|
+
*/
|
|
20677
|
+
resolveLevel(tool) {
|
|
20678
|
+
return mostRestrictive(this.resolveBaseLevel(tool), this.resolveCeilingLevel(tool));
|
|
20679
|
+
}
|
|
20680
|
+
resolveBaseLevel(tool) {
|
|
20681
|
+
const matched = this.policy.permissions && matchLevel(tool, this.policy.permissions);
|
|
20682
|
+
if (matched) return matched;
|
|
20683
|
+
if (tool.mutates && this.policy.mutatingDefault) return this.policy.mutatingDefault;
|
|
20684
|
+
if (tool.permission) return tool.permission;
|
|
20685
|
+
if (this.policy.defaultPermission) return this.policy.defaultPermission;
|
|
20686
|
+
if (tool.mutates) return this.defaultForMutating;
|
|
20687
|
+
return this.defaultForReadOnly;
|
|
20688
|
+
}
|
|
20689
|
+
resolveCeilingLevel(tool) {
|
|
20690
|
+
const c = this.ceiling;
|
|
20691
|
+
if (!c) return "allow";
|
|
20692
|
+
const matched = c.overrides && matchLevel(tool, c.overrides);
|
|
20693
|
+
if (matched) return matched;
|
|
20694
|
+
return c.defaultLevel ?? "allow";
|
|
20695
|
+
}
|
|
20696
|
+
async decide(level, name, input) {
|
|
20697
|
+
if (level === "allow") return "allow";
|
|
20698
|
+
if (level === "deny") return "deny";
|
|
20699
|
+
if (this.sessionAllow.size && matchesAnyGlob(name, [...this.sessionAllow])) return "allow";
|
|
20700
|
+
if (!this.prompt) return "deny";
|
|
20701
|
+
return this.prompt.ask({ tool: name, input });
|
|
20702
|
+
}
|
|
20703
|
+
};
|
|
20704
|
+
|
|
20608
20705
|
// ../harness/guardrail/serialize.ts
|
|
20609
20706
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
20610
20707
|
|
|
@@ -20647,7 +20744,7 @@ async function runCrewAgentCli(opts) {
|
|
|
20647
20744
|
opts.warn(`agent "${opts.agent}" is disabled; enable it before running`);
|
|
20648
20745
|
return 2;
|
|
20649
20746
|
}
|
|
20650
|
-
setGatewayBase(opts.base
|
|
20747
|
+
setGatewayBase(apiBase2(opts.base));
|
|
20651
20748
|
const token = await nodeAuthToken().getToken();
|
|
20652
20749
|
if (!token) {
|
|
20653
20750
|
opts.warn("not signed in: set CORENEL_TOKEN, or run `corenel login` on this machine");
|
|
@@ -20704,20 +20801,76 @@ import { createRequire } from "node:module";
|
|
|
20704
20801
|
import { existsSync, readFileSync } from "node:fs";
|
|
20705
20802
|
import { dirname as dirname2, join as join3 } from "node:path";
|
|
20706
20803
|
import { fileURLToPath } from "node:url";
|
|
20707
|
-
|
|
20708
|
-
|
|
20804
|
+
|
|
20805
|
+
// src/extensions.ts
|
|
20806
|
+
var SIDECAR = { pkg: "@corenel/sidecar", entry: "dist/cli.js" };
|
|
20807
|
+
var EXTENSIONS = [
|
|
20808
|
+
{
|
|
20809
|
+
command: "sidecar",
|
|
20810
|
+
...SIDECAR,
|
|
20811
|
+
summary: "run the sidecar on this machine",
|
|
20812
|
+
// Everything after the verb is the sidecar's business -- no flag parsing
|
|
20813
|
+
// here, so a flag added there needs no change in this package. A leading
|
|
20814
|
+
// `start` is absorbed because it reads naturally and the sidecar has no
|
|
20815
|
+
// such verb; its real subcommands must pass through untouched.
|
|
20816
|
+
argv: (rest) => rest[0] === "start" ? rest.slice(1) : rest
|
|
20817
|
+
},
|
|
20818
|
+
{
|
|
20819
|
+
command: "acp",
|
|
20820
|
+
...SIDECAR,
|
|
20821
|
+
summary: "proxy an external coding agent under Corenel policy",
|
|
20822
|
+
/* `corenel acp claude-code --acp-policy read-only` -> the sidecar's own flags.
|
|
20823
|
+
*
|
|
20824
|
+
* ONLY a bare first word is promoted to the target. Anything already spelled
|
|
20825
|
+
* as a flag passes through untouched, because the sidecar is the authority
|
|
20826
|
+
* on its own options -- and because injecting `--acp` in front of `--help`
|
|
20827
|
+
* made the sidecar read "--help" as the name of an agent to proxy. With no
|
|
20828
|
+
* arguments at all there is nothing to run, so show the flags instead of
|
|
20829
|
+
* failing on a missing value. */
|
|
20830
|
+
argv: (rest) => {
|
|
20831
|
+
if (!rest.length) return ["--help"];
|
|
20832
|
+
if (rest[0].startsWith("-")) return rest;
|
|
20833
|
+
return ["--acp", rest[0], ...rest.slice(1)];
|
|
20834
|
+
}
|
|
20835
|
+
},
|
|
20836
|
+
{
|
|
20837
|
+
command: "sessions",
|
|
20838
|
+
...SIDECAR,
|
|
20839
|
+
summary: "list and inspect local sandbox sessions",
|
|
20840
|
+
argv: (rest) => ["sessions", ...rest]
|
|
20841
|
+
}
|
|
20842
|
+
];
|
|
20843
|
+
function findExtension(command) {
|
|
20844
|
+
return EXTENSIONS.find((e) => e.command === command);
|
|
20845
|
+
}
|
|
20846
|
+
var EXTENSION_COMMANDS = EXTENSIONS.map((e) => e.command);
|
|
20847
|
+
function missingMessage(e) {
|
|
20848
|
+
return [
|
|
20849
|
+
`${e.command} needs ${e.pkg}, which is not installed.`,
|
|
20850
|
+
"",
|
|
20851
|
+
` npm install -g ${e.pkg}`,
|
|
20852
|
+
` pnpm add -g ${e.pkg}`,
|
|
20853
|
+
"",
|
|
20854
|
+
"It ships separately because it is a server with its own release line."
|
|
20855
|
+
].join("\n");
|
|
20709
20856
|
}
|
|
20857
|
+
|
|
20858
|
+
// src/sidecar.ts
|
|
20710
20859
|
function findSidecarEntry(look = {}) {
|
|
20860
|
+
return findExtensionEntry("@corenel/sidecar", "dist/cli.js", look);
|
|
20861
|
+
}
|
|
20862
|
+
function findExtensionEntry(pkg, entry, look = {}) {
|
|
20711
20863
|
const exists = look.exists ?? existsSync;
|
|
20712
20864
|
const req = look.resolve ?? createRequire(import.meta.url).resolve;
|
|
20713
20865
|
try {
|
|
20714
|
-
const direct = req(
|
|
20866
|
+
const direct = req(`${pkg}/${entry}`);
|
|
20715
20867
|
if (exists(direct)) return direct;
|
|
20716
20868
|
} catch {
|
|
20717
20869
|
}
|
|
20718
20870
|
let dir = look.fromDir ?? dirname2(fileURLToPath(import.meta.url));
|
|
20871
|
+
const parts = [...pkg.split("/"), ...entry.split("/")];
|
|
20719
20872
|
for (let up = 0; up < 8; up++) {
|
|
20720
|
-
const candidate = join3(dir, "node_modules",
|
|
20873
|
+
const candidate = join3(dir, "node_modules", ...parts);
|
|
20721
20874
|
if (exists(candidate)) return candidate;
|
|
20722
20875
|
const parent = dirname2(dir);
|
|
20723
20876
|
if (parent === dir) break;
|
|
@@ -20746,20 +20899,20 @@ var SIDECAR_MISSING = [
|
|
|
20746
20899
|
"It ships separately because it is a server with its own release line.",
|
|
20747
20900
|
"Once installed, `corenel sidecar \u2026` and `corenel-sidecar \u2026` are the same thing."
|
|
20748
20901
|
].join("\n");
|
|
20749
|
-
async function
|
|
20750
|
-
const entry =
|
|
20902
|
+
async function runExtension(ext, rest, look = {}) {
|
|
20903
|
+
const entry = findExtensionEntry(ext.pkg, ext.entry, look);
|
|
20751
20904
|
if (!entry) {
|
|
20752
|
-
process.stderr.write(`corenel: ${
|
|
20905
|
+
process.stderr.write(`corenel: ${missingMessage(ext)}
|
|
20753
20906
|
`);
|
|
20754
20907
|
return 127;
|
|
20755
20908
|
}
|
|
20756
|
-
process.stderr.write(`corenel:
|
|
20909
|
+
process.stderr.write(`corenel: ${ext.pkg.replace("@corenel/", "")} ${versionAt(entry)} (${entry})
|
|
20757
20910
|
`);
|
|
20758
|
-
const child = spawn(process.execPath, [entry, ...
|
|
20911
|
+
const child = spawn(process.execPath, [entry, ...ext.argv(rest)], {
|
|
20759
20912
|
stdio: "inherit",
|
|
20760
|
-
// So
|
|
20761
|
-
// than
|
|
20762
|
-
env: { ...process.env, CORENEL_ARGV0:
|
|
20913
|
+
// So the extension's own --help prints the command the user actually typed
|
|
20914
|
+
// rather than its standalone name.
|
|
20915
|
+
env: { ...process.env, CORENEL_ARGV0: `corenel ${ext.command}` }
|
|
20763
20916
|
});
|
|
20764
20917
|
const forward = (sig) => () => {
|
|
20765
20918
|
if (!child.killed) child.kill(sig);
|
|
@@ -20781,6 +20934,539 @@ async function proxyToSidecar(rest, look = {}) {
|
|
|
20781
20934
|
}
|
|
20782
20935
|
}
|
|
20783
20936
|
|
|
20937
|
+
// src/commands.ts
|
|
20938
|
+
var COMMANDS = [
|
|
20939
|
+
{ name: "", args: "", summary: "with no command: an interactive agent in this directory" },
|
|
20940
|
+
{ name: "run", args: '"<prompt>" [--session ID]', summary: "one-shot turn, then exit (--session runs it inside a sandbox)" },
|
|
20941
|
+
{ name: "run-agent", args: '<name> --input "<text>"', summary: "run a crew agent; events as JSON Lines on stdout" },
|
|
20942
|
+
{ name: "sidecar", args: "[start] [flags]", summary: "run the sidecar on this machine" },
|
|
20943
|
+
{ name: "acp", args: "<agent> [flags]", summary: "proxy an external coding agent under Corenel policy" },
|
|
20944
|
+
{ name: "sessions", args: "[list|show|create|run]", summary: "create, list and run in local sandbox sessions" },
|
|
20945
|
+
{ name: "login", args: "[--base URL]", summary: "sign in through your browser (device flow)" },
|
|
20946
|
+
{ name: "auth", summary: "show whether you are signed in, and as what" },
|
|
20947
|
+
{ name: "logout", summary: "forget the stored token" },
|
|
20948
|
+
{ name: "doctor", summary: "check the things that usually turn out to be wrong" }
|
|
20949
|
+
];
|
|
20950
|
+
var COMMAND_NAMES = COMMANDS.map((c) => c.name).filter(Boolean);
|
|
20951
|
+
function isCommand(name) {
|
|
20952
|
+
return COMMAND_NAMES.includes(name);
|
|
20953
|
+
}
|
|
20954
|
+
function isHelpFlag(a) {
|
|
20955
|
+
return a === "--help" || a === "-h" || a === "help";
|
|
20956
|
+
}
|
|
20957
|
+
function isVersionFlag(a) {
|
|
20958
|
+
return a === "--version" || a === "-v" || a === "version";
|
|
20959
|
+
}
|
|
20960
|
+
function helpText(version2) {
|
|
20961
|
+
const shown = COMMANDS.filter((c) => c.name);
|
|
20962
|
+
const left = (c) => `corenel ${c.name}${c.args ? ` ${c.args}` : ""}`;
|
|
20963
|
+
const width = Math.max(...shown.map((c) => left(c).length));
|
|
20964
|
+
const bare = COMMANDS.find((c) => !c.name);
|
|
20965
|
+
return [
|
|
20966
|
+
`corenel ${version2} \u2014 the harness, in node.`,
|
|
20967
|
+
"",
|
|
20968
|
+
"Usage:",
|
|
20969
|
+
` corenel${" ".repeat(Math.max(1, width - 7))} ${bare ? bare.summary : ""}`,
|
|
20970
|
+
...shown.map((c) => ` ${left(c).padEnd(width)} ${c.summary}`),
|
|
20971
|
+
"",
|
|
20972
|
+
"Common flags:",
|
|
20973
|
+
" --model <id> model for this turn (default gpt-4o-mini)",
|
|
20974
|
+
" --base <url> API base (default https://api.corenel.ai/api, or CORENEL_API_BASE)",
|
|
20975
|
+
" --allow-shell run commands without asking each time",
|
|
20976
|
+
" --no-tui plain line-by-line mode (automatic when output is piped)",
|
|
20977
|
+
" --tui force the full terminal face, and fail if it cannot start",
|
|
20978
|
+
" --resume [id] reopen the last conversation, or the one named",
|
|
20979
|
+
" --debug trace every agent step (also CORENEL_DEBUG=1)",
|
|
20980
|
+
" --version, -v print the version",
|
|
20981
|
+
" --help, -h print this",
|
|
20982
|
+
"",
|
|
20983
|
+
"--resume reopens a CONVERSATION (this face's own chat log, saved under",
|
|
20984
|
+
".corenel/sessions/) -- not the same thing as `run --session ID` or the",
|
|
20985
|
+
"`sessions` command below, which forward into a sandbox on the sidecar.",
|
|
20986
|
+
"Same word, two different nouns.",
|
|
20987
|
+
"",
|
|
20988
|
+
"sidecar, acp and sessions are provided by @corenel/sidecar, installed separately.",
|
|
20989
|
+
"Each takes its own flags: `corenel sidecar --help`.",
|
|
20990
|
+
""
|
|
20991
|
+
].join("\n");
|
|
20992
|
+
}
|
|
20993
|
+
|
|
20994
|
+
// src/version.ts
|
|
20995
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
20996
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
20997
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
20998
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
20999
|
+
function selfPath() {
|
|
21000
|
+
try {
|
|
21001
|
+
return fileURLToPath2(import.meta.url);
|
|
21002
|
+
} catch {
|
|
21003
|
+
return process.argv[1] ?? "(unknown)";
|
|
21004
|
+
}
|
|
21005
|
+
}
|
|
21006
|
+
function version(read = (p) => readFileSync2(p, "utf8")) {
|
|
21007
|
+
let dir = dirname3(selfPath());
|
|
21008
|
+
for (let up = 0; up < 4; up++) {
|
|
21009
|
+
try {
|
|
21010
|
+
const parsed = JSON.parse(read(join4(dir, "package.json")));
|
|
21011
|
+
const v = parsed;
|
|
21012
|
+
if (v.name === "@corenel/cli" && typeof v.version === "string") return v.version;
|
|
21013
|
+
} catch {
|
|
21014
|
+
}
|
|
21015
|
+
const parent = dirname3(dir);
|
|
21016
|
+
if (parent === dir) break;
|
|
21017
|
+
dir = parent;
|
|
21018
|
+
}
|
|
21019
|
+
try {
|
|
21020
|
+
const req = createRequire2(import.meta.url);
|
|
21021
|
+
const parsed = JSON.parse(read(req.resolve("@corenel/cli/package.json")));
|
|
21022
|
+
const v = parsed.version;
|
|
21023
|
+
if (typeof v === "string") return v;
|
|
21024
|
+
} catch {
|
|
21025
|
+
}
|
|
21026
|
+
return "(unknown)";
|
|
21027
|
+
}
|
|
21028
|
+
|
|
21029
|
+
// src/auth.ts
|
|
21030
|
+
function hintOf(token) {
|
|
21031
|
+
const t = token.trim();
|
|
21032
|
+
if (t.length <= 8) return "****";
|
|
21033
|
+
return `${t.slice(0, 4)}\u2026${t.slice(-2)} (${t.length} chars)`;
|
|
21034
|
+
}
|
|
21035
|
+
async function authState(read = readAuthToken, env = process.env) {
|
|
21036
|
+
const path = authTokenPath();
|
|
21037
|
+
const stored = await read();
|
|
21038
|
+
if (stored) return { source: "file", path, hint: hintOf(stored) };
|
|
21039
|
+
if (env.CORENEL_TOKEN) return { source: "env", path, hint: hintOf(env.CORENEL_TOKEN) };
|
|
21040
|
+
return { source: "none", path };
|
|
21041
|
+
}
|
|
21042
|
+
function describeAuth(s, base) {
|
|
21043
|
+
if (s.source === "none") {
|
|
21044
|
+
return [
|
|
21045
|
+
"Not signed in.",
|
|
21046
|
+
` Run \`corenel login\`, or set CORENEL_TOKEN=<token>.`,
|
|
21047
|
+
` Token would be stored at ${s.path}`
|
|
21048
|
+
].join("\n");
|
|
21049
|
+
}
|
|
21050
|
+
return [
|
|
21051
|
+
`Signed in (${s.source === "env" ? "CORENEL_TOKEN environment variable" : s.path}).`,
|
|
21052
|
+
` token ${s.hint}`,
|
|
21053
|
+
` api ${base}`,
|
|
21054
|
+
s.source === "env" ? " NOTE: the environment wins over any stored token, so `corenel logout` will not change this." : null
|
|
21055
|
+
].filter(Boolean).join("\n");
|
|
21056
|
+
}
|
|
21057
|
+
async function runAuth(out = (s) => process.stdout.write(s)) {
|
|
21058
|
+
out(`${describeAuth(await authState(), apiBase2())}
|
|
21059
|
+
`);
|
|
21060
|
+
}
|
|
21061
|
+
async function runLogout(out = (s) => process.stdout.write(s)) {
|
|
21062
|
+
const before = await authState();
|
|
21063
|
+
await clearAuthToken();
|
|
21064
|
+
if (before.source === "file") out(`Signed out. Removed ${before.path}
|
|
21065
|
+
`);
|
|
21066
|
+
else out("Nothing to forget \u2014 no stored token.\n");
|
|
21067
|
+
if (process.env.CORENEL_TOKEN) {
|
|
21068
|
+
out(" NOTE: CORENEL_TOKEN is still set in this environment, so you are still authenticated.\n");
|
|
21069
|
+
}
|
|
21070
|
+
}
|
|
21071
|
+
|
|
21072
|
+
// src/doctor.ts
|
|
21073
|
+
var MARK = { ok: " ok ", warn: " warn ", fail: " FAIL " };
|
|
21074
|
+
function formatChecks(checks) {
|
|
21075
|
+
return checks.map((c) => `[${MARK[c.status]}] ${c.name.padEnd(12)} ${c.detail}`).join("\n");
|
|
21076
|
+
}
|
|
21077
|
+
async function checkToken(base, token, f = fetch) {
|
|
21078
|
+
if (!token) return { name: "token", status: "warn", detail: "no credential \u2014 run `corenel login`" };
|
|
21079
|
+
let res;
|
|
21080
|
+
try {
|
|
21081
|
+
res = await f(`${base}/v1/chat/completions`, {
|
|
21082
|
+
method: "POST",
|
|
21083
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
21084
|
+
body: JSON.stringify({ model: "gpt-4o-mini", messages: [] })
|
|
21085
|
+
});
|
|
21086
|
+
} catch (e) {
|
|
21087
|
+
return { name: "token", status: "fail", detail: `could not reach ${base} (${e instanceof Error ? e.message : String(e)})` };
|
|
21088
|
+
}
|
|
21089
|
+
if (res.status === 401 || res.status === 403) {
|
|
21090
|
+
return { name: "token", status: "fail", detail: `rejected by ${base} (${res.status}) \u2014 run \`corenel login\` again` };
|
|
21091
|
+
}
|
|
21092
|
+
if (res.status === 404) {
|
|
21093
|
+
return { name: "token", status: "fail", detail: `${base}/v1/chat/completions is 404 \u2014 the base is wrong (it usually needs /api)` };
|
|
21094
|
+
}
|
|
21095
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
21096
|
+
if (!ct.includes("json")) {
|
|
21097
|
+
return { name: "token", status: "fail", detail: `${base} answered ${res.status} ${ct || "no content-type"} \u2014 that is not the API` };
|
|
21098
|
+
}
|
|
21099
|
+
return { name: "token", status: "ok", detail: `accepted by ${base} (${res.status})` };
|
|
21100
|
+
}
|
|
21101
|
+
async function collectChecks(f = fetch) {
|
|
21102
|
+
const base = apiBase2();
|
|
21103
|
+
const checks = [
|
|
21104
|
+
{ name: "binary", status: "ok", detail: selfPath() },
|
|
21105
|
+
{ name: "version", status: "ok", detail: `@corenel/cli ${version()}` },
|
|
21106
|
+
{ name: "node", status: "ok", detail: process.version },
|
|
21107
|
+
{
|
|
21108
|
+
name: "api",
|
|
21109
|
+
status: "ok",
|
|
21110
|
+
detail: base === DEFAULT_API_BASE ? base : `${base} (overridden; default is ${DEFAULT_API_BASE})`
|
|
21111
|
+
}
|
|
21112
|
+
];
|
|
21113
|
+
try {
|
|
21114
|
+
const u = new URL(base);
|
|
21115
|
+
if (u.pathname === "" || u.pathname === "/") {
|
|
21116
|
+
checks.push({ name: "api path", status: "warn", detail: "base has no path \u2014 the API is mounted under /api" });
|
|
21117
|
+
}
|
|
21118
|
+
} catch {
|
|
21119
|
+
checks.push({ name: "api", status: "fail", detail: `${base} is not a URL` });
|
|
21120
|
+
}
|
|
21121
|
+
const auth = await authState();
|
|
21122
|
+
checks.push({
|
|
21123
|
+
name: "signed in",
|
|
21124
|
+
status: auth.source === "none" ? "warn" : "ok",
|
|
21125
|
+
detail: auth.source === "none" ? "no" : `yes, from ${auth.source === "env" ? "CORENEL_TOKEN" : auth.path} (${auth.hint})`
|
|
21126
|
+
});
|
|
21127
|
+
checks.push(await checkToken(base, await readAuthToken() ?? process.env.CORENEL_TOKEN ?? null, f));
|
|
21128
|
+
const sidecar = findSidecarEntry();
|
|
21129
|
+
checks.push({
|
|
21130
|
+
name: "sidecar",
|
|
21131
|
+
status: sidecar ? "ok" : "warn",
|
|
21132
|
+
detail: sidecar ? `${versionAt(sidecar)} at ${sidecar}` : "not installed \u2014 `npm i -g @corenel/sidecar`"
|
|
21133
|
+
});
|
|
21134
|
+
return checks;
|
|
21135
|
+
}
|
|
21136
|
+
async function runDoctor(out = (s) => process.stdout.write(s), f = fetch) {
|
|
21137
|
+
const checks = await collectChecks(f);
|
|
21138
|
+
out(`${formatChecks(checks)}
|
|
21139
|
+
`);
|
|
21140
|
+
const failed = checks.filter((c) => c.status === "fail");
|
|
21141
|
+
if (failed.length) {
|
|
21142
|
+
out(`
|
|
21143
|
+
${failed.length} problem${failed.length > 1 ? "s" : ""} above.
|
|
21144
|
+
`);
|
|
21145
|
+
return 1;
|
|
21146
|
+
}
|
|
21147
|
+
return 0;
|
|
21148
|
+
}
|
|
21149
|
+
|
|
21150
|
+
// src/repl.ts
|
|
21151
|
+
import { createInterface } from "node:readline";
|
|
21152
|
+
import { TermSession } from "@corenel/term/session";
|
|
21153
|
+
import { describeToolCall } from "@corenel/term/describe";
|
|
21154
|
+
function isQuit(line) {
|
|
21155
|
+
const t = line.trim().toLowerCase();
|
|
21156
|
+
return t === "/exit" || t === "/quit" || t === "exit" || t === "quit";
|
|
21157
|
+
}
|
|
21158
|
+
function nextShownCursor(itemsLength, shown) {
|
|
21159
|
+
return itemsLength < shown ? 0 : shown;
|
|
21160
|
+
}
|
|
21161
|
+
function formatQuestion(q) {
|
|
21162
|
+
const lines = [` ${q.header} ${q.question}`];
|
|
21163
|
+
q.options.forEach((o, i) => {
|
|
21164
|
+
lines.push(` ${i + 1}) ${o.label}`);
|
|
21165
|
+
});
|
|
21166
|
+
return `${lines.join("\n")}
|
|
21167
|
+
`;
|
|
21168
|
+
}
|
|
21169
|
+
function parseQuestionAnswer(q, line) {
|
|
21170
|
+
if (line === null) return null;
|
|
21171
|
+
const t = line.trim();
|
|
21172
|
+
if (!t) return null;
|
|
21173
|
+
if (/^\d+$/.test(t)) {
|
|
21174
|
+
const n = Number(t);
|
|
21175
|
+
if (n >= 1 && n <= q.options.length) return { [q.header]: [q.options[n - 1].label] };
|
|
21176
|
+
}
|
|
21177
|
+
return { [q.header]: [t] };
|
|
21178
|
+
}
|
|
21179
|
+
var REPL_BANNER = (model, cwd) => [
|
|
21180
|
+
`corenel \u2014 ${model}, working in ${cwd}`,
|
|
21181
|
+
"Type a request. /clear forgets the conversation, /exit leaves, Ctrl-C stops a turn.",
|
|
21182
|
+
""
|
|
21183
|
+
].join("\n");
|
|
21184
|
+
function makeEventRenderer(write) {
|
|
21185
|
+
let streaming = false;
|
|
21186
|
+
const endStream = () => {
|
|
21187
|
+
if (streaming) {
|
|
21188
|
+
write("\n");
|
|
21189
|
+
streaming = false;
|
|
21190
|
+
}
|
|
21191
|
+
};
|
|
21192
|
+
return (e) => {
|
|
21193
|
+
switch (e.type) {
|
|
21194
|
+
case "assistant-delta":
|
|
21195
|
+
streaming = true;
|
|
21196
|
+
write(e.delta);
|
|
21197
|
+
break;
|
|
21198
|
+
case "tool-call": {
|
|
21199
|
+
endStream();
|
|
21200
|
+
const subject = describeToolCall(e.name, e.args);
|
|
21201
|
+
write(` \xB7 ${e.name}${subject ? ` ${subject}` : ""}
|
|
21202
|
+
`);
|
|
21203
|
+
break;
|
|
21204
|
+
}
|
|
21205
|
+
case "tool-result":
|
|
21206
|
+
if (e.isError) write(` ! ${e.name} failed
|
|
21207
|
+
`);
|
|
21208
|
+
break;
|
|
21209
|
+
case "done":
|
|
21210
|
+
endStream();
|
|
21211
|
+
break;
|
|
21212
|
+
default:
|
|
21213
|
+
break;
|
|
21214
|
+
}
|
|
21215
|
+
};
|
|
21216
|
+
}
|
|
21217
|
+
async function runRepl(deps) {
|
|
21218
|
+
const input = deps.input ?? process.stdin;
|
|
21219
|
+
const output = deps.output ?? process.stdout;
|
|
21220
|
+
let atLineStart = true;
|
|
21221
|
+
const write = (s) => {
|
|
21222
|
+
output.write(s);
|
|
21223
|
+
if (s.length > 0) atLineStart = s.endsWith("\n");
|
|
21224
|
+
};
|
|
21225
|
+
const writeLine = (s) => {
|
|
21226
|
+
if (!atLineStart) write("\n");
|
|
21227
|
+
write(s);
|
|
21228
|
+
};
|
|
21229
|
+
write(REPL_BANNER(deps.model, deps.cwd));
|
|
21230
|
+
const render = makeEventRenderer(write);
|
|
21231
|
+
const session = new TermSession({
|
|
21232
|
+
cwd: deps.cwd,
|
|
21233
|
+
model: deps.model,
|
|
21234
|
+
system: deps.system,
|
|
21235
|
+
client: deps.client,
|
|
21236
|
+
tools: deps.tools,
|
|
21237
|
+
toolCtx: (signal, askUser) => deps.toolCtx(signal, askUser),
|
|
21238
|
+
onEvent: render,
|
|
21239
|
+
...deps.runner ? { runner: deps.runner } : {},
|
|
21240
|
+
...deps.approveAll ? { approveAll: true } : {},
|
|
21241
|
+
...deps.persistence ? { persistence: deps.persistence } : {}
|
|
21242
|
+
});
|
|
21243
|
+
let shown = 0;
|
|
21244
|
+
session.subscribe(() => {
|
|
21245
|
+
const items = session.getSnapshot().committed;
|
|
21246
|
+
shown = nextShownCursor(items.length, shown);
|
|
21247
|
+
for (; shown < items.length; shown++) {
|
|
21248
|
+
const it = items[shown];
|
|
21249
|
+
if (it.kind !== "note") continue;
|
|
21250
|
+
writeLine(` ${it.level === "info" ? "" : "! "}${it.text}
|
|
21251
|
+
`);
|
|
21252
|
+
if (it.detail) write(`${it.detail}
|
|
21253
|
+
`);
|
|
21254
|
+
}
|
|
21255
|
+
});
|
|
21256
|
+
if (deps.resume) {
|
|
21257
|
+
await session.resume(deps.resume.id);
|
|
21258
|
+
const restored = session.getSnapshot();
|
|
21259
|
+
if (restored.session) {
|
|
21260
|
+
writeLine(` resumed ${restored.session.id} - ${restored.committed.length} messages
|
|
21261
|
+
`);
|
|
21262
|
+
}
|
|
21263
|
+
}
|
|
21264
|
+
const rl = createInterface({ input, output });
|
|
21265
|
+
let closed = false;
|
|
21266
|
+
rl.on("close", () => {
|
|
21267
|
+
closed = true;
|
|
21268
|
+
});
|
|
21269
|
+
const ask = (q) => closed ? Promise.resolve(null) : new Promise((resolve2) => {
|
|
21270
|
+
const onClose = () => resolve2(null);
|
|
21271
|
+
rl.once("close", onClose);
|
|
21272
|
+
rl.question(q, (answer) => {
|
|
21273
|
+
rl.off("close", onClose);
|
|
21274
|
+
resolve2(answer);
|
|
21275
|
+
});
|
|
21276
|
+
});
|
|
21277
|
+
let turnActive = false;
|
|
21278
|
+
const onSigint = () => {
|
|
21279
|
+
if (turnActive) session.abort();
|
|
21280
|
+
else {
|
|
21281
|
+
write("\n");
|
|
21282
|
+
rl.close();
|
|
21283
|
+
}
|
|
21284
|
+
};
|
|
21285
|
+
rl.on("SIGINT", onSigint);
|
|
21286
|
+
const permission = new PermissionService({
|
|
21287
|
+
policy: STANDARD_POLICY,
|
|
21288
|
+
prompt: {
|
|
21289
|
+
ask: async (req) => {
|
|
21290
|
+
if (deps.approveAll) return "allow";
|
|
21291
|
+
const detail = req.input?.command;
|
|
21292
|
+
write(`
|
|
21293
|
+
${req.tool}${typeof detail === "string" ? `: ${detail}` : ""}
|
|
21294
|
+
`);
|
|
21295
|
+
const answer = await ask(" run it? [y/N] ");
|
|
21296
|
+
return answer !== null && /^y(es)?$/i.test(answer.trim()) ? "allow" : "deny";
|
|
21297
|
+
}
|
|
21298
|
+
}
|
|
21299
|
+
});
|
|
21300
|
+
session.attachPermission(permission);
|
|
21301
|
+
let questionOpen = false;
|
|
21302
|
+
session.subscribe(() => {
|
|
21303
|
+
const modal = session.getSnapshot().modal;
|
|
21304
|
+
if (!modal || modal.kind !== "user") {
|
|
21305
|
+
questionOpen = false;
|
|
21306
|
+
return;
|
|
21307
|
+
}
|
|
21308
|
+
if (questionOpen) return;
|
|
21309
|
+
questionOpen = true;
|
|
21310
|
+
const q = modal.questions[0];
|
|
21311
|
+
if (!q) {
|
|
21312
|
+
session.answer(null);
|
|
21313
|
+
return;
|
|
21314
|
+
}
|
|
21315
|
+
writeLine(formatQuestion(q));
|
|
21316
|
+
void ask(" answer (number, text, or empty to skip): ").then((line) => {
|
|
21317
|
+
if (session.getSnapshot().modal?.kind !== "user") return;
|
|
21318
|
+
session.answer(parseQuestionAnswer(q, line));
|
|
21319
|
+
});
|
|
21320
|
+
});
|
|
21321
|
+
for (; ; ) {
|
|
21322
|
+
const line = await ask("\u203A ");
|
|
21323
|
+
if (line === null) break;
|
|
21324
|
+
const text = line.trim();
|
|
21325
|
+
if (!text) continue;
|
|
21326
|
+
if (isQuit(text)) break;
|
|
21327
|
+
turnActive = true;
|
|
21328
|
+
await session.submit(text);
|
|
21329
|
+
turnActive = false;
|
|
21330
|
+
if (session.wantsExit) break;
|
|
21331
|
+
}
|
|
21332
|
+
rl.off("SIGINT", onSigint);
|
|
21333
|
+
rl.close();
|
|
21334
|
+
return 0;
|
|
21335
|
+
}
|
|
21336
|
+
|
|
21337
|
+
// src/cli.ts
|
|
21338
|
+
import { createSessionPersistence } from "@corenel/term/persist";
|
|
21339
|
+
|
|
21340
|
+
// src/shellTool.ts
|
|
21341
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
21342
|
+
var MAX_OUTPUT = 3e4;
|
|
21343
|
+
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
21344
|
+
function truncate(s, max = MAX_OUTPUT) {
|
|
21345
|
+
if (s.length <= max) return s;
|
|
21346
|
+
const kept = s.slice(0, max);
|
|
21347
|
+
return `${kept}
|
|
21348
|
+
\u2026 [${s.length - max} more characters truncated]`;
|
|
21349
|
+
}
|
|
21350
|
+
function formatResult(r) {
|
|
21351
|
+
const parts = [r.timedOut ? "timed out" : `exit ${r.code ?? "unknown"}`];
|
|
21352
|
+
if (r.stdout.trim()) parts.push(`stdout:
|
|
21353
|
+
${truncate(r.stdout)}`);
|
|
21354
|
+
if (r.stderr.trim()) parts.push(`stderr:
|
|
21355
|
+
${truncate(r.stderr)}`);
|
|
21356
|
+
if (!r.stdout.trim() && !r.stderr.trim()) parts.push("(no output)");
|
|
21357
|
+
return parts.join("\n");
|
|
21358
|
+
}
|
|
21359
|
+
function killTree(child) {
|
|
21360
|
+
const pid = child.pid;
|
|
21361
|
+
if (pid === void 0) {
|
|
21362
|
+
child.kill("SIGKILL");
|
|
21363
|
+
return;
|
|
21364
|
+
}
|
|
21365
|
+
if (process.platform === "win32") {
|
|
21366
|
+
spawn2("taskkill", ["/pid", String(pid), "/T", "/F"], { stdio: "ignore" }).on("error", () => {
|
|
21367
|
+
child.kill("SIGKILL");
|
|
21368
|
+
});
|
|
21369
|
+
return;
|
|
21370
|
+
}
|
|
21371
|
+
try {
|
|
21372
|
+
process.kill(-pid, "SIGKILL");
|
|
21373
|
+
} catch {
|
|
21374
|
+
child.kill("SIGKILL");
|
|
21375
|
+
}
|
|
21376
|
+
}
|
|
21377
|
+
function execute(command, opts) {
|
|
21378
|
+
return new Promise((resolve2) => {
|
|
21379
|
+
const child = spawn2(command, {
|
|
21380
|
+
cwd: opts.cwd,
|
|
21381
|
+
shell: true,
|
|
21382
|
+
// Its own process group on POSIX, so killTree can signal the group rather
|
|
21383
|
+
// than the shell alone. On Windows this is a no-op; taskkill /T does it.
|
|
21384
|
+
detached: process.platform !== "win32",
|
|
21385
|
+
// A child inheriting this process's stdin would compete with the REPL's
|
|
21386
|
+
// readline for keystrokes; an interactive command gets EOF instead of
|
|
21387
|
+
// silently eating the next thing typed.
|
|
21388
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
21389
|
+
});
|
|
21390
|
+
let stdout = "";
|
|
21391
|
+
let stderr = "";
|
|
21392
|
+
let timedOut = false;
|
|
21393
|
+
child.stdout?.on("data", (d) => {
|
|
21394
|
+
stdout += d.toString();
|
|
21395
|
+
});
|
|
21396
|
+
child.stderr?.on("data", (d) => {
|
|
21397
|
+
stderr += d.toString();
|
|
21398
|
+
});
|
|
21399
|
+
const timer = setTimeout(() => {
|
|
21400
|
+
timedOut = true;
|
|
21401
|
+
killTree(child);
|
|
21402
|
+
}, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
21403
|
+
const onAbort = () => {
|
|
21404
|
+
killTree(child);
|
|
21405
|
+
};
|
|
21406
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
21407
|
+
const finish = (code) => {
|
|
21408
|
+
clearTimeout(timer);
|
|
21409
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
21410
|
+
resolve2({ code, stdout, stderr, timedOut });
|
|
21411
|
+
};
|
|
21412
|
+
child.on("error", (e) => {
|
|
21413
|
+
stderr += String(e);
|
|
21414
|
+
finish(null);
|
|
21415
|
+
});
|
|
21416
|
+
child.on("close", (code) => finish(code));
|
|
21417
|
+
});
|
|
21418
|
+
}
|
|
21419
|
+
function shellTool(cwd) {
|
|
21420
|
+
return {
|
|
21421
|
+
name: "shell",
|
|
21422
|
+
description: "Run a shell command in the working directory and return its exit code and output. Use for build, test, install, git and any other command the user asks you to run. Commands run one at a time; chain with && if order matters.",
|
|
21423
|
+
namespace: "shell",
|
|
21424
|
+
mutates: true,
|
|
21425
|
+
// Shown beside the permission prompt: a rule named `shell` only answers
|
|
21426
|
+
// "what can it do to me" if you already know the catalogue.
|
|
21427
|
+
means: "run any command on this machine, as you",
|
|
21428
|
+
parameters: {
|
|
21429
|
+
type: "object",
|
|
21430
|
+
properties: {
|
|
21431
|
+
command: { type: "string", description: "The command line to run, exactly as typed in a terminal." }
|
|
21432
|
+
},
|
|
21433
|
+
required: ["command"]
|
|
21434
|
+
},
|
|
21435
|
+
async run(args, ctx) {
|
|
21436
|
+
const command = args.command;
|
|
21437
|
+
if (typeof command !== "string" || !command.trim()) return "error: no command given";
|
|
21438
|
+
const opts = { cwd };
|
|
21439
|
+
if (ctx.signal) opts.signal = ctx.signal;
|
|
21440
|
+
return formatResult(await execute(command, opts));
|
|
21441
|
+
}
|
|
21442
|
+
};
|
|
21443
|
+
}
|
|
21444
|
+
|
|
21445
|
+
// src/tuiChoice.ts
|
|
21446
|
+
function chooseFace(env) {
|
|
21447
|
+
if (env.argv.includes("--no-tui")) return "readline";
|
|
21448
|
+
if (env.argv.includes("--tui")) return "tui";
|
|
21449
|
+
if (!env.stdinTty || !env.stdoutTty) return "readline";
|
|
21450
|
+
if (env.term === "dumb") return "readline";
|
|
21451
|
+
if (env.ci) return "readline";
|
|
21452
|
+
return "tui";
|
|
21453
|
+
}
|
|
21454
|
+
var TuiUnavailableError = class extends Error {
|
|
21455
|
+
constructor(cause) {
|
|
21456
|
+
super(`the terminal face could not start: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
21457
|
+
this.name = "TuiUnavailableError";
|
|
21458
|
+
}
|
|
21459
|
+
};
|
|
21460
|
+
function currentFaceEnv(argv) {
|
|
21461
|
+
return {
|
|
21462
|
+
stdinTty: process.stdin.isTTY === true,
|
|
21463
|
+
stdoutTty: process.stdout.isTTY === true,
|
|
21464
|
+
term: process.env.TERM,
|
|
21465
|
+
ci: Boolean(process.env.CI),
|
|
21466
|
+
argv
|
|
21467
|
+
};
|
|
21468
|
+
}
|
|
21469
|
+
|
|
20784
21470
|
// src/cli.ts
|
|
20785
21471
|
function flag(argv, name, fallback) {
|
|
20786
21472
|
const i = argv.indexOf(`--${name}`);
|
|
@@ -20808,31 +21494,45 @@ function promptOf(argv) {
|
|
|
20808
21494
|
}
|
|
20809
21495
|
return parts.join(" ").trim();
|
|
20810
21496
|
}
|
|
20811
|
-
async function
|
|
20812
|
-
|
|
20813
|
-
if (!prompt) {
|
|
20814
|
-
process.stderr.write('usage: corenel run "<prompt>" [--model M] [--base URL]\n');
|
|
20815
|
-
process.exit(2);
|
|
20816
|
-
}
|
|
20817
|
-
setGatewayBase(flag(argv, "base", process.env.CORENEL_API_BASE || "https://api.prompd.app/api"));
|
|
21497
|
+
async function agentSetup(argv) {
|
|
21498
|
+
setGatewayBase(apiBase2(flag(argv, "base", "")));
|
|
20818
21499
|
const token = await nodeAuthToken().getToken();
|
|
20819
21500
|
if (!token) {
|
|
20820
21501
|
process.stderr.write("corenel: not signed in.\n Run `corenel login`, or set CORENEL_TOKEN=<token> (a gateway bearer token), then try again.\n");
|
|
20821
21502
|
process.exit(2);
|
|
20822
21503
|
}
|
|
20823
21504
|
registerGuard(tokenGuard(() => token));
|
|
20824
|
-
const
|
|
20825
|
-
|
|
20826
|
-
setPromptHost(nodePromptHost(new NodeFileService(join4(corenelDir(), "config"))));
|
|
21505
|
+
const tools = [...allTools(), shellTool(process.cwd())];
|
|
21506
|
+
setPromptHost(nodePromptHost(new NodeFileService(join5(corenelDir(), "config"))));
|
|
20827
21507
|
let system = "You are corenel, a concise CLI assistant.";
|
|
20828
21508
|
try {
|
|
20829
21509
|
system = await composeAgentSystem({ mode: "auto", tools: tools.map((t) => ({ name: t.name, description: t.description })) });
|
|
20830
21510
|
} catch {
|
|
20831
21511
|
}
|
|
21512
|
+
return {
|
|
21513
|
+
client: createChatClient({ getToken: async () => token }),
|
|
21514
|
+
model: flag(argv, "model", "gpt-4o-mini"),
|
|
21515
|
+
system,
|
|
21516
|
+
tools
|
|
21517
|
+
};
|
|
21518
|
+
}
|
|
21519
|
+
async function run(argv) {
|
|
21520
|
+
const prompt = promptOf(argv);
|
|
21521
|
+
if (!prompt) {
|
|
21522
|
+
process.stderr.write('usage: corenel run "<prompt>" [--model M] [--base URL] [--session ID]\n');
|
|
21523
|
+
process.exit(2);
|
|
21524
|
+
}
|
|
21525
|
+
const session = flag(argv, "session", "");
|
|
21526
|
+
if (session) {
|
|
21527
|
+
const ext = findExtension("sessions");
|
|
21528
|
+
process.exitCode = ext ? await runExtension(ext, ["run", session, prompt]) : 2;
|
|
21529
|
+
return;
|
|
21530
|
+
}
|
|
21531
|
+
const { client, model, system, tools } = await agentSetup(argv);
|
|
20832
21532
|
const ac = new AbortController();
|
|
20833
21533
|
const result = await runAgent({
|
|
20834
21534
|
client,
|
|
20835
|
-
model
|
|
21535
|
+
model,
|
|
20836
21536
|
system,
|
|
20837
21537
|
messages: [{ role: "user", content: prompt }],
|
|
20838
21538
|
tools,
|
|
@@ -20841,8 +21541,71 @@ async function run(argv) {
|
|
|
20841
21541
|
});
|
|
20842
21542
|
process.stdout.write(result.text + "\n");
|
|
20843
21543
|
}
|
|
21544
|
+
async function interactive(argv) {
|
|
21545
|
+
const { client, model, system, tools } = await agentSetup(argv);
|
|
21546
|
+
const approveAll = argv.includes("--allow-shell");
|
|
21547
|
+
const cwd = process.cwd();
|
|
21548
|
+
const files = new NodeFileService(cwd);
|
|
21549
|
+
const persistence = createSessionPersistence(files);
|
|
21550
|
+
const resumeAt = argv.indexOf("--resume");
|
|
21551
|
+
const resumeId = resumeAt >= 0 && argv[resumeAt + 1] && !argv[resumeAt + 1].startsWith("--") ? argv[resumeAt + 1] : void 0;
|
|
21552
|
+
const resume = resumeAt >= 0 ? { id: resumeId } : void 0;
|
|
21553
|
+
if (chooseFace(currentFaceEnv(argv)) === "tui") {
|
|
21554
|
+
try {
|
|
21555
|
+
const { runTui } = await import("@corenel/term/ink");
|
|
21556
|
+
process.exitCode = await runTui({
|
|
21557
|
+
cwd,
|
|
21558
|
+
model,
|
|
21559
|
+
system,
|
|
21560
|
+
client,
|
|
21561
|
+
tools,
|
|
21562
|
+
version: version(),
|
|
21563
|
+
toolCtx: (signal, ask) => nodeToolCtx(signal, { files, ask }),
|
|
21564
|
+
...approveAll ? { approveAll: true } : {},
|
|
21565
|
+
persistence,
|
|
21566
|
+
...resume ? { resume } : {}
|
|
21567
|
+
});
|
|
21568
|
+
return;
|
|
21569
|
+
} catch (e) {
|
|
21570
|
+
if (argv.includes("--tui")) throw new TuiUnavailableError(e);
|
|
21571
|
+
process.stderr.write(`corenel: terminal face unavailable, falling back (${e instanceof Error ? e.message : String(e)})
|
|
21572
|
+
`);
|
|
21573
|
+
}
|
|
21574
|
+
}
|
|
21575
|
+
process.exitCode = await runRepl({
|
|
21576
|
+
client,
|
|
21577
|
+
model,
|
|
21578
|
+
system,
|
|
21579
|
+
tools,
|
|
21580
|
+
toolCtx: (signal, ask) => nodeToolCtx(signal, { files, ...ask ? { ask } : {} }),
|
|
21581
|
+
cwd,
|
|
21582
|
+
// --allow-shell skips the per-command prompt. Named after the sidecar's
|
|
21583
|
+
// flag, which grants the same thing.
|
|
21584
|
+
approveAll,
|
|
21585
|
+
persistence,
|
|
21586
|
+
...resume ? { resume } : {}
|
|
21587
|
+
});
|
|
21588
|
+
}
|
|
20844
21589
|
async function main() {
|
|
20845
21590
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
21591
|
+
setAgentLogging(process.argv.includes("--debug") || process.env.CORENEL_DEBUG === "1");
|
|
21592
|
+
if (cmd !== void 0 && isVersionFlag(cmd)) {
|
|
21593
|
+
process.stdout.write(`${version()}
|
|
21594
|
+
`);
|
|
21595
|
+
return;
|
|
21596
|
+
}
|
|
21597
|
+
if (cmd !== void 0 && isHelpFlag(cmd)) {
|
|
21598
|
+
process.stdout.write(helpText(version()));
|
|
21599
|
+
return;
|
|
21600
|
+
}
|
|
21601
|
+
if (cmd === void 0) {
|
|
21602
|
+
await interactive([]);
|
|
21603
|
+
return;
|
|
21604
|
+
}
|
|
21605
|
+
if (!isCommand(cmd) && cmd.startsWith("-")) {
|
|
21606
|
+
await interactive([cmd, ...rest]);
|
|
21607
|
+
return;
|
|
21608
|
+
}
|
|
20846
21609
|
switch (cmd) {
|
|
20847
21610
|
case "run":
|
|
20848
21611
|
await run(rest);
|
|
@@ -20867,33 +21630,36 @@ async function main() {
|
|
|
20867
21630
|
process.exitCode = code;
|
|
20868
21631
|
break;
|
|
20869
21632
|
}
|
|
20870
|
-
case "sidecar":
|
|
20871
|
-
|
|
21633
|
+
case "sidecar":
|
|
21634
|
+
case "acp":
|
|
21635
|
+
case "sessions": {
|
|
21636
|
+
const ext = findExtension(cmd);
|
|
21637
|
+
process.exitCode = ext ? await runExtension(ext, rest) : 2;
|
|
20872
21638
|
break;
|
|
20873
21639
|
}
|
|
20874
21640
|
case "login": {
|
|
20875
|
-
const base = flag(rest, "base",
|
|
21641
|
+
const base = apiBase2(flag(rest, "base", ""));
|
|
20876
21642
|
await deviceLogin({ base, store: writeAuthToken });
|
|
20877
21643
|
process.stdout.write(`
|
|
20878
21644
|
Logged in. Token saved to ${authTokenPath()}
|
|
20879
21645
|
`);
|
|
20880
21646
|
break;
|
|
20881
21647
|
}
|
|
21648
|
+
case "auth":
|
|
21649
|
+
await runAuth();
|
|
21650
|
+
break;
|
|
21651
|
+
case "logout":
|
|
21652
|
+
await runLogout();
|
|
21653
|
+
break;
|
|
21654
|
+
case "doctor":
|
|
21655
|
+
process.exitCode = await runDoctor();
|
|
21656
|
+
break;
|
|
20882
21657
|
default:
|
|
20883
|
-
process.
|
|
20884
|
-
|
|
20885
|
-
|
|
20886
|
-
|
|
20887
|
-
|
|
20888
|
-
' corenel run-agent <name> --input "<text>" run a crew agent; events as JSON Lines on stdout',
|
|
20889
|
-
" corenel sidecar [start] [flags] run the sidecar on this machine (needs @corenel/sidecar)",
|
|
20890
|
-
"",
|
|
20891
|
-
" `corenel sidecar --help` lists its flags. It is also installed standalone",
|
|
20892
|
-
" as `corenel-sidecar`, for machines that run only the sidecar.",
|
|
20893
|
-
"",
|
|
20894
|
-
" (ask/chat to follow.)",
|
|
20895
|
-
""
|
|
20896
|
-
].join("\n"));
|
|
21658
|
+
process.stderr.write(`corenel: unknown command "${cmd}"
|
|
21659
|
+
|
|
21660
|
+
`);
|
|
21661
|
+
process.stderr.write(helpText(version()));
|
|
21662
|
+
process.exitCode = 2;
|
|
20897
21663
|
}
|
|
20898
21664
|
}
|
|
20899
21665
|
function friendlyError(msg) {
|