@rengler33/prov 0.1.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/README.md +314 -0
- package/dist/cli.d.ts +26 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +381 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agent.d.ts +107 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +197 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/agent.test.d.ts +5 -0
- package/dist/commands/agent.test.d.ts.map +1 -0
- package/dist/commands/agent.test.js +199 -0
- package/dist/commands/agent.test.js.map +1 -0
- package/dist/commands/constraint.d.ts +100 -0
- package/dist/commands/constraint.d.ts.map +1 -0
- package/dist/commands/constraint.js +763 -0
- package/dist/commands/constraint.js.map +1 -0
- package/dist/commands/constraint.test.d.ts +9 -0
- package/dist/commands/constraint.test.d.ts.map +1 -0
- package/dist/commands/constraint.test.js +470 -0
- package/dist/commands/constraint.test.js.map +1 -0
- package/dist/commands/graph.d.ts +99 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +552 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/graph.test.d.ts +2 -0
- package/dist/commands/graph.test.d.ts.map +1 -0
- package/dist/commands/graph.test.js +258 -0
- package/dist/commands/graph.test.js.map +1 -0
- package/dist/commands/impact.d.ts +83 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +319 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/impact.test.d.ts +2 -0
- package/dist/commands/impact.test.d.ts.map +1 -0
- package/dist/commands/impact.test.js +234 -0
- package/dist/commands/impact.test.js.map +1 -0
- package/dist/commands/init.d.ts +45 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +94 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +7 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +174 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/integration.test.d.ts +10 -0
- package/dist/commands/integration.test.d.ts.map +1 -0
- package/dist/commands/integration.test.js +456 -0
- package/dist/commands/integration.test.js.map +1 -0
- package/dist/commands/mcp.d.ts +21 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +616 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/mcp.test.d.ts +7 -0
- package/dist/commands/mcp.test.d.ts.map +1 -0
- package/dist/commands/mcp.test.js +132 -0
- package/dist/commands/mcp.test.js.map +1 -0
- package/dist/commands/plan.d.ts +218 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +1307 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/plan.test.d.ts +9 -0
- package/dist/commands/plan.test.d.ts.map +1 -0
- package/dist/commands/plan.test.js +569 -0
- package/dist/commands/plan.test.js.map +1 -0
- package/dist/commands/spec.d.ts +94 -0
- package/dist/commands/spec.d.ts.map +1 -0
- package/dist/commands/spec.js +635 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/commands/spec.test.d.ts +9 -0
- package/dist/commands/spec.test.d.ts.map +1 -0
- package/dist/commands/spec.test.js +407 -0
- package/dist/commands/spec.test.js.map +1 -0
- package/dist/commands/trace.d.ts +157 -0
- package/dist/commands/trace.d.ts.map +1 -0
- package/dist/commands/trace.js +847 -0
- package/dist/commands/trace.js.map +1 -0
- package/dist/commands/trace.test.d.ts +9 -0
- package/dist/commands/trace.test.d.ts.map +1 -0
- package/dist/commands/trace.test.js +524 -0
- package/dist/commands/trace.test.js.map +1 -0
- package/dist/graph.d.ts +204 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +496 -0
- package/dist/graph.js.map +1 -0
- package/dist/graph.test.d.ts +2 -0
- package/dist/graph.test.d.ts.map +1 -0
- package/dist/graph.test.js +382 -0
- package/dist/graph.test.js.map +1 -0
- package/dist/hash.d.ts +72 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +137 -0
- package/dist/hash.js.map +1 -0
- package/dist/hash.test.d.ts +2 -0
- package/dist/hash.test.d.ts.map +1 -0
- package/dist/hash.test.js +227 -0
- package/dist/hash.test.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +11 -0
- package/dist/index.test.js.map +1 -0
- package/dist/output.d.ts +84 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +175 -0
- package/dist/output.js.map +1 -0
- package/dist/output.test.d.ts +7 -0
- package/dist/output.test.d.ts.map +1 -0
- package/dist/output.test.js +146 -0
- package/dist/output.test.js.map +1 -0
- package/dist/staleness.d.ts +162 -0
- package/dist/staleness.d.ts.map +1 -0
- package/dist/staleness.js +309 -0
- package/dist/staleness.js.map +1 -0
- package/dist/staleness.test.d.ts +2 -0
- package/dist/staleness.test.d.ts.map +1 -0
- package/dist/staleness.test.js +448 -0
- package/dist/staleness.test.js.map +1 -0
- package/dist/storage.d.ts +267 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +623 -0
- package/dist/storage.js.map +1 -0
- package/dist/storage.test.d.ts +5 -0
- package/dist/storage.test.d.ts.map +1 -0
- package/dist/storage.test.js +434 -0
- package/dist/storage.test.js.map +1 -0
- package/dist/types.d.ts +270 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/types.test.d.ts +2 -0
- package/dist/types.test.d.ts.map +1 -0
- package/dist/types.test.js +232 -0
- package/dist/types.test.js.map +1 -0
- package/dist/watcher.d.ts +139 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +406 -0
- package/dist/watcher.js.map +1 -0
- package/dist/watcher.test.d.ts +5 -0
- package/dist/watcher.test.d.ts.map +1 -0
- package/dist/watcher.test.js +327 -0
- package/dist/watcher.test.js.map +1 -0
- package/package.json +53 -0
package/dist/output.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities for CLI commands.
|
|
3
|
+
*
|
|
4
|
+
* Supports multiple output formats:
|
|
5
|
+
* - table: Human-readable columnar format (default for TTY)
|
|
6
|
+
* - yaml: YAML format (default for pipes)
|
|
7
|
+
* - json: Machine-parseable JSON format
|
|
8
|
+
*
|
|
9
|
+
* @see req:cli:output-formats
|
|
10
|
+
*/
|
|
11
|
+
import * as YAML from 'yaml';
|
|
12
|
+
/**
|
|
13
|
+
* Detect the default output format based on environment.
|
|
14
|
+
* Returns 'table' for TTY, 'yaml' for pipes/redirects.
|
|
15
|
+
*/
|
|
16
|
+
export function detectFormat(isTty) {
|
|
17
|
+
const tty = isTty ?? process.stdout.isTTY ?? false;
|
|
18
|
+
return tty ? 'table' : 'yaml';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the format to use, considering explicit format and TTY detection.
|
|
22
|
+
*/
|
|
23
|
+
export function resolveFormat(options = {}) {
|
|
24
|
+
if (options.format) {
|
|
25
|
+
return options.format;
|
|
26
|
+
}
|
|
27
|
+
return detectFormat(options.isTty);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Truncate a string to maxWidth, adding ellipsis if needed.
|
|
31
|
+
*/
|
|
32
|
+
function truncate(str, maxWidth) {
|
|
33
|
+
if (str.length <= maxWidth)
|
|
34
|
+
return str;
|
|
35
|
+
return str.slice(0, maxWidth - 1) + '\u2026'; // Unicode ellipsis
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Pad a string to specified width with given alignment.
|
|
39
|
+
*/
|
|
40
|
+
function pad(str, width, align = 'left') {
|
|
41
|
+
if (str.length >= width)
|
|
42
|
+
return str;
|
|
43
|
+
const padding = width - str.length;
|
|
44
|
+
switch (align) {
|
|
45
|
+
case 'right':
|
|
46
|
+
return ' '.repeat(padding) + str;
|
|
47
|
+
case 'center': {
|
|
48
|
+
const left = Math.floor(padding / 2);
|
|
49
|
+
return ' '.repeat(left) + str + ' '.repeat(padding - left);
|
|
50
|
+
}
|
|
51
|
+
default:
|
|
52
|
+
return str + ' '.repeat(padding);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Format data as a table.
|
|
57
|
+
*/
|
|
58
|
+
export function formatTable(data, columns, includeHeaders = true) {
|
|
59
|
+
if (data.length === 0) {
|
|
60
|
+
return '';
|
|
61
|
+
}
|
|
62
|
+
// Calculate column widths
|
|
63
|
+
const widths = columns.map((col) => {
|
|
64
|
+
const headerWidth = col.header.length;
|
|
65
|
+
const minWidth = col.minWidth ?? headerWidth;
|
|
66
|
+
const dataWidth = Math.max(...data.map((row) => String(row[col.key] ?? '').length));
|
|
67
|
+
const width = Math.max(minWidth, headerWidth, dataWidth);
|
|
68
|
+
return col.maxWidth !== undefined ? Math.min(width, col.maxWidth) : width;
|
|
69
|
+
});
|
|
70
|
+
const lines = [];
|
|
71
|
+
// Header row
|
|
72
|
+
if (includeHeaders) {
|
|
73
|
+
const headerRow = columns
|
|
74
|
+
.map((col, i) => pad(col.header, widths[i], col.align))
|
|
75
|
+
.join(' ');
|
|
76
|
+
lines.push(headerRow);
|
|
77
|
+
// Separator
|
|
78
|
+
const separator = widths.map((w) => '-'.repeat(w)).join(' ');
|
|
79
|
+
lines.push(separator);
|
|
80
|
+
}
|
|
81
|
+
// Data rows
|
|
82
|
+
for (const row of data) {
|
|
83
|
+
const dataRow = columns
|
|
84
|
+
.map((col, i) => {
|
|
85
|
+
let value = String(row[col.key] ?? '');
|
|
86
|
+
if (col.maxWidth !== undefined && value.length > col.maxWidth) {
|
|
87
|
+
value = truncate(value, col.maxWidth);
|
|
88
|
+
}
|
|
89
|
+
return pad(value, widths[i], col.align);
|
|
90
|
+
})
|
|
91
|
+
.join(' ');
|
|
92
|
+
lines.push(dataRow);
|
|
93
|
+
}
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Format data as YAML.
|
|
98
|
+
*/
|
|
99
|
+
export function formatYaml(data) {
|
|
100
|
+
return YAML.stringify(data, { indent: 2 });
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Format data as JSON.
|
|
104
|
+
*/
|
|
105
|
+
export function formatJson(data) {
|
|
106
|
+
return JSON.stringify(data, null, 2);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Format data in the specified format.
|
|
110
|
+
*/
|
|
111
|
+
export function format(data, options = {}) {
|
|
112
|
+
const fmt = resolveFormat(options);
|
|
113
|
+
switch (fmt) {
|
|
114
|
+
case 'json':
|
|
115
|
+
return formatJson(data);
|
|
116
|
+
case 'yaml':
|
|
117
|
+
return formatYaml(data);
|
|
118
|
+
case 'table':
|
|
119
|
+
if (!Array.isArray(data)) {
|
|
120
|
+
// Single object - convert to key-value table
|
|
121
|
+
const entries = Object.entries(data);
|
|
122
|
+
const tableData = entries.map(([key, value]) => ({
|
|
123
|
+
key,
|
|
124
|
+
value: typeof value === 'object' ? JSON.stringify(value) : String(value),
|
|
125
|
+
}));
|
|
126
|
+
const columns = [
|
|
127
|
+
{ header: 'Key', key: 'key', minWidth: 10 },
|
|
128
|
+
{ header: 'Value', key: 'value', maxWidth: 60 },
|
|
129
|
+
];
|
|
130
|
+
return formatTable(tableData, options.columns ?? columns, options.headers ?? true);
|
|
131
|
+
}
|
|
132
|
+
// Array - need columns defined
|
|
133
|
+
if (!options.columns || options.columns.length === 0) {
|
|
134
|
+
// Auto-generate columns from first item
|
|
135
|
+
const first = data[0];
|
|
136
|
+
const autoColumns = Object.keys(first).map((key) => ({
|
|
137
|
+
header: key,
|
|
138
|
+
key,
|
|
139
|
+
maxWidth: 40,
|
|
140
|
+
}));
|
|
141
|
+
return formatTable(data, autoColumns, options.headers ?? true);
|
|
142
|
+
}
|
|
143
|
+
return formatTable(data, options.columns, options.headers ?? true);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Output data to stdout in the specified format.
|
|
148
|
+
*/
|
|
149
|
+
export function output(data, options = {}) {
|
|
150
|
+
const formatted = format(data, options);
|
|
151
|
+
process.stdout.write(formatted);
|
|
152
|
+
// Add newline if not already present
|
|
153
|
+
if (!formatted.endsWith('\n')) {
|
|
154
|
+
process.stdout.write('\n');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Output an error message to stderr.
|
|
159
|
+
*/
|
|
160
|
+
export function error(message) {
|
|
161
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Output a success message to stdout.
|
|
165
|
+
*/
|
|
166
|
+
export function success(message) {
|
|
167
|
+
process.stdout.write(`${message}\n`);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Output a warning message to stderr.
|
|
171
|
+
*/
|
|
172
|
+
export function warn(message) {
|
|
173
|
+
process.stderr.write(`Warning: ${message}\n`);
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAqC7B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAe;IAC1C,MAAM,GAAG,GAAG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;IACnD,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,UAAyB,EAAE;IACvD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,GAAW,EAAE,QAAgB;IAC7C,IAAI,GAAG,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,GAAG,CAAC;IACvC,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,mBAAmB;AACnE,CAAC;AAED;;GAEG;AACH,SAAS,GAAG,CAAC,GAAW,EAAE,KAAa,EAAE,QAAqC,MAAM;IAClF,IAAI,GAAG,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,GAAG,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;IACnC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC;QACnC,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YACrC,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QAC7D,CAAC;QACD;YACE,OAAO,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,IAAwC,EACxC,OAAsB,EACtB,cAAc,GAAG,IAAI;IAErB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,0BAA0B;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACjC,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;QACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,WAAW,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CACxB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CACxD,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QACzD,OAAO,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,aAAa;IACb,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;aACvD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtB,YAAY;QACZ,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9D,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,YAAY;IACZ,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,OAAO;aACpB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;YACd,IAAI,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACvC,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAC9D,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxC,CAAC;YACD,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CACpB,IAAa,EACb,UAAyB,EAAE;IAE3B,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEnC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,KAAK,MAAM;YACT,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,KAAK,OAAO;YACV,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,6CAA6C;gBAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAA+B,CAAC,CAAC;gBAChE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC/C,GAAG;oBACH,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBACzE,CAAC,CAAC,CAAC;gBACJ,MAAM,OAAO,GAAkB;oBAC7B,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;oBAC3C,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;iBAChD,CAAC;gBACF,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;YACrF,CAAC;YACD,+BAA+B;YAC/B,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrD,wCAAwC;gBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAA4B,CAAC;gBACjD,MAAM,WAAW,GAAkB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBAClE,MAAM,EAAE,GAAG;oBACX,GAAG;oBACH,QAAQ,EAAE,EAAE;iBACb,CAAC,CAAC,CAAC;gBACJ,OAAO,WAAW,CAAC,IAAiC,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;YAC9F,CAAC;YACD,OAAO,WAAW,CAAC,IAAiC,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IACpG,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAa,EAAE,UAAyB,EAAE;IAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC,qCAAqC;IACrC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.test.d.ts","sourceRoot":"","sources":["../src/output.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for output formatting utilities.
|
|
3
|
+
*
|
|
4
|
+
* @see req:cli:output-formats
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import { detectFormat, resolveFormat, formatTable, formatYaml, formatJson, format, } from './output.js';
|
|
8
|
+
describe('output', () => {
|
|
9
|
+
describe('detectFormat', () => {
|
|
10
|
+
it('should return table for TTY', () => {
|
|
11
|
+
expect(detectFormat(true)).toBe('table');
|
|
12
|
+
});
|
|
13
|
+
it('should return yaml for non-TTY', () => {
|
|
14
|
+
expect(detectFormat(false)).toBe('yaml');
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
describe('resolveFormat', () => {
|
|
18
|
+
it('should use explicit format when provided', () => {
|
|
19
|
+
expect(resolveFormat({ format: 'json' })).toBe('json');
|
|
20
|
+
expect(resolveFormat({ format: 'yaml' })).toBe('yaml');
|
|
21
|
+
expect(resolveFormat({ format: 'table' })).toBe('table');
|
|
22
|
+
});
|
|
23
|
+
it('should detect format when not provided', () => {
|
|
24
|
+
expect(resolveFormat({ isTty: true })).toBe('table');
|
|
25
|
+
expect(resolveFormat({ isTty: false })).toBe('yaml');
|
|
26
|
+
});
|
|
27
|
+
it('should handle empty options', () => {
|
|
28
|
+
// Default behavior depends on process.stdout.isTTY
|
|
29
|
+
const result = resolveFormat({});
|
|
30
|
+
expect(['table', 'yaml']).toContain(result);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('formatTable', () => {
|
|
34
|
+
const columns = [
|
|
35
|
+
{ header: 'ID', key: 'id', minWidth: 5 },
|
|
36
|
+
{ header: 'Name', key: 'name' },
|
|
37
|
+
{ header: 'Status', key: 'status' },
|
|
38
|
+
];
|
|
39
|
+
const data = [
|
|
40
|
+
{ id: '1', name: 'Alice', status: 'active' },
|
|
41
|
+
{ id: '2', name: 'Bob', status: 'inactive' },
|
|
42
|
+
];
|
|
43
|
+
it('should format data as table with headers', () => {
|
|
44
|
+
const result = formatTable(data, columns, true);
|
|
45
|
+
expect(result).toContain('ID');
|
|
46
|
+
expect(result).toContain('Name');
|
|
47
|
+
expect(result).toContain('Status');
|
|
48
|
+
expect(result).toContain('Alice');
|
|
49
|
+
expect(result).toContain('Bob');
|
|
50
|
+
expect(result).toContain('active');
|
|
51
|
+
expect(result).toContain('inactive');
|
|
52
|
+
});
|
|
53
|
+
it('should format data as table without headers', () => {
|
|
54
|
+
const result = formatTable(data, columns, false);
|
|
55
|
+
expect(result).not.toContain('ID ');
|
|
56
|
+
expect(result).toContain('Alice');
|
|
57
|
+
});
|
|
58
|
+
it('should return empty string for empty data', () => {
|
|
59
|
+
expect(formatTable([], columns)).toBe('');
|
|
60
|
+
});
|
|
61
|
+
it('should respect maxWidth and truncate', () => {
|
|
62
|
+
const narrowColumns = [
|
|
63
|
+
{ header: 'Name', key: 'name', maxWidth: 5 },
|
|
64
|
+
];
|
|
65
|
+
const longData = [{ name: 'VeryLongName' }];
|
|
66
|
+
const result = formatTable(longData, narrowColumns);
|
|
67
|
+
expect(result).toContain('\u2026'); // ellipsis
|
|
68
|
+
});
|
|
69
|
+
it('should handle missing values gracefully', () => {
|
|
70
|
+
const sparseData = [
|
|
71
|
+
{ id: '1', name: 'Alice' }, // missing status
|
|
72
|
+
];
|
|
73
|
+
const result = formatTable(sparseData, columns);
|
|
74
|
+
expect(result).toContain('Alice');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('formatYaml', () => {
|
|
78
|
+
it('should format object as YAML', () => {
|
|
79
|
+
const data = { name: 'test', value: 42 };
|
|
80
|
+
const result = formatYaml(data);
|
|
81
|
+
expect(result).toContain('name: test');
|
|
82
|
+
expect(result).toContain('value: 42');
|
|
83
|
+
});
|
|
84
|
+
it('should format array as YAML', () => {
|
|
85
|
+
const data = [{ id: 1 }, { id: 2 }];
|
|
86
|
+
const result = formatYaml(data);
|
|
87
|
+
expect(result).toContain('- id: 1');
|
|
88
|
+
expect(result).toContain('- id: 2');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('formatJson', () => {
|
|
92
|
+
it('should format object as pretty JSON', () => {
|
|
93
|
+
const data = { name: 'test', value: 42 };
|
|
94
|
+
const result = formatJson(data);
|
|
95
|
+
expect(JSON.parse(result)).toEqual(data);
|
|
96
|
+
expect(result).toContain('\n'); // pretty printed
|
|
97
|
+
});
|
|
98
|
+
it('should format array as pretty JSON', () => {
|
|
99
|
+
const data = [1, 2, 3];
|
|
100
|
+
const result = formatJson(data);
|
|
101
|
+
expect(JSON.parse(result)).toEqual(data);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('format', () => {
|
|
105
|
+
const data = [
|
|
106
|
+
{ id: '1', name: 'Alice' },
|
|
107
|
+
{ id: '2', name: 'Bob' },
|
|
108
|
+
];
|
|
109
|
+
it('should format as JSON when specified', () => {
|
|
110
|
+
const result = format(data, { format: 'json' });
|
|
111
|
+
expect(JSON.parse(result)).toEqual(data);
|
|
112
|
+
});
|
|
113
|
+
it('should format as YAML when specified', () => {
|
|
114
|
+
const result = format(data, { format: 'yaml' });
|
|
115
|
+
expect(result).toContain('- id:');
|
|
116
|
+
});
|
|
117
|
+
it('should format as table when specified', () => {
|
|
118
|
+
const result = format(data, { format: 'table' });
|
|
119
|
+
expect(result).toContain('id');
|
|
120
|
+
expect(result).toContain('name');
|
|
121
|
+
expect(result).toContain('Alice');
|
|
122
|
+
});
|
|
123
|
+
it('should auto-generate columns for table format', () => {
|
|
124
|
+
const result = format(data, { format: 'table' });
|
|
125
|
+
expect(result).toContain('id');
|
|
126
|
+
expect(result).toContain('name');
|
|
127
|
+
});
|
|
128
|
+
it('should use custom columns when provided', () => {
|
|
129
|
+
const columns = [
|
|
130
|
+
{ header: 'ID', key: 'id' },
|
|
131
|
+
];
|
|
132
|
+
const result = format(data, { format: 'table', columns });
|
|
133
|
+
expect(result).toContain('ID');
|
|
134
|
+
expect(result).not.toContain('name');
|
|
135
|
+
});
|
|
136
|
+
it('should format single object as key-value table', () => {
|
|
137
|
+
const obj = { name: 'test', value: 42 };
|
|
138
|
+
const result = format(obj, { format: 'table' });
|
|
139
|
+
expect(result).toContain('Key');
|
|
140
|
+
expect(result).toContain('Value');
|
|
141
|
+
expect(result).toContain('name');
|
|
142
|
+
expect(result).toContain('test');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=output.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.test.js","sourceRoot":"","sources":["../src/output.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staleness detection for the intent graph.
|
|
3
|
+
*
|
|
4
|
+
* Detects when graph nodes are stale due to upstream changes:
|
|
5
|
+
* - Plan staleness: source specs/constraints have changed
|
|
6
|
+
* - Trace staleness: artifact files have changed
|
|
7
|
+
* - Derived staleness: nodes that depend on stale nodes
|
|
8
|
+
*
|
|
9
|
+
* @see req:graph:staleness-detection
|
|
10
|
+
*/
|
|
11
|
+
import { IntentGraph } from './graph.js';
|
|
12
|
+
import type { EntityId, Hash, Plan, Trace } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Reason why an entity is stale.
|
|
15
|
+
*/
|
|
16
|
+
export type StalenessReason = {
|
|
17
|
+
type: 'source_changed';
|
|
18
|
+
sourceId: EntityId;
|
|
19
|
+
expectedHash: Hash;
|
|
20
|
+
actualHash: Hash;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'artifact_changed';
|
|
23
|
+
path: string;
|
|
24
|
+
expectedHash: Hash;
|
|
25
|
+
actualHash: Hash;
|
|
26
|
+
} | {
|
|
27
|
+
type: 'artifact_missing';
|
|
28
|
+
path: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'derived_from_stale';
|
|
31
|
+
upstreamId: EntityId;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'source_missing';
|
|
34
|
+
sourceId: EntityId;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Staleness information for a single entity.
|
|
38
|
+
*/
|
|
39
|
+
export interface StalenessInfo {
|
|
40
|
+
/** Entity ID */
|
|
41
|
+
readonly id: EntityId;
|
|
42
|
+
/** Whether the entity is stale */
|
|
43
|
+
readonly stale: boolean;
|
|
44
|
+
/** Reasons for staleness (empty if not stale) */
|
|
45
|
+
readonly reasons: readonly StalenessReason[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Result of staleness detection for the entire graph.
|
|
49
|
+
*/
|
|
50
|
+
export interface StalenessResult {
|
|
51
|
+
/** Total number of nodes checked */
|
|
52
|
+
readonly totalNodes: number;
|
|
53
|
+
/** Number of stale nodes */
|
|
54
|
+
readonly staleCount: number;
|
|
55
|
+
/** Staleness info for each checked node */
|
|
56
|
+
readonly nodes: ReadonlyMap<EntityId, StalenessInfo>;
|
|
57
|
+
/** IDs of directly stale nodes (not transitively stale) */
|
|
58
|
+
readonly directlyStale: readonly EntityId[];
|
|
59
|
+
/** IDs of transitively stale nodes (stale due to upstream) */
|
|
60
|
+
readonly transitivelyStale: readonly EntityId[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Options for staleness detection.
|
|
64
|
+
*/
|
|
65
|
+
export interface StalenessOptions {
|
|
66
|
+
/** Project root directory (default: cwd) */
|
|
67
|
+
readonly projectRoot?: string;
|
|
68
|
+
/** Check only specific node types */
|
|
69
|
+
readonly nodeTypes?: readonly ('plan' | 'artifact')[];
|
|
70
|
+
/** Include transitive staleness detection */
|
|
71
|
+
readonly includeTransitive?: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Compute the hash of a file's raw contents.
|
|
75
|
+
*
|
|
76
|
+
* This hashes the raw file bytes, unlike watcher.computeFileHash which
|
|
77
|
+
* parses YAML and computes a canonical hash. Used for artifact staleness.
|
|
78
|
+
*
|
|
79
|
+
* @param filePath - Absolute or relative path to the file
|
|
80
|
+
* @param projectRoot - Project root for resolving relative paths
|
|
81
|
+
* @returns Hash of file contents, or null if file doesn't exist
|
|
82
|
+
*/
|
|
83
|
+
export declare function computeArtifactHash(filePath: string, projectRoot?: string): Hash | null;
|
|
84
|
+
/**
|
|
85
|
+
* Check if a plan is stale due to source changes.
|
|
86
|
+
*
|
|
87
|
+
* A plan is stale if any of its source specs/constraints have changed
|
|
88
|
+
* (i.e., current hash differs from the hash recorded at plan creation).
|
|
89
|
+
*
|
|
90
|
+
* @param plan - The plan to check
|
|
91
|
+
* @param graph - The intent graph containing source nodes
|
|
92
|
+
* @returns Staleness info for the plan
|
|
93
|
+
*/
|
|
94
|
+
export declare function checkPlanStaleness(plan: Plan, graph: IntentGraph): StalenessInfo;
|
|
95
|
+
/**
|
|
96
|
+
* Check if a trace is stale due to artifact changes.
|
|
97
|
+
*
|
|
98
|
+
* A trace is stale if:
|
|
99
|
+
* - The artifact file no longer exists
|
|
100
|
+
* - The artifact file's hash differs from the recorded hash
|
|
101
|
+
*
|
|
102
|
+
* @param trace - The trace to check
|
|
103
|
+
* @param projectRoot - Project root for resolving file paths
|
|
104
|
+
* @returns Staleness info for the trace
|
|
105
|
+
*/
|
|
106
|
+
export declare function checkTraceStaleness(trace: Trace, projectRoot?: string): StalenessInfo;
|
|
107
|
+
/**
|
|
108
|
+
* Find all nodes that are transitively stale.
|
|
109
|
+
*
|
|
110
|
+
* A node is transitively stale if any of its upstream nodes are stale.
|
|
111
|
+
* Uses forward traversal from stale nodes to find all affected downstream nodes.
|
|
112
|
+
*
|
|
113
|
+
* @param graph - The intent graph
|
|
114
|
+
* @param directlyStale - Set of directly stale node IDs
|
|
115
|
+
* @returns Set of transitively stale node IDs (excluding directly stale)
|
|
116
|
+
*/
|
|
117
|
+
export declare function findTransitivelyStale(graph: IntentGraph, directlyStale: Set<EntityId>): Set<EntityId>;
|
|
118
|
+
/**
|
|
119
|
+
* Detect staleness across the entire intent graph.
|
|
120
|
+
*
|
|
121
|
+
* @param graph - The intent graph to check
|
|
122
|
+
* @param options - Detection options
|
|
123
|
+
* @returns Comprehensive staleness result
|
|
124
|
+
*/
|
|
125
|
+
export declare function detectStaleness(graph: IntentGraph, options?: StalenessOptions): StalenessResult;
|
|
126
|
+
/**
|
|
127
|
+
* Check if a specific node is stale.
|
|
128
|
+
*
|
|
129
|
+
* @param graph - The intent graph
|
|
130
|
+
* @param nodeId - ID of the node to check
|
|
131
|
+
* @param options - Detection options
|
|
132
|
+
* @returns Staleness info for the node, or null if node not found
|
|
133
|
+
*/
|
|
134
|
+
export declare function isNodeStale(graph: IntentGraph, nodeId: EntityId, options?: StalenessOptions): StalenessInfo | null;
|
|
135
|
+
/**
|
|
136
|
+
* Get all stale nodes in the graph.
|
|
137
|
+
*
|
|
138
|
+
* @param graph - The intent graph
|
|
139
|
+
* @param options - Detection options
|
|
140
|
+
* @returns Array of stale node IDs
|
|
141
|
+
*/
|
|
142
|
+
export declare function getStaleNodes(graph: IntentGraph, options?: StalenessOptions): EntityId[];
|
|
143
|
+
/**
|
|
144
|
+
* Get stale plans and their reasons.
|
|
145
|
+
*
|
|
146
|
+
* @param graph - The intent graph
|
|
147
|
+
* @returns Array of staleness info for stale plans only
|
|
148
|
+
*/
|
|
149
|
+
export declare function getStalePlans(graph: IntentGraph): StalenessInfo[];
|
|
150
|
+
/**
|
|
151
|
+
* Get stale traces and their reasons.
|
|
152
|
+
*
|
|
153
|
+
* @param graph - The intent graph
|
|
154
|
+
* @param projectRoot - Project root for resolving file paths
|
|
155
|
+
* @returns Array of staleness info for stale traces only
|
|
156
|
+
*/
|
|
157
|
+
export declare function getStaleTraces(graph: IntentGraph, projectRoot?: string): StalenessInfo[];
|
|
158
|
+
/**
|
|
159
|
+
* Format staleness reason as human-readable string.
|
|
160
|
+
*/
|
|
161
|
+
export declare function formatStalenessReason(reason: StalenessReason): string;
|
|
162
|
+
//# sourceMappingURL=staleness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staleness.d.ts","sourceRoot":"","sources":["../src/staleness.ts"],"names":[],"mappings":"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"}
|