@iseoane/agent-depot 0.6.0 → 0.6.2

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.
@@ -33,11 +33,89 @@ function previewField(line) {
33
33
  const label = PREVIEW_FIELD_LABELS.find(candidate => line.startsWith(candidate));
34
34
  return label === undefined ? undefined : { label, value: line.slice(label.length) };
35
35
  }
36
+ function previewSpan(text, color, bold = false) {
37
+ return { text, color, bold };
38
+ }
39
+ function profilePreviewSpans(line) {
40
+ if (line.startsWith("Destination: ")) {
41
+ return [previewSpan("Destination:", theme.field), previewSpan(line.slice("Destination:".length), theme.value)];
42
+ }
43
+ if (line === "Preview: export portable user-global profile" || line === "Preview: import portable user-global profile") {
44
+ return [previewSpan("Preview:", theme.field), previewSpan(line.slice("Preview:".length), theme.value)];
45
+ }
46
+ if (line.startsWith("WARNING:"))
47
+ return [previewSpan(line, theme.warning)];
48
+ const source = /^Source (git:[^ ]+) (.+) \(included: (true|false)\)$/u.exec(line);
49
+ if (source)
50
+ return [previewSpan("Source", theme.field), previewSpan(" ", theme.value),
51
+ previewSpan(source[1], theme.muted), previewSpan(" ", theme.value), previewSpan(source[2], theme.value),
52
+ previewSpan(" (", theme.value), previewSpan("included:", theme.field), previewSpan(` ${source[3]})`, theme.value)];
53
+ const skill = /^Skill (.+) \[([^\]]*)\] \((latest|fixed(?: [^)]+)?)\)$/u.exec(line);
54
+ if (skill)
55
+ return [previewSpan("Skill", theme.field), previewSpan(" ", theme.value), previewSpan(skill[1], theme.value, true),
56
+ previewSpan(" [", theme.value), previewSpan(skill[2], theme.marker), previewSpan("] (", theme.value),
57
+ previewSpan(skill[3], theme.version), previewSpan(")", theme.value)];
58
+ const app = /^App recipe (.+) \(([^;]+); approval not transferred\)$/u.exec(line);
59
+ if (app)
60
+ return [previewSpan("App recipe", theme.field), previewSpan(" ", theme.value), previewSpan(app[1], theme.value, true),
61
+ previewSpan(" (", theme.value), previewSpan(app[2], theme.marker), previewSpan("; approval not transferred)", theme.value)];
62
+ const packageLine = /^Package (.+) from (.+) \((latest|fixed [^;]+); saved selection\)(.*)$/u.exec(line);
63
+ if (packageLine)
64
+ return [previewSpan("Package", theme.field), previewSpan(" ", theme.value),
65
+ previewSpan(packageLine[1], theme.value, true), previewSpan(" from ", theme.value), previewSpan(packageLine[2], theme.value),
66
+ previewSpan(" (", theme.value), previewSpan(packageLine[3], theme.version),
67
+ previewSpan(`; saved selection)${packageLine[4]}`, theme.value)];
68
+ const replica = /^Replica intent (Installed Skill|Installed App|Installed Package) (.+?)(; .*)?$/u.exec(line);
69
+ if (replica)
70
+ return [previewSpan("Replica intent", theme.field), previewSpan(" ", theme.value),
71
+ previewSpan(replica[1], theme.field), previewSpan(" ", theme.value), previewSpan(replica[2], theme.value, true),
72
+ previewSpan(replica[3] ?? "", theme.value)];
73
+ if (line.startsWith(" Source "))
74
+ return [previewSpan(" Source", theme.field), previewSpan(line.slice(" Source".length), theme.value)];
75
+ if (line.startsWith("Origin replica intent:"))
76
+ return [previewSpan("Origin replica intent:", theme.field),
77
+ previewSpan(line.slice("Origin replica intent:".length), theme.value)];
78
+ const imported = /^(add|same|conflict|skip)( \(discovery inclusion is not imported\))?: (Source|Skill|App recipe|Package) (.+)$/u.exec(line);
79
+ if (imported)
80
+ return [previewSpan(`${imported[1]}${imported[2] ?? ""}:`, theme.field), previewSpan(` ${imported[3]}`, theme.field),
81
+ previewSpan(" ", theme.value), previewSpan(imported[4], theme.value, true)];
82
+ const hosts = /^ {2}hosts: ([^;]*); version policy: (latest|fixed(?: .+)?)$/u.exec(line);
83
+ if (hosts)
84
+ return [previewSpan(" hosts:", theme.field), previewSpan(" ", theme.value),
85
+ previewSpan(hosts[1], theme.marker), previewSpan("; ", theme.value), previewSpan("version policy:", theme.field),
86
+ previewSpan(` ${hosts[2]}`, theme.version)];
87
+ return undefined;
88
+ }
89
+ function visiblePreviewSpans(spans, offset, length) {
90
+ const end = offset + length;
91
+ let spanStart = 0;
92
+ const visible = [];
93
+ for (const span of spans) {
94
+ const spanEnd = spanStart + span.text.length;
95
+ const start = Math.max(offset, spanStart);
96
+ const stop = Math.min(end, spanEnd);
97
+ if (start < stop)
98
+ visible.push({ ...span, text: span.text.slice(start - spanStart, stop - spanStart) });
99
+ spanStart = spanEnd;
100
+ }
101
+ return visible;
102
+ }
103
+ function PreviewLine({ line, position, warnFirst, logicalLine, offset = 0 }) {
104
+ const profileSpans = logicalLine === undefined ? profilePreviewSpans(line) : profilePreviewSpans(logicalLine);
105
+ if (profileSpans) {
106
+ const spans = logicalLine === undefined ? profileSpans : visiblePreviewSpans(profileSpans, offset, line.length);
107
+ return _jsx(Text, { children: spans.map((span, index) => _jsx(Text, { color: span.color, bold: span.bold, children: span.text }, index)) }, position);
108
+ }
109
+ const field = previewField(logicalLine ?? line);
110
+ if (field) {
111
+ const fieldSpans = [previewSpan(field.label, theme.field), previewSpan(field.value, theme.value)];
112
+ const spans = logicalLine === undefined ? fieldSpans : visiblePreviewSpans(fieldSpans, offset, line.length);
113
+ return _jsx(Text, { children: spans.map((span, index) => _jsx(Text, { color: span.color, children: span.text }, index)) }, position);
114
+ }
115
+ return _jsx(Text, { color: warnFirst && position === 0 ? theme.warning : theme.value, children: line }, position);
116
+ }
36
117
  export function PreviewLines({ lines, warnFirst = false }) {
37
- return (_jsx(_Fragment, { children: lines.map((line, position) => {
38
- const field = previewField(line);
39
- return field ? (_jsxs(Text, { children: [_jsx(Text, { color: theme.field, children: field.label }), _jsx(Text, { color: theme.value, children: field.value })] }, position)) : _jsx(Text, { color: warnFirst && position === 0 ? theme.warning : theme.value, children: line }, position);
40
- }) }));
118
+ return _jsx(_Fragment, { children: lines.map((line, position) => _jsx(PreviewLine, { line: line, position: position, warnFirst: warnFirst }, position)) });
41
119
  }
42
120
  /** Under a list: the window indicator, how many items are marked, and the last result. */
43
121
  export function ListFooter({ indicator, selectedCount, message }) {
@@ -48,7 +126,10 @@ export function PreviewConfirm({ title = "Confirmation", lines, question, warnFi
48
126
  const { rows, columns } = useWindowSize();
49
127
  const viewport = cursor === undefined ? undefined : previewViewport(lines, cursor, rows || 24, columns || 80, chrome ?? { title, questions: [question], footerRows: 2 });
50
128
  const shown = viewport?.rows ?? lines;
51
- return (_jsxs(BorderPanel, { title: title, children: [_jsx(PreviewLines, { lines: shown, warnFirst: warnFirst && (viewport?.start ?? 0) === 0 }), viewport && viewport.total > viewport.height ? _jsxs(Text, { color: theme.muted, children: [viewport.start + 1, "\u2013", viewport.end, " of ", viewport.total] }) : null, viewport ? _jsxs(Text, { color: theme.legend, children: ["Review ", viewport.cursor + 1, " of ", viewport.total, " \u00B7 arrows/Pg page"] }) : null, question.includes("y/n") ? (() => {
129
+ return (_jsxs(BorderPanel, { title: title, children: [viewport ? shown.map((line, position) => {
130
+ const sourceLine = viewport.sourceLines[position];
131
+ return _jsx(PreviewLine, { line: line, position: position, warnFirst: Boolean(warnFirst && viewport.start === 0), logicalLine: lines[sourceLine], offset: viewport.sourceOffsets[position] }, position);
132
+ }) : _jsx(PreviewLines, { lines: shown, warnFirst: warnFirst }), viewport && viewport.total > viewport.height ? _jsxs(Text, { color: theme.muted, children: [viewport.start + 1, "\u2013", viewport.end, " of ", viewport.total] }) : null, viewport ? _jsxs(Text, { color: theme.legend, children: ["Review ", viewport.cursor + 1, " of ", viewport.total, " \u00B7 arrows/Pg page"] }) : null, question.includes("y/n") ? (() => {
52
133
  const marker = question.indexOf("y/n");
53
134
  return _jsxs(Text, { children: [_jsx(Text, { color: theme.warning, children: question.slice(0, marker) }), _jsx(Text, { color: theme.success, bold: true, children: "y" }), _jsx(Text, { color: theme.legend, children: "/" }), _jsx(Text, { color: theme.error, children: "n" }), _jsx(Text, { color: theme.legend, children: question.slice(marker + 3) })] });
54
135
  })() : _jsx(Text, { color: theme.legend, children: question })] }));
@@ -4,26 +4,28 @@ const graphemes = new Intl.Segmenter(undefined, { granularity: "grapheme" });
4
4
  function wrapLine(line, width) {
5
5
  const segments = [...graphemes.segment(line)];
6
6
  if (segments.length === 0)
7
- return [""];
7
+ return [{ row: "", offset: 0 }];
8
8
  const wrapped = [];
9
9
  let row = "";
10
10
  let rowWidth = 0;
11
- for (const { segment } of segments) {
11
+ let rowOffset = 0;
12
+ for (const { segment, index } of segments) {
12
13
  const segmentWidth = stringWidth(segment);
13
14
  if (row !== "" && rowWidth + segmentWidth > width) {
14
- wrapped.push(row);
15
+ wrapped.push({ row, offset: rowOffset });
15
16
  row = "";
16
17
  rowWidth = 0;
18
+ rowOffset = index;
17
19
  }
18
20
  row += segment;
19
21
  rowWidth += segmentWidth;
20
22
  }
21
- wrapped.push(row);
23
+ wrapped.push({ row, offset: rowOffset });
22
24
  return wrapped;
23
25
  }
24
26
  export function previewViewport(lines, cursor, terminalRows, terminalColumns, chrome = { title: "Confirmation", questions: ["Scroll to end before y; n cancels.", "Confirm? y/n"] }) {
25
27
  const contentWidth = Math.max(terminalColumns - 8, 1);
26
- const wrapped = lines.flatMap((line, sourceLine) => wrapLine(line, contentWidth).map((row) => ({ row, sourceLine })));
28
+ const wrapped = lines.flatMap((line, sourceLine) => wrapLine(line, contentWidth).map(({ row, offset }) => ({ row, sourceLine, offset })));
27
29
  const previewRows = wrapped.map(({ row }) => row);
28
30
  const headerRows = headerTabRowCount(contentWidth) + 3;
29
31
  const titleRows = wrapLine(chrome.title, contentWidth).length;
@@ -38,6 +40,7 @@ export function previewViewport(lines, cursor, terminalRows, terminalColumns, ch
38
40
  return {
39
41
  rows: previewRows.slice(start, end),
40
42
  sourceLines: wrapped.slice(start, end).map(({ sourceLine }) => sourceLine),
43
+ sourceOffsets: wrapped.slice(start, end).map(({ offset }) => offset),
41
44
  start,
42
45
  end,
43
46
  total: previewRows.length,