@algolia/wizard 0.46.0-rc.136.345 → 0.46.0-rc.146.324
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/dist/main.js +419 -553
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { render } from "ink";
|
|
5
5
|
|
|
6
6
|
// src/ui/App.tsx
|
|
7
|
-
import { Box as
|
|
7
|
+
import { Box as Box19, Text as Text19, useApp, useInput as useInput7, useWindowSize as useWindowSize8 } from "ink";
|
|
8
8
|
import Spinner2 from "ink-spinner";
|
|
9
9
|
|
|
10
10
|
// src/core/store.ts
|
|
@@ -239,9 +239,6 @@ function describeInputValue(value) {
|
|
|
239
239
|
}
|
|
240
240
|
var NOTICE_INTERVAL_MS = 2e3;
|
|
241
241
|
var CLI_OUTPUT_LIMIT = 200;
|
|
242
|
-
function commandApprovalKey(command, cwd) {
|
|
243
|
-
return `${cwd}\0${command}`;
|
|
244
|
-
}
|
|
245
242
|
var useWizard = create((set, get) => ({
|
|
246
243
|
phase: "idle",
|
|
247
244
|
homeScreen: "home",
|
|
@@ -355,17 +352,10 @@ var useWizard = create((set, get) => ({
|
|
|
355
352
|
setTargetIndex: (index) => set({ targetIndex: index }),
|
|
356
353
|
recordWrittenFile: (path) => set((s) => ({ writtenFiles: [...s.writtenFiles, path] })),
|
|
357
354
|
clearWrittenFiles: () => set({ writtenFiles: [] }),
|
|
358
|
-
isCommandApproved: (command, cwd) => get().approvedCommands.has(
|
|
355
|
+
isCommandApproved: (command, cwd) => get().approvedCommands.has(`${cwd}\0${command}`),
|
|
359
356
|
approveCommand: (command, cwd) => set((s) => ({
|
|
360
|
-
approvedCommands: new Set(s.approvedCommands).add(
|
|
361
|
-
commandApprovalKey(command, cwd)
|
|
362
|
-
)
|
|
357
|
+
approvedCommands: new Set(s.approvedCommands).add(`${cwd}\0${command}`)
|
|
363
358
|
})),
|
|
364
|
-
revokeCommand: (command, cwd) => set((s) => {
|
|
365
|
-
const approvedCommands = new Set(s.approvedCommands);
|
|
366
|
-
approvedCommands.delete(commandApprovalKey(command, cwd));
|
|
367
|
-
return { approvedCommands };
|
|
368
|
-
}),
|
|
369
359
|
logStart: (kind, name, input) => {
|
|
370
360
|
const id = nanoid();
|
|
371
361
|
set((s) => ({
|
|
@@ -509,23 +499,112 @@ function CliOutput() {
|
|
|
509
499
|
}
|
|
510
500
|
|
|
511
501
|
// src/ui/Notices.tsx
|
|
512
|
-
import { Box as
|
|
513
|
-
import { useEffect as useEffect2, useState as
|
|
502
|
+
import { Box as Box4, Text as Text4, useWindowSize as useWindowSize4 } from "ink";
|
|
503
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
514
504
|
|
|
515
|
-
// src/ui/
|
|
505
|
+
// src/ui/ScrollView.tsx
|
|
516
506
|
import { Box as Box2, Text as Text2, measureElement, useWindowSize as useWindowSize2 } from "ink";
|
|
517
|
-
import {
|
|
507
|
+
import { useCallback, useLayoutEffect, useRef, useState } from "react";
|
|
508
|
+
import { jsxs as jsxs2 } from "react/jsx-runtime";
|
|
509
|
+
var INDICATOR_ROWS = 2;
|
|
510
|
+
function fittedWidth(node, columns) {
|
|
511
|
+
let left = 0;
|
|
512
|
+
for (let n = node; n; n = n.parentNode) {
|
|
513
|
+
left += n.yogaNode?.getComputedLeft() ?? 0;
|
|
514
|
+
}
|
|
515
|
+
return Math.max(Math.min(measureElement(node).width, columns - left), 0);
|
|
516
|
+
}
|
|
517
|
+
function useScrollWindow({
|
|
518
|
+
itemCount,
|
|
519
|
+
rowHeight = 1,
|
|
520
|
+
followBottom = false
|
|
521
|
+
}) {
|
|
522
|
+
const viewportRef = useRef(null);
|
|
523
|
+
const { columns } = useWindowSize2();
|
|
524
|
+
const [size, setSize] = useState(
|
|
525
|
+
null
|
|
526
|
+
);
|
|
527
|
+
useLayoutEffect(() => {
|
|
528
|
+
if (!viewportRef.current) return;
|
|
529
|
+
const width = fittedWidth(viewportRef.current, columns);
|
|
530
|
+
const { height } = measureElement(viewportRef.current);
|
|
531
|
+
setSize(
|
|
532
|
+
(prev) => prev?.width === width && prev.height === height ? prev : { width, height }
|
|
533
|
+
);
|
|
534
|
+
});
|
|
535
|
+
const capacity = size === null || itemCount * rowHeight <= size.height ? itemCount : Math.max(Math.floor((size.height - INDICATOR_ROWS) / rowHeight), 1);
|
|
536
|
+
const maxOffset = Math.max(itemCount - capacity, 0);
|
|
537
|
+
const [offset, setOffset] = useState(0);
|
|
538
|
+
const prevMaxOffsetRef = useRef(0);
|
|
539
|
+
useLayoutEffect(() => {
|
|
540
|
+
const wasAtBottom = offset >= prevMaxOffsetRef.current;
|
|
541
|
+
prevMaxOffsetRef.current = maxOffset;
|
|
542
|
+
setOffset(
|
|
543
|
+
(o) => followBottom && wasAtBottom ? maxOffset : Math.min(o, maxOffset)
|
|
544
|
+
);
|
|
545
|
+
}, [maxOffset, followBottom]);
|
|
546
|
+
const scrollBy = useCallback(
|
|
547
|
+
(delta) => {
|
|
548
|
+
setOffset((o) => Math.min(Math.max(o + delta, 0), maxOffset));
|
|
549
|
+
},
|
|
550
|
+
[maxOffset]
|
|
551
|
+
);
|
|
552
|
+
const revealIndex = useCallback(
|
|
553
|
+
(index) => {
|
|
554
|
+
setOffset((o) => {
|
|
555
|
+
if (index < o) return index;
|
|
556
|
+
if (index >= o + capacity) {
|
|
557
|
+
return Math.min(index - capacity + 1, maxOffset);
|
|
558
|
+
}
|
|
559
|
+
return o;
|
|
560
|
+
});
|
|
561
|
+
},
|
|
562
|
+
[capacity, maxOffset]
|
|
563
|
+
);
|
|
564
|
+
const visibleCount = Math.min(capacity, Math.max(itemCount - offset, 0));
|
|
565
|
+
return {
|
|
566
|
+
viewportRef,
|
|
567
|
+
measured: size !== null,
|
|
568
|
+
width: size?.width ?? columns,
|
|
569
|
+
offset,
|
|
570
|
+
capacity,
|
|
571
|
+
maxOffset,
|
|
572
|
+
hiddenAbove: Math.min(offset, itemCount),
|
|
573
|
+
hiddenBelow: Math.max(itemCount - offset - visibleCount, 0),
|
|
574
|
+
scrollBy,
|
|
575
|
+
revealIndex
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function ScrollView({ scroll, children }) {
|
|
579
|
+
return /* @__PURE__ */ jsxs2(Box2, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
|
|
580
|
+
scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs2(Text2, { color: COLORS.dim, children: [
|
|
581
|
+
"\u2191 ",
|
|
582
|
+
scroll.hiddenAbove,
|
|
583
|
+
" more"
|
|
584
|
+
] }),
|
|
585
|
+
children,
|
|
586
|
+
scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs2(Text2, { color: COLORS.dim, children: [
|
|
587
|
+
"\u2193 ",
|
|
588
|
+
scroll.hiddenBelow,
|
|
589
|
+
" more"
|
|
590
|
+
] })
|
|
591
|
+
] });
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// src/ui/Table.tsx
|
|
595
|
+
import { Box as Box3, Text as Text3, measureElement as measureElement2, useWindowSize as useWindowSize3 } from "ink";
|
|
596
|
+
import { useEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
518
597
|
import { jsx } from "react/jsx-runtime";
|
|
519
598
|
function Table({ columns, rows }) {
|
|
520
|
-
const { columns: termCols } =
|
|
521
|
-
const ref =
|
|
522
|
-
const [width, setWidth] =
|
|
599
|
+
const { columns: termCols } = useWindowSize3();
|
|
600
|
+
const ref = useRef2(null);
|
|
601
|
+
const [width, setWidth] = useState2(0);
|
|
523
602
|
useEffect(() => {
|
|
524
|
-
if (ref.current) setWidth(
|
|
603
|
+
if (ref.current) setWidth(measureElement2(ref.current).width);
|
|
525
604
|
}, [termCols, columns, rows]);
|
|
526
605
|
if (rows.length === 0) return null;
|
|
527
606
|
const lines = formatTable(columns, rows, width || void 0);
|
|
528
|
-
return /* @__PURE__ */ jsx(
|
|
607
|
+
return /* @__PURE__ */ jsx(Box3, { flexDirection: "column", ref, children: lines.map((line, i) => /* @__PURE__ */ jsx(Text3, { color: COLORS.primary, wrap: "truncate", children: line }, `tbl-${i}`)) });
|
|
529
608
|
}
|
|
530
609
|
function formatTable(columns, rows, width) {
|
|
531
610
|
const natural = columns.map(
|
|
@@ -566,7 +645,7 @@ function resize(widths, budget) {
|
|
|
566
645
|
var truncate = (s, width) => s.length <= width ? s : width <= 1 ? s.slice(0, width) : `${s.slice(0, width - 1)}\u2026`;
|
|
567
646
|
|
|
568
647
|
// src/ui/Notices.tsx
|
|
569
|
-
import { jsx as jsx2
|
|
648
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
570
649
|
var AGENT_MARKER = "\u2726";
|
|
571
650
|
var PULSE_STEPS = 12;
|
|
572
651
|
var PULSE_STEP_MS = 150;
|
|
@@ -588,14 +667,48 @@ function parseHex(hex) {
|
|
|
588
667
|
b: parseInt(n.slice(4, 6), 16)
|
|
589
668
|
};
|
|
590
669
|
}
|
|
670
|
+
function flattenRows(notices, width) {
|
|
671
|
+
const rows = [];
|
|
672
|
+
notices.forEach((notice, noticeIndex) => {
|
|
673
|
+
if (noticeIndex > 0 && notice.table) {
|
|
674
|
+
rows.push({ noticeIndex, text: " ", plain: true });
|
|
675
|
+
}
|
|
676
|
+
notice.messages?.forEach((m, j) => {
|
|
677
|
+
const line = typeof m === "string" ? { text: m } : m;
|
|
678
|
+
rows.push({
|
|
679
|
+
noticeIndex,
|
|
680
|
+
text: `${j === 0 ? `${AGENT_MARKER} ` : " "}${line.text}`,
|
|
681
|
+
color: line.color,
|
|
682
|
+
bold: line.bold
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
if (notice.table) {
|
|
686
|
+
for (const text of formatTable(
|
|
687
|
+
notice.table.columns,
|
|
688
|
+
notice.table.rows,
|
|
689
|
+
width
|
|
690
|
+
)) {
|
|
691
|
+
rows.push({ noticeIndex, text, plain: true });
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
return rows;
|
|
696
|
+
}
|
|
591
697
|
function Notices({
|
|
592
698
|
showAll = false,
|
|
593
699
|
border = true
|
|
594
700
|
} = {}) {
|
|
595
701
|
const notices = useWizard((s) => s.notices);
|
|
596
|
-
const
|
|
597
|
-
const
|
|
598
|
-
const [
|
|
702
|
+
const { columns } = useWindowSize4();
|
|
703
|
+
const latestIndex = notices.length - 1;
|
|
704
|
+
const visible = showAll ? notices : latestIndex >= 0 ? [notices[latestIndex]] : [];
|
|
705
|
+
const latestRowIndex = showAll ? latestIndex : 0;
|
|
706
|
+
const measuredRows = flattenRows(visible, columns);
|
|
707
|
+
const scroll = useScrollWindow({
|
|
708
|
+
itemCount: measuredRows.length,
|
|
709
|
+
followBottom: true
|
|
710
|
+
});
|
|
711
|
+
const [pulseStep, setPulseStep] = useState3(0);
|
|
599
712
|
useEffect2(() => {
|
|
600
713
|
let direction = 1;
|
|
601
714
|
const id = setInterval(() => {
|
|
@@ -610,8 +723,10 @@ function Notices({
|
|
|
610
723
|
}, []);
|
|
611
724
|
if (visible.length === 0) return null;
|
|
612
725
|
const pulseColor = PULSE_COLORS[pulseStep];
|
|
726
|
+
const rows = scroll.width === columns ? measuredRows : flattenRows(visible, scroll.width);
|
|
727
|
+
const windowed = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
613
728
|
return /* @__PURE__ */ jsx2(
|
|
614
|
-
|
|
729
|
+
Box4,
|
|
615
730
|
{
|
|
616
731
|
borderColor: border ? COLORS.border : void 0,
|
|
617
732
|
borderStyle: border ? "single" : void 0,
|
|
@@ -621,26 +736,18 @@ function Notices({
|
|
|
621
736
|
borderBottom: false,
|
|
622
737
|
paddingTop: border ? 1 : 0,
|
|
623
738
|
flexDirection: "column",
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
line.text
|
|
637
|
-
]
|
|
638
|
-
},
|
|
639
|
-
`notice-line-${j}`
|
|
640
|
-
);
|
|
641
|
-
}),
|
|
642
|
-
notice.table && /* @__PURE__ */ jsx2(Table, { columns: notice.table.columns, rows: notice.table.rows })
|
|
643
|
-
] }, `notice-${i}`))
|
|
739
|
+
flexGrow: 1,
|
|
740
|
+
minHeight: 0,
|
|
741
|
+
children: /* @__PURE__ */ jsx2(ScrollView, { scroll, children: windowed.map((row, i) => /* @__PURE__ */ jsx2(
|
|
742
|
+
Text4,
|
|
743
|
+
{
|
|
744
|
+
color: row.plain ? COLORS.primary : row.color ?? (row.noticeIndex === latestRowIndex ? pulseColor : COLORS.dim),
|
|
745
|
+
bold: row.bold,
|
|
746
|
+
wrap: "truncate",
|
|
747
|
+
children: row.text
|
|
748
|
+
},
|
|
749
|
+
`notice-row-${scroll.offset + i}`
|
|
750
|
+
)) })
|
|
644
751
|
}
|
|
645
752
|
);
|
|
646
753
|
}
|
|
@@ -651,14 +758,14 @@ import TextInput from "ink-text-input";
|
|
|
651
758
|
import { useState as useState6 } from "react";
|
|
652
759
|
|
|
653
760
|
// src/ui/CommandApproval.tsx
|
|
654
|
-
import { Box as
|
|
761
|
+
import { Box as Box7, Text as Text7 } from "ink";
|
|
655
762
|
|
|
656
763
|
// src/ui/DecisionSelect.tsx
|
|
657
|
-
import { Box as
|
|
658
|
-
import { useState as
|
|
764
|
+
import { Box as Box6, Text as Text6, useInput } from "ink";
|
|
765
|
+
import { useState as useState4 } from "react";
|
|
659
766
|
|
|
660
767
|
// src/ui/SelectRow.tsx
|
|
661
|
-
import { Box as
|
|
768
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
662
769
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
663
770
|
function SelectRow({
|
|
664
771
|
highlighted,
|
|
@@ -671,15 +778,15 @@ function SelectRow({
|
|
|
671
778
|
}) {
|
|
672
779
|
const labelColor = highlighted ? highlightBackground ? COLORS.highlight.fg : COLORS.success : COLORS.primary;
|
|
673
780
|
return /* @__PURE__ */ jsxs3(
|
|
674
|
-
|
|
781
|
+
Box5,
|
|
675
782
|
{
|
|
676
783
|
width,
|
|
677
784
|
paddingX: usePadding ? 1 : 0,
|
|
678
785
|
paddingY: usePadding ? 1 : 0,
|
|
679
786
|
backgroundColor: highlighted && highlightBackground ? COLORS.highlight.bg : void 0,
|
|
680
787
|
children: [
|
|
681
|
-
/* @__PURE__ */ jsx3(
|
|
682
|
-
|
|
788
|
+
/* @__PURE__ */ jsx3(Box5, { width: labelWidth, children: /* @__PURE__ */ jsxs3(
|
|
789
|
+
Text5,
|
|
683
790
|
{
|
|
684
791
|
color: labelColor,
|
|
685
792
|
bold: highlighted && !highlightBackground,
|
|
@@ -702,7 +809,7 @@ function DecisionSelect({
|
|
|
702
809
|
actions,
|
|
703
810
|
onDecide
|
|
704
811
|
}) {
|
|
705
|
-
const [index, setIndex] =
|
|
812
|
+
const [index, setIndex] = useState4(0);
|
|
706
813
|
useInput((input, key) => {
|
|
707
814
|
if (key.upArrow || input === "k") {
|
|
708
815
|
setIndex((i) => (i - 1 + actions.length) % actions.length);
|
|
@@ -714,8 +821,8 @@ function DecisionSelect({
|
|
|
714
821
|
onDecide(actions[1].value);
|
|
715
822
|
}
|
|
716
823
|
});
|
|
717
|
-
return /* @__PURE__ */ jsxs4(
|
|
718
|
-
/* @__PURE__ */ jsx4(
|
|
824
|
+
return /* @__PURE__ */ jsxs4(Box6, { flexDirection: "column", gap: 1, children: [
|
|
825
|
+
/* @__PURE__ */ jsx4(Box6, { flexDirection: "column", children: actions.map((action, i) => /* @__PURE__ */ jsx4(
|
|
719
826
|
SelectRow,
|
|
720
827
|
{
|
|
721
828
|
highlighted: i === index,
|
|
@@ -724,14 +831,14 @@ function DecisionSelect({
|
|
|
724
831
|
},
|
|
725
832
|
action.label
|
|
726
833
|
)) }),
|
|
727
|
-
/* @__PURE__ */ jsxs4(
|
|
728
|
-
/* @__PURE__ */ jsxs4(
|
|
729
|
-
/* @__PURE__ */ jsx4(
|
|
730
|
-
/* @__PURE__ */ jsx4(
|
|
834
|
+
/* @__PURE__ */ jsxs4(Box6, { gap: 2, children: [
|
|
835
|
+
/* @__PURE__ */ jsxs4(Text6, { children: [
|
|
836
|
+
/* @__PURE__ */ jsx4(Text6, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
|
|
837
|
+
/* @__PURE__ */ jsx4(Text6, { color: COLORS.dim, children: " move" })
|
|
731
838
|
] }),
|
|
732
|
-
/* @__PURE__ */ jsxs4(
|
|
733
|
-
/* @__PURE__ */ jsx4(
|
|
734
|
-
/* @__PURE__ */ jsx4(
|
|
839
|
+
/* @__PURE__ */ jsxs4(Text6, { children: [
|
|
840
|
+
/* @__PURE__ */ jsx4(Text6, { color: COLORS.primary, children: "[enter]" }),
|
|
841
|
+
/* @__PURE__ */ jsx4(Text6, { color: COLORS.dim, children: " confirm" })
|
|
735
842
|
] })
|
|
736
843
|
] })
|
|
737
844
|
] });
|
|
@@ -741,14 +848,12 @@ function DecisionSelect({
|
|
|
741
848
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
742
849
|
function CommandApproval({
|
|
743
850
|
command,
|
|
744
|
-
messages,
|
|
745
851
|
onDecide
|
|
746
852
|
}) {
|
|
747
|
-
return /* @__PURE__ */ jsxs5(
|
|
748
|
-
|
|
749
|
-
/* @__PURE__ */ jsx5(Text6, { color: COLORS.primary, bold: true, children: "Run this command?" }),
|
|
853
|
+
return /* @__PURE__ */ jsxs5(Box7, { flexDirection: "column", gap: 1, children: [
|
|
854
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.primary, bold: true, children: "Run this command?" }),
|
|
750
855
|
/* @__PURE__ */ jsxs5(
|
|
751
|
-
|
|
856
|
+
Box7,
|
|
752
857
|
{
|
|
753
858
|
flexDirection: "column",
|
|
754
859
|
paddingLeft: 2,
|
|
@@ -759,17 +864,17 @@ function CommandApproval({
|
|
|
759
864
|
borderRight: false,
|
|
760
865
|
gap: 1,
|
|
761
866
|
children: [
|
|
762
|
-
/* @__PURE__ */ jsxs5(
|
|
763
|
-
/* @__PURE__ */ jsx5(
|
|
764
|
-
/* @__PURE__ */ jsx5(
|
|
867
|
+
/* @__PURE__ */ jsxs5(Box7, { children: [
|
|
868
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.muted, children: "$ " }),
|
|
869
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.strong, wrap: "wrap", children: command.command })
|
|
765
870
|
] }),
|
|
766
|
-
/* @__PURE__ */ jsxs5(
|
|
767
|
-
/* @__PURE__ */ jsx5(
|
|
768
|
-
/* @__PURE__ */ jsx5(
|
|
871
|
+
/* @__PURE__ */ jsxs5(Box7, { gap: 1, children: [
|
|
872
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.muted, children: "in:" }),
|
|
873
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.muted, wrap: "wrap", children: command.cwd })
|
|
769
874
|
] }),
|
|
770
|
-
command.explanation && /* @__PURE__ */ jsxs5(
|
|
771
|
-
/* @__PURE__ */ jsx5(
|
|
772
|
-
/* @__PURE__ */ jsx5(
|
|
875
|
+
command.explanation && /* @__PURE__ */ jsxs5(Box7, { gap: 1, children: [
|
|
876
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.muted, children: "why:" }),
|
|
877
|
+
/* @__PURE__ */ jsx5(Text7, { color: COLORS.accent, wrap: "wrap", children: command.explanation })
|
|
773
878
|
] })
|
|
774
879
|
]
|
|
775
880
|
}
|
|
@@ -788,100 +893,9 @@ function CommandApproval({
|
|
|
788
893
|
}
|
|
789
894
|
|
|
790
895
|
// src/ui/SelectPrompt.tsx
|
|
791
|
-
import { Box as Box8, Text as Text8, useInput as useInput2, useWindowSize as
|
|
896
|
+
import { Box as Box8, Text as Text8, useInput as useInput2, useWindowSize as useWindowSize5 } from "ink";
|
|
792
897
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState5 } from "react";
|
|
793
|
-
|
|
794
|
-
// src/ui/ScrollView.tsx
|
|
795
|
-
import { Box as Box7, Text as Text7, measureElement as measureElement2, useWindowSize as useWindowSize3 } from "ink";
|
|
796
|
-
import { useCallback, useLayoutEffect, useRef as useRef2, useState as useState4 } from "react";
|
|
797
|
-
import { jsxs as jsxs6 } from "react/jsx-runtime";
|
|
798
|
-
var INDICATOR_ROWS = 2;
|
|
799
|
-
function fittedWidth(node, columns) {
|
|
800
|
-
let left = 0;
|
|
801
|
-
for (let n = node; n; n = n.parentNode) {
|
|
802
|
-
left += n.yogaNode?.getComputedLeft() ?? 0;
|
|
803
|
-
}
|
|
804
|
-
return Math.max(Math.min(measureElement2(node).width, columns - left), 0);
|
|
805
|
-
}
|
|
806
|
-
function useScrollWindow({
|
|
807
|
-
itemCount,
|
|
808
|
-
rowHeight = 1,
|
|
809
|
-
followBottom = false
|
|
810
|
-
}) {
|
|
811
|
-
const viewportRef = useRef2(null);
|
|
812
|
-
const { columns } = useWindowSize3();
|
|
813
|
-
const [size, setSize] = useState4(
|
|
814
|
-
null
|
|
815
|
-
);
|
|
816
|
-
useLayoutEffect(() => {
|
|
817
|
-
if (!viewportRef.current) return;
|
|
818
|
-
const width = fittedWidth(viewportRef.current, columns);
|
|
819
|
-
const { height } = measureElement2(viewportRef.current);
|
|
820
|
-
setSize(
|
|
821
|
-
(prev) => prev?.width === width && prev.height === height ? prev : { width, height }
|
|
822
|
-
);
|
|
823
|
-
});
|
|
824
|
-
const capacity = size === null || itemCount * rowHeight <= size.height ? itemCount : Math.max(Math.floor((size.height - INDICATOR_ROWS) / rowHeight), 1);
|
|
825
|
-
const maxOffset = Math.max(itemCount - capacity, 0);
|
|
826
|
-
const [offset, setOffset] = useState4(0);
|
|
827
|
-
const prevMaxOffsetRef = useRef2(0);
|
|
828
|
-
useLayoutEffect(() => {
|
|
829
|
-
const wasAtBottom = offset >= prevMaxOffsetRef.current;
|
|
830
|
-
prevMaxOffsetRef.current = maxOffset;
|
|
831
|
-
setOffset(
|
|
832
|
-
(o) => followBottom && wasAtBottom ? maxOffset : Math.min(o, maxOffset)
|
|
833
|
-
);
|
|
834
|
-
}, [maxOffset, followBottom]);
|
|
835
|
-
const scrollBy = useCallback(
|
|
836
|
-
(delta) => {
|
|
837
|
-
setOffset((o) => Math.min(Math.max(o + delta, 0), maxOffset));
|
|
838
|
-
},
|
|
839
|
-
[maxOffset]
|
|
840
|
-
);
|
|
841
|
-
const revealIndex = useCallback(
|
|
842
|
-
(index) => {
|
|
843
|
-
setOffset((o) => {
|
|
844
|
-
if (index < o) return index;
|
|
845
|
-
if (index >= o + capacity) {
|
|
846
|
-
return Math.min(index - capacity + 1, maxOffset);
|
|
847
|
-
}
|
|
848
|
-
return o;
|
|
849
|
-
});
|
|
850
|
-
},
|
|
851
|
-
[capacity, maxOffset]
|
|
852
|
-
);
|
|
853
|
-
const visibleCount = Math.min(capacity, Math.max(itemCount - offset, 0));
|
|
854
|
-
return {
|
|
855
|
-
viewportRef,
|
|
856
|
-
measured: size !== null,
|
|
857
|
-
width: size?.width ?? columns,
|
|
858
|
-
offset,
|
|
859
|
-
capacity,
|
|
860
|
-
maxOffset,
|
|
861
|
-
hiddenAbove: Math.min(offset, itemCount),
|
|
862
|
-
hiddenBelow: Math.max(itemCount - offset - visibleCount, 0),
|
|
863
|
-
scrollBy,
|
|
864
|
-
revealIndex
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
function ScrollView({ scroll, children }) {
|
|
868
|
-
return /* @__PURE__ */ jsxs6(Box7, { ref: scroll.viewportRef, flexDirection: "column", flexGrow: 1, children: [
|
|
869
|
-
scroll.hiddenAbove > 0 && /* @__PURE__ */ jsxs6(Text7, { color: COLORS.dim, children: [
|
|
870
|
-
"\u2191 ",
|
|
871
|
-
scroll.hiddenAbove,
|
|
872
|
-
" more"
|
|
873
|
-
] }),
|
|
874
|
-
children,
|
|
875
|
-
scroll.hiddenBelow > 0 && /* @__PURE__ */ jsxs6(Text7, { color: COLORS.dim, children: [
|
|
876
|
-
"\u2193 ",
|
|
877
|
-
scroll.hiddenBelow,
|
|
878
|
-
" more"
|
|
879
|
-
] })
|
|
880
|
-
] });
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// src/ui/SelectPrompt.tsx
|
|
884
|
-
import { jsx as jsx6, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
898
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
885
899
|
var CANCEL = "cancel";
|
|
886
900
|
var ARROW_WIDTH = 4;
|
|
887
901
|
var COLUMN_GAP = 2;
|
|
@@ -912,7 +926,7 @@ function SelectPrompt({
|
|
|
912
926
|
if (multi) hints.push({ key: "[space]", label: "select" });
|
|
913
927
|
hints.push({ key: "[enter]", label: "confirm" });
|
|
914
928
|
const containerRef = useRef3(null);
|
|
915
|
-
const { columns } =
|
|
929
|
+
const { columns } = useWindowSize5();
|
|
916
930
|
const [width, setWidth] = useState5(columns);
|
|
917
931
|
useLayoutEffect2(() => {
|
|
918
932
|
if (!containerRef.current) return;
|
|
@@ -966,12 +980,12 @@ function SelectPrompt({
|
|
|
966
980
|
}
|
|
967
981
|
}
|
|
968
982
|
});
|
|
969
|
-
return /* @__PURE__ */ jsx6(Box8, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */
|
|
970
|
-
/* @__PURE__ */
|
|
983
|
+
return /* @__PURE__ */ jsx6(Box8, { ref: containerRef, flexGrow: 1, children: /* @__PURE__ */ jsxs6(Box8, { flexDirection: "column", gap: 1, width, children: [
|
|
984
|
+
/* @__PURE__ */ jsxs6(Box8, { flexDirection: "column", gap: 1, flexShrink: 0, children: [
|
|
971
985
|
error && /* @__PURE__ */ jsx6(Text8, { color: COLORS.danger, children: error }),
|
|
972
986
|
messages?.map((m, i) => /* @__PURE__ */ jsx6(Text8, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
973
987
|
table && /* @__PURE__ */ jsx6(Table, { columns: table.columns, rows: table.rows }),
|
|
974
|
-
/* @__PURE__ */
|
|
988
|
+
/* @__PURE__ */ jsxs6(Box8, { flexDirection: "column", children: [
|
|
975
989
|
question && /* @__PURE__ */ jsx6(Text8, { color: COLORS.muted, children: question }),
|
|
976
990
|
helpText && /* @__PURE__ */ jsx6(Text8, { color: COLORS.dim, children: helpText })
|
|
977
991
|
] })
|
|
@@ -983,7 +997,7 @@ function SelectPrompt({
|
|
|
983
997
|
const bullet = multi && !isCancel ? checked.has(i) ? "\u25CF " : "\u25CB " : "";
|
|
984
998
|
const sec = isCancel ? void 0 : secondary?.[i];
|
|
985
999
|
const isText = sec?.kind === "text";
|
|
986
|
-
return /* @__PURE__ */
|
|
1000
|
+
return /* @__PURE__ */ jsxs6(
|
|
987
1001
|
SelectRow,
|
|
988
1002
|
{
|
|
989
1003
|
highlighted,
|
|
@@ -1006,10 +1020,10 @@ function SelectPrompt({
|
|
|
1006
1020
|
`row-${i}`
|
|
1007
1021
|
);
|
|
1008
1022
|
}) }),
|
|
1009
|
-
/* @__PURE__ */ jsx6(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx6(Text8, { color: COLORS.dim, children: hints.map(({ key, label }, i) => /* @__PURE__ */
|
|
1023
|
+
/* @__PURE__ */ jsx6(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx6(Text8, { color: COLORS.dim, children: hints.map(({ key, label }, i) => /* @__PURE__ */ jsxs6(Text8, { color: COLORS.dim, children: [
|
|
1010
1024
|
i > 0 ? " " : "",
|
|
1011
1025
|
/* @__PURE__ */ jsx6(Text8, { color: COLORS.primary, children: key }),
|
|
1012
|
-
/* @__PURE__ */
|
|
1026
|
+
/* @__PURE__ */ jsxs6(Text8, { color: COLORS.dim, children: [
|
|
1013
1027
|
" ",
|
|
1014
1028
|
label
|
|
1015
1029
|
] })
|
|
@@ -1018,14 +1032,14 @@ function SelectPrompt({
|
|
|
1018
1032
|
}
|
|
1019
1033
|
|
|
1020
1034
|
// src/ui/PromptInput.tsx
|
|
1021
|
-
import { jsx as jsx7, jsxs as
|
|
1035
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1022
1036
|
var ACCEPT_REJECT_OPTIONS = ["Accept", "Reject"];
|
|
1023
1037
|
function EnterToContinuePrompt({
|
|
1024
1038
|
question,
|
|
1025
1039
|
messages,
|
|
1026
1040
|
onDecide
|
|
1027
1041
|
}) {
|
|
1028
|
-
return /* @__PURE__ */
|
|
1042
|
+
return /* @__PURE__ */ jsxs7(Box9, { flexDirection: "column", gap: 1, children: [
|
|
1029
1043
|
messages?.map((m, i) => /* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
1030
1044
|
question && /* @__PURE__ */ jsx7(Text9, { color: COLORS.primary, children: question }),
|
|
1031
1045
|
/* @__PURE__ */ jsx7(
|
|
@@ -1086,6 +1100,7 @@ function PromptInput() {
|
|
|
1086
1100
|
return /* @__PURE__ */ jsx7(Box9, { flexGrow: 1, children: /* @__PURE__ */ jsx7(
|
|
1087
1101
|
SelectPrompt,
|
|
1088
1102
|
{
|
|
1103
|
+
question: inputReq.prompt,
|
|
1089
1104
|
messages: inputReq.messages,
|
|
1090
1105
|
options: ["Continue"],
|
|
1091
1106
|
onSelect: submitInput
|
|
@@ -1104,14 +1119,7 @@ function PromptInput() {
|
|
|
1104
1119
|
);
|
|
1105
1120
|
}
|
|
1106
1121
|
if (inputReq.promptType === "commandApproval" && inputReq.command) {
|
|
1107
|
-
return /* @__PURE__ */ jsx7(
|
|
1108
|
-
CommandApproval,
|
|
1109
|
-
{
|
|
1110
|
-
command: inputReq.command,
|
|
1111
|
-
messages: inputReq.messages,
|
|
1112
|
-
onDecide: submitInput
|
|
1113
|
-
}
|
|
1114
|
-
);
|
|
1122
|
+
return /* @__PURE__ */ jsx7(CommandApproval, { command: inputReq.command, onDecide: submitInput });
|
|
1115
1123
|
}
|
|
1116
1124
|
if (inputReq.promptType === "acceptReject") {
|
|
1117
1125
|
const labels = inputReq.options?.length ? inputReq.options : ACCEPT_REJECT_OPTIONS;
|
|
@@ -1127,11 +1135,11 @@ function PromptInput() {
|
|
|
1127
1135
|
promptKey
|
|
1128
1136
|
) });
|
|
1129
1137
|
}
|
|
1130
|
-
return /* @__PURE__ */
|
|
1138
|
+
return /* @__PURE__ */ jsxs7(Box9, { flexDirection: "column", children: [
|
|
1131
1139
|
inputReq.error && /* @__PURE__ */ jsx7(Text9, { color: COLORS.danger, children: inputReq.error }),
|
|
1132
1140
|
inputReq.messages?.map((m, i) => /* @__PURE__ */ jsx7(Text9, { color: COLORS.muted, children: m }, `msg-${i}`)),
|
|
1133
|
-
/* @__PURE__ */
|
|
1134
|
-
/* @__PURE__ */
|
|
1141
|
+
/* @__PURE__ */ jsxs7(Box9, { children: [
|
|
1142
|
+
/* @__PURE__ */ jsxs7(Text9, { color: COLORS.primary, children: [
|
|
1135
1143
|
inputReq.prompt,
|
|
1136
1144
|
" "
|
|
1137
1145
|
] }),
|
|
@@ -1153,7 +1161,7 @@ function PromptInput() {
|
|
|
1153
1161
|
// src/ui/Review.tsx
|
|
1154
1162
|
import { Box as Box10, Text as Text10, useInput as useInput3 } from "ink";
|
|
1155
1163
|
import { useLayoutEffect as useLayoutEffect3, useState as useState7 } from "react";
|
|
1156
|
-
import { jsx as jsx8, jsxs as
|
|
1164
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1157
1165
|
var INGEST_SCRIPT = ".algolia-wizard/ingest.sh";
|
|
1158
1166
|
function wrapText(text, width) {
|
|
1159
1167
|
if (width <= 0) return [text];
|
|
@@ -1251,8 +1259,8 @@ function ReviewPanel({ review: review2 }) {
|
|
|
1251
1259
|
{ isActive: scrollable }
|
|
1252
1260
|
);
|
|
1253
1261
|
const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
1254
|
-
return /* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */ jsx8(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */
|
|
1262
|
+
return /* @__PURE__ */ jsxs8(Box10, { flexDirection: "column", flexGrow: 1, children: [
|
|
1263
|
+
/* @__PURE__ */ jsx8(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */ jsxs8(Text10, { wrap: "truncate", children: [
|
|
1256
1264
|
row.prefix && /* @__PURE__ */ jsx8(Text10, { color: row.prefixColor ?? row.color, bold: row.bold, children: row.prefix }),
|
|
1257
1265
|
/* @__PURE__ */ jsx8(Text10, { color: row.color, bold: row.bold, children: row.text })
|
|
1258
1266
|
] }, `review-row-${i}`)) }),
|
|
@@ -2574,16 +2582,9 @@ function searchFilesTool(ctx) {
|
|
|
2574
2582
|
}
|
|
2575
2583
|
|
|
2576
2584
|
// src/lib/tools/runShell.ts
|
|
2577
|
-
import { tool as
|
|
2585
|
+
import { tool as tool8, generateText, Output } from "ai";
|
|
2578
2586
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2579
|
-
import z16 from "zod";
|
|
2580
|
-
import { relative as relative5 } from "node:path";
|
|
2581
|
-
|
|
2582
|
-
// src/lib/tools/reviewScript.ts
|
|
2583
|
-
import { tool as tool8 } from "ai";
|
|
2584
2587
|
import z15 from "zod";
|
|
2585
|
-
import { createHash } from "node:crypto";
|
|
2586
|
-
import { readFile as readFile7, stat as stat2 } from "node:fs/promises";
|
|
2587
2588
|
import { relative as relative4 } from "node:path";
|
|
2588
2589
|
|
|
2589
2590
|
// src/lib/tools/utils/prompt.ts
|
|
@@ -2595,116 +2596,6 @@ function serializePrompt(work) {
|
|
|
2595
2596
|
return result;
|
|
2596
2597
|
}
|
|
2597
2598
|
|
|
2598
|
-
// src/lib/tools/reviewScript.ts
|
|
2599
|
-
var reviewedCommandApprovals = /* @__PURE__ */ new WeakMap();
|
|
2600
|
-
async function fileDigest(filePath) {
|
|
2601
|
-
const content = await readFile7(filePath);
|
|
2602
|
-
return createHash("sha256").update(content).digest("hex");
|
|
2603
|
-
}
|
|
2604
|
-
function grantReviewedCommandApproval(ctx, approval) {
|
|
2605
|
-
reviewedCommandApprovals.set(ctx, approval);
|
|
2606
|
-
}
|
|
2607
|
-
function getReviewedCommandApproval(ctx, command, cwd) {
|
|
2608
|
-
const approval = reviewedCommandApprovals.get(ctx);
|
|
2609
|
-
if (approval?.command !== command || approval.cwd !== cwd) return void 0;
|
|
2610
|
-
return approval;
|
|
2611
|
-
}
|
|
2612
|
-
function clearReviewedCommandApproval(ctx) {
|
|
2613
|
-
reviewedCommandApprovals.delete(ctx);
|
|
2614
|
-
}
|
|
2615
|
-
function revokeCommandApprovals(ctx, command, cwd) {
|
|
2616
|
-
clearReviewedCommandApproval(ctx);
|
|
2617
|
-
useWizard.getState().revokeCommand(command, cwd);
|
|
2618
|
-
}
|
|
2619
|
-
async function reviewedCommandApprovalIsCurrent(approval) {
|
|
2620
|
-
const currentDigest = await fileDigest(approval.filePath).catch(() => null);
|
|
2621
|
-
return currentDigest === approval.digest;
|
|
2622
|
-
}
|
|
2623
|
-
function reviewScriptTool(ctx) {
|
|
2624
|
-
return tool8({
|
|
2625
|
-
description: "Call this as soon as the ingestion script is finished and before you run it. It summarizes the records that will be written, then asks the user to review the script and approve the exact command that will run it, so a matching runShell call needs no second approval.",
|
|
2626
|
-
inputSchema: z15.object({
|
|
2627
|
-
filePath: z15.string().describe(
|
|
2628
|
-
"Path to the script to review, relative to the project root."
|
|
2629
|
-
),
|
|
2630
|
-
command: z15.string().min(1).describe("The exact command that runShell will use to run the script."),
|
|
2631
|
-
cwd: z15.string().describe(
|
|
2632
|
-
"The exact working directory that runShell will use, relative to the current tool working directory."
|
|
2633
|
-
),
|
|
2634
|
-
entityName: z15.string().trim().min(1).max(100).regex(/^[^\r\n]+$/).describe("The exact entity name selected by the user."),
|
|
2635
|
-
usesGeneratedRecords: z15.boolean().describe(
|
|
2636
|
-
"Whether the script reads generated sample records instead of the selected real data source."
|
|
2637
|
-
)
|
|
2638
|
-
}),
|
|
2639
|
-
execute: async ({
|
|
2640
|
-
filePath,
|
|
2641
|
-
command,
|
|
2642
|
-
cwd,
|
|
2643
|
-
entityName,
|
|
2644
|
-
usesGeneratedRecords
|
|
2645
|
-
}) => {
|
|
2646
|
-
logger.info(
|
|
2647
|
-
{ filePath, command, cwd, entityName, usesGeneratedRecords },
|
|
2648
|
-
"called reviewScript tool"
|
|
2649
|
-
);
|
|
2650
|
-
const resolved2 = resolveInRoot(ctx, filePath);
|
|
2651
|
-
if (resolved2.ok === false) return resolved2.error;
|
|
2652
|
-
const resolvedCwd = resolveInRoot(ctx, cwd);
|
|
2653
|
-
if (resolvedCwd.ok === false) return resolvedCwd.error;
|
|
2654
|
-
const displayCwd = relative4(ctx.root, resolvedCwd.target) || ".";
|
|
2655
|
-
const displayFilePath = relative4(ctx.root, resolved2.target);
|
|
2656
|
-
const ingestionSummary = usesGeneratedRecords ? `This will push ${entityName} records from generated sample data to Algolia. You can replace the sample dataset with your real data source in ${displayFilePath}.` : `This will push ${entityName} records from your selected source to Algolia.`;
|
|
2657
|
-
return serializePrompt(async () => {
|
|
2658
|
-
revokeCommandApprovals(ctx, command, resolvedCwd.target);
|
|
2659
|
-
const isFile = await stat2(resolved2.target).then(
|
|
2660
|
-
(s) => s.isFile(),
|
|
2661
|
-
() => false
|
|
2662
|
-
);
|
|
2663
|
-
if (!isFile) {
|
|
2664
|
-
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
2665
|
-
}
|
|
2666
|
-
const reviewedDigest = await fileDigest(resolved2.target).catch(
|
|
2667
|
-
() => null
|
|
2668
|
-
);
|
|
2669
|
-
if (reviewedDigest === null) {
|
|
2670
|
-
return `Refused: ${filePath} could not be read. Write the script first, then review it again.`;
|
|
2671
|
-
}
|
|
2672
|
-
const answer = await useWizard.getState().requestUserInput({
|
|
2673
|
-
prompt: "Run this command?",
|
|
2674
|
-
promptType: "commandApproval",
|
|
2675
|
-
options: [],
|
|
2676
|
-
messages: [
|
|
2677
|
-
`We have created your ingestion script. Please review it at ${displayFilePath} before approving.`
|
|
2678
|
-
],
|
|
2679
|
-
command: {
|
|
2680
|
-
command,
|
|
2681
|
-
cwd: displayCwd,
|
|
2682
|
-
explanation: ingestionSummary
|
|
2683
|
-
}
|
|
2684
|
-
});
|
|
2685
|
-
if (answer !== "approve") {
|
|
2686
|
-
revokeCommandApprovals(ctx, command, resolvedCwd.target);
|
|
2687
|
-
return "The user declined to run this ingestion script. Do not run it.";
|
|
2688
|
-
}
|
|
2689
|
-
const approvedDigest = await fileDigest(resolved2.target).catch(
|
|
2690
|
-
() => null
|
|
2691
|
-
);
|
|
2692
|
-
if (approvedDigest !== reviewedDigest) {
|
|
2693
|
-
return "The ingestion script changed while it was being reviewed. Call reviewScript again before running it.";
|
|
2694
|
-
}
|
|
2695
|
-
ctx.reviewed.push(resolved2.target);
|
|
2696
|
-
grantReviewedCommandApproval(ctx, {
|
|
2697
|
-
command,
|
|
2698
|
-
cwd: resolvedCwd.target,
|
|
2699
|
-
filePath: resolved2.target,
|
|
2700
|
-
digest: reviewedDigest
|
|
2701
|
-
});
|
|
2702
|
-
return "The user reviewed the script and approved this exact command. Run it now with the same cwd.";
|
|
2703
|
-
});
|
|
2704
|
-
}
|
|
2705
|
-
});
|
|
2706
|
-
}
|
|
2707
|
-
|
|
2708
2599
|
// src/lib/tools/utils/runShell.ts
|
|
2709
2600
|
import { spawn as spawn2 } from "node:child_process";
|
|
2710
2601
|
|
|
@@ -2803,7 +2694,7 @@ function storeApproval(root) {
|
|
|
2803
2694
|
return async (req) => {
|
|
2804
2695
|
const store = useWizard.getState();
|
|
2805
2696
|
if (store.isCommandApproved(req.command, req.cwd)) return "approve";
|
|
2806
|
-
const rel =
|
|
2697
|
+
const rel = relative4(root, req.cwd);
|
|
2807
2698
|
const answer = await store.requestUserInput({
|
|
2808
2699
|
prompt: "Run this command?",
|
|
2809
2700
|
promptType: "commandApproval",
|
|
@@ -2956,9 +2847,9 @@ function fastPathSafety(command) {
|
|
|
2956
2847
|
return void 0;
|
|
2957
2848
|
}
|
|
2958
2849
|
var CLASSIFIER_MODEL = "claude-haiku-4-5";
|
|
2959
|
-
var commandSafetySchema =
|
|
2960
|
-
safe:
|
|
2961
|
-
reason:
|
|
2850
|
+
var commandSafetySchema = z15.object({
|
|
2851
|
+
safe: z15.boolean(),
|
|
2852
|
+
reason: z15.string().describe("One short sentence explaining the verdict.")
|
|
2962
2853
|
});
|
|
2963
2854
|
function defaultCreateModel() {
|
|
2964
2855
|
const token = getAuthToken();
|
|
@@ -3018,15 +2909,12 @@ async function classifyCommandSafety(createModel, command, cwd, explanation, app
|
|
|
3018
2909
|
return false;
|
|
3019
2910
|
}
|
|
3020
2911
|
}
|
|
3021
|
-
async function
|
|
3022
|
-
|
|
2912
|
+
async function runAndRecord(ctx, command, cwd) {
|
|
2913
|
+
useWizard.getState().pushNotice({ messages: [`Running: ${command}`] });
|
|
2914
|
+
const env = await ctx.shell.env().catch((err) => {
|
|
3023
2915
|
logger.warn({ err, command }, "runShell: could not resolve command env");
|
|
3024
2916
|
return {};
|
|
3025
2917
|
});
|
|
3026
|
-
}
|
|
3027
|
-
async function runAndRecord(ctx, command, cwd, resolvedEnv) {
|
|
3028
|
-
useWizard.getState().pushNotice({ messages: [`Running: ${command}`] });
|
|
3029
|
-
const env = resolvedEnv ?? await resolveShellEnv(ctx, command);
|
|
3030
2918
|
const run2 = await (ctx.shell.run ?? runShell)(command, {
|
|
3031
2919
|
cwd,
|
|
3032
2920
|
env,
|
|
@@ -3057,16 +2945,6 @@ async function runAndRecord(ctx, command, cwd, resolvedEnv) {
|
|
|
3057
2945
|
output: run2.output
|
|
3058
2946
|
};
|
|
3059
2947
|
}
|
|
3060
|
-
async function runReviewedCommand(ctx, command, cwd) {
|
|
3061
|
-
const approval = getReviewedCommandApproval(ctx, command, cwd);
|
|
3062
|
-
if (!approval) return void 0;
|
|
3063
|
-
const env = await resolveShellEnv(ctx, command);
|
|
3064
|
-
if (!await reviewedCommandApprovalIsCurrent(approval)) {
|
|
3065
|
-
return `Refused: ${relative5(ctx.root, approval.filePath)} changed after review. Call reviewScript again before running it.`;
|
|
3066
|
-
}
|
|
3067
|
-
clearReviewedCommandApproval(ctx);
|
|
3068
|
-
return runAndRecord(ctx, command, cwd, env);
|
|
3069
|
-
}
|
|
3070
2948
|
async function approveAndRun(ctx, command, cwd, explanation) {
|
|
3071
2949
|
const decision = await ctx.shell.approve({ command, cwd, explanation });
|
|
3072
2950
|
if (decision === "reject") {
|
|
@@ -3077,16 +2955,16 @@ async function approveAndRun(ctx, command, cwd, explanation) {
|
|
|
3077
2955
|
return runAndRecord(ctx, command, cwd);
|
|
3078
2956
|
}
|
|
3079
2957
|
function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
3080
|
-
return
|
|
2958
|
+
return tool8({
|
|
3081
2959
|
description: "Run a shell command in the project. Use this for anything the project needs done in its own ecosystem: installing dependencies, running a script you wrote, running the project's lint/typecheck/test commands. Do not use this to find or read files \u2014 use listFiles, searchFiles, and readFile instead of shell file-listing, reading, or search commands (ls/find/tree/cat/head/tail/grep/rg and similar). This tool refuses all of those outright: the dedicated tools enforce the project-root boundary and secret redaction that a raw shell read would bypass, and they won't count against this tool's command budget. The user approves any command that could change the project before it runs, so write a clear `explanation`. A command judged read-only (inspection, or running tests/typecheck/lint without an autofix flag, in any language) runs immediately without approval. If the user rejects a command, do not retry it \u2014 propose a different approach.",
|
|
3082
|
-
inputSchema:
|
|
3083
|
-
command:
|
|
2960
|
+
inputSchema: z15.object({
|
|
2961
|
+
command: z15.string().describe(
|
|
3084
2962
|
"The command to run, exactly as it would be typed in a shell. Pipes, && and redirects are allowed."
|
|
3085
2963
|
),
|
|
3086
|
-
cwd:
|
|
2964
|
+
cwd: z15.string().optional().describe(
|
|
3087
2965
|
"Directory to run in, relative to the project root. Defaults to the project root."
|
|
3088
2966
|
),
|
|
3089
|
-
explanation:
|
|
2967
|
+
explanation: z15.string().describe(
|
|
3090
2968
|
"One short line telling the user what this command does and why, including any side effect (e.g. writes records to Algolia). This is what they approve against."
|
|
3091
2969
|
)
|
|
3092
2970
|
}),
|
|
@@ -3095,22 +2973,16 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3095
2973
|
return `Refused: command limit (${ctx.limits.shell}) reached. Stop running commands and report what you have.`;
|
|
3096
2974
|
}
|
|
3097
2975
|
const resolved2 = resolveInRoot(ctx, cwd ?? ".");
|
|
3098
|
-
if (resolved2.ok
|
|
2976
|
+
if (!resolved2.ok) return resolved2.error;
|
|
3099
2977
|
if (isFileIOCommand(command)) {
|
|
3100
2978
|
return "Refused: use listFiles or searchFiles to find files, and readFile to read one, instead of a shell file-listing, reading, or search command (ls/find/fd/tree/dir/locate/cat/head/tail/less/more/tac/nl/grep/egrep/fgrep/rg/ack/ag/xxd/hexdump/od/strings).";
|
|
3101
2979
|
}
|
|
3102
2980
|
logger.info({ command, cwd: resolved2.target }, "called runShell tool");
|
|
3103
|
-
const reviewed = await serializePrompt(
|
|
3104
|
-
() => runReviewedCommand(ctx, command, resolved2.target)
|
|
3105
|
-
);
|
|
3106
|
-
if (reviewed !== void 0) return reviewed;
|
|
3107
2981
|
const fast = fastPathSafety(command);
|
|
3108
2982
|
let isSafe = fast;
|
|
3109
|
-
let usedStoredApproval = false;
|
|
3110
2983
|
if (isSafe === void 0) {
|
|
3111
2984
|
const store = useWizard.getState();
|
|
3112
|
-
|
|
3113
|
-
isSafe = usedStoredApproval;
|
|
2985
|
+
isSafe = store.isCommandApproved(command, resolved2.target);
|
|
3114
2986
|
if (!isSafe) {
|
|
3115
2987
|
isSafe = await classifyCommandSafety(
|
|
3116
2988
|
createModel,
|
|
@@ -3121,18 +2993,54 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
3121
2993
|
);
|
|
3122
2994
|
}
|
|
3123
2995
|
}
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
ctx,
|
|
3127
|
-
command,
|
|
3128
|
-
resolved2.target
|
|
2996
|
+
if (isSafe) {
|
|
2997
|
+
return serializePrompt(
|
|
2998
|
+
() => runAndRecord(ctx, command, resolved2.target)
|
|
3129
2999
|
);
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3000
|
+
}
|
|
3001
|
+
return serializePrompt(
|
|
3002
|
+
() => approveAndRun(ctx, command, resolved2.target, explanation)
|
|
3003
|
+
);
|
|
3004
|
+
}
|
|
3005
|
+
});
|
|
3006
|
+
}
|
|
3007
|
+
|
|
3008
|
+
// src/lib/tools/reviewScript.ts
|
|
3009
|
+
import { tool as tool9 } from "ai";
|
|
3010
|
+
import z16 from "zod";
|
|
3011
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
3012
|
+
import { relative as relative5 } from "node:path";
|
|
3013
|
+
function reviewScriptTool(ctx) {
|
|
3014
|
+
return tool9({
|
|
3015
|
+
description: "Call this as soon as the ingestion script is finished and before you run it, so the user can review it.It shows the file path and returns once they have confirmed reviewing it.",
|
|
3016
|
+
inputSchema: z16.object({
|
|
3017
|
+
filePath: z16.string().describe(
|
|
3018
|
+
"Path to the script to review, relative to the project root."
|
|
3019
|
+
)
|
|
3020
|
+
}),
|
|
3021
|
+
execute: async ({ filePath }) => {
|
|
3022
|
+
logger.info({ filePath }, "called reviewScript tool");
|
|
3023
|
+
const resolved2 = resolveInRoot(ctx, filePath);
|
|
3024
|
+
if (resolved2.ok === false) return resolved2.error;
|
|
3025
|
+
const isFile = await stat2(resolved2.target).then(
|
|
3026
|
+
(s) => s.isFile(),
|
|
3027
|
+
() => false
|
|
3028
|
+
);
|
|
3029
|
+
if (!isFile) {
|
|
3030
|
+
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
3031
|
+
}
|
|
3032
|
+
return serializePrompt(async () => {
|
|
3033
|
+
await useWizard.getState().requestUserInput({
|
|
3034
|
+
prompt: "",
|
|
3035
|
+
promptType: "enterToContinue",
|
|
3036
|
+
options: [],
|
|
3037
|
+
messages: [
|
|
3038
|
+
`Please review ${relative5(ctx.root, resolved2.target)} before it runs:`,
|
|
3039
|
+
resolved2.target
|
|
3040
|
+
]
|
|
3041
|
+
});
|
|
3042
|
+
ctx.reviewed.push(resolved2.target);
|
|
3043
|
+
return "The user has reviewed the script. You may run it now.";
|
|
3136
3044
|
});
|
|
3137
3045
|
}
|
|
3138
3046
|
});
|
|
@@ -3627,7 +3535,7 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3627
3535
|
// package.json
|
|
3628
3536
|
var package_default = {
|
|
3629
3537
|
name: "@algolia/wizard",
|
|
3630
|
-
version: "0.46.0-rc.
|
|
3538
|
+
version: "0.46.0-rc.146.324",
|
|
3631
3539
|
description: "Magically implement Algolia functionality in your codebase",
|
|
3632
3540
|
type: "module",
|
|
3633
3541
|
engines: {
|
|
@@ -4330,8 +4238,8 @@ function ingestionInstructions(input) {
|
|
|
4330
4238
|
...algoliaClientDoc(input),
|
|
4331
4239
|
"Install the Algolia client with the project's own package manager via runShell, declaring it in whatever manifest the project uses (e.g. package.json, requirements.txt, Gemfile, go.mod, composer.json) so the dependency is not just installed ad hoc.",
|
|
4332
4240
|
`If the script loads its env vars from a file (e.g. via dotenv or an equivalent for its language) rather than the process environment directly, decide that up front and call writeCredentials on that file before you finish the script \u2014 do not wait to discover the need for it by having a writeFile call refused.`,
|
|
4333
|
-
|
|
4334
|
-
'Then
|
|
4241
|
+
"When the script is finished, call reviewScript with its path and wait: running it writes records to a live index, so the developer reads it first. Do not run it before that call returns.",
|
|
4242
|
+
'Then run the script yourself via runShell, and report the command you ran as "ingestCommand" so the developer can re-run it. Its explanation must say that running it writes records to Algolia.',
|
|
4335
4243
|
"The summary should be extremely concise.",
|
|
4336
4244
|
...sourceSpecificInstructions(input)
|
|
4337
4245
|
] : []
|
|
@@ -4703,33 +4611,19 @@ ${detail}` : ""}`
|
|
|
4703
4611
|
product_area: "AI Wizard"
|
|
4704
4612
|
});
|
|
4705
4613
|
}
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
}
|
|
4719
|
-
const commandMessages = ingestCommand ? [`Ingestion command: ${ingestCommand}`] : [];
|
|
4720
|
-
await ctx.requestUserInput({
|
|
4721
|
-
prompt: "",
|
|
4722
|
-
promptType: "enterToContinue",
|
|
4723
|
-
options: [],
|
|
4724
|
-
// One message per line: Notices.tsx counts a message as one wrapped
|
|
4725
|
-
// line, so an embedded newline overflows the panel's height accounting.
|
|
4726
|
-
messages: [
|
|
4727
|
-
ingestOutcomeMessage,
|
|
4728
|
-
...ingestFailureDetail?.split("\n").filter((l) => l.trim()) ?? [],
|
|
4729
|
-
...commandMessages
|
|
4730
|
-
]
|
|
4731
|
-
});
|
|
4732
|
-
}
|
|
4614
|
+
const commandMessages = ingestCommand ? [`Ingestion command: ${ingestCommand}`] : [];
|
|
4615
|
+
await ctx.requestUserInput({
|
|
4616
|
+
prompt: "",
|
|
4617
|
+
promptType: "enterToContinue",
|
|
4618
|
+
options: [],
|
|
4619
|
+
// One message per line: Notices.tsx counts a message as one wrapped
|
|
4620
|
+
// line, so an embedded newline overflows the panel's height accounting.
|
|
4621
|
+
messages: [
|
|
4622
|
+
ingestOutcomeMessage,
|
|
4623
|
+
...ingestFailureDetail?.split("\n").filter((l) => l.trim()) ?? [],
|
|
4624
|
+
...commandMessages
|
|
4625
|
+
]
|
|
4626
|
+
});
|
|
4733
4627
|
}
|
|
4734
4628
|
let searchConfigFile;
|
|
4735
4629
|
if (useCases.includes("search")) {
|
|
@@ -4929,7 +4823,7 @@ function getWorkflow(id) {
|
|
|
4929
4823
|
import { dirname as dirname8, join as join11 } from "node:path";
|
|
4930
4824
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4931
4825
|
import { useState as useState8 } from "react";
|
|
4932
|
-
import { Box as Box11, Spacer, Text as Text11, useInput as useInput4, useWindowSize as
|
|
4826
|
+
import { Box as Box11, Spacer, Text as Text11, useInput as useInput4, useWindowSize as useWindowSize6 } from "ink";
|
|
4933
4827
|
|
|
4934
4828
|
// src/ui/copy/welcome.ts
|
|
4935
4829
|
var sidebarItems = [
|
|
@@ -4957,7 +4851,7 @@ var sidebarItems = [
|
|
|
4957
4851
|
|
|
4958
4852
|
// src/ui/Welcome.tsx
|
|
4959
4853
|
import Image, { TerminalInfoContext, defaultTerminalInfo } from "ink-picture";
|
|
4960
|
-
import { jsx as jsx9, jsxs as
|
|
4854
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4961
4855
|
var IMAGE_PATH = join11(dirname8(fileURLToPath2(import.meta.url)), "algolia.png");
|
|
4962
4856
|
var TERMINAL_INFO = {
|
|
4963
4857
|
...defaultTerminalInfo,
|
|
@@ -4968,12 +4862,12 @@ function SidebarItem({
|
|
|
4968
4862
|
title,
|
|
4969
4863
|
description
|
|
4970
4864
|
}) {
|
|
4971
|
-
return /* @__PURE__ */
|
|
4972
|
-
/* @__PURE__ */
|
|
4865
|
+
return /* @__PURE__ */ jsxs9(Box11, { flexDirection: "column", children: [
|
|
4866
|
+
/* @__PURE__ */ jsxs9(Box11, { gap: 1, children: [
|
|
4973
4867
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.success, children: "\u2192" }),
|
|
4974
4868
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.strong, bold: true, children: title })
|
|
4975
4869
|
] }),
|
|
4976
|
-
/* @__PURE__ */
|
|
4870
|
+
/* @__PURE__ */ jsxs9(Box11, { flexDirection: "row", gap: 2, children: [
|
|
4977
4871
|
/* @__PURE__ */ jsx9(Spacer, {}),
|
|
4978
4872
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.muted, children: description })
|
|
4979
4873
|
] })
|
|
@@ -4982,7 +4876,7 @@ function SidebarItem({
|
|
|
4982
4876
|
function Welcome() {
|
|
4983
4877
|
const confirmStart = useWizard((s) => s.confirmStart);
|
|
4984
4878
|
const openLearnMore = useWizard((s) => s.openLearnMore);
|
|
4985
|
-
const { rows } =
|
|
4879
|
+
const { rows } = useWindowSize6();
|
|
4986
4880
|
const actions = [
|
|
4987
4881
|
{ label: "start wizard", run: confirmStart },
|
|
4988
4882
|
{ label: "learn more", run: openLearnMore }
|
|
@@ -5011,7 +4905,7 @@ function Welcome() {
|
|
|
5011
4905
|
if (rows < 30) {
|
|
5012
4906
|
layout = scales["small"];
|
|
5013
4907
|
}
|
|
5014
|
-
return /* @__PURE__ */
|
|
4908
|
+
return /* @__PURE__ */ jsxs9(Box11, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
|
|
5015
4909
|
/* @__PURE__ */ jsx9(
|
|
5016
4910
|
Box11,
|
|
5017
4911
|
{
|
|
@@ -5019,7 +4913,7 @@ function Welcome() {
|
|
|
5019
4913
|
paddingX: layout.main.padding.x,
|
|
5020
4914
|
flexDirection: "column",
|
|
5021
4915
|
justifyContent: "center",
|
|
5022
|
-
children: /* @__PURE__ */
|
|
4916
|
+
children: /* @__PURE__ */ jsxs9(Box11, { flexDirection: "column", gap: 2, children: [
|
|
5023
4917
|
/* @__PURE__ */ jsx9(TerminalInfoContext.Provider, { value: TERMINAL_INFO, children: /* @__PURE__ */ jsx9(
|
|
5024
4918
|
Image,
|
|
5025
4919
|
{
|
|
@@ -5041,12 +4935,12 @@ function Welcome() {
|
|
|
5041
4935
|
},
|
|
5042
4936
|
action.label
|
|
5043
4937
|
)) }),
|
|
5044
|
-
/* @__PURE__ */
|
|
5045
|
-
/* @__PURE__ */
|
|
4938
|
+
/* @__PURE__ */ jsxs9(Box11, { gap: 2, children: [
|
|
4939
|
+
/* @__PURE__ */ jsxs9(Text11, { children: [
|
|
5046
4940
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
|
|
5047
4941
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.dim, children: " move" })
|
|
5048
4942
|
] }),
|
|
5049
|
-
/* @__PURE__ */
|
|
4943
|
+
/* @__PURE__ */ jsxs9(Text11, { children: [
|
|
5050
4944
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.primary, children: "[enter]" }),
|
|
5051
4945
|
/* @__PURE__ */ jsx9(Text11, { color: COLORS.dim, children: " confirm" })
|
|
5052
4946
|
] })
|
|
@@ -5054,7 +4948,7 @@ function Welcome() {
|
|
|
5054
4948
|
] })
|
|
5055
4949
|
}
|
|
5056
4950
|
),
|
|
5057
|
-
/* @__PURE__ */
|
|
4951
|
+
/* @__PURE__ */ jsxs9(
|
|
5058
4952
|
Box11,
|
|
5059
4953
|
{
|
|
5060
4954
|
backgroundColor: COLORS.bg.sidebar,
|
|
@@ -5075,7 +4969,7 @@ function Welcome() {
|
|
|
5075
4969
|
|
|
5076
4970
|
// src/ui/LearnMore.tsx
|
|
5077
4971
|
import { Fragment } from "react";
|
|
5078
|
-
import { Box as Box12, Text as Text12, useInput as useInput5, useWindowSize as
|
|
4972
|
+
import { Box as Box12, Text as Text12, useInput as useInput5, useWindowSize as useWindowSize7 } from "ink";
|
|
5079
4973
|
|
|
5080
4974
|
// src/ui/copy/learn-more.ts
|
|
5081
4975
|
var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
|
|
@@ -5117,7 +5011,7 @@ var policyLinks = [
|
|
|
5117
5011
|
];
|
|
5118
5012
|
|
|
5119
5013
|
// src/ui/LearnMore.tsx
|
|
5120
|
-
import { jsx as jsx10, jsxs as
|
|
5014
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5121
5015
|
var TAG_COLORS = {
|
|
5122
5016
|
READ: COLORS.success,
|
|
5123
5017
|
WRITE: COLORS.badge,
|
|
@@ -5134,7 +5028,7 @@ function NeverLine({
|
|
|
5134
5028
|
}) {
|
|
5135
5029
|
const used = segments.reduce((n, s) => n + s.text.length, 0);
|
|
5136
5030
|
const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
|
|
5137
|
-
return /* @__PURE__ */
|
|
5031
|
+
return /* @__PURE__ */ jsxs10(Text12, { color: COLORS.primary, children: [
|
|
5138
5032
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: "\u2502" }),
|
|
5139
5033
|
" ".repeat(NEVER_BOX_PAD_X),
|
|
5140
5034
|
segments.map((s, i) => /* @__PURE__ */ jsx10(Text12, { color: s.color, bold: s.bold, children: s.text }, i)),
|
|
@@ -5145,13 +5039,13 @@ function NeverLine({
|
|
|
5145
5039
|
function LearnMore() {
|
|
5146
5040
|
const confirmStart = useWizard((s) => s.confirmStart);
|
|
5147
5041
|
const backToHome = useWizard((s) => s.backToHome);
|
|
5148
|
-
const { columns } =
|
|
5042
|
+
const { columns } = useWindowSize7();
|
|
5149
5043
|
const dividerWidth = Math.max(0, columns - PADDING_X * 2);
|
|
5150
5044
|
useInput5((_input, key) => {
|
|
5151
5045
|
if (key.escape) backToHome();
|
|
5152
5046
|
else if (key.return) confirmStart();
|
|
5153
5047
|
});
|
|
5154
|
-
return /* @__PURE__ */
|
|
5048
|
+
return /* @__PURE__ */ jsxs10(
|
|
5155
5049
|
Box12,
|
|
5156
5050
|
{
|
|
5157
5051
|
flexDirection: "column",
|
|
@@ -5162,17 +5056,17 @@ function LearnMore() {
|
|
|
5162
5056
|
children: [
|
|
5163
5057
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: "What algolia wizard accesses" }),
|
|
5164
5058
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: accessIntro }),
|
|
5165
|
-
/* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */
|
|
5059
|
+
/* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: accessItems.map((item) => /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", marginTop: 1, children: [
|
|
5166
5060
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.border, children: "\u2500".repeat(dividerWidth) }),
|
|
5167
|
-
/* @__PURE__ */
|
|
5061
|
+
/* @__PURE__ */ jsxs10(Box12, { flexDirection: "row", gap: 1, marginTop: 1, children: [
|
|
5168
5062
|
/* @__PURE__ */ jsx10(Box12, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx10(Text12, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
|
|
5169
|
-
/* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: /* @__PURE__ */
|
|
5063
|
+
/* @__PURE__ */ jsx10(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsxs10(Text12, { color: COLORS.primary, children: [
|
|
5170
5064
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: item.title }),
|
|
5171
5065
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
|
|
5172
5066
|
] }) })
|
|
5173
5067
|
] })
|
|
5174
5068
|
] }, item.tag)) }),
|
|
5175
|
-
/* @__PURE__ */
|
|
5069
|
+
/* @__PURE__ */ jsxs10(Box12, { marginTop: 1, flexDirection: "column", children: [
|
|
5176
5070
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
|
|
5177
5071
|
/* @__PURE__ */ jsx10(NeverLine, { width: dividerWidth }),
|
|
5178
5072
|
/* @__PURE__ */ jsx10(
|
|
@@ -5182,7 +5076,7 @@ function LearnMore() {
|
|
|
5182
5076
|
segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
|
|
5183
5077
|
}
|
|
5184
5078
|
),
|
|
5185
|
-
neverItems.map((item) => /* @__PURE__ */
|
|
5079
|
+
neverItems.map((item) => /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
5186
5080
|
/* @__PURE__ */ jsx10(NeverLine, { width: dividerWidth }),
|
|
5187
5081
|
/* @__PURE__ */ jsx10(
|
|
5188
5082
|
NeverLine,
|
|
@@ -5199,17 +5093,17 @@ function LearnMore() {
|
|
|
5199
5093
|
/* @__PURE__ */ jsx10(NeverLine, { width: dividerWidth }),
|
|
5200
5094
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
|
|
5201
5095
|
] }),
|
|
5202
|
-
/* @__PURE__ */ jsx10(Box12, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */
|
|
5096
|
+
/* @__PURE__ */ jsx10(Box12, { marginTop: 1, flexDirection: "column", children: policyLinks.map((link) => /* @__PURE__ */ jsxs10(Box12, { flexDirection: "row", gap: 1, children: [
|
|
5203
5097
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.strong, bold: true, children: `${link.label}:` }),
|
|
5204
5098
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.accent, children: link.url })
|
|
5205
5099
|
] }, link.label)) }),
|
|
5206
|
-
/* @__PURE__ */
|
|
5207
|
-
/* @__PURE__ */
|
|
5100
|
+
/* @__PURE__ */ jsxs10(Box12, { marginTop: 1, flexDirection: "row", gap: 3, children: [
|
|
5101
|
+
/* @__PURE__ */ jsxs10(Box12, { flexDirection: "row", gap: 1, children: [
|
|
5208
5102
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "[" }),
|
|
5209
5103
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.primary, children: "esc" }),
|
|
5210
5104
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "] back" })
|
|
5211
5105
|
] }),
|
|
5212
|
-
/* @__PURE__ */
|
|
5106
|
+
/* @__PURE__ */ jsxs10(Box12, { flexDirection: "row", gap: 1, children: [
|
|
5213
5107
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "[" }),
|
|
5214
5108
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.primary, children: "enter" }),
|
|
5215
5109
|
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "]" }),
|
|
@@ -5227,11 +5121,11 @@ import { Box as Box15, Text as Text15 } from "ink";
|
|
|
5227
5121
|
// src/ui/Steps.tsx
|
|
5228
5122
|
import { Box as Box13, Text as Text13 } from "ink";
|
|
5229
5123
|
import Spinner from "ink-spinner";
|
|
5230
|
-
import { jsx as jsx11, jsxs as
|
|
5124
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5231
5125
|
function Steps() {
|
|
5232
5126
|
const { steps } = useWizard();
|
|
5233
5127
|
const visibleSteps = steps.filter(isStepVisible);
|
|
5234
|
-
return /* @__PURE__ */ jsx11(Box13, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx11(Box13, { flexDirection: "column", children: /* @__PURE__ */
|
|
5128
|
+
return /* @__PURE__ */ jsx11(Box13, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx11(Box13, { flexDirection: "column", children: /* @__PURE__ */ jsxs11(Text13, { color: COLORS.status[s.status], children: [
|
|
5235
5129
|
s.status === "running" ? /* @__PURE__ */ jsx11(Spinner, { type: "dots" }) : MARKER[s.status],
|
|
5236
5130
|
" ",
|
|
5237
5131
|
s.title
|
|
@@ -5241,7 +5135,7 @@ function CurrentStep() {
|
|
|
5241
5135
|
const { steps } = useWizard();
|
|
5242
5136
|
const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
|
|
5243
5137
|
if (!currentStep) return null;
|
|
5244
|
-
return /* @__PURE__ */
|
|
5138
|
+
return /* @__PURE__ */ jsxs11(Text13, { color: COLORS.status.running, children: [
|
|
5245
5139
|
/* @__PURE__ */ jsx11(Spinner, { type: "dots" }),
|
|
5246
5140
|
" ",
|
|
5247
5141
|
` ${currentStep.title}`
|
|
@@ -5250,14 +5144,14 @@ function CurrentStep() {
|
|
|
5250
5144
|
|
|
5251
5145
|
// src/ui/Progress.tsx
|
|
5252
5146
|
import { Box as Box14, Text as Text14 } from "ink";
|
|
5253
|
-
import { jsx as jsx12, jsxs as
|
|
5147
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
5254
5148
|
function Progress() {
|
|
5255
5149
|
const { steps, currentStepIndex } = useWizard();
|
|
5256
5150
|
const visibleSteps = steps.filter(isStepVisible);
|
|
5257
5151
|
if (visibleSteps.length === 0) return null;
|
|
5258
5152
|
const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
|
|
5259
5153
|
const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
|
|
5260
|
-
return /* @__PURE__ */
|
|
5154
|
+
return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "row", gap: 1, children: [
|
|
5261
5155
|
/* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "STEP" }),
|
|
5262
5156
|
/* @__PURE__ */ jsx12(Text14, { color: COLORS.strong, bold: true, children: activeStepNumber }),
|
|
5263
5157
|
/* @__PURE__ */ jsx12(Text14, { color: COLORS.strong, bold: true, children: "/" }),
|
|
@@ -5272,9 +5166,9 @@ var sidebarCommands = [
|
|
|
5272
5166
|
];
|
|
5273
5167
|
|
|
5274
5168
|
// src/ui/Sidebar.tsx
|
|
5275
|
-
import { jsx as jsx13, jsxs as
|
|
5169
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5276
5170
|
function Sidebar() {
|
|
5277
|
-
return /* @__PURE__ */
|
|
5171
|
+
return /* @__PURE__ */ jsxs13(
|
|
5278
5172
|
Box15,
|
|
5279
5173
|
{
|
|
5280
5174
|
backgroundColor: "#14171E",
|
|
@@ -5284,14 +5178,14 @@ function Sidebar() {
|
|
|
5284
5178
|
flexDirection: "column",
|
|
5285
5179
|
justifyContent: "space-between",
|
|
5286
5180
|
children: [
|
|
5287
|
-
/* @__PURE__ */
|
|
5181
|
+
/* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", gap: 1, children: [
|
|
5288
5182
|
/* @__PURE__ */ jsx13(Text15, { color: COLORS.muted, children: "PROGRESS" }),
|
|
5289
5183
|
/* @__PURE__ */ jsx13(Steps, {})
|
|
5290
5184
|
] }),
|
|
5291
|
-
/* @__PURE__ */
|
|
5185
|
+
/* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", gap: 1, children: [
|
|
5292
5186
|
/* @__PURE__ */ jsx13(Progress, {}),
|
|
5293
5187
|
/* @__PURE__ */ jsx13(Box15, { flexDirection: "column", children: sidebarCommands.map((c) => {
|
|
5294
|
-
return /* @__PURE__ */
|
|
5188
|
+
return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "row", gap: 1, children: [
|
|
5295
5189
|
/* @__PURE__ */ jsx13(Text15, { color: COLORS.primary, children: `[${c.keyHint}]` }),
|
|
5296
5190
|
/* @__PURE__ */ jsx13(Text15, { color: COLORS.muted, children: c.description })
|
|
5297
5191
|
] }, c.keyHint);
|
|
@@ -5304,10 +5198,10 @@ function Sidebar() {
|
|
|
5304
5198
|
|
|
5305
5199
|
// src/ui/Ribbon.tsx
|
|
5306
5200
|
import { Box as Box16, Text as Text16 } from "ink";
|
|
5307
|
-
import { jsx as jsx14, jsxs as
|
|
5201
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5308
5202
|
function Ribbon() {
|
|
5309
5203
|
const firstCommand = sidebarCommands[0];
|
|
5310
|
-
return /* @__PURE__ */
|
|
5204
|
+
return /* @__PURE__ */ jsxs14(
|
|
5311
5205
|
Box16,
|
|
5312
5206
|
{
|
|
5313
5207
|
backgroundColor: "#14171E",
|
|
@@ -5318,7 +5212,7 @@ function Ribbon() {
|
|
|
5318
5212
|
children: [
|
|
5319
5213
|
/* @__PURE__ */ jsx14(Progress, {}),
|
|
5320
5214
|
/* @__PURE__ */ jsx14(CurrentStep, {}),
|
|
5321
|
-
/* @__PURE__ */
|
|
5215
|
+
/* @__PURE__ */ jsxs14(Box16, { flexDirection: "row", gap: 1, children: [
|
|
5322
5216
|
/* @__PURE__ */ jsx14(Text16, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
|
|
5323
5217
|
/* @__PURE__ */ jsx14(Text16, { color: COLORS.muted, children: firstCommand.description })
|
|
5324
5218
|
] })
|
|
@@ -5332,7 +5226,7 @@ import { useState as useState10 } from "react";
|
|
|
5332
5226
|
|
|
5333
5227
|
// src/ui/Logs.tsx
|
|
5334
5228
|
import { Box as Box17, Text as Text17, useInput as useInput6 } from "ink";
|
|
5335
|
-
import { jsx as jsx15, jsxs as
|
|
5229
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5336
5230
|
var KIND_COLOR = {
|
|
5337
5231
|
tool: COLORS.primary,
|
|
5338
5232
|
prompt: COLORS.badge
|
|
@@ -5368,7 +5262,7 @@ function Logs() {
|
|
|
5368
5262
|
else if (key.downArrow) scroll.scrollBy(1);
|
|
5369
5263
|
});
|
|
5370
5264
|
const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
5371
|
-
return /* @__PURE__ */
|
|
5265
|
+
return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
|
|
5372
5266
|
logs.length === 0 && /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: "No logs yet." }),
|
|
5373
5267
|
/* @__PURE__ */ jsx15(ScrollView, { scroll, children: visible.map((entry) => {
|
|
5374
5268
|
const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
|
|
@@ -5380,7 +5274,7 @@ function Logs() {
|
|
|
5380
5274
|
const name = truncate3(entry.name, budget);
|
|
5381
5275
|
budget -= name.length;
|
|
5382
5276
|
const preview = rawPreview ? truncate3(rawPreview, budget) : "";
|
|
5383
|
-
return /* @__PURE__ */
|
|
5277
|
+
return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "row", gap: ROW_GAP, children: [
|
|
5384
5278
|
/* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, children: timestamp }),
|
|
5385
5279
|
/* @__PURE__ */ jsx15(Text17, { color: logNameColor(entry), wrap: "truncate", children: name }),
|
|
5386
5280
|
preview && /* @__PURE__ */ jsx15(Text17, { color: COLORS.dim, wrap: "truncate", children: preview }),
|
|
@@ -5393,37 +5287,8 @@ function Logs() {
|
|
|
5393
5287
|
|
|
5394
5288
|
// src/ui/Tips.tsx
|
|
5395
5289
|
import { useEffect as useEffect3, useRef as useRef4, useState as useState9 } from "react";
|
|
5396
|
-
import { Box as Box19, Text as Text19 } from "ink";
|
|
5397
|
-
import terminalLink from "terminal-link";
|
|
5398
|
-
|
|
5399
|
-
// src/ui/Code.tsx
|
|
5400
5290
|
import { Box as Box18, Text as Text18 } from "ink";
|
|
5401
|
-
import
|
|
5402
|
-
var TOKEN_RE = /("(?:\\.|[^"\\])*"|\btrue\b|\bfalse\b|\bnull\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[{}[\]:,])/g;
|
|
5403
|
-
function highlightJson(json) {
|
|
5404
|
-
const parts = json.split(TOKEN_RE);
|
|
5405
|
-
return parts.map((part, i) => {
|
|
5406
|
-
if (!part) return null;
|
|
5407
|
-
if (part[0] === '"') {
|
|
5408
|
-
const next = parts.slice(i + 1).find((p) => p.trim());
|
|
5409
|
-
const isKey = next?.trimStart().startsWith(":");
|
|
5410
|
-
return /* @__PURE__ */ jsx16(Text18, { color: isKey ? "cyan" : "green", children: part }, i);
|
|
5411
|
-
}
|
|
5412
|
-
if (part === "true" || part === "false" || part === "null") {
|
|
5413
|
-
return /* @__PURE__ */ jsx16(Text18, { color: "magenta", children: part }, i);
|
|
5414
|
-
}
|
|
5415
|
-
if (/^-?\d/.test(part)) {
|
|
5416
|
-
return /* @__PURE__ */ jsx16(Text18, { color: "yellow", children: part }, i);
|
|
5417
|
-
}
|
|
5418
|
-
if (/^[{}[\]:,]$/.test(part)) {
|
|
5419
|
-
return /* @__PURE__ */ jsx16(Text18, { color: COLORS.dim, children: part }, i);
|
|
5420
|
-
}
|
|
5421
|
-
return /* @__PURE__ */ jsx16(Text18, { children: part }, i);
|
|
5422
|
-
});
|
|
5423
|
-
}
|
|
5424
|
-
function Code({ children }) {
|
|
5425
|
-
return /* @__PURE__ */ jsx16(Box18, { children: /* @__PURE__ */ jsx16(Text18, { children: highlightJson(children) }) });
|
|
5426
|
-
}
|
|
5291
|
+
import terminalLink from "terminal-link";
|
|
5427
5292
|
|
|
5428
5293
|
// src/ui/copy/tips.ts
|
|
5429
5294
|
var tips = [
|
|
@@ -5455,23 +5320,7 @@ var tips = [
|
|
|
5455
5320
|
},
|
|
5456
5321
|
{
|
|
5457
5322
|
type: "text",
|
|
5458
|
-
value: "
|
|
5459
|
-
},
|
|
5460
|
-
{
|
|
5461
|
-
type: "code",
|
|
5462
|
-
value: JSON.stringify(
|
|
5463
|
-
{
|
|
5464
|
-
objectID: "sku_48213",
|
|
5465
|
-
name: "Trail Running Shoe",
|
|
5466
|
-
brand: "Northline",
|
|
5467
|
-
categories: ["Footwear", "Running", "Mens"],
|
|
5468
|
-
price: 129.99,
|
|
5469
|
-
in_stock: true,
|
|
5470
|
-
rating: 4.6
|
|
5471
|
-
},
|
|
5472
|
-
null,
|
|
5473
|
-
2
|
|
5474
|
-
)
|
|
5323
|
+
value: "Fields, nesting and types are up to you \u2014 index the shape your app already uses."
|
|
5475
5324
|
}
|
|
5476
5325
|
]
|
|
5477
5326
|
},
|
|
@@ -5636,26 +5485,26 @@ function tipsByIds(ids) {
|
|
|
5636
5485
|
}
|
|
5637
5486
|
|
|
5638
5487
|
// src/ui/Tips.tsx
|
|
5639
|
-
import { jsx as
|
|
5488
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
5640
5489
|
var TICK_MS = 16;
|
|
5641
5490
|
var CHUNK_HOLD_MS = 2e3;
|
|
5642
5491
|
var HOLD_MS = 12e3;
|
|
5643
5492
|
function TipTitle({ children }) {
|
|
5644
|
-
return /* @__PURE__ */
|
|
5645
|
-
/* @__PURE__ */
|
|
5646
|
-
/* @__PURE__ */
|
|
5493
|
+
return /* @__PURE__ */ jsxs16(Text18, { children: [
|
|
5494
|
+
/* @__PURE__ */ jsx16(Text18, { color: "cyan", children: "\u2726 " }),
|
|
5495
|
+
/* @__PURE__ */ jsx16(Text18, { color: "white", bold: true, children })
|
|
5647
5496
|
] });
|
|
5648
5497
|
}
|
|
5649
5498
|
function InlineSegment({ segment }) {
|
|
5650
5499
|
switch (segment.type) {
|
|
5651
5500
|
case "highlight":
|
|
5652
|
-
return /* @__PURE__ */
|
|
5501
|
+
return /* @__PURE__ */ jsx16(Text18, { color: COLORS.success, children: segment.value });
|
|
5653
5502
|
case "link":
|
|
5654
|
-
return /* @__PURE__ */
|
|
5503
|
+
return /* @__PURE__ */ jsx16(Text18, { color: "cyan", underline: true, children: segment.href ? terminalLink(segment.value, segment.href) : segment.value });
|
|
5655
5504
|
case "codeword":
|
|
5656
|
-
return /* @__PURE__ */
|
|
5505
|
+
return /* @__PURE__ */ jsx16(Text18, { color: COLORS.highlight.fg, backgroundColor: COLORS.highlight.bg, children: segment.value });
|
|
5657
5506
|
default:
|
|
5658
|
-
return /* @__PURE__ */
|
|
5507
|
+
return /* @__PURE__ */ jsx16(Text18, { color: COLORS.muted, children: segment.value });
|
|
5659
5508
|
}
|
|
5660
5509
|
}
|
|
5661
5510
|
function TipContent({
|
|
@@ -5663,38 +5512,42 @@ function TipContent({
|
|
|
5663
5512
|
revealed
|
|
5664
5513
|
}) {
|
|
5665
5514
|
let remaining = revealed;
|
|
5666
|
-
const
|
|
5515
|
+
const segments = [];
|
|
5516
|
+
for (const chunk of chunks) {
|
|
5667
5517
|
const slice = chunk.value.slice(0, Math.max(0, remaining));
|
|
5668
5518
|
remaining -= chunk.value.length;
|
|
5669
|
-
return slice;
|
|
5670
|
-
});
|
|
5671
|
-
const blocks = [];
|
|
5672
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
5673
|
-
const chunk = chunks[i];
|
|
5674
|
-
const slice = slices[i];
|
|
5675
5519
|
if (!slice) continue;
|
|
5676
|
-
const
|
|
5520
|
+
const last = segments[segments.length - 1];
|
|
5521
|
+
if (chunk.type === "text" && last?.type === "text") {
|
|
5522
|
+
last.value = `${last.value} ${slice}`;
|
|
5523
|
+
continue;
|
|
5524
|
+
}
|
|
5525
|
+
segments.push({
|
|
5677
5526
|
type: chunk.type,
|
|
5678
5527
|
value: slice,
|
|
5679
5528
|
href: chunk.type === "link" ? chunk.href : void 0
|
|
5680
|
-
};
|
|
5681
|
-
if (chunk.type === "code") {
|
|
5682
|
-
blocks.push({ type: "code", segment });
|
|
5683
|
-
continue;
|
|
5684
|
-
}
|
|
5685
|
-
const last = blocks[blocks.length - 1];
|
|
5686
|
-
if (last?.type === "inline") {
|
|
5687
|
-
last.segments.push(segment);
|
|
5688
|
-
} else {
|
|
5689
|
-
blocks.push({ type: "inline", segments: [segment] });
|
|
5690
|
-
}
|
|
5529
|
+
});
|
|
5691
5530
|
}
|
|
5692
|
-
return /* @__PURE__ */
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5531
|
+
return /* @__PURE__ */ jsx16(Box18, { marginLeft: 2, children: /* @__PURE__ */ jsx16(Text18, { children: segments.map((segment, i) => /* @__PURE__ */ jsxs16(Text18, { children: [
|
|
5532
|
+
i > 0 && " ",
|
|
5533
|
+
/* @__PURE__ */ jsx16(InlineSegment, { segment })
|
|
5534
|
+
] }, i)) }) });
|
|
5535
|
+
}
|
|
5536
|
+
var TIP_PANEL_ROWS = 11;
|
|
5537
|
+
function TipCard({
|
|
5538
|
+
tip,
|
|
5539
|
+
revealed
|
|
5540
|
+
}) {
|
|
5541
|
+
return /* @__PURE__ */ jsxs16(Box18, { flexDirection: "column", gap: 1, children: [
|
|
5542
|
+
/* @__PURE__ */ jsx16(TipTitle, { children: tip.title.slice(0, revealed) }),
|
|
5543
|
+
/* @__PURE__ */ jsx16(
|
|
5544
|
+
TipContent,
|
|
5545
|
+
{
|
|
5546
|
+
chunks: tip.chunks,
|
|
5547
|
+
revealed: Math.max(0, revealed - tip.title.length)
|
|
5548
|
+
}
|
|
5549
|
+
)
|
|
5550
|
+
] });
|
|
5698
5551
|
}
|
|
5699
5552
|
var progress = { stepId: null, tipIndex: 0, revealed: 0 };
|
|
5700
5553
|
function Tips({
|
|
@@ -5767,16 +5620,11 @@ function Tips({
|
|
|
5767
5620
|
return () => clearTimeout(timer);
|
|
5768
5621
|
}, [revealed, totalLength, tips2.length]);
|
|
5769
5622
|
if (!tip) return null;
|
|
5770
|
-
|
|
5771
|
-
const contentRevealed = Math.max(0, revealed - tip.title.length);
|
|
5772
|
-
return /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", marginBottom: 1, gap: 1, children: [
|
|
5773
|
-
/* @__PURE__ */ jsx17(TipTitle, { children: titleRevealed }),
|
|
5774
|
-
/* @__PURE__ */ jsx17(TipContent, { chunks: tip.chunks, revealed: contentRevealed })
|
|
5775
|
-
] });
|
|
5623
|
+
return /* @__PURE__ */ jsx16(TipCard, { tip, revealed });
|
|
5776
5624
|
}
|
|
5777
5625
|
|
|
5778
5626
|
// src/ui/App.tsx
|
|
5779
|
-
import { jsx as
|
|
5627
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5780
5628
|
function App() {
|
|
5781
5629
|
const {
|
|
5782
5630
|
phase,
|
|
@@ -5790,7 +5638,7 @@ function App() {
|
|
|
5790
5638
|
review: review2
|
|
5791
5639
|
} = useWizard();
|
|
5792
5640
|
const { exit } = useApp();
|
|
5793
|
-
const { columns, rows } =
|
|
5641
|
+
const { columns, rows } = useWindowSize8();
|
|
5794
5642
|
const [showLogs, setShowLogs] = useState10(false);
|
|
5795
5643
|
const [tipState, setTipState] = useState10("idle");
|
|
5796
5644
|
const finished = phase === "done" || phase === "error";
|
|
@@ -5803,7 +5651,6 @@ function App() {
|
|
|
5803
5651
|
const promptPending = isAwaitingUserInput && !isCommandApprovalPrompt;
|
|
5804
5652
|
const holdForTip = stepHasTips && promptPending && tipState === "revealing";
|
|
5805
5653
|
const showTips = stepHasTips && (phase === "running" || isCommandApprovalPrompt || holdForTip);
|
|
5806
|
-
const showNoticesInMain = !stepHasTips;
|
|
5807
5654
|
const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
|
|
5808
5655
|
useInput7(
|
|
5809
5656
|
(_input, key) => {
|
|
@@ -5838,14 +5685,15 @@ function App() {
|
|
|
5838
5685
|
});
|
|
5839
5686
|
const mainWindowVisible = phase === "authenticating" || phase === "preflight" || phase === "running" || phase === "awaitingInput" || phase === "error" || phase === "done";
|
|
5840
5687
|
const flexDirection = columns > 90 ? "row" : "column";
|
|
5688
|
+
const tipPanelRows = Math.min(TIP_PANEL_ROWS, Math.max(8, rows - 16));
|
|
5841
5689
|
const showSidebar = flexDirection === "row";
|
|
5842
5690
|
const scrollsPastViewport = phase === "idle" && homeScreen === "learnMore";
|
|
5843
5691
|
return (
|
|
5844
5692
|
/* Clamped to exactly the viewport: a taller frame makes Ink clear and repaint
|
|
5845
5693
|
the whole screen, and the scrolling throws off its cursor arithmetic —
|
|
5846
5694
|
flicker and leftover rows. */
|
|
5847
|
-
/* @__PURE__ */
|
|
5848
|
-
|
|
5695
|
+
/* @__PURE__ */ jsxs17(
|
|
5696
|
+
Box19,
|
|
5849
5697
|
{
|
|
5850
5698
|
backgroundColor: COLORS.bg.main,
|
|
5851
5699
|
flexDirection: "row",
|
|
@@ -5853,16 +5701,16 @@ function App() {
|
|
|
5853
5701
|
height: scrollsPastViewport ? void 0 : rows,
|
|
5854
5702
|
overflow: scrollsPastViewport ? "visible" : "hidden",
|
|
5855
5703
|
children: [
|
|
5856
|
-
mainWindowVisible && /* @__PURE__ */
|
|
5857
|
-
|
|
5704
|
+
mainWindowVisible && /* @__PURE__ */ jsxs17(
|
|
5705
|
+
Box19,
|
|
5858
5706
|
{
|
|
5859
5707
|
flexDirection,
|
|
5860
5708
|
width: "100%",
|
|
5861
5709
|
maxHeight: rows,
|
|
5862
5710
|
justifyContent: "space-between",
|
|
5863
5711
|
children: [
|
|
5864
|
-
showLogs ? /* @__PURE__ */
|
|
5865
|
-
|
|
5712
|
+
showLogs ? /* @__PURE__ */ jsx17(Logs, {}) : /* @__PURE__ */ jsxs17(
|
|
5713
|
+
Box19,
|
|
5866
5714
|
{
|
|
5867
5715
|
flexDirection: "column",
|
|
5868
5716
|
paddingX: 4,
|
|
@@ -5871,49 +5719,67 @@ function App() {
|
|
|
5871
5719
|
flexGrow: 1,
|
|
5872
5720
|
gap: 1,
|
|
5873
5721
|
children: [
|
|
5874
|
-
/* @__PURE__ */
|
|
5875
|
-
phase === "preflight" && !user && /* @__PURE__ */
|
|
5876
|
-
/* @__PURE__ */
|
|
5722
|
+
/* @__PURE__ */ jsxs17(Box19, { flexGrow: 2, flexDirection: "column", children: [
|
|
5723
|
+
phase === "preflight" && !user && /* @__PURE__ */ jsx17(Box19, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
|
|
5724
|
+
/* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
|
|
5877
5725
|
" Signing in to Algolia"
|
|
5878
5726
|
] }) }),
|
|
5879
|
-
phase === "preflight" && user && /* @__PURE__ */
|
|
5880
|
-
/* @__PURE__ */
|
|
5727
|
+
phase === "preflight" && user && /* @__PURE__ */ jsx17(Box19, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
|
|
5728
|
+
/* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
|
|
5881
5729
|
" Getting things ready"
|
|
5882
5730
|
] }) }),
|
|
5883
|
-
phase === "authenticating" && /* @__PURE__ */
|
|
5884
|
-
/* @__PURE__ */
|
|
5885
|
-
/* @__PURE__ */
|
|
5731
|
+
phase === "authenticating" && /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", marginBottom: 1, children: [
|
|
5732
|
+
/* @__PURE__ */ jsxs17(Text19, { color: COLORS.strong, bold: true, children: [
|
|
5733
|
+
/* @__PURE__ */ jsx17(Spinner2, { type: "dots" }),
|
|
5886
5734
|
" Signing in to Algolia"
|
|
5887
5735
|
] }),
|
|
5888
|
-
/* @__PURE__ */
|
|
5736
|
+
/* @__PURE__ */ jsx17(Text19, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
|
|
5889
5737
|
] }),
|
|
5890
|
-
/* @__PURE__ */
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
ids: tipIds,
|
|
5896
|
-
onRevealStateChange: setTipState
|
|
5897
|
-
}
|
|
5898
|
-
),
|
|
5899
|
-
showNoticesInMain && showNotices && /* @__PURE__ */ jsx18(Notices, { showAll: true, border: false }),
|
|
5900
|
-
/* @__PURE__ */ jsx18(Review, {}),
|
|
5901
|
-
!showTips && /* @__PURE__ */ jsx18(PromptInput, {}),
|
|
5902
|
-
phase === "error" && error && /* @__PURE__ */ jsx18(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs18(Text20, { color: COLORS.status.error, children: [
|
|
5738
|
+
/* @__PURE__ */ jsx17(CliOutput, {}),
|
|
5739
|
+
showNotices && /* @__PURE__ */ jsx17(Notices, { showAll: true, border: false }),
|
|
5740
|
+
/* @__PURE__ */ jsx17(Review, {}),
|
|
5741
|
+
!showTips && /* @__PURE__ */ jsx17(PromptInput, {}),
|
|
5742
|
+
phase === "error" && error && /* @__PURE__ */ jsx17(Box19, { marginTop: 1, children: /* @__PURE__ */ jsxs17(Text19, { color: COLORS.status.error, children: [
|
|
5903
5743
|
"\u2716 ",
|
|
5904
5744
|
error
|
|
5905
5745
|
] }) })
|
|
5906
5746
|
] }),
|
|
5907
|
-
|
|
5908
|
-
|
|
5747
|
+
showTips && currentStep && /* Fixed height: a panel that grew as the tip streamed would
|
|
5748
|
+
re-measure the notice feed above it on every character and
|
|
5749
|
+
walk its scroll window. */
|
|
5750
|
+
/* @__PURE__ */ jsx17(
|
|
5751
|
+
Box19,
|
|
5752
|
+
{
|
|
5753
|
+
borderColor: COLORS.border,
|
|
5754
|
+
borderStyle: "single",
|
|
5755
|
+
borderBackgroundColor: COLORS.bg.main,
|
|
5756
|
+
borderLeft: false,
|
|
5757
|
+
borderRight: false,
|
|
5758
|
+
borderBottom: false,
|
|
5759
|
+
paddingTop: 1,
|
|
5760
|
+
height: tipPanelRows,
|
|
5761
|
+
flexShrink: 0,
|
|
5762
|
+
overflow: "hidden",
|
|
5763
|
+
flexDirection: "column",
|
|
5764
|
+
children: /* @__PURE__ */ jsx17(
|
|
5765
|
+
Tips,
|
|
5766
|
+
{
|
|
5767
|
+
stepId: currentStep.id,
|
|
5768
|
+
ids: tipIds,
|
|
5769
|
+
onRevealStateChange: setTipState
|
|
5770
|
+
}
|
|
5771
|
+
)
|
|
5772
|
+
}
|
|
5773
|
+
),
|
|
5774
|
+
showTips && !holdForTip && /* @__PURE__ */ jsx17(PromptInput, {})
|
|
5909
5775
|
]
|
|
5910
5776
|
}
|
|
5911
5777
|
),
|
|
5912
|
-
showSidebar ? /* @__PURE__ */
|
|
5778
|
+
showSidebar ? /* @__PURE__ */ jsx17(Sidebar, {}) : /* @__PURE__ */ jsx17(Ribbon, {})
|
|
5913
5779
|
]
|
|
5914
5780
|
}
|
|
5915
5781
|
),
|
|
5916
|
-
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */
|
|
5782
|
+
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx17(LearnMore, {}) : /* @__PURE__ */ jsx17(Welcome, {}))
|
|
5917
5783
|
]
|
|
5918
5784
|
}
|
|
5919
5785
|
)
|
|
@@ -5921,7 +5787,7 @@ function App() {
|
|
|
5921
5787
|
}
|
|
5922
5788
|
|
|
5923
5789
|
// src/lib/envAppId.ts
|
|
5924
|
-
import { readFile as
|
|
5790
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
5925
5791
|
import { join as join12 } from "node:path";
|
|
5926
5792
|
var ENV_FILES = [".env", ".env.local"];
|
|
5927
5793
|
var APP_ID_LINE = /^[ \t]*(?:export[ \t]+)?([A-Z0-9_]*ALGOLIA_APP(?:LICATION)?_ID)[ \t]*=[ \t]*(.*)$/gm;
|
|
@@ -5929,7 +5795,7 @@ async function findEnvApplicationId(root = process.cwd()) {
|
|
|
5929
5795
|
for (const file of ENV_FILES) {
|
|
5930
5796
|
let content;
|
|
5931
5797
|
try {
|
|
5932
|
-
content = await
|
|
5798
|
+
content = await readFile7(join12(root, file), "utf8");
|
|
5933
5799
|
} catch (err) {
|
|
5934
5800
|
if (err.code !== "ENOENT") {
|
|
5935
5801
|
logger.warn(
|
|
@@ -6332,7 +6198,7 @@ function delay(ms) {
|
|
|
6332
6198
|
}
|
|
6333
6199
|
|
|
6334
6200
|
// src/main.tsx
|
|
6335
|
-
import { jsx as
|
|
6201
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
6336
6202
|
async function startup() {
|
|
6337
6203
|
setProjectRoot(process.cwd());
|
|
6338
6204
|
let args;
|
|
@@ -6382,7 +6248,7 @@ ${formatStepList(workflow)}`);
|
|
|
6382
6248
|
}
|
|
6383
6249
|
async function run(workflow) {
|
|
6384
6250
|
const store = useWizard.getState();
|
|
6385
|
-
const instance = render(/* @__PURE__ */
|
|
6251
|
+
const instance = render(/* @__PURE__ */ jsx18(App, {}), { incrementalRendering: true });
|
|
6386
6252
|
await store.waitForStart();
|
|
6387
6253
|
store.syncSteps(
|
|
6388
6254
|
workflow.steps.map((s) => ({
|