@rayul/kordis 0.1.17 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +183 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ var init_primitives = __esm({
|
|
|
45
45
|
|
|
46
46
|
// ../../packages/contracts/src/enums.ts
|
|
47
47
|
import { z as z2 } from "zod";
|
|
48
|
-
var HarnessTypeSchema, PHASE_1_TYPES, TierSchema, TIER_OF_TYPE, SortModeSchema, TimeWindowSchema, VisibilitySchema, ReviewStatusSchema, PublishStatusSchema, DependencyKindSchema, OAuthProviderSchema, UserRoleSchema, ReportReasonSchema;
|
|
48
|
+
var HarnessTypeSchema, PHASE_1_TYPES, TierSchema, TIER_OF_TYPE, CAPABILITIES_OF_TYPE, SortModeSchema, TimeWindowSchema, VisibilitySchema, ReviewStatusSchema, PublishStatusSchema, DependencyKindSchema, OAuthProviderSchema, UserRoleSchema, ReportReasonSchema;
|
|
49
49
|
var init_enums = __esm({
|
|
50
50
|
"../../packages/contracts/src/enums.ts"() {
|
|
51
51
|
"use strict";
|
|
@@ -77,6 +77,16 @@ var init_enums = __esm({
|
|
|
77
77
|
"mdc-rule": "C",
|
|
78
78
|
plugin: "D"
|
|
79
79
|
};
|
|
80
|
+
CAPABILITIES_OF_TYPE = {
|
|
81
|
+
skill: { jit_eligible: true, executable: false },
|
|
82
|
+
"project-rules": { jit_eligible: true, executable: false },
|
|
83
|
+
"custom-agent": { jit_eligible: true, executable: false },
|
|
84
|
+
"scoped-rule": { jit_eligible: true, executable: false },
|
|
85
|
+
"mdc-rule": { jit_eligible: true, executable: false },
|
|
86
|
+
"mcp-server": { jit_eligible: false, executable: true },
|
|
87
|
+
hook: { jit_eligible: false, executable: true },
|
|
88
|
+
plugin: { jit_eligible: false, executable: true }
|
|
89
|
+
};
|
|
80
90
|
SortModeSchema = z2.enum([
|
|
81
91
|
"stars",
|
|
82
92
|
"downloads",
|
|
@@ -281,6 +291,14 @@ var init_package = __esm({
|
|
|
281
291
|
tools_compatible: z6.array(ToolSlugSchema),
|
|
282
292
|
tags: z6.array(TagSchema),
|
|
283
293
|
agent_skills_compliant: z6.boolean().optional(),
|
|
294
|
+
/**
|
|
295
|
+
* Capability flags — explicit declaration of behavior. Defaults derive from
|
|
296
|
+
* `type` via `CAPABILITIES_OF_TYPE`; frontmatter MAY override. Optional in
|
|
297
|
+
* the schema so old API responses (pre-0.2.0) parse cleanly; consumers that
|
|
298
|
+
* need a value should fall back to `CAPABILITIES_OF_TYPE[type]`.
|
|
299
|
+
*/
|
|
300
|
+
jit_eligible: z6.boolean().optional(),
|
|
301
|
+
executable: z6.boolean().optional(),
|
|
284
302
|
review_status: ReviewStatusSchema,
|
|
285
303
|
visibility: VisibilitySchema,
|
|
286
304
|
installed_locally: z6.boolean().optional(),
|
|
@@ -1154,6 +1172,8 @@ import ora from "ora";
|
|
|
1154
1172
|
var jsonMode = false;
|
|
1155
1173
|
function setJsonMode(on) {
|
|
1156
1174
|
jsonMode = on;
|
|
1175
|
+
if (on) process.env["KORDIS_JSON"] = "1";
|
|
1176
|
+
else delete process.env["KORDIS_JSON"];
|
|
1157
1177
|
}
|
|
1158
1178
|
function isJsonMode() {
|
|
1159
1179
|
return jsonMode;
|
|
@@ -1374,18 +1394,21 @@ function parseFrontmatter(source) {
|
|
|
1374
1394
|
parsed = parseYaml(raw);
|
|
1375
1395
|
} catch (err) {
|
|
1376
1396
|
const msg = err.message;
|
|
1377
|
-
const hint = msg.includes("Nested mapping") || msg.includes("compact mapping") ? '
|
|
1378
|
-
throw new FrontmatterParseError(
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
);
|
|
1397
|
+
const hint = msg.includes("Nested mapping") || msg.includes("compact mapping") ? 'If the value contains ":" wrap it in quotes, e.g. description: "Use when X. Trigger: Y"' : 'Frontmatter must be valid YAML between two "---" fences. Validate at https://yamllint.com';
|
|
1398
|
+
throw new FrontmatterParseError(`YAML frontmatter is malformed: ${msg}`, {
|
|
1399
|
+
cause: err,
|
|
1400
|
+
hint
|
|
1401
|
+
});
|
|
1382
1402
|
}
|
|
1383
1403
|
if (parsed === null || parsed === void 0) {
|
|
1384
1404
|
return { frontmatter: {}, body: stripped.slice(match[0].length), bodyOffset: match[0].length };
|
|
1385
1405
|
}
|
|
1386
1406
|
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1387
1407
|
throw new FrontmatterParseError(
|
|
1388
|
-
"YAML frontmatter must decode to an object, got " + typeof parsed
|
|
1408
|
+
"YAML frontmatter must decode to an object, got " + typeof parsed,
|
|
1409
|
+
{
|
|
1410
|
+
hint: "Frontmatter must be a YAML mapping (key: value pairs), not a list or scalar."
|
|
1411
|
+
}
|
|
1389
1412
|
);
|
|
1390
1413
|
}
|
|
1391
1414
|
return {
|
|
@@ -1395,9 +1418,12 @@ function parseFrontmatter(source) {
|
|
|
1395
1418
|
};
|
|
1396
1419
|
}
|
|
1397
1420
|
var FrontmatterParseError = class extends Error {
|
|
1421
|
+
/** Agent-actionable fix snippet, ready to render under the error. */
|
|
1422
|
+
hint;
|
|
1398
1423
|
constructor(message, options) {
|
|
1399
1424
|
super(message, options);
|
|
1400
1425
|
this.name = "FrontmatterParseError";
|
|
1426
|
+
if (options?.hint) this.hint = options.hint;
|
|
1401
1427
|
}
|
|
1402
1428
|
};
|
|
1403
1429
|
|
|
@@ -1428,7 +1454,7 @@ function pushCommand() {
|
|
|
1428
1454
|
const v = fm["name"];
|
|
1429
1455
|
if (typeof v === "string") nameFromFm = v;
|
|
1430
1456
|
} catch (err) {
|
|
1431
|
-
throw new Error(err
|
|
1457
|
+
throw err instanceof Error ? err : new Error(String(err));
|
|
1432
1458
|
}
|
|
1433
1459
|
let targetUser = null;
|
|
1434
1460
|
let targetSlug = null;
|
|
@@ -1820,37 +1846,43 @@ function validatePackageSource(source) {
|
|
|
1820
1846
|
rawFrontmatter = parsed.frontmatter;
|
|
1821
1847
|
} catch (err) {
|
|
1822
1848
|
if (err instanceof FrontmatterParseError) {
|
|
1823
|
-
|
|
1849
|
+
const extra = err.hint ? { hint: err.hint } : {};
|
|
1850
|
+
return earlyExit(flag("malformed_frontmatter", err.message, extra));
|
|
1824
1851
|
}
|
|
1825
1852
|
throw err;
|
|
1826
1853
|
}
|
|
1827
1854
|
if (!rawFrontmatter) {
|
|
1828
|
-
return earlyExit(
|
|
1855
|
+
return earlyExit(
|
|
1856
|
+
flag("missing_frontmatter", "package must start with a YAML frontmatter block", {
|
|
1857
|
+
hint: "Add a YAML block at the top:\n---\ntype: skill\nname: my-skill\ndescription: ...\n---"
|
|
1858
|
+
})
|
|
1859
|
+
);
|
|
1829
1860
|
}
|
|
1830
1861
|
const typeValue = rawFrontmatter["type"];
|
|
1831
1862
|
if (typeof typeValue !== "string") {
|
|
1832
1863
|
return earlyExit(
|
|
1833
|
-
flag("missing_required_frontmatter", "`type` is required in frontmatter", {
|
|
1864
|
+
flag("missing_required_frontmatter", "`type` is required in frontmatter", {
|
|
1865
|
+
field: "type",
|
|
1866
|
+
hint: "Add type: skill (or one of: mcp-server, project-rules, custom-agent, hook)"
|
|
1867
|
+
})
|
|
1834
1868
|
);
|
|
1835
1869
|
}
|
|
1836
1870
|
const typeParse = HarnessTypeSchema.safeParse(typeValue);
|
|
1837
1871
|
if (!typeParse.success) {
|
|
1838
1872
|
return earlyExit(
|
|
1839
|
-
flag(
|
|
1840
|
-
"
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
)
|
|
1873
|
+
flag("unknown_type", `type "${typeValue}" is not a recognised Harness type`, {
|
|
1874
|
+
field: "type",
|
|
1875
|
+
hint: "Allowed types: skill, mcp-server, project-rules, custom-agent, hook"
|
|
1876
|
+
})
|
|
1844
1877
|
);
|
|
1845
1878
|
}
|
|
1846
1879
|
const type = typeParse.data;
|
|
1847
1880
|
if (!PHASE_1_TYPES.includes(type)) {
|
|
1848
1881
|
flags.push(
|
|
1849
|
-
flag(
|
|
1850
|
-
"
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
)
|
|
1882
|
+
flag("type_not_phase1", `type "${type}" is planned for Phase 2+ and is not yet accepted`, {
|
|
1883
|
+
field: "type",
|
|
1884
|
+
hint: "Use one of the Phase 1 types: skill, mcp-server, project-rules, custom-agent, hook"
|
|
1885
|
+
})
|
|
1854
1886
|
);
|
|
1855
1887
|
return earlyExit(null, { flags, body });
|
|
1856
1888
|
}
|
|
@@ -1858,22 +1890,69 @@ function validatePackageSource(source) {
|
|
|
1858
1890
|
type: _discard_type,
|
|
1859
1891
|
depends: _discard_depends,
|
|
1860
1892
|
recommends: _discard_recommends,
|
|
1893
|
+
jit_eligible: rawJitEligible,
|
|
1894
|
+
executable: rawExecutable,
|
|
1861
1895
|
...typeSpecific
|
|
1862
1896
|
} = rawFrontmatter;
|
|
1863
1897
|
void _discard_type;
|
|
1864
1898
|
void _discard_depends;
|
|
1865
1899
|
void _discard_recommends;
|
|
1900
|
+
let jitOverride;
|
|
1901
|
+
let execOverride;
|
|
1902
|
+
if (rawJitEligible !== void 0) {
|
|
1903
|
+
if (typeof rawJitEligible !== "boolean") {
|
|
1904
|
+
flags.push(
|
|
1905
|
+
flag(
|
|
1906
|
+
"invalid_frontmatter",
|
|
1907
|
+
"jit_eligible must be a boolean (true / false)",
|
|
1908
|
+
{
|
|
1909
|
+
field: "jit_eligible",
|
|
1910
|
+
hint: "Example: jit_eligible: true"
|
|
1911
|
+
}
|
|
1912
|
+
)
|
|
1913
|
+
);
|
|
1914
|
+
} else {
|
|
1915
|
+
jitOverride = rawJitEligible;
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
if (rawExecutable !== void 0) {
|
|
1919
|
+
if (typeof rawExecutable !== "boolean") {
|
|
1920
|
+
flags.push(
|
|
1921
|
+
flag("invalid_frontmatter", "executable must be a boolean (true / false)", {
|
|
1922
|
+
field: "executable",
|
|
1923
|
+
hint: "Example: executable: false"
|
|
1924
|
+
})
|
|
1925
|
+
);
|
|
1926
|
+
} else {
|
|
1927
|
+
execOverride = rawExecutable;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1866
1930
|
const result = dispatchValidation(type, typeSpecific);
|
|
1867
1931
|
if (!result.ok) {
|
|
1868
1932
|
flags.push(...result.flags);
|
|
1869
1933
|
return earlyExit(null, { flags, body });
|
|
1870
1934
|
}
|
|
1935
|
+
const defaults = CAPABILITIES_OF_TYPE[type];
|
|
1936
|
+
const capabilities = {
|
|
1937
|
+
jit_eligible: jitOverride ?? defaults.jit_eligible,
|
|
1938
|
+
executable: execOverride ?? defaults.executable
|
|
1939
|
+
};
|
|
1871
1940
|
const common = {
|
|
1872
1941
|
title: typeof rawFrontmatter["title"] === "string" ? rawFrontmatter["title"] : typeof rawFrontmatter["name"] === "string" ? rawFrontmatter["name"] : null,
|
|
1873
1942
|
description: typeof rawFrontmatter["description"] === "string" ? rawFrontmatter["description"] : null
|
|
1874
1943
|
};
|
|
1875
|
-
if (!common.title)
|
|
1876
|
-
|
|
1944
|
+
if (!common.title)
|
|
1945
|
+
flags.push(
|
|
1946
|
+
flag("missing_title", "title (or name) is required", {
|
|
1947
|
+
hint: 'Add title: "Human Readable Title" (or rely on name: ... for skills)'
|
|
1948
|
+
})
|
|
1949
|
+
);
|
|
1950
|
+
if (!common.description)
|
|
1951
|
+
flags.push(
|
|
1952
|
+
flag("missing_description", "description is required", {
|
|
1953
|
+
hint: "Add a description field (1\u20132048 chars) explaining when to invoke this package."
|
|
1954
|
+
})
|
|
1955
|
+
);
|
|
1877
1956
|
let depends = [];
|
|
1878
1957
|
let recommends = [];
|
|
1879
1958
|
try {
|
|
@@ -1883,7 +1962,12 @@ function validatePackageSource(source) {
|
|
|
1883
1962
|
kind: DependencyKindSchema.parse("required")
|
|
1884
1963
|
}));
|
|
1885
1964
|
} catch (err) {
|
|
1886
|
-
flags.push(
|
|
1965
|
+
flags.push(
|
|
1966
|
+
flag("invalid_depends", err.message, {
|
|
1967
|
+
field: "depends",
|
|
1968
|
+
hint: 'Each entry must be "{username}/{slug}" optionally with "@^1.2.0". Example: alice/json-pretty@^1.0.0'
|
|
1969
|
+
})
|
|
1970
|
+
);
|
|
1887
1971
|
}
|
|
1888
1972
|
try {
|
|
1889
1973
|
recommends = normaliseDepList(rawFrontmatter["recommends"]).map((d) => ({
|
|
@@ -1892,13 +1976,26 @@ function validatePackageSource(source) {
|
|
|
1892
1976
|
kind: DependencyKindSchema.parse("recommended")
|
|
1893
1977
|
}));
|
|
1894
1978
|
} catch (err) {
|
|
1895
|
-
flags.push(
|
|
1979
|
+
flags.push(
|
|
1980
|
+
flag("invalid_recommends", err.message, {
|
|
1981
|
+
field: "recommends",
|
|
1982
|
+
hint: 'Each entry must be "{username}/{slug}" optionally with "@^1.2.0".'
|
|
1983
|
+
})
|
|
1984
|
+
);
|
|
1896
1985
|
}
|
|
1897
1986
|
if (body.trim().length < 50) {
|
|
1898
|
-
flags.push(
|
|
1987
|
+
flags.push(
|
|
1988
|
+
flag("content_too_short", "body must be at least 50 non-whitespace characters", {
|
|
1989
|
+
hint: 'Add an "## Instructions" section explaining when and how to use this package.'
|
|
1990
|
+
})
|
|
1991
|
+
);
|
|
1899
1992
|
}
|
|
1900
1993
|
if (body.length > 1e5) {
|
|
1901
|
-
flags.push(
|
|
1994
|
+
flags.push(
|
|
1995
|
+
flag("content_too_long", "body exceeds 100 kB cap", {
|
|
1996
|
+
hint: "Split long examples or transcripts into asset files under references/."
|
|
1997
|
+
})
|
|
1998
|
+
);
|
|
1902
1999
|
}
|
|
1903
2000
|
const ok = flags.every((f) => !BLOCKING_CODES.has(f.code));
|
|
1904
2001
|
return {
|
|
@@ -1908,6 +2005,7 @@ function validatePackageSource(source) {
|
|
|
1908
2005
|
frontmatter: result.frontmatter,
|
|
1909
2006
|
body,
|
|
1910
2007
|
common,
|
|
2008
|
+
capabilities,
|
|
1911
2009
|
depends,
|
|
1912
2010
|
recommends,
|
|
1913
2011
|
flags
|
|
@@ -1938,6 +2036,7 @@ function earlyExit(firstFlag, override = {}) {
|
|
|
1938
2036
|
frontmatter: null,
|
|
1939
2037
|
body: "",
|
|
1940
2038
|
common: { title: null, description: null },
|
|
2039
|
+
capabilities: null,
|
|
1941
2040
|
depends: [],
|
|
1942
2041
|
recommends: [],
|
|
1943
2042
|
flags: firstFlag ? [firstFlag] : [],
|
|
@@ -1976,7 +2075,10 @@ function dispatchValidation(type, raw) {
|
|
|
1976
2075
|
ok: false,
|
|
1977
2076
|
frontmatter: null,
|
|
1978
2077
|
flags: [
|
|
1979
|
-
flag("type_not_phase1", `type "${type}" not accepted in Phase 1`, {
|
|
2078
|
+
flag("type_not_phase1", `type "${type}" not accepted in Phase 1`, {
|
|
2079
|
+
field: "type",
|
|
2080
|
+
hint: "Use one of the Phase 1 types: skill, mcp-server, project-rules, custom-agent, hook"
|
|
2081
|
+
})
|
|
1980
2082
|
]
|
|
1981
2083
|
};
|
|
1982
2084
|
}
|
|
@@ -1985,16 +2087,29 @@ function zodFail(issues) {
|
|
|
1985
2087
|
return {
|
|
1986
2088
|
ok: false,
|
|
1987
2089
|
frontmatter: null,
|
|
1988
|
-
flags: issues.map(
|
|
1989
|
-
|
|
1990
|
-
|
|
2090
|
+
flags: issues.map((i) => {
|
|
2091
|
+
const field = i.path.join(".") || void 0;
|
|
2092
|
+
const msg = i.message.toLowerCase();
|
|
2093
|
+
let hint;
|
|
2094
|
+
if (field === "name" && msg.includes("lowercase")) {
|
|
2095
|
+
hint = 'name must be lowercase-with-hyphens, e.g. "my-cool-skill" not "MyCoolSkill"';
|
|
2096
|
+
} else if (field === "description" && (msg.includes("big") || msg.includes("large") || msg.includes("long"))) {
|
|
2097
|
+
hint = "description must be 1\u20132048 chars; current is too long. Move detail into the body.";
|
|
2098
|
+
} else if (field === "description" && msg.includes("small")) {
|
|
2099
|
+
hint = "description must be 1\u20132048 chars; provide a one-paragraph summary.";
|
|
2100
|
+
}
|
|
2101
|
+
const extra = {};
|
|
2102
|
+
if (field) extra.field = field;
|
|
2103
|
+
if (hint) extra.hint = hint;
|
|
2104
|
+
return flag("invalid_frontmatter", i.message, extra);
|
|
2105
|
+
})
|
|
1991
2106
|
};
|
|
1992
2107
|
}
|
|
1993
2108
|
|
|
1994
2109
|
// ../../packages/translators/src/skill/identity.ts
|
|
1995
2110
|
function buildSkillFile(input, outputPath) {
|
|
1996
2111
|
const body = input.body.trimStart();
|
|
1997
|
-
const fm = input.frontmatter;
|
|
2112
|
+
const fm = input.frontmatter["version"] === void 0 && input.version ? { ...input.frontmatter, version: input.version } : input.frontmatter;
|
|
1998
2113
|
const name = typeof fm["name"] === "string" ? fm["name"] : input.fullSlug.split("/")[1];
|
|
1999
2114
|
const frontmatter = ["---"];
|
|
2000
2115
|
for (const [k, v] of Object.entries(fm)) {
|
|
@@ -2628,6 +2743,7 @@ function readCommand() {
|
|
|
2628
2743
|
}
|
|
2629
2744
|
|
|
2630
2745
|
// src/commands/info.ts
|
|
2746
|
+
init_src();
|
|
2631
2747
|
import { Command as Command7 } from "commander";
|
|
2632
2748
|
function infoCommand() {
|
|
2633
2749
|
return new Command7("info").description("show details about a package").argument("<full_slug>", "package identifier {username}/{slug}").action(async (fullSlug) => {
|
|
@@ -2635,6 +2751,9 @@ function infoCommand() {
|
|
|
2635
2751
|
if (!username || !slug) throw new Error('full_slug must be "{username}/{slug}"');
|
|
2636
2752
|
const bundle = await useClient();
|
|
2637
2753
|
const detail = await bundle.api.getPackage(username, slug);
|
|
2754
|
+
const typeDefaults = CAPABILITIES_OF_TYPE[detail.type];
|
|
2755
|
+
const jitEligible = detail.jit_eligible ?? typeDefaults.jit_eligible;
|
|
2756
|
+
const executable = detail.executable ?? typeDefaults.executable;
|
|
2638
2757
|
printDual({
|
|
2639
2758
|
json: detail,
|
|
2640
2759
|
human: () => {
|
|
@@ -2642,6 +2761,12 @@ function infoCommand() {
|
|
|
2642
2761
|
printHuman(" " + detail.description);
|
|
2643
2762
|
printHuman("");
|
|
2644
2763
|
printHuman(` ${c.cyan("Type")}: ${detail.type} (tier ${detail.tier})`);
|
|
2764
|
+
printHuman(
|
|
2765
|
+
` ${c.cyan("JIT-readable")}: ${jitEligible ? c.green("yes") : c.red("no")}`
|
|
2766
|
+
);
|
|
2767
|
+
printHuman(
|
|
2768
|
+
` ${c.cyan("Executable")}: ${executable ? c.yellow("yes") : c.gray("no")}`
|
|
2769
|
+
);
|
|
2645
2770
|
printHuman(` ${c.cyan("Author")}: ${detail.author.username}`);
|
|
2646
2771
|
printHuman(` ${c.cyan("Stats")}: \u2605 ${detail.stars} \xB7 \u21E3 ${detail.downloads}`);
|
|
2647
2772
|
if (detail.tools_compatible.length > 0) {
|
|
@@ -3370,6 +3495,11 @@ function diffCommand() {
|
|
|
3370
3495
|
printHuman("");
|
|
3371
3496
|
if (!diff.unified_diff) {
|
|
3372
3497
|
printHuman(c.dim("(no content changes between these versions)"));
|
|
3498
|
+
printHuman(
|
|
3499
|
+
c.dim(
|
|
3500
|
+
" \u2192 likely a metadata-only bump: description, deps, license, or version field"
|
|
3501
|
+
)
|
|
3502
|
+
);
|
|
3373
3503
|
return;
|
|
3374
3504
|
}
|
|
3375
3505
|
for (const line of diff.unified_diff.split("\n")) {
|
|
@@ -3441,6 +3571,11 @@ function handleError(err) {
|
|
|
3441
3571
|
printHuman(c.red(`\u2717 ${err.code}: ${err.message}`));
|
|
3442
3572
|
for (const f of err.flags) {
|
|
3443
3573
|
printHuman(c.red(` - ${f.code}${f.message ? `: ${f.message}` : ""}`));
|
|
3574
|
+
if (f.hint) {
|
|
3575
|
+
for (const line of f.hint.split("\n")) {
|
|
3576
|
+
printHuman(c.gray(` \u2192 ${line}`));
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3444
3579
|
}
|
|
3445
3580
|
if (err.retryAfter !== void 0) {
|
|
3446
3581
|
printHuman(c.yellow(` retry after: ${err.retryAfter}s`));
|
|
@@ -3457,8 +3592,22 @@ function handleError(err) {
|
|
|
3457
3592
|
process.exit(err.exitCode());
|
|
3458
3593
|
}
|
|
3459
3594
|
if (err instanceof Error) {
|
|
3460
|
-
|
|
3461
|
-
|
|
3595
|
+
const hint = err.hint;
|
|
3596
|
+
const hintStr = typeof hint === "string" ? hint : void 0;
|
|
3597
|
+
if (isJsonMode()) {
|
|
3598
|
+
printJson({
|
|
3599
|
+
error: {
|
|
3600
|
+
code: "generic_failure",
|
|
3601
|
+
message: err.message,
|
|
3602
|
+
...hintStr ? { hint: hintStr } : {}
|
|
3603
|
+
}
|
|
3604
|
+
});
|
|
3605
|
+
} else {
|
|
3606
|
+
printHuman(c.red(`\u2717 ${err.message}`));
|
|
3607
|
+
if (hintStr) {
|
|
3608
|
+
for (const line of hintStr.split("\n")) printHuman(c.gray(` \u2192 ${line}`));
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3462
3611
|
process.exit(1);
|
|
3463
3612
|
}
|
|
3464
3613
|
if (isJsonMode()) printJson({ error: { code: "generic_failure", message: String(err) } });
|