@magnusekdahl/parallix 1.2.0 → 1.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/lib/agents/agents.js +737 -838
- package/lib/agents/agents.ts +930 -0
- package/lib/agents/claude-telemetry.js +149 -154
- package/lib/agents/claude-telemetry.ts +233 -0
- package/lib/agents/claude.js +121 -131
- package/lib/agents/claude.ts +156 -0
- package/lib/agents/codex-telemetry.js +176 -164
- package/lib/agents/codex-telemetry.ts +205 -0
- package/lib/agents/codex.js +168 -201
- package/lib/agents/codex.ts +236 -0
- package/lib/agents/limit-hit.js +216 -226
- package/lib/agents/limit-hit.ts +262 -0
- package/lib/agents/mistral-telemetry.js +7 -10
- package/lib/agents/mistral-telemetry.ts +44 -0
- package/lib/agents/mistral.js +40 -58
- package/lib/agents/mistral.ts +84 -0
- package/lib/agents/opencode-export.js +126 -127
- package/lib/agents/opencode-export.ts +160 -0
- package/lib/agents/opencode-telemetry.js +282 -261
- package/lib/agents/opencode-telemetry.ts +350 -0
- package/lib/agents/opencode.js +263 -305
- package/lib/agents/opencode.ts +370 -0
- package/lib/agents/stage-telemetry.js +23 -24
- package/lib/agents/stage-telemetry.ts +47 -0
- package/lib/commands/integrate.js +9 -3
- package/lib/core/fmt.js +140 -211
- package/lib/core/fmt.ts +189 -0
- package/lib/core/git.js +121 -102
- package/lib/core/git.ts +146 -0
- package/lib/core/gitignore.js +59 -106
- package/lib/core/gitignore.ts +103 -0
- package/lib/core/mission-utils.js +833 -875
- package/lib/core/mission-utils.ts +998 -0
- package/lib/core/persistent-data-migration.js +247 -205
- package/lib/core/persistent-data-migration.ts +255 -0
- package/lib/core/product-config.js +400 -476
- package/lib/core/product-config.ts +518 -0
- package/lib/core/runtime-matrix.js +41 -87
- package/lib/core/runtime-matrix.ts +84 -0
- package/lib/core/spawn-tee.js +152 -192
- package/lib/core/spawn-tee.ts +202 -0
- package/lib/core/state-map.js +92 -92
- package/lib/core/state-map.ts +115 -0
- package/lib/core/storage.js +101 -129
- package/lib/core/storage.ts +182 -0
- package/lib/core/verification.js +148 -138
- package/lib/core/verification.ts +200 -0
- package/package.json +4 -2
- package/prompts/draft.md +1 -0
- package/prompts/portfolio.md +1 -1
- package/px.js +0 -2
package/lib/core/fmt.js
CHANGED
|
@@ -1,249 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Shared formatting and palette layer for workflow-owned output.
|
|
3
4
|
* Uses Node.js built-in util.styleText for color rendering (ADR 0042).
|
|
4
5
|
* No external dependencies.
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.colors = exports.log = void 0;
|
|
9
|
+
exports.colorize = colorize;
|
|
10
|
+
exports.stripAnsi = stripAnsi;
|
|
11
|
+
exports.visibleWidth = visibleWidth;
|
|
12
|
+
exports.padVisibleEnd = padVisibleEnd;
|
|
13
|
+
exports.status = status;
|
|
14
|
+
exports.agent = agent;
|
|
15
|
+
exports.bold = bold;
|
|
16
|
+
exports.dim = dim;
|
|
17
|
+
exports.kv = kv;
|
|
18
|
+
exports.table = table;
|
|
19
|
+
exports.list = list;
|
|
20
|
+
exports.path = path;
|
|
21
|
+
exports.slug = slug;
|
|
22
|
+
exports.branch = branch;
|
|
23
|
+
exports.sha = sha;
|
|
24
|
+
exports.command = command;
|
|
25
|
+
exports.setLogger = setLogger;
|
|
26
|
+
const node_util_1 = require("node:util");
|
|
9
27
|
const colors = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
reset: 'reset',
|
|
29
|
+
bold: 'bold',
|
|
30
|
+
red: 'red',
|
|
31
|
+
green: 'green',
|
|
32
|
+
yellow: 'yellow',
|
|
33
|
+
blue: 'blue',
|
|
34
|
+
magenta: 'magenta',
|
|
35
|
+
cyan: 'cyan',
|
|
36
|
+
white: 'white',
|
|
37
|
+
dim: 'gray',
|
|
20
38
|
};
|
|
21
|
-
|
|
39
|
+
exports.colors = colors;
|
|
22
40
|
const statusMap = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
PASS: 'green',
|
|
42
|
+
FAIL: 'red',
|
|
43
|
+
WARN: 'yellow',
|
|
44
|
+
INFO: 'cyan',
|
|
45
|
+
DEBUG: 'gray',
|
|
28
46
|
};
|
|
29
|
-
|
|
30
47
|
const agentMap = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
codex: 'magenta',
|
|
49
|
+
claude: 'blue',
|
|
50
|
+
gemini: 'cyan',
|
|
51
|
+
custom: 'yellow',
|
|
35
52
|
};
|
|
36
|
-
|
|
37
|
-
/** @param {import('node:util').InspectColor} format @param {string} text */
|
|
38
53
|
function colorize(format, text) {
|
|
39
|
-
|
|
54
|
+
return (0, node_util_1.styleText)(format, String(text ?? ''));
|
|
40
55
|
}
|
|
41
|
-
|
|
42
|
-
/** @param {string} text */
|
|
43
56
|
function stripAnsi(text) {
|
|
44
|
-
|
|
57
|
+
return String(text ?? '').replace(/\x1B\[[0-9;]*m/g, '');
|
|
45
58
|
}
|
|
46
|
-
|
|
47
|
-
/** @param {string} text */
|
|
48
59
|
function visibleWidth(text) {
|
|
49
|
-
|
|
60
|
+
return stripAnsi(text).length;
|
|
50
61
|
}
|
|
51
|
-
|
|
52
|
-
/** @param {string} text @param {number} width */
|
|
53
62
|
function padVisibleEnd(text, width) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
const stringValue = String(text ?? '');
|
|
64
|
+
const padLength = Math.max(0, width - visibleWidth(stringValue));
|
|
65
|
+
return stringValue + ' '.repeat(padLength);
|
|
57
66
|
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Formats a status line prefix (e.g. "[PASS]").
|
|
61
|
-
*/
|
|
62
|
-
/** @param {string} type @param {string} text */
|
|
63
67
|
function status(type, text) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
const format = statusMap[type];
|
|
69
|
+
if (!format) {
|
|
70
|
+
return `[${type}] ${text}`;
|
|
71
|
+
}
|
|
72
|
+
return `${colorize(format, `[${type}]`)} ${text}`;
|
|
69
73
|
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Formats an agent family name.
|
|
73
|
-
*/
|
|
74
|
-
/** @param {string} family @param {string} [text] */
|
|
75
74
|
function agent(family, text = family) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const am = agentMap;
|
|
86
|
-
const format = am[family];
|
|
87
|
-
if (!format) {return label;}
|
|
88
|
-
return colorize(/** @type {import('node:util').InspectColor} */(format), label);
|
|
75
|
+
let label = text;
|
|
76
|
+
if (family === 'custom' && text !== 'custom') {
|
|
77
|
+
label = 'custom (opencode)';
|
|
78
|
+
}
|
|
79
|
+
const format = agentMap[family];
|
|
80
|
+
if (!format) {
|
|
81
|
+
return label;
|
|
82
|
+
}
|
|
83
|
+
return colorize(format, label);
|
|
89
84
|
}
|
|
90
|
-
|
|
91
|
-
/** @param {string} text */
|
|
92
85
|
function bold(text) {
|
|
93
|
-
|
|
86
|
+
return colorize('bold', text);
|
|
94
87
|
}
|
|
95
|
-
|
|
96
|
-
/** @param {string} text */
|
|
97
88
|
function dim(text) {
|
|
98
|
-
|
|
89
|
+
return colorize('gray', text);
|
|
99
90
|
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Aligned key-value pair.
|
|
103
|
-
*/
|
|
104
|
-
/** @param {string} key @param {string} value @param {number} width */
|
|
105
91
|
function kv(key, value, width = 30) {
|
|
106
|
-
|
|
92
|
+
return `${bold(key.padEnd(width))} ${value}`;
|
|
107
93
|
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Aligned table of columns.
|
|
111
|
-
*/
|
|
112
|
-
/** @param {string[][]} rows @param {{indent?: number, colPadding?: number}} [opts] */
|
|
113
94
|
function table(rows, { indent = 2, colPadding = 2 } = {}) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
95
|
+
if (rows.length === 0) {
|
|
96
|
+
return '';
|
|
97
|
+
}
|
|
98
|
+
const colWidths = rows[0].map((_, i) => Math.max(...rows.map(row => visibleWidth(row[i] ?? ''))));
|
|
99
|
+
const padding = ' '.repeat(indent);
|
|
100
|
+
return rows.map(row => padding + row.map((col, i) => padVisibleEnd(col ?? '', colWidths[i] + colPadding)).join('')).join('\n');
|
|
120
101
|
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Bulleted list.
|
|
124
|
-
*/
|
|
125
|
-
/** @param {string[]} items @param {{bullet?: string, indent?: number}} [opts] */
|
|
126
102
|
function list(items, { bullet = '-', indent = 2 } = {}) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return items.map(item => `${padding}${bullet} ${item}`).join('\n');
|
|
103
|
+
const padding = ' '.repeat(indent);
|
|
104
|
+
return items.map(item => `${padding}${bullet} ${item}`).join('\n');
|
|
130
105
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
sha: /** @param {string} text */(text) => colorize('yellow', text),
|
|
137
|
-
command: /** @param {string} text */(text) => colorize('green', text),
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
/** @type {{log: Function, error: Function}} */
|
|
106
|
+
function path(text) { return colorize('blue', text); }
|
|
107
|
+
function slug(text) { return colorize('cyan', bold(text)); }
|
|
108
|
+
function branch(text) { return colorize('magenta', text); }
|
|
109
|
+
function sha(text) { return colorize('yellow', text); }
|
|
110
|
+
function command(text) { return colorize('green', text); }
|
|
141
111
|
let currentLogger = {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
/** @param {...any} args */
|
|
145
|
-
error: (...args) => console.error(...args),
|
|
112
|
+
log: (...args) => console.log(...args),
|
|
113
|
+
error: (...args) => console.error(...args),
|
|
146
114
|
};
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
return text.toString().split('\n').map(line => {
|
|
202
|
-
const s = status('DEBUG', line);
|
|
203
|
-
currentLogger.log(s);
|
|
204
|
-
return s;
|
|
205
|
-
}).join('\n');
|
|
206
|
-
},
|
|
207
|
-
/** @param {string} text */
|
|
208
|
-
plain: (text) => {
|
|
209
|
-
/** @param {string} line */
|
|
210
|
-
text.toString().split('\n').forEach(line => currentLogger.log(line));
|
|
211
|
-
return text;
|
|
212
|
-
},
|
|
213
|
-
/** @param {string} text */
|
|
214
|
-
plainError: (text) => {
|
|
215
|
-
/** @param {string} line */
|
|
216
|
-
text.toString().split('\n').forEach(line => currentLogger.error(line));
|
|
217
|
-
return text;
|
|
218
|
-
},
|
|
115
|
+
exports.log = {
|
|
116
|
+
info: (text) => {
|
|
117
|
+
return text.toString().split('\n').map(line => {
|
|
118
|
+
const s = status('INFO', line);
|
|
119
|
+
currentLogger.log(s);
|
|
120
|
+
return s;
|
|
121
|
+
}).join('\n');
|
|
122
|
+
},
|
|
123
|
+
pass: (text) => {
|
|
124
|
+
return text.toString().split('\n').map(line => {
|
|
125
|
+
const s = status('PASS', line);
|
|
126
|
+
currentLogger.log(s);
|
|
127
|
+
return s;
|
|
128
|
+
}).join('\n');
|
|
129
|
+
},
|
|
130
|
+
fail: (text) => {
|
|
131
|
+
return text.toString().split('\n').map(line => {
|
|
132
|
+
const s = status('FAIL', line);
|
|
133
|
+
currentLogger.error(s);
|
|
134
|
+
return s;
|
|
135
|
+
}).join('\n');
|
|
136
|
+
},
|
|
137
|
+
warn: (text) => {
|
|
138
|
+
return text.toString().split('\n').map(line => {
|
|
139
|
+
const s = status('WARN', line);
|
|
140
|
+
currentLogger.log(s);
|
|
141
|
+
return s;
|
|
142
|
+
}).join('\n');
|
|
143
|
+
},
|
|
144
|
+
error: (text) => {
|
|
145
|
+
return text.toString().split('\n').map(line => {
|
|
146
|
+
const s = status('FAIL', line);
|
|
147
|
+
currentLogger.error(s);
|
|
148
|
+
return s;
|
|
149
|
+
}).join('\n');
|
|
150
|
+
},
|
|
151
|
+
debug: (text) => {
|
|
152
|
+
if (!process.env.DEBUG) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
return text.toString().split('\n').map(line => {
|
|
156
|
+
const s = status('DEBUG', line);
|
|
157
|
+
currentLogger.log(s);
|
|
158
|
+
return s;
|
|
159
|
+
}).join('\n');
|
|
160
|
+
},
|
|
161
|
+
plain: (text) => {
|
|
162
|
+
text.toString().split('\n').forEach(line => currentLogger.log(line));
|
|
163
|
+
return text;
|
|
164
|
+
},
|
|
165
|
+
plainError: (text) => {
|
|
166
|
+
text.toString().split('\n').forEach(line => currentLogger.error(line));
|
|
167
|
+
return text;
|
|
168
|
+
},
|
|
219
169
|
};
|
|
220
|
-
|
|
221
|
-
/** @param {LoggerObj|Function} newLogger */
|
|
222
170
|
function setLogger(newLogger) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return old;
|
|
171
|
+
const old = currentLogger;
|
|
172
|
+
const logger = newLogger;
|
|
173
|
+
currentLogger = {
|
|
174
|
+
log: typeof logger.log === 'function' ? logger.log : (() => { }),
|
|
175
|
+
error: typeof logger.error === 'function' ? logger.error : (typeof logger.log === 'function' ? logger.log : (() => { })),
|
|
176
|
+
};
|
|
177
|
+
return old;
|
|
231
178
|
}
|
|
232
|
-
|
|
233
|
-
module.exports = {
|
|
234
|
-
colors,
|
|
235
|
-
status,
|
|
236
|
-
agent,
|
|
237
|
-
bold,
|
|
238
|
-
dim,
|
|
239
|
-
colorize,
|
|
240
|
-
stripAnsi,
|
|
241
|
-
visibleWidth,
|
|
242
|
-
padVisibleEnd,
|
|
243
|
-
kv,
|
|
244
|
-
table,
|
|
245
|
-
list,
|
|
246
|
-
...semantic,
|
|
247
|
-
log,
|
|
248
|
-
setLogger,
|
|
249
|
-
};
|
package/lib/core/fmt.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared formatting and palette layer for workflow-owned output.
|
|
3
|
+
* Uses Node.js built-in util.styleText for color rendering (ADR 0042).
|
|
4
|
+
* No external dependencies.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { styleText } from 'node:util';
|
|
8
|
+
|
|
9
|
+
const colors = {
|
|
10
|
+
reset: 'reset',
|
|
11
|
+
bold: 'bold',
|
|
12
|
+
red: 'red',
|
|
13
|
+
green: 'green',
|
|
14
|
+
yellow: 'yellow',
|
|
15
|
+
blue: 'blue',
|
|
16
|
+
magenta: 'magenta',
|
|
17
|
+
cyan: 'cyan',
|
|
18
|
+
white: 'white',
|
|
19
|
+
dim: 'gray',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const statusMap: Record<string, string> = {
|
|
23
|
+
PASS: 'green',
|
|
24
|
+
FAIL: 'red',
|
|
25
|
+
WARN: 'yellow',
|
|
26
|
+
INFO: 'cyan',
|
|
27
|
+
DEBUG: 'gray',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const agentMap: Record<string, string> = {
|
|
31
|
+
codex: 'magenta',
|
|
32
|
+
claude: 'blue',
|
|
33
|
+
gemini: 'cyan',
|
|
34
|
+
custom: 'yellow',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export function colorize(format: string, text: string): string {
|
|
38
|
+
return styleText(format as import('node:util').InspectColor, String(text ?? ''));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function stripAnsi(text: string): string {
|
|
42
|
+
return String(text ?? '').replace(/\x1B\[[0-9;]*m/g, '');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function visibleWidth(text: string): number {
|
|
46
|
+
return stripAnsi(text).length;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function padVisibleEnd(text: string, width: number): string {
|
|
50
|
+
const stringValue = String(text ?? '');
|
|
51
|
+
const padLength = Math.max(0, width - visibleWidth(stringValue));
|
|
52
|
+
return stringValue + ' '.repeat(padLength);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function status(type: string, text: string): string {
|
|
56
|
+
const format = statusMap[type];
|
|
57
|
+
if (!format) {return `[${type}] ${text}`;}
|
|
58
|
+
return `${colorize(format, `[${type}]`)} ${text}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function agent(family: string, text: string = family): string {
|
|
62
|
+
let label = text;
|
|
63
|
+
if (family === 'custom' && text !== 'custom') {
|
|
64
|
+
label = 'custom (opencode)';
|
|
65
|
+
}
|
|
66
|
+
const format = agentMap[family];
|
|
67
|
+
if (!format) {return label;}
|
|
68
|
+
return colorize(format, label);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function bold(text: string): string {
|
|
72
|
+
return colorize('bold', text);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function dim(text: string): string {
|
|
76
|
+
return colorize('gray', text);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function kv(key: string, value: string, width: number = 30): string {
|
|
80
|
+
return `${bold(key.padEnd(width))} ${value}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function table(rows: string[][], { indent = 2, colPadding = 2 }: { indent?: number; colPadding?: number } = {}): string {
|
|
84
|
+
if (rows.length === 0) {return '';}
|
|
85
|
+
const colWidths = rows[0].map((_, i) => Math.max(...rows.map(row => visibleWidth(row[i] ?? ''))));
|
|
86
|
+
const padding = ' '.repeat(indent);
|
|
87
|
+
return rows.map(row => padding + row.map((col, i) => padVisibleEnd(col ?? '', colWidths[i] + colPadding)).join('')).join('\n');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function list(items: string[], { bullet = '-', indent = 2 }: { bullet?: string; indent?: number } = {}): string {
|
|
91
|
+
const padding = ' '.repeat(indent);
|
|
92
|
+
return items.map(item => `${padding}${bullet} ${item}`).join('\n');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function path(text: string): string { return colorize('blue', text); }
|
|
96
|
+
export function slug(text: string): string { return colorize('cyan', bold(text)); }
|
|
97
|
+
export function branch(text: string): string { return colorize('magenta', text); }
|
|
98
|
+
export function sha(text: string): string { return colorize('yellow', text); }
|
|
99
|
+
export function command(text: string): string { return colorize('green', text); }
|
|
100
|
+
|
|
101
|
+
type LogFn = (...args: unknown[]) => void;
|
|
102
|
+
type LogFunc = (text: string) => string | null;
|
|
103
|
+
|
|
104
|
+
type Logger = {
|
|
105
|
+
log: LogFn;
|
|
106
|
+
error: LogFn;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type LoggerInput = { log?: LogFn; error?: LogFn } | LogFn;
|
|
110
|
+
|
|
111
|
+
let currentLogger: Logger = {
|
|
112
|
+
log: (...args: unknown[]) => console.log(...args),
|
|
113
|
+
error: (...args: unknown[]) => console.error(...args),
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const log: {
|
|
117
|
+
info: LogFunc;
|
|
118
|
+
pass: LogFunc;
|
|
119
|
+
fail: LogFunc;
|
|
120
|
+
warn: LogFunc;
|
|
121
|
+
error: LogFunc;
|
|
122
|
+
debug: LogFunc;
|
|
123
|
+
plain: LogFunc;
|
|
124
|
+
plainError: LogFunc;
|
|
125
|
+
} = {
|
|
126
|
+
info: (text: string): string => {
|
|
127
|
+
return text.toString().split('\n').map(line => {
|
|
128
|
+
const s = status('INFO', line);
|
|
129
|
+
currentLogger.log(s);
|
|
130
|
+
return s;
|
|
131
|
+
}).join('\n');
|
|
132
|
+
},
|
|
133
|
+
pass: (text: string): string => {
|
|
134
|
+
return text.toString().split('\n').map(line => {
|
|
135
|
+
const s = status('PASS', line);
|
|
136
|
+
currentLogger.log(s);
|
|
137
|
+
return s;
|
|
138
|
+
}).join('\n');
|
|
139
|
+
},
|
|
140
|
+
fail: (text: string): string => {
|
|
141
|
+
return text.toString().split('\n').map(line => {
|
|
142
|
+
const s = status('FAIL', line);
|
|
143
|
+
currentLogger.error(s);
|
|
144
|
+
return s;
|
|
145
|
+
}).join('\n');
|
|
146
|
+
},
|
|
147
|
+
warn: (text: string): string => {
|
|
148
|
+
return text.toString().split('\n').map(line => {
|
|
149
|
+
const s = status('WARN', line);
|
|
150
|
+
currentLogger.log(s);
|
|
151
|
+
return s;
|
|
152
|
+
}).join('\n');
|
|
153
|
+
},
|
|
154
|
+
error: (text: string): string => {
|
|
155
|
+
return text.toString().split('\n').map(line => {
|
|
156
|
+
const s = status('FAIL', line);
|
|
157
|
+
currentLogger.error(s);
|
|
158
|
+
return s;
|
|
159
|
+
}).join('\n');
|
|
160
|
+
},
|
|
161
|
+
debug: (text: string): string | null => {
|
|
162
|
+
if (!process.env.DEBUG) {return null;}
|
|
163
|
+
return text.toString().split('\n').map(line => {
|
|
164
|
+
const s = status('DEBUG', line);
|
|
165
|
+
currentLogger.log(s);
|
|
166
|
+
return s;
|
|
167
|
+
}).join('\n');
|
|
168
|
+
},
|
|
169
|
+
plain: (text: string): string => {
|
|
170
|
+
text.toString().split('\n').forEach(line => currentLogger.log(line));
|
|
171
|
+
return text;
|
|
172
|
+
},
|
|
173
|
+
plainError: (text: string): string => {
|
|
174
|
+
text.toString().split('\n').forEach(line => currentLogger.error(line));
|
|
175
|
+
return text;
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export function setLogger(newLogger: LoggerInput): Logger {
|
|
180
|
+
const old = currentLogger;
|
|
181
|
+
const logger = newLogger as { log?: LogFn; error?: LogFn };
|
|
182
|
+
currentLogger = {
|
|
183
|
+
log: typeof logger.log === 'function' ? logger.log : (() => {}),
|
|
184
|
+
error: typeof logger.error === 'function' ? logger.error : (typeof logger.log === 'function' ? logger.log : (() => {})),
|
|
185
|
+
};
|
|
186
|
+
return old;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export { colors };
|