@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.
Files changed (51) hide show
  1. package/lib/agents/agents.js +737 -838
  2. package/lib/agents/agents.ts +930 -0
  3. package/lib/agents/claude-telemetry.js +149 -154
  4. package/lib/agents/claude-telemetry.ts +233 -0
  5. package/lib/agents/claude.js +121 -131
  6. package/lib/agents/claude.ts +156 -0
  7. package/lib/agents/codex-telemetry.js +176 -164
  8. package/lib/agents/codex-telemetry.ts +205 -0
  9. package/lib/agents/codex.js +168 -201
  10. package/lib/agents/codex.ts +236 -0
  11. package/lib/agents/limit-hit.js +216 -226
  12. package/lib/agents/limit-hit.ts +262 -0
  13. package/lib/agents/mistral-telemetry.js +7 -10
  14. package/lib/agents/mistral-telemetry.ts +44 -0
  15. package/lib/agents/mistral.js +40 -58
  16. package/lib/agents/mistral.ts +84 -0
  17. package/lib/agents/opencode-export.js +126 -127
  18. package/lib/agents/opencode-export.ts +160 -0
  19. package/lib/agents/opencode-telemetry.js +282 -261
  20. package/lib/agents/opencode-telemetry.ts +350 -0
  21. package/lib/agents/opencode.js +263 -305
  22. package/lib/agents/opencode.ts +370 -0
  23. package/lib/agents/stage-telemetry.js +23 -24
  24. package/lib/agents/stage-telemetry.ts +47 -0
  25. package/lib/commands/integrate.js +9 -3
  26. package/lib/core/fmt.js +140 -211
  27. package/lib/core/fmt.ts +189 -0
  28. package/lib/core/git.js +121 -102
  29. package/lib/core/git.ts +146 -0
  30. package/lib/core/gitignore.js +59 -106
  31. package/lib/core/gitignore.ts +103 -0
  32. package/lib/core/mission-utils.js +833 -875
  33. package/lib/core/mission-utils.ts +998 -0
  34. package/lib/core/persistent-data-migration.js +247 -205
  35. package/lib/core/persistent-data-migration.ts +255 -0
  36. package/lib/core/product-config.js +400 -476
  37. package/lib/core/product-config.ts +518 -0
  38. package/lib/core/runtime-matrix.js +41 -87
  39. package/lib/core/runtime-matrix.ts +84 -0
  40. package/lib/core/spawn-tee.js +152 -192
  41. package/lib/core/spawn-tee.ts +202 -0
  42. package/lib/core/state-map.js +92 -92
  43. package/lib/core/state-map.ts +115 -0
  44. package/lib/core/storage.js +101 -129
  45. package/lib/core/storage.ts +182 -0
  46. package/lib/core/verification.js +148 -138
  47. package/lib/core/verification.ts +200 -0
  48. package/package.json +4 -2
  49. package/prompts/draft.md +1 -0
  50. package/prompts/portfolio.md +1 -1
  51. 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
- const { styleText } = require('node:util');
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
- 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',
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
- PASS: 'green',
24
- FAIL: 'red',
25
- WARN: 'yellow',
26
- INFO: 'cyan',
27
- DEBUG: 'gray',
41
+ PASS: 'green',
42
+ FAIL: 'red',
43
+ WARN: 'yellow',
44
+ INFO: 'cyan',
45
+ DEBUG: 'gray',
28
46
  };
29
-
30
47
  const agentMap = {
31
- codex: 'magenta',
32
- claude: 'blue',
33
- gemini: 'cyan',
34
- custom: 'yellow',
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
- return styleText(format, String(text ?? ''));
54
+ return (0, node_util_1.styleText)(format, String(text ?? ''));
40
55
  }
41
-
42
- /** @param {string} text */
43
56
  function stripAnsi(text) {
44
- return String(text ?? '').replace(/\x1B\[[0-9;]*m/g, '');
57
+ return String(text ?? '').replace(/\x1B\[[0-9;]*m/g, '');
45
58
  }
46
-
47
- /** @param {string} text */
48
59
  function visibleWidth(text) {
49
- return stripAnsi(text).length;
60
+ return stripAnsi(text).length;
50
61
  }
51
-
52
- /** @param {string} text @param {number} width */
53
62
  function padVisibleEnd(text, width) {
54
- const stringValue = String(text ?? '');
55
- const padLength = Math.max(0, width - visibleWidth(stringValue));
56
- return stringValue + ' '.repeat(padLength);
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
- /** @type {Record<string,string>} */
65
- const sm = statusMap;
66
- const format = sm[type];
67
- if (!format) {return `[${type}] ${text}`;}
68
- return `${colorize(/** @type {import('node:util').InspectColor} */(format), `[${type}]`)} ${text}`;
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
- let label = text;
77
- // Disambiguate the opencode-backed `custom` family only when the caller
78
- // passes a distinct display text (e.g. a model id): show `custom (opencode)`
79
- // so the underlying runtime is explicit. When text is just `custom`, render
80
- // it plainly to avoid the redundant `custom (opencode)` suffix.
81
- if (family === 'custom' && text !== 'custom') {
82
- label = 'custom (opencode)';
83
- }
84
- /** @type {Record<string,string>} */
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
- return colorize('bold', text);
86
+ return colorize('bold', text);
94
87
  }
95
-
96
- /** @param {string} text */
97
88
  function dim(text) {
98
- return colorize('gray', text);
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
- return `${bold(key.padEnd(width))} ${value}`;
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
- if (rows.length === 0) {return '';}
115
- /** @param {unknown} _ @param {number} i */
116
- const colWidths = rows[0].map((_, i) => Math.max(...rows.map(row => visibleWidth(row[i] ?? ''))));
117
- const padding = ' '.repeat(indent);
118
- /** @param {string[]} row */
119
- return rows.map(row => padding + row.map((col, i) => padVisibleEnd(col ?? '', colWidths[i] + colPadding)).join('')).join('\n');
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
- const padding = ' '.repeat(indent);
128
- /** @param {string} item */
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
- const semantic = {
133
- path: /** @param {string} text */(text) => colorize('blue', text),
134
- slug: /** @param {string} text */(text) => colorize('cyan', bold(text)),
135
- branch: /** @param {string} text */(text) => colorize('magenta', text),
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
- /** @param {...any} args */
143
- log: (...args) => console.log(...args),
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
- /** @typedef {{log?: Function, error?: Function}} LoggerObj */
149
-
150
- /** @type{{info: Function, pass: Function, fail: Function, warn: Function, error: Function, debug: Function, plain: Function, plainError: Function}} */
151
- const log = {
152
- /** @param {string} text */
153
- info: (text) => {
154
- /** @param {string} line */
155
- return text.toString().split('\n').map(line => {
156
- const s = status('INFO', line);
157
- currentLogger.log(s);
158
- return s;
159
- }).join('\n');
160
- },
161
- /** @param {string} text */
162
- pass: (text) => {
163
- /** @param {string} line */
164
- return text.toString().split('\n').map(line => {
165
- const s = status('PASS', line);
166
- currentLogger.log(s);
167
- return s;
168
- }).join('\n');
169
- },
170
- /** @param {string} text */
171
- fail: (text) => {
172
- /** @param {string} line */
173
- return text.toString().split('\n').map(line => {
174
- const s = status('FAIL', line);
175
- currentLogger.error(s);
176
- return s;
177
- }).join('\n');
178
- },
179
- /** @param {string} text */
180
- warn: (text) => {
181
- /** @param {string} line */
182
- return text.toString().split('\n').map(line => {
183
- const s = status('WARN', line);
184
- currentLogger.log(s);
185
- return s;
186
- }).join('\n');
187
- },
188
- /** @param {string} text */
189
- error: (text) => {
190
- /** @param {string} line */
191
- return text.toString().split('\n').map(line => {
192
- const s = status('FAIL', line);
193
- currentLogger.error(s);
194
- return s;
195
- }).join('\n');
196
- },
197
- /** @param {string} text */
198
- debug: (text) => {
199
- if (!process.env.DEBUG) {return null;}
200
- /** @param {string} line */
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
- const old = currentLogger;
224
- /** @type {LoggerObj} */
225
- const logger = /** @type {LoggerObj} */(newLogger);
226
- currentLogger = {
227
- log: typeof logger.log === 'function' ? logger.log : (() => {}),
228
- error: typeof logger.error === 'function' ? logger.error : (typeof logger.log === 'function' ? logger.log : (() => {})),
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
- };
@@ -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 };