@thymian/common-cli 0.1.11 → 0.1.12-canary.20260709-74e687c
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/cli-report-renderer.d.ts +1 -1
- package/dist/cli-report-renderer.d.ts.map +1 -1
- package/dist/cli-report-renderer.js +64 -80
- package/dist/cli-report-renderer.js.map +1 -1
- package/dist/default-config.d.ts.map +1 -1
- package/dist/default-config.js +1 -3
- package/dist/default-config.js.map +1 -1
- package/dist/flags/option-flag.d.ts +2 -2
- package/dist/flags/option-flag.js +5 -5
- package/dist/workflow-outcome.d.ts +8 -3
- package/dist/workflow-outcome.d.ts.map +1 -1
- package/dist/workflow-outcome.js +11 -13
- package/dist/workflow-outcome.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-report-renderer.d.ts","sourceRoot":"","sources":["../src/cli-report-renderer.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"cli-report-renderer.d.ts","sourceRoot":"","sources":["../src/cli-report-renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,MAAM,EAKX,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AA+HvB,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,aAAa,CAAA;CAAO,GACvC,MAAM,CA2CR"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { colorize } from '@oclif/core/ux';
|
|
2
|
-
import {
|
|
2
|
+
import { buildRuleIndex, findingDetails, formatLocation, resolveExecutionSeverity, resolveThymianFormatForRun, walkExecutions, } from '@thymian/core';
|
|
3
3
|
const COLORS = {
|
|
4
4
|
error: 'red',
|
|
5
5
|
warn: 'yellow',
|
|
@@ -24,67 +24,58 @@ function symbolForSeverity(severity) {
|
|
|
24
24
|
return '•';
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (!format) {
|
|
32
|
-
return fallbackThymianFormatLocation(location);
|
|
33
|
-
}
|
|
34
|
-
if (location.elementType === 'node') {
|
|
35
|
-
const node = format.getNode(location.elementId);
|
|
36
|
-
if (node && isNodeType(node, 'http-request')) {
|
|
37
|
-
return thymianRequestToString(node);
|
|
38
|
-
}
|
|
39
|
-
if (node && isNodeType(node, 'http-response')) {
|
|
40
|
-
return thymianResponseToString(node);
|
|
41
|
-
}
|
|
42
|
-
return fallbackThymianFormatLocation(location);
|
|
43
|
-
}
|
|
44
|
-
try {
|
|
45
|
-
const [source, target] = format.graph.extremities(location.elementId);
|
|
46
|
-
const transaction = format.getEdge(location.elementId);
|
|
47
|
-
const request = format.getNode(source);
|
|
48
|
-
const response = format.getNode(target);
|
|
49
|
-
if (transaction && request && response) {
|
|
50
|
-
return thymianHttpTransactionToString(request, response);
|
|
51
|
-
}
|
|
27
|
+
function renderFinding(finding, indent = ' ') {
|
|
28
|
+
const lines = [`${indent}${finding.title}`];
|
|
29
|
+
if (finding.message?.text && finding.message.text !== finding.title) {
|
|
30
|
+
lines.push(`${indent} ${finding.message.text}`);
|
|
52
31
|
}
|
|
53
|
-
|
|
54
|
-
|
|
32
|
+
for (const detail of findingDetails(finding)) {
|
|
33
|
+
lines.push(`${indent} ${detail.label}: ${detail.value}`);
|
|
55
34
|
}
|
|
56
|
-
return
|
|
35
|
+
return lines;
|
|
57
36
|
}
|
|
58
|
-
function
|
|
59
|
-
switch (
|
|
60
|
-
case '
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
case '
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
37
|
+
function renderStatus(status, severity) {
|
|
38
|
+
switch (status.kind) {
|
|
39
|
+
case 'passed': {
|
|
40
|
+
const duration = status.durationMilliseconds !== undefined
|
|
41
|
+
? ` (${status.durationMilliseconds.toFixed(2)}ms)`
|
|
42
|
+
: '';
|
|
43
|
+
return `${symbolForSeverity('info')} passed${duration}`;
|
|
44
|
+
}
|
|
45
|
+
case 'failed': {
|
|
46
|
+
const resolved = severity ?? 'error';
|
|
47
|
+
const reason = status.reason ? `: ${status.reason}` : '';
|
|
48
|
+
const duration = status.durationMilliseconds !== undefined
|
|
49
|
+
? ` (${status.durationMilliseconds.toFixed(2)}ms)`
|
|
50
|
+
: '';
|
|
51
|
+
return colorizeText(`${symbolForSeverity(resolved)} failed${reason}${duration}`, resolved);
|
|
52
|
+
}
|
|
53
|
+
case 'skipped':
|
|
54
|
+
return `${symbolForSeverity('hint')} skipped${status.reason ? `: ${status.reason}` : ''}`;
|
|
70
55
|
}
|
|
71
56
|
}
|
|
72
|
-
function
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
57
|
+
function renderExecution(execution, ruleIndex, format) {
|
|
58
|
+
const label = execution.kind === 'test'
|
|
59
|
+
? execution.name
|
|
60
|
+
: formatLocation(execution.location, format);
|
|
61
|
+
const lines = [` ${label}${execution.ruleId ? ` ${execution.ruleId}` : ''}`];
|
|
62
|
+
const severity = resolveExecutionSeverity(execution, ruleIndex);
|
|
63
|
+
lines.push(` ${renderStatus(execution.status, severity)}`);
|
|
64
|
+
if (execution.kind === 'test') {
|
|
65
|
+
for (const step of execution.steps) {
|
|
66
|
+
if (step.findings.length === 0) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
lines.push(` ${step.name} ${formatLocation(step.location, format)}`);
|
|
70
|
+
for (const finding of step.findings) {
|
|
71
|
+
lines.push(...renderFinding(finding, ' '));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
84
74
|
}
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
75
|
+
else {
|
|
76
|
+
for (const finding of execution.findings) {
|
|
77
|
+
lines.push(...renderFinding(finding, ' '));
|
|
78
|
+
}
|
|
88
79
|
}
|
|
89
80
|
return lines;
|
|
90
81
|
}
|
|
@@ -95,16 +86,14 @@ function collectSeverityCounts(report) {
|
|
|
95
86
|
info: 0,
|
|
96
87
|
hint: 0,
|
|
97
88
|
};
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
89
|
+
for (const run of report.runs) {
|
|
90
|
+
const ruleIndex = buildRuleIndex(run.rules);
|
|
91
|
+
for (const { execution } of walkExecutions(run.executions)) {
|
|
92
|
+
const severity = resolveExecutionSeverity(execution, ruleIndex);
|
|
93
|
+
if (severity !== undefined) {
|
|
94
|
+
counts[severity] += 1;
|
|
102
95
|
}
|
|
103
|
-
visit(execution.children);
|
|
104
96
|
}
|
|
105
|
-
};
|
|
106
|
-
for (const run of report.runs) {
|
|
107
|
-
visit(run.executions);
|
|
108
97
|
}
|
|
109
98
|
return counts;
|
|
110
99
|
}
|
|
@@ -113,33 +102,28 @@ export function renderReport(report, options = {}) {
|
|
|
113
102
|
return 'No tool runs were reported.';
|
|
114
103
|
}
|
|
115
104
|
const lines = [];
|
|
116
|
-
const format = options.format ??
|
|
117
|
-
(report.thymianFormat
|
|
118
|
-
? ThymianFormat.import(report.thymianFormat)
|
|
119
|
-
: undefined);
|
|
120
105
|
for (const run of report.runs) {
|
|
106
|
+
const format = options.format ??
|
|
107
|
+
resolveThymianFormatForRun(report.thymianFormat, run.thymianFormatVersion);
|
|
121
108
|
lines.push(`${run.tool.name} ${Array.from({
|
|
122
109
|
length: Math.max(1, 80 - run.tool.name.length),
|
|
123
110
|
})
|
|
124
111
|
.map(() => '─')
|
|
125
112
|
.join('')}`);
|
|
126
113
|
lines.push('');
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
lines.push(...renderFinding(finding));
|
|
131
|
-
}
|
|
132
|
-
for (const child of execution.children ?? []) {
|
|
133
|
-
lines.push(` ${formatLocation(child.location, format)}`);
|
|
134
|
-
for (const finding of child.findings) {
|
|
135
|
-
lines.push(...renderFinding(finding, ' '));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
114
|
+
const ruleIndex = buildRuleIndex(run.rules);
|
|
115
|
+
for (const { execution } of walkExecutions(run.executions)) {
|
|
116
|
+
lines.push(...renderExecution(execution, ruleIndex, format));
|
|
138
117
|
}
|
|
139
118
|
lines.push('');
|
|
140
119
|
}
|
|
120
|
+
// Counts failed executions by resolved severity (see collectSeverityCounts /
|
|
121
|
+
// resolveExecutionSeverity) — not `informational`-kind findings, which are
|
|
122
|
+
// never counted here and can render in the body while this stays 0
|
|
123
|
+
// (BaggersIO PR-311 finding 6). Labelled uniformly as severities, not
|
|
124
|
+
// "finding(s)", to avoid implying otherwise.
|
|
141
125
|
const counts = collectSeverityCounts(report);
|
|
142
|
-
lines.push(`Summary: ${counts.error} error(s), ${counts.warn} warning(s), ${counts.hint} hint(s), ${counts.info} info
|
|
126
|
+
lines.push(`Summary: ${counts.error} error(s), ${counts.warn} warning(s), ${counts.hint} hint(s), ${counts.info} info(s).`);
|
|
143
127
|
return lines.join('\n').trimEnd();
|
|
144
128
|
}
|
|
145
129
|
//# sourceMappingURL=cli-report-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-report-renderer.js","sourceRoot":"","sources":["../src/cli-report-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"cli-report-renderer.js","sourceRoot":"","sources":["../src/cli-report-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-config.d.ts","sourceRoot":"","sources":["../src/default-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"default-config.d.ts","sourceRoot":"","sources":["../src/default-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,eAAO,MAAM,aAAa,EAAE,aAuB3B,CAAC"}
|
package/dist/default-config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-config.js","sourceRoot":"","sources":["../src/default-config.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE;QACR,yBAAyB;QACzB,2CAA2C;KAC5C;IACD,YAAY,EAAE,OAAO;IACrB,KAAK,EAAE,EAAE;IACT,OAAO,EAAE;QACP,6BAA6B,EAAE,EAAE;QACjC,yBAAyB,EAAE,EAAE;QAC7B,oCAAoC,EAAE,EAAE;QACxC,yBAAyB,EAAE,EAAE;QAC7B,0BAA0B,EAAE;YAC1B,OAAO,EAAE;gBACP,UAAU,EAAE
|
|
1
|
+
{"version":3,"file":"default-config.js","sourceRoot":"","sources":["../src/default-config.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE;QACR,yBAAyB;QACzB,2CAA2C;KAC5C;IACD,YAAY,EAAE,OAAO;IACrB,KAAK,EAAE,EAAE;IACT,OAAO,EAAE;QACP,6BAA6B,EAAE,EAAE;QACjC,yBAAyB,EAAE,EAAE;QAC7B,oCAAoC,EAAE,EAAE;QACxC,yBAAyB,EAAE,EAAE;QAC7B,0BAA0B,EAAE;YAC1B,OAAO,EAAE;gBACP,UAAU,EAAE,EAAE;aACf;SACF;QACD,6BAA6B,EAAE,EAAE;QACjC,+BAA+B,EAAE,EAAE;QACnC,qBAAqB,EAAE,EAAE;KAC1B;CACF,CAAC"}
|
|
@@ -13,7 +13,7 @@ export interface PluginOptionOverride {
|
|
|
13
13
|
* path supports arbitrarily deep nesting via dot notation and bracket
|
|
14
14
|
* array indexing, following the Helm `--set` convention:
|
|
15
15
|
*
|
|
16
|
-
* @thymian/plugin-reporter.formatters.
|
|
16
|
+
* @thymian/plugin-reporter.formatters.markdown.path=./report.md
|
|
17
17
|
* @thymian/plugin-sampler.items[0].name=Authorization
|
|
18
18
|
*/
|
|
19
19
|
export declare function parseOptionFlag(input: string): PluginOptionOverride;
|
|
@@ -22,7 +22,7 @@ export declare function parseOptionFlag(input: string): PluginOptionOverride;
|
|
|
22
22
|
* indices into an array of string keys and numeric indices.
|
|
23
23
|
*
|
|
24
24
|
* Examples:
|
|
25
|
-
* `formatters.
|
|
25
|
+
* `formatters.markdown.path` → ['formatters', 'markdown', 'path']
|
|
26
26
|
* `items[0].name` → ['items', 0, 'name']
|
|
27
27
|
* `a[1][2].b` → ['a', 1, 2, 'b']
|
|
28
28
|
*/
|
|
@@ -10,7 +10,7 @@ import { safeParse } from '../safe-parse.js';
|
|
|
10
10
|
* path supports arbitrarily deep nesting via dot notation and bracket
|
|
11
11
|
* array indexing, following the Helm `--set` convention:
|
|
12
12
|
*
|
|
13
|
-
* @thymian/plugin-reporter.formatters.
|
|
13
|
+
* @thymian/plugin-reporter.formatters.markdown.path=./report.md
|
|
14
14
|
* @thymian/plugin-sampler.items[0].name=Authorization
|
|
15
15
|
*/
|
|
16
16
|
export function parseOptionFlag(input) {
|
|
@@ -31,9 +31,9 @@ export function parseOptionFlag(input) {
|
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* Split a full key like `@thymian/plugin-reporter.formatters.
|
|
35
|
-
* the plugin name (`@thymian/plugin-reporter`) and the property path
|
|
36
|
-
* (`['formatters', '
|
|
34
|
+
* Split a full key like `@thymian/plugin-reporter.formatters.markdown.path`
|
|
35
|
+
* into the plugin name (`@thymian/plugin-reporter`) and the property path
|
|
36
|
+
* segments (`['formatters', 'markdown', 'path']`).
|
|
37
37
|
*
|
|
38
38
|
* Scoped packages (`@scope/name`) are handled: the plugin name extends
|
|
39
39
|
* up to and including the segment that contains a `/`.
|
|
@@ -73,7 +73,7 @@ function splitPluginNameAndPath(fullKey) {
|
|
|
73
73
|
* indices into an array of string keys and numeric indices.
|
|
74
74
|
*
|
|
75
75
|
* Examples:
|
|
76
|
-
* `formatters.
|
|
76
|
+
* `formatters.markdown.path` → ['formatters', 'markdown', 'path']
|
|
77
77
|
* `items[0].name` → ['items', 0, 'name']
|
|
78
78
|
* `a[1][2].b` → ['a', 1, 2, 'b']
|
|
79
79
|
*/
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { Command } from '@oclif/core';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Execution, Report } from '@thymian/core';
|
|
3
3
|
export declare const HIGH_COUNT_THRESHOLD = 20;
|
|
4
|
+
/**
|
|
5
|
+
* Predicates that decide the CLI outcome from a report's executions. Outcomes
|
|
6
|
+
* are now carried by each execution's `status` (a `failed` status ≡ a rule
|
|
7
|
+
* violation), so classification is execution-based rather than finding-based.
|
|
8
|
+
*/
|
|
4
9
|
export interface ReportClassificationOptions {
|
|
5
|
-
isFinding?: (
|
|
6
|
-
isToolError?: (
|
|
10
|
+
isFinding?: (execution: Execution) => boolean;
|
|
11
|
+
isToolError?: (execution: Execution) => boolean;
|
|
7
12
|
}
|
|
8
13
|
type CliReportClassification = 'clean-run' | 'findings' | 'tool-error';
|
|
9
14
|
export declare function classificationToExitCode(classification: CliReportClassification): 0 | 1 | 2;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-outcome.d.ts","sourceRoot":"","sources":["../src/workflow-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"workflow-outcome.d.ts","sourceRoot":"","sources":["../src/workflow-outcome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIvD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC;IAC9C,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC;CACjD;AAED,KAAK,uBAAuB,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;AAEvE,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,uBAAuB,GACtC,CAAC,GAAG,CAAC,GAAG,CAAC,CASX;AAMD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,2BAAgC,GACxC,uBAAuB,CAmBzB;AAsBD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACpE,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,2BAAgC,GACxC,IAAI,CAYN"}
|
package/dist/workflow-outcome.js
CHANGED
|
@@ -11,23 +11,21 @@ export function classificationToExitCode(classification) {
|
|
|
11
11
|
return 2;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
...execution.findings,
|
|
17
|
-
...visit(execution.children),
|
|
18
|
-
]);
|
|
19
|
-
return report.runs.flatMap((run) => visit(run.executions));
|
|
14
|
+
function collectExecutions(report) {
|
|
15
|
+
return report.runs.flatMap((run) => run.executions ?? []);
|
|
20
16
|
}
|
|
21
17
|
export function classifyReport(report, options = {}) {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
const executions = collectExecutions(report);
|
|
19
|
+
// Technical "couldn't run" now maps to a `failed` status (there is no distinct
|
|
20
|
+
// tool-error signal in the model), so by default nothing is a tool error;
|
|
21
|
+
// callers may still opt in via a custom predicate.
|
|
22
|
+
const isToolError = options.isToolError ?? (() => false);
|
|
25
23
|
const isFinding = options.isFinding ??
|
|
26
|
-
((
|
|
27
|
-
if (
|
|
24
|
+
((execution) => execution.status.kind === 'failed');
|
|
25
|
+
if (executions.some(isToolError)) {
|
|
28
26
|
return 'tool-error';
|
|
29
27
|
}
|
|
30
|
-
if (
|
|
28
|
+
if (executions.some(isFinding)) {
|
|
31
29
|
return 'findings';
|
|
32
30
|
}
|
|
33
31
|
return 'clean-run';
|
|
@@ -36,7 +34,7 @@ function emitGuidance(command, report, classification) {
|
|
|
36
34
|
if (classification !== 'findings') {
|
|
37
35
|
return;
|
|
38
36
|
}
|
|
39
|
-
const totalViolations =
|
|
37
|
+
const totalViolations = collectExecutions(report).filter((execution) => execution.status.kind === 'failed').length;
|
|
40
38
|
if (totalViolations > HIGH_COUNT_THRESHOLD) {
|
|
41
39
|
command.guidance(`\n${String.fromCodePoint(0x2139)} Running Thymian on an existing API often surfaces many findings. This doesn't mean your API is broken — it means there are HTTP conformance improvements available. Start with errors and work through them incrementally.`);
|
|
42
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-outcome.js","sourceRoot":"","sources":["../src/workflow-outcome.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-outcome.js","sourceRoot":"","sources":["../src/workflow-outcome.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAcvC,MAAM,UAAU,wBAAwB,CACtC,cAAuC;IAEvC,QAAQ,cAAc,EAAE,CAAC;QACvB,KAAK,WAAW;YACd,OAAO,CAAC,CAAC;QACX,KAAK,UAAU;YACb,OAAO,CAAC,CAAC;QACX,KAAK,YAAY;YACf,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,UAAuC,EAAE;IAEzC,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,0EAA0E;IAC1E,mDAAmD;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,SAAS,GACb,OAAO,CAAC,SAAS;QACjB,CAAC,CAAC,SAAoB,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAEjE,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACjC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,YAAY,CACnB,OAA4C,EAC5C,MAAc,EACd,cAAuC;IAEvC,IAAI,cAAc,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,CACtD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAClD,CAAC,MAAM,CAAC;IAET,IAAI,eAAe,GAAG,oBAAoB,EAAE,CAAC;QAC3C,OAAO,CAAC,QAAQ,CACd,KAAK,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,6NAA6N,CAC/P,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAAoE,EACpE,MAAc,EACd,UAAuC,EAAE;IAEzC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAC;IAE1D,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thymian/common-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12-canary.20260709-74e687c",
|
|
4
4
|
"description": "Shared CLI utilities, commands, and configuration management for Thymian",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"bugs": {
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
"tslib": "^2.3.0",
|
|
48
48
|
"yaml": "^2.8.3",
|
|
49
49
|
"@oclif/core": "^4.3.3",
|
|
50
|
-
"@thymian/core": "0.1.
|
|
50
|
+
"@thymian/core": "0.1.12-canary.20260709-74e687c"
|
|
51
51
|
}
|
|
52
52
|
}
|