@trenchwork/erosolar 1.1.35 → 1.1.37

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 (47) hide show
  1. package/dist/bin/erosolar.js +152 -85
  2. package/dist/bin/erosolar.js.map +1 -1
  3. package/dist/bin/selfTest.d.ts.map +1 -1
  4. package/dist/bin/selfTest.js +38 -51
  5. package/dist/bin/selfTest.js.map +1 -1
  6. package/dist/cli/offsecInstall.d.ts.map +1 -1
  7. package/dist/cli/offsecInstall.js +104 -37
  8. package/dist/cli/offsecInstall.js.map +1 -1
  9. package/dist/core/auth.d.ts.map +1 -1
  10. package/dist/core/auth.js +35 -9
  11. package/dist/core/auth.js.map +1 -1
  12. package/dist/core/hitl.d.ts +4 -1
  13. package/dist/core/hitl.d.ts.map +1 -1
  14. package/dist/core/hitl.js +60 -171
  15. package/dist/core/hitl.js.map +1 -1
  16. package/dist/tools/interactionTools.d.ts.map +1 -1
  17. package/dist/tools/interactionTools.js +31 -15
  18. package/dist/tools/interactionTools.js.map +1 -1
  19. package/dist/ui/ink/AskUserMenu.d.ts +16 -0
  20. package/dist/ui/ink/AskUserMenu.d.ts.map +1 -0
  21. package/dist/ui/ink/AskUserMenu.js +85 -0
  22. package/dist/ui/ink/AskUserMenu.js.map +1 -0
  23. package/dist/ui/ink/AuthWaiting.d.ts +17 -0
  24. package/dist/ui/ink/AuthWaiting.d.ts.map +1 -0
  25. package/dist/ui/ink/AuthWaiting.js +20 -0
  26. package/dist/ui/ink/AuthWaiting.js.map +1 -0
  27. package/dist/ui/ink/HitlDecisionMenu.d.ts +23 -0
  28. package/dist/ui/ink/HitlDecisionMenu.d.ts.map +1 -0
  29. package/dist/ui/ink/HitlDecisionMenu.js +124 -0
  30. package/dist/ui/ink/HitlDecisionMenu.js.map +1 -0
  31. package/dist/ui/ink/OffsecInstallApp.d.ts +31 -0
  32. package/dist/ui/ink/OffsecInstallApp.d.ts.map +1 -0
  33. package/dist/ui/ink/OffsecInstallApp.js +62 -0
  34. package/dist/ui/ink/OffsecInstallApp.js.map +1 -0
  35. package/dist/ui/ink/SelfTestApp.d.ts +23 -0
  36. package/dist/ui/ink/SelfTestApp.d.ts.map +1 -0
  37. package/dist/ui/ink/SelfTestApp.js +47 -0
  38. package/dist/ui/ink/SelfTestApp.js.map +1 -0
  39. package/dist/ui/ink/oneShot.d.ts +33 -0
  40. package/dist/ui/ink/oneShot.d.ts.map +1 -0
  41. package/dist/ui/ink/oneShot.js +70 -0
  42. package/dist/ui/ink/oneShot.js.map +1 -0
  43. package/dist/utils/statusReporter.d.ts +13 -0
  44. package/dist/utils/statusReporter.d.ts.map +1 -1
  45. package/dist/utils/statusReporter.js +26 -0
  46. package/dist/utils/statusReporter.js.map +1 -1
  47. package/package.json +1 -1
@@ -0,0 +1,124 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * HitlDecisionMenu — Ink-rendered HUMAN DECISION REQUIRED prompt.
4
+ *
5
+ * Replaces the manual `\x1b[2J\x1b[H` + chalk-bordered ASCII box +
6
+ * stdin raw-mode keypress loop in src/core/hitl.ts. Owns its own
7
+ * Ink mount via showHitlDecision(); the caller awaits the resolve.
8
+ *
9
+ * Three states:
10
+ * 1. menu — arrow-key list, last item is "Enter your own"
11
+ * 2. custom — single-line text input for the operator's freeform answer
12
+ * 3. cancelled — Ctrl+C handled by parent (signal handler) → unmounts
13
+ */
14
+ import React, { useState } from 'react';
15
+ import { Box, Text, useInput, useApp } from 'ink';
16
+ function buildMenuItems(req) {
17
+ return [
18
+ ...req.options.map((opt) => ({
19
+ id: opt.id,
20
+ label: opt.label,
21
+ description: opt.description ?? '',
22
+ })),
23
+ {
24
+ id: req.customId ?? '__custom__',
25
+ label: 'Enter your own',
26
+ description: 'Type a custom plan, instruction, or alternative approach',
27
+ isCustom: true,
28
+ },
29
+ ];
30
+ }
31
+ function HitlDecision({ request, onResolve, }) {
32
+ const items = React.useMemo(() => buildMenuItems(request), [request]);
33
+ // Default focus on "Enter your own" — matches the prior CLI behavior
34
+ // where the operator could just hit Enter to compose a free-form answer.
35
+ const [selected, setSelected] = useState(items.length - 1);
36
+ const [phase, setPhase] = useState('menu');
37
+ const [customInput, setCustomInput] = useState('');
38
+ const { exit } = useApp();
39
+ useInput((input, key) => {
40
+ if (phase === 'menu') {
41
+ if (key.upArrow || input === 'k') {
42
+ setSelected((i) => Math.max(0, i - 1));
43
+ return;
44
+ }
45
+ if (key.downArrow || input === 'j') {
46
+ setSelected((i) => Math.min(items.length - 1, i + 1));
47
+ return;
48
+ }
49
+ if (key.return) {
50
+ const item = items[selected];
51
+ if (item.isCustom) {
52
+ setPhase('custom');
53
+ }
54
+ else {
55
+ onResolve({ selectedOptionId: item.id });
56
+ exit();
57
+ }
58
+ return;
59
+ }
60
+ if (key.ctrl && input === 'c') {
61
+ // Surface as a cancelled-by-default selection — the parent
62
+ // (hitl.ts) decides what to do with the cancel (it currently
63
+ // hooks Ctrl+C globally and shuts down).
64
+ const fallback = items[0]?.id ?? '__cancelled__';
65
+ onResolve({ selectedOptionId: fallback });
66
+ exit();
67
+ return;
68
+ }
69
+ return;
70
+ }
71
+ // phase === 'custom'
72
+ if (key.return) {
73
+ const trimmed = customInput.trim();
74
+ const customId = items[items.length - 1].id;
75
+ if (trimmed) {
76
+ onResolve({ selectedOptionId: customId, userInput: trimmed });
77
+ }
78
+ else {
79
+ const fallback = items[0]?.id ?? customId;
80
+ onResolve({ selectedOptionId: fallback });
81
+ }
82
+ exit();
83
+ return;
84
+ }
85
+ if (key.escape) {
86
+ setPhase('menu');
87
+ setCustomInput('');
88
+ return;
89
+ }
90
+ if (key.backspace || key.delete) {
91
+ setCustomInput((s) => s.slice(0, -1));
92
+ return;
93
+ }
94
+ if (input && !key.ctrl && !key.meta) {
95
+ setCustomInput((s) => s + input);
96
+ }
97
+ });
98
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 0, children: [_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: "cyan", children: "\u25A3 HUMAN DECISION REQUIRED" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { bold: true, children: request.title }) }), request.description && (_jsx(Box, { children: _jsx(Text, { color: "gray", children: request.description }) })), request.context && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "blue", children: "\u25BE Context" }), _jsx(Text, { color: "gray", children: request.context })] }))] }), phase === 'menu' && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "green", children: "\u2191\u2193 to select \u00B7 Enter to confirm \u00B7 Ctrl+C to cancel" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: items.map((item, i) => {
99
+ const active = i === selected;
100
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: active ? 'cyan' : undefined, bold: active, children: [active ? '▸ ' : ' ', item.label] }) }), item.description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: active ? 'cyan' : 'gray', dimColor: !active, children: item.description }) }))] }, item.id));
101
+ }) })] })), phase === 'custom' && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "\u21B3 Enter your custom plan \u00B7 Esc to go back \u00B7 Enter to submit" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "magenta", bold: true, children: "\uD83D\uDC49 " }), _jsx(Text, { children: customInput }), _jsx(Text, { color: "cyan", children: "\u2588" })] })] }))] }));
102
+ }
103
+ /**
104
+ * Mount the Ink decision menu, await the operator's selection, unmount.
105
+ * The caller (hitl.ts) handles bookkeeping (event emit, history, etc.).
106
+ */
107
+ export async function showHitlDecision(request) {
108
+ const { render } = await import('ink');
109
+ return new Promise((resolve) => {
110
+ let result = null;
111
+ const inst = render(React.createElement(HitlDecision, {
112
+ request,
113
+ onResolve: (r) => { result = r; },
114
+ }));
115
+ inst.waitUntilExit().finally(() => {
116
+ try {
117
+ inst.unmount();
118
+ }
119
+ catch (_) { /* already torn down */ }
120
+ resolve(result ?? { selectedOptionId: request.options[0]?.id ?? '__cancelled__' });
121
+ });
122
+ });
123
+ }
124
+ //# sourceMappingURL=HitlDecisionMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HitlDecisionMenu.js","sourceRoot":"","sources":["../../../src/ui/ink/HitlDecisionMenu.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export type OffsecRowStatus = 'pending' | 'already-present' | 'no-native-channel' | 'installing' | 'installed' | 'failed' | 'skipped' | 'dry-run';
3
+ export interface OffsecRowState {
4
+ bin: string;
5
+ capability: string;
6
+ description: string;
7
+ status: OffsecRowStatus;
8
+ command?: string | null;
9
+ channel?: string | null;
10
+ note?: string | null;
11
+ error?: string | null;
12
+ }
13
+ export interface OffsecSummary {
14
+ installed: number;
15
+ alreadyPresent: number;
16
+ noNativeChannel: number;
17
+ failed: number;
18
+ failures: Array<{
19
+ bin: string;
20
+ reason: string;
21
+ }>;
22
+ }
23
+ export declare class OffsecEventBus extends EventEmitter {
24
+ emitHeader(text: string): void;
25
+ emitRow(row: OffsecRowState): void;
26
+ emitSummary(summary: OffsecSummary): void;
27
+ }
28
+ export declare function OffsecInstallApp({ bus }: {
29
+ bus: OffsecEventBus;
30
+ }): import("react/jsx-runtime").JSX.Element;
31
+ //# sourceMappingURL=OffsecInstallApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OffsecInstallApp.d.ts","sourceRoot":"","sources":["../../../src/ui/ink/OffsecInstallApp.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,GACZ,WAAW,GACX,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED,qBAAa,cAAe,SAAQ,YAAY;IAC9C,UAAU,CAAC,IAAI,EAAE,MAAM;IACvB,OAAO,CAAC,GAAG,EAAE,cAAc;IAC3B,WAAW,CAAC,OAAO,EAAE,aAAa;CACnC;AAaD,wBAAgB,gBAAgB,CAAC,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,cAAc,CAAA;CAAE,2CAmFhE"}
@@ -0,0 +1,62 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * OffsecInstallApp — Ink-rendered live view for `erosolar offsec install` /
4
+ * `erosolar offsec status`.
5
+ *
6
+ * Replaces the raw console.log + readline.question dance with one
7
+ * panel per binary: spinner while installing, ✓ on success, ✗ on
8
+ * failure, ⊘ when there's no native install path. The runner emits
9
+ * row events on the bus; the React tree re-renders in place.
10
+ */
11
+ import { useEffect, useState } from 'react';
12
+ import { Box, Text } from 'ink';
13
+ import Spinner from 'ink-spinner';
14
+ import { EventEmitter } from 'node:events';
15
+ export class OffsecEventBus extends EventEmitter {
16
+ emitHeader(text) { this.emit('header', text); }
17
+ emitRow(row) { this.emit('row', row); }
18
+ emitSummary(summary) { this.emit('summary', summary); }
19
+ }
20
+ const STATUS_GLYPH = {
21
+ pending: { glyph: '·', color: 'gray' },
22
+ 'already-present': { glyph: '✓', color: 'green' },
23
+ 'no-native-channel': { glyph: '⊘', color: 'gray' },
24
+ installing: { glyph: '·', color: 'cyan' }, // overridden by Spinner
25
+ installed: { glyph: '✓', color: 'green' },
26
+ failed: { glyph: '✗', color: 'red' },
27
+ skipped: { glyph: '–', color: 'yellow' },
28
+ 'dry-run': { glyph: '◦', color: 'cyan' },
29
+ };
30
+ export function OffsecInstallApp({ bus }) {
31
+ const [header, setHeader] = useState('');
32
+ const [rows, setRows] = useState({});
33
+ const [order, setOrder] = useState([]);
34
+ const [summary, setSummary] = useState(null);
35
+ useEffect(() => {
36
+ const onHeader = (text) => setHeader(text);
37
+ const onRow = (row) => {
38
+ setRows((r) => ({ ...r, [row.bin]: row }));
39
+ setOrder((o) => o.includes(row.bin) ? o : [...o, row.bin]);
40
+ };
41
+ const onSummary = (s) => setSummary(s);
42
+ bus.on('header', onHeader);
43
+ bus.on('row', onRow);
44
+ bus.on('summary', onSummary);
45
+ return () => {
46
+ bus.off('header', onHeader);
47
+ bus.off('row', onRow);
48
+ bus.off('summary', onSummary);
49
+ };
50
+ }, [bus]);
51
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [header && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "cyan", children: ["\u25A3 ", header] }) })), order.map((bin) => {
52
+ const row = rows[bin];
53
+ const sg = STATUS_GLYPH[row.status];
54
+ const isSpinning = row.status === 'installing';
55
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: isSpinning ? 0 : 0, children: [_jsxs(Box, { children: [_jsx(Box, { width: 3, children: isSpinning
56
+ ? _jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) })
57
+ : _jsx(Text, { color: sg.color, children: sg.glyph }) }), _jsxs(Text, { color: "gray", children: ["[", row.capability, "] "] }), _jsx(Text, { bold: true, children: row.bin }), row.command && row.status !== 'installed' && row.status !== 'failed' && (_jsxs(Text, { color: "gray", children: [" ", row.channel, ": ", row.command] }))] }), row.note && row.status !== 'installed' && (_jsx(Box, { paddingLeft: 3, children: _jsxs(Text, { color: "gray", children: ["note: ", row.note] }) })), row.error && (_jsx(Box, { paddingLeft: 3, children: _jsx(Text, { color: "red", children: row.error }) }))] }, bin));
58
+ }), summary && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: "white", children: "\u2550 Summary \u2550" }), _jsxs(Text, { children: [" installed: ", summary.installed] }), _jsxs(Text, { children: [" already present: ", summary.alreadyPresent] }), _jsxs(Text, { children: [" skipped (no native): ", summary.noNativeChannel] }), summary.failed > 0
59
+ ? _jsxs(Text, { color: "red", children: [" failed: ", summary.failed] })
60
+ : _jsx(Text, { color: "green", children: " failed: 0" }), summary.failures.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: summary.failures.map((f, i) => (_jsxs(Text, { color: "red", children: [" \u00B7 ", f.bin, ": ", f.reason] }, i))) }))] }))] }));
61
+ }
62
+ //# sourceMappingURL=OffsecInstallApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OffsecInstallApp.js","sourceRoot":"","sources":["../../../src/ui/ink/OffsecInstallApp.tsx"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;AACH,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA+B3C,MAAM,OAAO,cAAe,SAAQ,YAAY;IAC9C,UAAU,CAAC,IAAY,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAmB,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACvD,WAAW,CAAC,OAAsB,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACvE;AAED,MAAM,YAAY,GAA8D;IAC9E,OAAO,EAAc,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IAClD,iBAAiB,EAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACnD,mBAAmB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;IAClD,UAAU,EAAW,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,wBAAwB;IAC5E,SAAS,EAAY,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE;IACnD,MAAM,EAAe,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE;IACjD,OAAO,EAAc,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;IACpD,SAAS,EAAY,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE;CACnD,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,EAAE,GAAG,EAA2B;IAC/D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAiC,EAAE,CAAC,CAAC;IACrE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAuB,IAAI,CAAC,CAAC;IAEnE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,CAAC,GAAmB,EAAE,EAAE;YACpC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAC3C,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC;QACF,MAAM,SAAS,GAAG,CAAC,CAAgB,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtD,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC3B,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrB,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC5B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACtB,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACpC,MAAM,IAAI,CACT,KAAC,GAAG,IAAC,YAAY,EAAE,CAAC,YAClB,MAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,MAAM,wBAAI,MAAM,IAAQ,GACrC,CACP,EAEA,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACjB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAE,CAAC;gBACvB,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACpC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,KAAK,YAAY,CAAC;gBAC/C,OAAO,CACL,MAAC,GAAG,IAAW,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aACpE,MAAC,GAAG,eACF,KAAC,GAAG,IAAC,KAAK,EAAE,CAAC,YACV,UAAU;wCACT,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAC,KAAC,OAAO,IAAC,IAAI,EAAC,MAAM,GAAG,GAAO;wCACnD,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAE,EAAE,CAAC,KAAK,YAAG,EAAE,CAAC,KAAK,GAAQ,GACxC,EACN,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAG,GAAG,CAAC,UAAU,UAAU,EAC7C,KAAC,IAAI,IAAC,IAAI,kBAAE,GAAG,CAAC,GAAG,GAAQ,EAC1B,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,CACvE,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,GAAG,CAAC,OAAO,QAAI,GAAG,CAAC,OAAO,IAAQ,CACzD,IACG,EACL,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,IAAI,CACzC,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,YACjB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBAAQ,GAAG,CAAC,IAAI,IAAQ,GACtC,CACP,EACA,GAAG,CAAC,KAAK,IAAI,CACZ,KAAC,GAAG,IAAC,WAAW,EAAE,CAAC,YACjB,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,YAAE,GAAG,CAAC,KAAK,GAAQ,GAChC,CACP,KAtBO,GAAG,CAuBP,CACP,CAAC;YACJ,CAAC,CAAC,EAED,OAAO,IAAI,CACV,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,OAAO,sCAAmB,EAC3C,MAAC,IAAI,0CAAyB,OAAO,CAAC,SAAS,IAAQ,EACvD,MAAC,IAAI,0CAAyB,OAAO,CAAC,cAAc,IAAQ,EAC5D,MAAC,IAAI,0CAAyB,OAAO,CAAC,eAAe,IAAQ,EAC5D,OAAO,CAAC,MAAM,GAAG,CAAC;wBACjB,CAAC,CAAC,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,wCAAyB,OAAO,CAAC,MAAM,IAAQ;wBAClE,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,yCAAgC,EACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAC9B,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,YACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC9B,MAAC,IAAI,IAAS,KAAK,EAAC,KAAK,0BAAM,CAAC,CAAC,GAAG,QAAI,CAAC,CAAC,MAAM,KAArC,CAAC,CAA4C,CACzD,CAAC,GACE,CACP,IACG,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { EventEmitter } from 'node:events';
2
+ export interface SelfTestRowState {
3
+ name: string;
4
+ phase: string;
5
+ status: 'pending' | 'pass' | 'fail';
6
+ durationMs?: number;
7
+ error?: string;
8
+ }
9
+ export interface SelfTestSummary {
10
+ total: number;
11
+ passed: number;
12
+ failed: number;
13
+ durationMs: number;
14
+ }
15
+ export declare class SelfTestEventBus extends EventEmitter {
16
+ emitPhase(phase: string): void;
17
+ emitRow(row: SelfTestRowState): void;
18
+ emitSummary(summary: SelfTestSummary): void;
19
+ }
20
+ export declare function SelfTestApp({ bus }: {
21
+ bus: SelfTestEventBus;
22
+ }): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=SelfTestApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelfTestApp.d.ts","sourceRoot":"","sources":["../../../src/ui/ink/SelfTestApp.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,SAAS,CAAC,KAAK,EAAE,MAAM;IACvB,OAAO,CAAC,GAAG,EAAE,gBAAgB;IAC7B,WAAW,CAAC,OAAO,EAAE,eAAe;CACrC;AAED,wBAAgB,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,gBAAgB,CAAA;CAAE,2CA0E7D"}
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SelfTestApp — Ink-rendered live view for `erosolar --self-test`.
4
+ *
5
+ * Replaces the hand-rolled \x1b[…m escape codes in src/bin/selfTest.ts.
6
+ * Subscribes to a TestEventBus the runner mutates as each test
7
+ * starts/finishes, so the row flips spinner → ✓/✗ live.
8
+ */
9
+ import { useEffect, useState } from 'react';
10
+ import { Box, Text } from 'ink';
11
+ import Spinner from 'ink-spinner';
12
+ import { EventEmitter } from 'node:events';
13
+ export class SelfTestEventBus extends EventEmitter {
14
+ emitPhase(phase) { this.emit('phase', phase); }
15
+ emitRow(row) { this.emit('row', row); }
16
+ emitSummary(summary) { this.emit('summary', summary); }
17
+ }
18
+ export function SelfTestApp({ bus }) {
19
+ const [phases, setPhases] = useState([]);
20
+ const [rows, setRows] = useState({});
21
+ const [order, setOrder] = useState([]);
22
+ const [summary, setSummary] = useState(null);
23
+ useEffect(() => {
24
+ const onPhase = (phase) => setPhases((p) => [...p, phase]);
25
+ const onRow = (row) => {
26
+ setRows((r) => ({ ...r, [row.name]: row }));
27
+ setOrder((o) => o.includes(row.name) ? o : [...o, row.name]);
28
+ };
29
+ const onSummary = (s) => setSummary(s);
30
+ bus.on('phase', onPhase);
31
+ bus.on('row', onRow);
32
+ bus.on('summary', onSummary);
33
+ return () => {
34
+ bus.off('phase', onPhase);
35
+ bus.off('row', onRow);
36
+ bus.off('summary', onSummary);
37
+ };
38
+ }, [bus]);
39
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "\u25A3 Erosolar CLI \u2014 self-test suite" }) }), phases.map((phase, i) => (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "cyan", bold: true, children: ["\u25B6 ", phase] }) }, `phase-${i}`))), order.map((name) => {
40
+ const row = rows[name];
41
+ const dur = typeof row.durationMs === 'number' ? `(${row.durationMs}ms)` : '';
42
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Box, { width: 3, children: [row.status === 'pending' && _jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), row.status === 'pass' && _jsx(Text, { color: "green", children: "\u2713" }), row.status === 'fail' && _jsx(Text, { color: "red", children: "\u2717" })] }), _jsxs(Text, { children: [row.name, " "] }), _jsx(Text, { color: "gray", children: dur })] }), row.status === 'fail' && row.error && (_jsx(Box, { paddingLeft: 3, children: _jsx(Text, { color: "red", children: row.error }) }))] }, name));
43
+ }), summary && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, color: "white", children: "\u2550 Summary \u2550" }), _jsxs(Text, { children: [" Total: ", summary.total] }), _jsxs(Text, { color: "green", children: [" Passed: ", summary.passed] }), summary.failed > 0 && _jsxs(Text, { color: "red", children: [" Failed: ", summary.failed] }), _jsxs(Text, { children: [" Duration: ", (summary.durationMs / 1000).toFixed(2), "s"] }), _jsx(Box, { marginTop: 1, children: summary.failed === 0
44
+ ? _jsx(Text, { bold: true, color: "green", children: "\u2713 ALL TESTS PASSED" })
45
+ : _jsx(Text, { bold: true, color: "red", children: "\u2717 SOME TESTS FAILED" }) })] }))] }));
46
+ }
47
+ //# sourceMappingURL=SelfTestApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelfTestApp.js","sourceRoot":"","sources":["../../../src/ui/ink/SelfTestApp.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export type CardTone = 'info' | 'success' | 'warn' | 'error';
2
+ /**
3
+ * Renders a single Ink card and unmounts after the next paint. Resolves
4
+ * once the panel has been flushed to the terminal so callers can safely
5
+ * `process.exit()` immediately after awaiting.
6
+ */
7
+ export declare function showCard(opts: {
8
+ tone?: CardTone;
9
+ title: string;
10
+ body?: string | string[];
11
+ hint?: string | null;
12
+ }): Promise<void>;
13
+ /**
14
+ * Renders a key/value table panel — used for --version banners,
15
+ * approval-denied summaries, install summaries, etc.
16
+ */
17
+ export declare function showKv(opts: {
18
+ tone?: CardTone;
19
+ title: string;
20
+ rows: Array<[string, string]>;
21
+ hint?: string | null;
22
+ }): Promise<void>;
23
+ /**
24
+ * Renders preformatted help text inside an Ink frame. The text body
25
+ * keeps its own formatting (newlines, indentation); Ink owns the
26
+ * decorative chrome around it.
27
+ */
28
+ export declare function showHelp(opts: {
29
+ title: string;
30
+ body: string;
31
+ foot?: string | null;
32
+ }): Promise<void>;
33
+ //# sourceMappingURL=oneShot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oneShot.d.ts","sourceRoot":"","sources":["../../../src/ui/ink/oneShot.tsx"],"names":[],"mappings":"AAYA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAS7D;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgChB;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE;IACjC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBzG"}
@@ -0,0 +1,70 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * oneShot — minimal helpers for "render a small Ink panel and exit"
4
+ * surfaces (--help, --version, --key save, error cards, etc.).
5
+ *
6
+ * The interactive shell owns its own Ink tree via InkPromptController;
7
+ * these one-shot mounts are for surfaces that print and exit before
8
+ * the shell ever starts. Each helper resolves once Ink has flushed at
9
+ * least one frame so the panel paints before the process exits.
10
+ */
11
+ import React from 'react';
12
+ import { Box, Text } from 'ink';
13
+ const TONE = {
14
+ info: { glyph: '▣', color: 'cyan' },
15
+ success: { glyph: '✓', color: 'green' },
16
+ warn: { glyph: '!', color: 'yellow' },
17
+ error: { glyph: '✗', color: 'red' },
18
+ };
19
+ /**
20
+ * Renders a single Ink card and unmounts after the next paint. Resolves
21
+ * once the panel has been flushed to the terminal so callers can safely
22
+ * `process.exit()` immediately after awaiting.
23
+ */
24
+ export async function showCard(opts) {
25
+ const { render } = await import('ink');
26
+ const tone = opts.tone ?? 'info';
27
+ const palette = TONE[tone];
28
+ const lines = Array.isArray(opts.body) ? opts.body : (opts.body ? [opts.body] : []);
29
+ const Card = () => (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 0, children: [_jsxs(Box, { children: [_jsxs(Text, { color: palette.color, children: [palette.glyph, " "] }), _jsx(Text, { color: palette.color, bold: true, children: opts.title })] }), lines.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: lines.length > 1 ? 1 : 0, children: lines.map((line, i) => (_jsx(Text, { color: tone === 'error' ? 'red' : 'gray', children: line }, i))) })), opts.hint && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: opts.hint }) }))] }));
30
+ const inst = render(React.createElement(Card));
31
+ // Two ticks: first paints the card, second lets Ink commit the static
32
+ // output before unmount tears the alternate-screen buffer.
33
+ await new Promise((r) => setTimeout(r, 30));
34
+ try {
35
+ inst.unmount();
36
+ }
37
+ catch (_) { /* already torn down */ }
38
+ }
39
+ /**
40
+ * Renders a key/value table panel — used for --version banners,
41
+ * approval-denied summaries, install summaries, etc.
42
+ */
43
+ export async function showKv(opts) {
44
+ const { render } = await import('ink');
45
+ const tone = opts.tone ?? 'info';
46
+ const palette = TONE[tone];
47
+ const Panel = () => (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { color: palette.color, children: [palette.glyph, " "] }), _jsx(Text, { color: palette.color, bold: true, children: opts.title })] }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: opts.rows.map(([k, v], i) => (_jsxs(Box, { children: [_jsx(Box, { width: 14, children: _jsx(Text, { color: "gray", children: k }) }), _jsx(Text, { color: tone === 'error' ? 'red' : 'white', children: v })] }, i))) }), opts.hint && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: opts.hint }) }))] }));
48
+ const inst = render(React.createElement(Panel));
49
+ await new Promise((r) => setTimeout(r, 30));
50
+ try {
51
+ inst.unmount();
52
+ }
53
+ catch (_) { /* already torn down */ }
54
+ }
55
+ /**
56
+ * Renders preformatted help text inside an Ink frame. The text body
57
+ * keeps its own formatting (newlines, indentation); Ink owns the
58
+ * decorative chrome around it.
59
+ */
60
+ export async function showHelp(opts) {
61
+ const { render } = await import('ink');
62
+ const View = () => (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 0, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, children: opts.title }) }), _jsx(Box, { children: _jsx(Text, { children: opts.body }) }), opts.foot && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: opts.foot }) }))] }));
63
+ const inst = render(React.createElement(View));
64
+ await new Promise((r) => setTimeout(r, 30));
65
+ try {
66
+ inst.unmount();
67
+ }
68
+ catch (_) { /* already torn down */ }
69
+ }
70
+ //# sourceMappingURL=oneShot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oneShot.js","sourceRoot":"","sources":["../../../src/ui/ink/oneShot.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,19 @@
1
1
  type StatusSink = (message: string) => void;
2
2
  export declare function setStatusSink(sink: StatusSink | null): void;
3
3
  export declare function reportStatus(message: string): void;
4
+ /**
5
+ * Render a fatal error as an Ink card and exit. Used by every catch
6
+ * block in src/bin/erosolar.ts so the user sees a consistent red panel
7
+ * instead of a one-line console.error. Falls back to stderr if Ink
8
+ * fails to mount (degraded TTY, ENOTTY, etc.) so the user always sees
9
+ * the message somewhere.
10
+ */
11
+ export declare function reportFatal(error: unknown, prefix?: string): Promise<void>;
12
+ /**
13
+ * Legacy non-Ink error reporter. Prefer reportFatal() for new call
14
+ * sites; this stays for low-level paths that can't await an import
15
+ * (e.g. signal handlers).
16
+ */
4
17
  export declare function reportStatusError(error: unknown, prefix?: string): void;
5
18
  export {};
6
19
  //# sourceMappingURL=statusReporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"statusReporter.d.ts","sourceRoot":"","sources":["../../src/utils/statusReporter.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAO5C,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAUlD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAgB,GAAG,IAAI,CAOhF"}
1
+ {"version":3,"file":"statusReporter.d.ts","sourceRoot":"","sources":["../../src/utils/statusReporter.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAO5C,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAYlD;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUzF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAgB,GAAG,IAAI,CAOhF"}
@@ -13,8 +13,34 @@ export function reportStatus(message) {
13
13
  statusSink(normalized);
14
14
  return;
15
15
  }
16
+ // Plain stdout fallback — used early in boot (before Ink is ready)
17
+ // and as the fallback for non-fatal status pings.
16
18
  stdout.write(`${normalized}\n`);
17
19
  }
20
+ /**
21
+ * Render a fatal error as an Ink card and exit. Used by every catch
22
+ * block in src/bin/erosolar.ts so the user sees a consistent red panel
23
+ * instead of a one-line console.error. Falls back to stderr if Ink
24
+ * fails to mount (degraded TTY, ENOTTY, etc.) so the user always sees
25
+ * the message somewhere.
26
+ */
27
+ export async function reportFatal(error, prefix = 'Error') {
28
+ const message = error instanceof Error ? error.message : String(error);
29
+ const safePrefix = prefix.trim() || 'Error';
30
+ try {
31
+ const { showCard } = await import('../ui/ink/oneShot.js');
32
+ await showCard({ tone: 'error', title: safePrefix, body: message });
33
+ }
34
+ catch {
35
+ // Ink failed (no TTY, etc.). Still surface the message.
36
+ process.stderr.write(`${safePrefix}: ${message}\n`);
37
+ }
38
+ }
39
+ /**
40
+ * Legacy non-Ink error reporter. Prefer reportFatal() for new call
41
+ * sites; this stays for low-level paths that can't await an import
42
+ * (e.g. signal handlers).
43
+ */
18
44
  export function reportStatusError(error, prefix = 'Error') {
19
45
  const message = error instanceof Error ? error.message : String(error);
20
46
  const safePrefix = prefix.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"statusReporter.js","sourceRoot":"","sources":["../../src/utils/statusReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAItC,IAAI,UAAU,GAAsB,IAAI,CAAC;AAEzC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAU,EAAE,CACzD,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAEtC,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;IACT,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,UAAU,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,SAAiB,OAAO;IACxE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,UAAU;QACrB,CAAC,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,EAAE;QAClE,CAAC,CAAC,OAAO,CAAC;IACZ,YAAY,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"statusReporter.js","sourceRoot":"","sources":["../../src/utils/statusReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAItC,IAAI,UAAU,GAAsB,IAAI,CAAC;AAEzC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAU,EAAE,CACzD,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAEtC,MAAM,UAAU,aAAa,CAAC,IAAuB;IACnD,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;IACT,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,UAAU,CAAC,UAAU,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;IACD,mEAAmE;IACnE,kDAAkD;IAClD,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAc,EAAE,SAAiB,OAAO;IACxE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAC1D,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;QACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,KAAK,OAAO,IAAI,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,SAAiB,OAAO;IACxE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,UAAU;QACrB,CAAC,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,EAAE;QAClE,CAAC,CAAC,OAAO,CAAC;IACZ,YAAY,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trenchwork/erosolar",
3
- "version": "1.1.35",
3
+ "version": "1.1.37",
4
4
  "description": "DeepSeek AI-powered CLI agent for code assistance and automation",
5
5
  "deepseek": {
6
6
  "rulebookSchema": "src/contracts/schemas/agent-rules.schema.json"