@algolia/wizard 0.76.0 → 0.77.0
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 +532 -286
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -4,9 +4,54 @@
|
|
|
4
4
|
import { render } from "ink";
|
|
5
5
|
|
|
6
6
|
// src/ui/App.tsx
|
|
7
|
-
import { Box as
|
|
7
|
+
import { Box as Box21, Text as Text22, useApp as useApp2, useInput as useInput9, useWindowSize as useWindowSize8 } from "ink";
|
|
8
8
|
import Spinner3 from "ink-spinner";
|
|
9
9
|
|
|
10
|
+
// src/lib/terminalSize.ts
|
|
11
|
+
var MIN_ROWS = 30;
|
|
12
|
+
var MIN_COLUMNS = 100;
|
|
13
|
+
var COMPACT_ROWS = 24;
|
|
14
|
+
var COMPACT_COLUMNS = 80;
|
|
15
|
+
var SIDEBAR_MIN_COLUMNS = 90;
|
|
16
|
+
function isCompactTerminal(columns, rows) {
|
|
17
|
+
return rows < COMPACT_ROWS || columns < COMPACT_COLUMNS;
|
|
18
|
+
}
|
|
19
|
+
async function requestTerminalSize(stdout = process.stdout, {
|
|
20
|
+
rows = MIN_ROWS,
|
|
21
|
+
columns = MIN_COLUMNS,
|
|
22
|
+
timeoutMs = 150,
|
|
23
|
+
settleMs = 120
|
|
24
|
+
} = {}) {
|
|
25
|
+
if (!stdout.isTTY) return;
|
|
26
|
+
const currentRows = stdout.rows ?? 0;
|
|
27
|
+
const currentColumns = stdout.columns ?? 0;
|
|
28
|
+
if (currentRows >= rows && currentColumns >= columns) return;
|
|
29
|
+
stdout.write(
|
|
30
|
+
`\x1B[8;${Math.max(currentRows, rows)};${Math.max(currentColumns, columns)}t`
|
|
31
|
+
);
|
|
32
|
+
const resized = await waitForResize(stdout, timeoutMs);
|
|
33
|
+
if (!resized) return;
|
|
34
|
+
await delay(settleMs);
|
|
35
|
+
stdout.write("\x1B[2J\x1B[H");
|
|
36
|
+
}
|
|
37
|
+
function waitForResize(stdout, timeoutMs) {
|
|
38
|
+
return new Promise((resolve6) => {
|
|
39
|
+
const finish = (didResize) => () => {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
stdout.off("resize", onResize);
|
|
42
|
+
resolve6(didResize);
|
|
43
|
+
};
|
|
44
|
+
const onResize = finish(true);
|
|
45
|
+
const timer = setTimeout(finish(false), timeoutMs);
|
|
46
|
+
stdout.once("resize", onResize);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function delay(ms) {
|
|
50
|
+
return new Promise((resolve6) => {
|
|
51
|
+
setTimeout(resolve6, ms);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
10
55
|
// src/core/store.ts
|
|
11
56
|
import { create } from "zustand";
|
|
12
57
|
import { nanoid } from "nanoid";
|
|
@@ -48,7 +93,7 @@ function runAlgoliaCli(args, { onOutput, redact } = {}) {
|
|
|
48
93
|
const store = useWizard.getState();
|
|
49
94
|
const command = mask(args.join(" "), redact);
|
|
50
95
|
const logId = store.logStart("tool", `algolia ${command}`);
|
|
51
|
-
return new Promise((
|
|
96
|
+
return new Promise((resolve6, reject) => {
|
|
52
97
|
const child = spawn("npx", npxArgs(args), { shell });
|
|
53
98
|
let stdout = "";
|
|
54
99
|
let stderr = "";
|
|
@@ -71,7 +116,7 @@ function runAlgoliaCli(args, { onOutput, redact } = {}) {
|
|
|
71
116
|
splitters.stdout.flush();
|
|
72
117
|
splitters.stderr.flush();
|
|
73
118
|
if (code === 0) {
|
|
74
|
-
|
|
119
|
+
resolve6(stdout);
|
|
75
120
|
} else {
|
|
76
121
|
const failed = stderr.trim();
|
|
77
122
|
let detail = "";
|
|
@@ -277,15 +322,15 @@ var useWizard = create((set, get) => ({
|
|
|
277
322
|
),
|
|
278
323
|
openLearnMore: () => set({ homeScreen: "learnMore" }),
|
|
279
324
|
backToHome: () => set({ homeScreen: "home" }),
|
|
280
|
-
waitForStart: () => new Promise((
|
|
325
|
+
waitForStart: () => new Promise((resolve6) => {
|
|
281
326
|
if (get().phase !== "idle") {
|
|
282
|
-
|
|
327
|
+
resolve6();
|
|
283
328
|
return;
|
|
284
329
|
}
|
|
285
330
|
const unsubscribe = useWizard.subscribe((s) => {
|
|
286
331
|
if (s.phase !== "idle") {
|
|
287
332
|
unsubscribe();
|
|
288
|
-
|
|
333
|
+
resolve6();
|
|
289
334
|
}
|
|
290
335
|
});
|
|
291
336
|
}),
|
|
@@ -392,11 +437,11 @@ var useWizard = create((set, get) => ({
|
|
|
392
437
|
(t) => t.id === id ? { ...t, status, durationMs: Date.now() - t.startedAt } : t
|
|
393
438
|
)
|
|
394
439
|
})),
|
|
395
|
-
requestUserInput: (req) => new Promise((
|
|
440
|
+
requestUserInput: (req) => new Promise((resolve6) => {
|
|
396
441
|
set({
|
|
397
442
|
phase: "awaitingInput",
|
|
398
443
|
inputReq: req,
|
|
399
|
-
_resolve:
|
|
444
|
+
_resolve: resolve6,
|
|
400
445
|
loadingMessage: null
|
|
401
446
|
});
|
|
402
447
|
}),
|
|
@@ -2261,7 +2306,7 @@ async function ensureApplication(resumeAppId) {
|
|
|
2261
2306
|
// package.json
|
|
2262
2307
|
var package_default = {
|
|
2263
2308
|
name: "@algolia/wizard",
|
|
2264
|
-
version: "0.
|
|
2309
|
+
version: "0.77.0",
|
|
2265
2310
|
description: "Magically implement Algolia functionality in your codebase",
|
|
2266
2311
|
type: "module",
|
|
2267
2312
|
engines: {
|
|
@@ -3315,10 +3360,10 @@ var GIT_ENV_OVERRIDES = [
|
|
|
3315
3360
|
function gitSucceeds(root, args) {
|
|
3316
3361
|
const env = { ...process.env };
|
|
3317
3362
|
for (const key of GIT_ENV_OVERRIDES) delete env[key];
|
|
3318
|
-
return new Promise((
|
|
3363
|
+
return new Promise((resolve6) => {
|
|
3319
3364
|
execFile("git", ["-C", root, ...args], { env }, (err) => {
|
|
3320
|
-
if (!err) return
|
|
3321
|
-
|
|
3365
|
+
if (!err) return resolve6(true);
|
|
3366
|
+
resolve6(
|
|
3322
3367
|
err.code === 1 ? false : void 0
|
|
3323
3368
|
);
|
|
3324
3369
|
});
|
|
@@ -3604,7 +3649,7 @@ import { tool as tool8 } from "ai";
|
|
|
3604
3649
|
import z15 from "zod";
|
|
3605
3650
|
import { createHash as createHash2 } from "node:crypto";
|
|
3606
3651
|
import { readFile as readFile8, stat as stat2 } from "node:fs/promises";
|
|
3607
|
-
import { relative as relative4 } from "node:path";
|
|
3652
|
+
import { basename as basename2, relative as relative4, resolve as resolve3 } from "node:path";
|
|
3608
3653
|
|
|
3609
3654
|
// src/lib/tools/utils/prompt.ts
|
|
3610
3655
|
var chain = Promise.resolve();
|
|
@@ -3624,11 +3669,92 @@ async function fileDigest(filePath) {
|
|
|
3624
3669
|
function grantReviewedCommandApproval(ctx, approval) {
|
|
3625
3670
|
reviewedCommandApprovals.set(ctx, approval);
|
|
3626
3671
|
}
|
|
3672
|
+
function scriptOperandTokens(command) {
|
|
3673
|
+
const tokens = [];
|
|
3674
|
+
let token = "";
|
|
3675
|
+
let quote = null;
|
|
3676
|
+
let escaped = false;
|
|
3677
|
+
let comment = false;
|
|
3678
|
+
let skipNext = false;
|
|
3679
|
+
let stop = false;
|
|
3680
|
+
const windowsPaths = process.platform === "win32";
|
|
3681
|
+
const finishToken = () => {
|
|
3682
|
+
if (token) {
|
|
3683
|
+
if (!stop) {
|
|
3684
|
+
if (skipNext) skipNext = false;
|
|
3685
|
+
else tokens.push(token);
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
token = "";
|
|
3689
|
+
};
|
|
3690
|
+
for (const character of command) {
|
|
3691
|
+
if (stop) break;
|
|
3692
|
+
if (comment) {
|
|
3693
|
+
if (character === "\n") comment = false;
|
|
3694
|
+
continue;
|
|
3695
|
+
}
|
|
3696
|
+
if (escaped) {
|
|
3697
|
+
token += character;
|
|
3698
|
+
escaped = false;
|
|
3699
|
+
continue;
|
|
3700
|
+
}
|
|
3701
|
+
if (quote) {
|
|
3702
|
+
if (character === quote) quote = null;
|
|
3703
|
+
else if (quote === '"' && character === "\\") escaped = true;
|
|
3704
|
+
else token += character;
|
|
3705
|
+
continue;
|
|
3706
|
+
}
|
|
3707
|
+
if (character === "\\") {
|
|
3708
|
+
if (windowsPaths) token += character;
|
|
3709
|
+
else escaped = true;
|
|
3710
|
+
} else if (character === '"' || character === "'") {
|
|
3711
|
+
quote = character;
|
|
3712
|
+
} else if (character === "#" && token === "") {
|
|
3713
|
+
comment = true;
|
|
3714
|
+
} else if (character === ">" || character === "<") {
|
|
3715
|
+
finishToken();
|
|
3716
|
+
skipNext = true;
|
|
3717
|
+
} else if (character === "|" || character === "&" || character === ";") {
|
|
3718
|
+
finishToken();
|
|
3719
|
+
stop = true;
|
|
3720
|
+
} else if (/\s/.test(character) || "()".includes(character)) {
|
|
3721
|
+
finishToken();
|
|
3722
|
+
} else {
|
|
3723
|
+
token += character;
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
finishToken();
|
|
3727
|
+
return tokens;
|
|
3728
|
+
}
|
|
3729
|
+
function tokenResolvesToScript(cwd, token, scriptPath) {
|
|
3730
|
+
if (resolve3(cwd, token) === scriptPath) return true;
|
|
3731
|
+
if (!token.includes("\\")) return false;
|
|
3732
|
+
return resolve3(cwd, token.replaceAll("\\", "/")) === scriptPath;
|
|
3733
|
+
}
|
|
3734
|
+
function commandReferencesScript(command, scriptPath, cwd) {
|
|
3735
|
+
return scriptOperandTokens(command).some(
|
|
3736
|
+
(token) => tokenResolvesToScript(cwd, token, scriptPath)
|
|
3737
|
+
);
|
|
3738
|
+
}
|
|
3627
3739
|
function getReviewedCommandApproval(ctx, command, cwd) {
|
|
3628
3740
|
const approval = reviewedCommandApprovals.get(ctx);
|
|
3629
3741
|
if (approval?.command !== command || approval.cwd !== cwd) return void 0;
|
|
3630
3742
|
return approval;
|
|
3631
3743
|
}
|
|
3744
|
+
function commandDiffersFromReviewedScript(ctx, command, cwd) {
|
|
3745
|
+
const approval = reviewedCommandApprovals.get(ctx);
|
|
3746
|
+
if (approval === void 0) return false;
|
|
3747
|
+
if (approval.command === command && approval.cwd === cwd) return false;
|
|
3748
|
+
if (approval.command === command) return true;
|
|
3749
|
+
const scriptReferences = [
|
|
3750
|
+
basename2(approval.filePath),
|
|
3751
|
+
relative4(ctx.root, approval.filePath),
|
|
3752
|
+
".algolia-wizard"
|
|
3753
|
+
];
|
|
3754
|
+
return scriptReferences.some(
|
|
3755
|
+
(reference) => reference !== "" && command.includes(reference)
|
|
3756
|
+
);
|
|
3757
|
+
}
|
|
3632
3758
|
function clearReviewedCommandApproval(ctx) {
|
|
3633
3759
|
reviewedCommandApprovals.delete(ctx);
|
|
3634
3760
|
}
|
|
@@ -3683,6 +3809,14 @@ function reviewScriptTool(ctx) {
|
|
|
3683
3809
|
if (!isFile) {
|
|
3684
3810
|
return `Refused: ${filePath} is not a file. Write the script first, then review the path you wrote.`;
|
|
3685
3811
|
}
|
|
3812
|
+
const relativeScriptPath = relative4(resolvedCwd.target, resolved2.target);
|
|
3813
|
+
if (!commandReferencesScript(
|
|
3814
|
+
command,
|
|
3815
|
+
resolved2.target,
|
|
3816
|
+
resolvedCwd.target
|
|
3817
|
+
)) {
|
|
3818
|
+
return `Refused: the command does not reference the reviewed script from its cwd. Use "${relativeScriptPath}" as the script path, then call reviewScript again.`;
|
|
3819
|
+
}
|
|
3686
3820
|
const reviewedDigest = await fileDigest(resolved2.target).catch(
|
|
3687
3821
|
() => null
|
|
3688
3822
|
);
|
|
@@ -3774,7 +3908,7 @@ var SIGKILL_DELAY_MS = 5e3;
|
|
|
3774
3908
|
function runShell(command, opts) {
|
|
3775
3909
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_SHELL_TIMEOUT_MS;
|
|
3776
3910
|
const startedAt = Date.now();
|
|
3777
|
-
return new Promise((
|
|
3911
|
+
return new Promise((resolve6) => {
|
|
3778
3912
|
let output = "";
|
|
3779
3913
|
let timedOut = false;
|
|
3780
3914
|
let settled = false;
|
|
@@ -3789,7 +3923,7 @@ function runShell(command, opts) {
|
|
|
3789
3923
|
settled = true;
|
|
3790
3924
|
clearTimeout(timer);
|
|
3791
3925
|
clearTimeout(killTimer);
|
|
3792
|
-
|
|
3926
|
+
resolve6({
|
|
3793
3927
|
exitCode,
|
|
3794
3928
|
output: truncateText(output.trim()),
|
|
3795
3929
|
timedOut,
|
|
@@ -4072,6 +4206,7 @@ async function classifyCommandSafety(createModel, command, cwd, explanation, app
|
|
|
4072
4206
|
prompt: [
|
|
4073
4207
|
"A coding agent wants to run this shell command in a user's project without asking for approval first. The command may be in any programming language or ecosystem.",
|
|
4074
4208
|
"Judge it SAFE only if it cannot modify, delete, move, rename, or install anything the project cares about, cannot push/publish/deploy/commit anything, and cannot make a network request that changes remote state.",
|
|
4209
|
+
"Never judge a command SAFE if it runs, imports, requires, or otherwise references an ingestion script or any path under `.algolia-wizard/`. This rule includes shell wrappers, inline code, variable indirection, and dry-run or check descriptions. Such a command always requires explicit user approval.",
|
|
4075
4210
|
"Three broad categories are safe, and most commands you will see fall into one of them:",
|
|
4076
4211
|
"(1) Reporting or listing existing state, with no side effect \u2014 e.g. `git status`, `npm ls`, `npm outdated`, `pip show`, `pip freeze`, `cargo tree`, `docker ps`, `docker images`, `kubectl get pods`, `terraform state list`. This includes a read-only GET-style query to a remote registry or API that only fetches public metadata and changes nothing remote (e.g. `npm view <package>`, `pip index versions <package>`, `curl` with no -X/--request other than GET and no -d/--data) \u2014 safe because nothing changes, not because it stays local.",
|
|
4077
4212
|
'(2) A "preview" or "check" mode that reports what a change WOULD do, or reports a problem, without making the change. This is a general pattern, not a fixed list \u2014 ANY command that takes a dry-run/check/plan/validate/diff/list-only flag is safe when that flag is present, regardless of whether the same flag would normally appear on a "safe" kind of command: `terraform plan`, `terraform validate`, `terraform fmt -check`, `black --check`, `prettier --check`, `isort --check`, `gofmt -l` (list-only), `stylelint` with no `--fix`, and equally `git push --dry-run`, `npm publish --dry-run`, `kubectl apply --dry-run=client` \u2014 these last three are otherwise-unsafe operations (push, publish, cluster changes) that the dry-run flag turns into a report. The corresponding command WITHOUT that flag (e.g. `terraform apply`, `black .`, `gofmt -w`, `git push`) is a different, unsafe command \u2014 the flag is what makes the difference, for any tool, not just the ones named here. This cuts both ways, so do not assume a bare invocation is the safe one: `cargo fmt`, `black`, `prettier`, `isort`, `rustfmt`, and `terraform fmt` all REWRITE FILES by default and need an explicit check/diff/dry-run flag to become safe, while `gofmt`, `eslint`, `stylelint`, `rubocop`, and `ruff check` default to a safe check-only mode and need an explicit fix/write flag to become unsafe \u2014 the same-looking bare command is safe for one group and unsafe for the other, so judge each by what its own flags actually say, not by resemblance to a tool you already judged.',
|
|
@@ -4199,6 +4334,9 @@ function runShellTool(ctx, createModel = defaultCreateModel) {
|
|
|
4199
4334
|
() => runReviewedCommand(ctx, command, resolved2.target)
|
|
4200
4335
|
);
|
|
4201
4336
|
if (reviewed !== void 0) return reviewed;
|
|
4337
|
+
if (commandDiffersFromReviewedScript(ctx, command, resolved2.target)) {
|
|
4338
|
+
return "Refused: this ingestion command differs from the reviewed command. Call reviewScript with this exact command and cwd before runShell.";
|
|
4339
|
+
}
|
|
4202
4340
|
const fast = fastPathSafety(command);
|
|
4203
4341
|
let isSafe = fast;
|
|
4204
4342
|
let usedStoredApproval = false;
|
|
@@ -5210,15 +5348,15 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
|
|
|
5210
5348
|
// src/actions/implement.ts
|
|
5211
5349
|
import z28 from "zod";
|
|
5212
5350
|
import { access, mkdir as mkdir5, readFile as readFile9 } from "node:fs/promises";
|
|
5213
|
-
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join11, relative as relative6, resolve as
|
|
5351
|
+
import { dirname as dirname5, isAbsolute as isAbsolute3, join as join11, relative as relative6, resolve as resolve5, sep as sep2 } from "node:path";
|
|
5214
5352
|
|
|
5215
5353
|
// src/lib/git.ts
|
|
5216
5354
|
import { execFile as execFile2 } from "node:child_process";
|
|
5217
5355
|
import { copyFile, mkdir as mkdir4, stat as stat3 } from "node:fs/promises";
|
|
5218
|
-
import { basename as
|
|
5356
|
+
import { basename as basename3, dirname as dirname3, isAbsolute as isAbsolute2, join as join9, resolve as resolve4 } from "node:path";
|
|
5219
5357
|
var MAX_BUFFER = 32 * 1024 * 1024;
|
|
5220
5358
|
function git(args) {
|
|
5221
|
-
return new Promise((
|
|
5359
|
+
return new Promise((resolve6, reject) => {
|
|
5222
5360
|
execFile2("git", args, { maxBuffer: MAX_BUFFER }, (err, stdout, stderr) => {
|
|
5223
5361
|
if (err)
|
|
5224
5362
|
return reject(
|
|
@@ -5226,7 +5364,7 @@ function git(args) {
|
|
|
5226
5364
|
`git ${args.join(" ")} failed: ${stderr.toString().trim() || err.message}`
|
|
5227
5365
|
)
|
|
5228
5366
|
);
|
|
5229
|
-
|
|
5367
|
+
resolve6(stdout.toString());
|
|
5230
5368
|
});
|
|
5231
5369
|
});
|
|
5232
5370
|
}
|
|
@@ -5244,7 +5382,7 @@ async function copyUploadIntoProject(repoRoot, ingestDir, sourcePath) {
|
|
|
5244
5382
|
if (!trimmed) {
|
|
5245
5383
|
return { ok: false, reason: "no file path was provided" };
|
|
5246
5384
|
}
|
|
5247
|
-
const source = isAbsolute2(trimmed) ? trimmed :
|
|
5385
|
+
const source = isAbsolute2(trimmed) ? trimmed : resolve4(repoRoot, trimmed);
|
|
5248
5386
|
try {
|
|
5249
5387
|
if (!(await stat3(source)).isFile()) {
|
|
5250
5388
|
return { ok: false, reason: `"${sourcePath}" is not a file` };
|
|
@@ -5252,9 +5390,9 @@ async function copyUploadIntoProject(repoRoot, ingestDir, sourcePath) {
|
|
|
5252
5390
|
} catch {
|
|
5253
5391
|
return { ok: false, reason: `"${sourcePath}" does not exist` };
|
|
5254
5392
|
}
|
|
5255
|
-
const relPath = join9(ingestDir,
|
|
5393
|
+
const relPath = join9(ingestDir, basename3(source));
|
|
5256
5394
|
const dest = join9(repoRoot, relPath);
|
|
5257
|
-
if (
|
|
5395
|
+
if (resolve4(source) === resolve4(dest)) {
|
|
5258
5396
|
return { ok: true, relPath };
|
|
5259
5397
|
}
|
|
5260
5398
|
try {
|
|
@@ -5478,8 +5616,16 @@ function ingestionInstructions(input) {
|
|
|
5478
5616
|
...algoliaClientDoc(input),
|
|
5479
5617
|
"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.",
|
|
5480
5618
|
`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.`,
|
|
5481
|
-
|
|
5619
|
+
"Before reviewScript, only use a non-executing parse check such as `node --check <script>` or `python -m py_compile <script>`. Never import, require, run, or dry-run the ingestion script before reviewScript returns.",
|
|
5620
|
+
"Check installed dependency presence at the manifest level, such as `npm ls <package>` or `pip show <package>`. Do not load the ingestion script to resolve dependencies.",
|
|
5621
|
+
...isJsProject(input.language) ? [
|
|
5622
|
+
"For Node.js, module resolution starts from the script path, not the cwd."
|
|
5623
|
+
] : [],
|
|
5624
|
+
`When the script is finished, decide the exact command and cwd you will use to run it. Make sure that the script path in the command resolves from that cwd to the filePath. Then call reviewScript with that filePath, command, cwd, the exact selected entityName, and usesGeneratedRecords set to ${input.ingestionSource === "generated"}. Wait for the developer to review it because running it writes records to a live index. Do not run it before that call returns. If you change the command or cwd after a failed run, call reviewScript again before runShell.`,
|
|
5482
5625
|
'Then, without changing directories, run the script yourself via runShell using the exact same command and cwd. 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.',
|
|
5626
|
+
"If external data access fails, do not run authentication commands, change accounts or machine configuration, or start proxies, containers, or services.",
|
|
5627
|
+
"Do not troubleshoot unavailable external infrastructure. Preserve the script and command, report success, and let the developer prepare the data source.",
|
|
5628
|
+
"If the script cannot access an external data source because credentials or a service are unavailable, do not report status=fail. Report status=success with the completed script, ingestCommand, and a concise failure summary. The wizard handles this run failure and tells the developer how to retry.",
|
|
5483
5629
|
"The summary should be extremely concise.",
|
|
5484
5630
|
...sourceSpecificInstructions(input)
|
|
5485
5631
|
] : []
|
|
@@ -5631,15 +5777,30 @@ function parseIngestRecordCount(output) {
|
|
|
5631
5777
|
const count = Number(match[1]);
|
|
5632
5778
|
return Number.isFinite(count) ? count : void 0;
|
|
5633
5779
|
}
|
|
5634
|
-
function
|
|
5780
|
+
function relativeIngestCwd(execution, repoRoot) {
|
|
5781
|
+
const cwd = relative6(repoRoot, execution.cwd);
|
|
5782
|
+
return cwd && cwd !== "." ? cwd : ".";
|
|
5783
|
+
}
|
|
5784
|
+
function reportedCommandWithCwdNote(execution, repoRoot) {
|
|
5785
|
+
const cwd = relativeIngestCwd(execution, repoRoot);
|
|
5786
|
+
return cwd === "." ? execution.command : `${execution.command} (run from ${cwd})`;
|
|
5787
|
+
}
|
|
5788
|
+
function ingestOutcome(executions, repoRoot, ingestCommand) {
|
|
5635
5789
|
const newestFirst = [...executions].reverse();
|
|
5790
|
+
const matchesReportedCommand = (execution) => {
|
|
5791
|
+
if (execution.command === ingestCommand) return true;
|
|
5792
|
+
if (!ingestCommand) return false;
|
|
5793
|
+
return ingestCommand === reportedCommandWithCwdNote(execution, repoRoot);
|
|
5794
|
+
};
|
|
5636
5795
|
const withCount = newestFirst.filter(
|
|
5637
5796
|
(e) => parseIngestRecordCount(e.output ?? "") != null
|
|
5638
5797
|
);
|
|
5639
|
-
const succeeded = newestFirst.filter(
|
|
5798
|
+
const succeeded = newestFirst.filter(
|
|
5799
|
+
(e) => e.approved && e.exitCode === 0 && !e.timedOut
|
|
5800
|
+
);
|
|
5640
5801
|
return {
|
|
5641
|
-
run: succeeded.find(
|
|
5642
|
-
attempt: ingestCommand ? newestFirst.find(
|
|
5802
|
+
run: succeeded.find(matchesReportedCommand) ?? succeeded.find((e) => withCount.includes(e)),
|
|
5803
|
+
attempt: ingestCommand ? newestFirst.find(matchesReportedCommand) : void 0,
|
|
5643
5804
|
recordCount: parseIngestRecordCount(withCount[0]?.output ?? "")
|
|
5644
5805
|
};
|
|
5645
5806
|
}
|
|
@@ -5733,7 +5894,7 @@ async function pathExists(path) {
|
|
|
5733
5894
|
async function frontendHasPackageJson(repoRoot, searchLocation) {
|
|
5734
5895
|
let directory = repoRoot;
|
|
5735
5896
|
if (searchLocation) {
|
|
5736
|
-
const candidate = dirname5(
|
|
5897
|
+
const candidate = dirname5(resolve5(repoRoot, searchLocation));
|
|
5737
5898
|
const candidateRelative = relative6(repoRoot, candidate);
|
|
5738
5899
|
const outsideRoot = candidateRelative === ".." || candidateRelative.startsWith(`..${sep2}`) || isAbsolute3(candidateRelative);
|
|
5739
5900
|
if (!outsideRoot) directory = candidate;
|
|
@@ -5986,7 +6147,12 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
5986
6147
|
run: ingestRun,
|
|
5987
6148
|
attempt: ingestAttempt,
|
|
5988
6149
|
recordCount
|
|
5989
|
-
} = ingestOutcome(executions, ingestCommand);
|
|
6150
|
+
} = ingestOutcome(executions, repoRoot, ingestCommand);
|
|
6151
|
+
let ingestCwd = ".";
|
|
6152
|
+
if (ingestAttempt) {
|
|
6153
|
+
ingestCommand = ingestAttempt.command;
|
|
6154
|
+
ingestCwd = relativeIngestCwd(ingestAttempt, repoRoot);
|
|
6155
|
+
}
|
|
5990
6156
|
ingestScriptRan = ingestRun != null;
|
|
5991
6157
|
ingestRecordCount = recordCount;
|
|
5992
6158
|
ingestDurationMs = ingestRun?.durationMs;
|
|
@@ -6062,7 +6228,10 @@ ${detail}` : ""}`
|
|
|
6062
6228
|
]
|
|
6063
6229
|
});
|
|
6064
6230
|
} else {
|
|
6065
|
-
const commandMessages = ingestCommand ? [
|
|
6231
|
+
const commandMessages = ingestCommand ? [
|
|
6232
|
+
`Ingestion command: ${ingestCommand}`,
|
|
6233
|
+
...ingestCwd !== "." ? [`Working directory: ${ingestCwd}`] : []
|
|
6234
|
+
] : [];
|
|
6066
6235
|
await ctx.requestUserInput({
|
|
6067
6236
|
prompt: "",
|
|
6068
6237
|
promptType: "enterToContinue",
|
|
@@ -6854,7 +7023,7 @@ async function pollUntilAssessed(ctx, uuid, indexName) {
|
|
|
6854
7023
|
ctx.logEnd(logId, logStatus);
|
|
6855
7024
|
}
|
|
6856
7025
|
}
|
|
6857
|
-
var sleep = (ms) => new Promise((
|
|
7026
|
+
var sleep = (ms) => new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
6858
7027
|
async function assessExecution(ctx, uuid, indexName) {
|
|
6859
7028
|
await retryOnDashboardError(
|
|
6860
7029
|
() => assessPlaybookExecution(uuid),
|
|
@@ -6992,7 +7161,19 @@ function getWorkflow(id) {
|
|
|
6992
7161
|
import { dirname as dirname6, join as join12 } from "node:path";
|
|
6993
7162
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6994
7163
|
import { useState as useState10 } from "react";
|
|
6995
|
-
import { Box as
|
|
7164
|
+
import { Box as Box12, Spacer, Text as Text13, useInput as useInput6, useWindowSize as useWindowSize6 } from "ink";
|
|
7165
|
+
|
|
7166
|
+
// src/ui/ResizeNotice.tsx
|
|
7167
|
+
import { Box as Box11, Text as Text12, useWindowSize as useWindowSize5 } from "ink";
|
|
7168
|
+
import { jsx as jsx10, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
7169
|
+
function ResizeNotice() {
|
|
7170
|
+
const { columns, rows } = useWindowSize5();
|
|
7171
|
+
if (rows >= MIN_ROWS && columns >= MIN_COLUMNS) return null;
|
|
7172
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
7173
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.badge, children: `Terminal is ${columns}x${rows}. Recommended size is ${MIN_COLUMNS}x${MIN_ROWS}.` }),
|
|
7174
|
+
/* @__PURE__ */ jsx10(Text12, { color: COLORS.muted, children: "Enlarge the pane for the full layout." })
|
|
7175
|
+
] });
|
|
7176
|
+
}
|
|
6996
7177
|
|
|
6997
7178
|
// src/ui/copy/welcome.ts
|
|
6998
7179
|
var sidebarItems = [
|
|
@@ -7020,7 +7201,7 @@ var sidebarItems = [
|
|
|
7020
7201
|
|
|
7021
7202
|
// src/ui/Welcome.tsx
|
|
7022
7203
|
import Image, { TerminalInfoContext, defaultTerminalInfo } from "ink-picture";
|
|
7023
|
-
import { jsx as
|
|
7204
|
+
import { jsx as jsx11, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
7024
7205
|
var IMAGE_PATH = join12(dirname6(fileURLToPath2(import.meta.url)), "algolia.png");
|
|
7025
7206
|
var TERMINAL_INFO = {
|
|
7026
7207
|
...defaultTerminalInfo,
|
|
@@ -7031,21 +7212,23 @@ function SidebarItem({
|
|
|
7031
7212
|
title,
|
|
7032
7213
|
description
|
|
7033
7214
|
}) {
|
|
7034
|
-
return /* @__PURE__ */
|
|
7035
|
-
/* @__PURE__ */
|
|
7036
|
-
/* @__PURE__ */
|
|
7037
|
-
/* @__PURE__ */
|
|
7215
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
7216
|
+
/* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
|
|
7217
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.success, children: "\u2192" }),
|
|
7218
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: title })
|
|
7038
7219
|
] }),
|
|
7039
|
-
/* @__PURE__ */
|
|
7040
|
-
/* @__PURE__ */
|
|
7041
|
-
/* @__PURE__ */
|
|
7220
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 2, children: [
|
|
7221
|
+
/* @__PURE__ */ jsx11(Spacer, {}),
|
|
7222
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: description })
|
|
7042
7223
|
] })
|
|
7043
7224
|
] });
|
|
7044
7225
|
}
|
|
7045
7226
|
function Welcome() {
|
|
7046
7227
|
const confirmStart = useWizard((s) => s.confirmStart);
|
|
7047
7228
|
const openLearnMore = useWizard((s) => s.openLearnMore);
|
|
7048
|
-
const { rows } =
|
|
7229
|
+
const { columns, rows } = useWindowSize6();
|
|
7230
|
+
const showSidebar = !isCompactTerminal(columns, rows) && columns > SIDEBAR_MIN_COLUMNS;
|
|
7231
|
+
const showLogo = showSidebar && rows >= MIN_ROWS && columns >= MIN_COLUMNS;
|
|
7049
7232
|
const actions = [
|
|
7050
7233
|
{ label: "start wizard", run: confirmStart },
|
|
7051
7234
|
{ label: "learn more", run: openLearnMore }
|
|
@@ -7071,19 +7254,20 @@ function Welcome() {
|
|
|
7071
7254
|
}
|
|
7072
7255
|
};
|
|
7073
7256
|
let layout = scales["large"];
|
|
7074
|
-
if (rows <
|
|
7257
|
+
if (rows < MIN_ROWS) {
|
|
7075
7258
|
layout = scales["small"];
|
|
7076
7259
|
}
|
|
7077
|
-
return /* @__PURE__ */
|
|
7078
|
-
/* @__PURE__ */
|
|
7079
|
-
|
|
7260
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", justifyContent: "space-between", width: "100%", children: [
|
|
7261
|
+
/* @__PURE__ */ jsx11(
|
|
7262
|
+
Box12,
|
|
7080
7263
|
{
|
|
7081
7264
|
paddingY: layout.main.padding.y,
|
|
7082
7265
|
paddingX: layout.main.padding.x,
|
|
7083
7266
|
flexDirection: "column",
|
|
7084
7267
|
justifyContent: "center",
|
|
7085
|
-
children: /* @__PURE__ */
|
|
7086
|
-
/* @__PURE__ */
|
|
7268
|
+
children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", gap: 2, children: [
|
|
7269
|
+
/* @__PURE__ */ jsx11(ResizeNotice, {}),
|
|
7270
|
+
showLogo && /* @__PURE__ */ jsx11(TerminalInfoContext.Provider, { value: TERMINAL_INFO, children: /* @__PURE__ */ jsx11(
|
|
7087
7271
|
Image,
|
|
7088
7272
|
{
|
|
7089
7273
|
src: IMAGE_PATH,
|
|
@@ -7094,8 +7278,8 @@ function Welcome() {
|
|
|
7094
7278
|
protocol: "halfBlock"
|
|
7095
7279
|
}
|
|
7096
7280
|
) }),
|
|
7097
|
-
/* @__PURE__ */
|
|
7098
|
-
/* @__PURE__ */
|
|
7281
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "\u2726 From zero \u2192 working search in ~10 minutes" }),
|
|
7282
|
+
/* @__PURE__ */ jsx11(Box12, { flexDirection: "column", children: actions.map((action, i) => /* @__PURE__ */ jsx11(
|
|
7099
7283
|
SelectRow,
|
|
7100
7284
|
{
|
|
7101
7285
|
highlighted: i === index,
|
|
@@ -7104,21 +7288,21 @@ function Welcome() {
|
|
|
7104
7288
|
},
|
|
7105
7289
|
action.label
|
|
7106
7290
|
)) }),
|
|
7107
|
-
/* @__PURE__ */
|
|
7108
|
-
/* @__PURE__ */
|
|
7109
|
-
/* @__PURE__ */
|
|
7110
|
-
/* @__PURE__ */
|
|
7291
|
+
/* @__PURE__ */ jsxs12(Box12, { gap: 2, children: [
|
|
7292
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
7293
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.primary, children: "[\u2191] [\u2193]" }),
|
|
7294
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.dim, children: " move" })
|
|
7111
7295
|
] }),
|
|
7112
|
-
/* @__PURE__ */
|
|
7113
|
-
/* @__PURE__ */
|
|
7114
|
-
/* @__PURE__ */
|
|
7296
|
+
/* @__PURE__ */ jsxs12(Text13, { children: [
|
|
7297
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.primary, children: "[enter]" }),
|
|
7298
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.dim, children: " confirm" })
|
|
7115
7299
|
] })
|
|
7116
7300
|
] })
|
|
7117
7301
|
] })
|
|
7118
7302
|
}
|
|
7119
7303
|
),
|
|
7120
|
-
/* @__PURE__ */
|
|
7121
|
-
|
|
7304
|
+
showSidebar && /* @__PURE__ */ jsxs12(
|
|
7305
|
+
Box12,
|
|
7122
7306
|
{
|
|
7123
7307
|
backgroundColor: COLORS.bg.sidebar,
|
|
7124
7308
|
width: 40,
|
|
@@ -7128,8 +7312,8 @@ function Welcome() {
|
|
|
7128
7312
|
flexDirection: "column",
|
|
7129
7313
|
justifyContent: "center",
|
|
7130
7314
|
children: [
|
|
7131
|
-
/* @__PURE__ */
|
|
7132
|
-
sidebarItems.map((i, idx) => /* @__PURE__ */
|
|
7315
|
+
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "WHAT THIS WIZARD WILL DO" }),
|
|
7316
|
+
sidebarItems.map((i, idx) => /* @__PURE__ */ jsx11(SidebarItem, { title: i.title, description: i.description }, idx))
|
|
7133
7317
|
]
|
|
7134
7318
|
}
|
|
7135
7319
|
)
|
|
@@ -7137,8 +7321,7 @@ function Welcome() {
|
|
|
7137
7321
|
}
|
|
7138
7322
|
|
|
7139
7323
|
// src/ui/LearnMore.tsx
|
|
7140
|
-
import {
|
|
7141
|
-
import { Box as Box12, Text as Text13, useInput as useInput7, useWindowSize as useWindowSize6 } from "ink";
|
|
7324
|
+
import { Box as Box13, Text as Text14, useInput as useInput7, useWindowSize as useWindowSize7 } from "ink";
|
|
7142
7325
|
|
|
7143
7326
|
// src/ui/copy/learn-more.ts
|
|
7144
7327
|
var accessIntro = "Everything runs locally on your machine. Nothing is written or sent without an explicit yes from you.";
|
|
@@ -7180,7 +7363,7 @@ var policyLinks = [
|
|
|
7180
7363
|
];
|
|
7181
7364
|
|
|
7182
7365
|
// src/ui/LearnMore.tsx
|
|
7183
|
-
import { jsx as
|
|
7366
|
+
import { jsx as jsx12, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7184
7367
|
var TAG_COLORS = {
|
|
7185
7368
|
READ: COLORS.success,
|
|
7186
7369
|
WRITE: COLORS.badge,
|
|
@@ -7191,92 +7374,156 @@ var TAG_COLORS = {
|
|
|
7191
7374
|
var TAG_COLUMN_WIDTH = 10;
|
|
7192
7375
|
var PADDING_X = 6;
|
|
7193
7376
|
var NEVER_BOX_PAD_X = 2;
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
segments = []
|
|
7197
|
-
}) {
|
|
7377
|
+
var BLANK3 = { parts: [{ text: " ", color: COLORS.dim }] };
|
|
7378
|
+
function neverRow(width, segments = []) {
|
|
7198
7379
|
const used = segments.reduce((n, s) => n + s.text.length, 0);
|
|
7199
7380
|
const rightPad = Math.max(0, width - 2 - NEVER_BOX_PAD_X - used);
|
|
7200
|
-
return
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7381
|
+
return {
|
|
7382
|
+
parts: [
|
|
7383
|
+
{ text: "\u2502", color: COLORS.danger },
|
|
7384
|
+
{ text: " ".repeat(NEVER_BOX_PAD_X), color: COLORS.primary },
|
|
7385
|
+
...segments.map((s) => ({
|
|
7386
|
+
text: s.text,
|
|
7387
|
+
color: s.color ?? COLORS.primary,
|
|
7388
|
+
bold: s.bold
|
|
7389
|
+
})),
|
|
7390
|
+
{ text: " ".repeat(rightPad), color: COLORS.primary },
|
|
7391
|
+
{ text: "\u2502", color: COLORS.danger }
|
|
7392
|
+
]
|
|
7393
|
+
};
|
|
7394
|
+
}
|
|
7395
|
+
function buildLearnMoreRows(contentWidth) {
|
|
7396
|
+
const width = Math.max(contentWidth, 1);
|
|
7397
|
+
const rows = [];
|
|
7398
|
+
rows.push({
|
|
7399
|
+
parts: [
|
|
7400
|
+
{
|
|
7401
|
+
text: "What algolia wizard accesses",
|
|
7402
|
+
color: COLORS.strong,
|
|
7403
|
+
bold: true
|
|
7404
|
+
}
|
|
7405
|
+
]
|
|
7406
|
+
});
|
|
7407
|
+
for (const line of wrapText(accessIntro, width)) {
|
|
7408
|
+
rows.push({ parts: [{ text: line, color: COLORS.muted }] });
|
|
7409
|
+
}
|
|
7410
|
+
for (const item of accessItems) {
|
|
7411
|
+
rows.push({
|
|
7412
|
+
parts: [{ text: "\u2500".repeat(width), color: COLORS.border }]
|
|
7413
|
+
});
|
|
7414
|
+
rows.push(BLANK3);
|
|
7415
|
+
const tag = `[${item.tag}]`.padEnd(TAG_COLUMN_WIDTH);
|
|
7416
|
+
const bodyWidth = Math.max(width - TAG_COLUMN_WIDTH, 1);
|
|
7417
|
+
const body = wrapText(`${item.title}: ${item.description}`, bodyWidth);
|
|
7418
|
+
body.forEach((line, i) => {
|
|
7419
|
+
const titleEnd = i === 0 ? item.title.length : 0;
|
|
7420
|
+
rows.push({
|
|
7421
|
+
parts: [
|
|
7422
|
+
{
|
|
7423
|
+
text: i === 0 ? tag : " ".repeat(TAG_COLUMN_WIDTH),
|
|
7424
|
+
color: TAG_COLORS[item.tag],
|
|
7425
|
+
bold: i === 0
|
|
7426
|
+
},
|
|
7427
|
+
{
|
|
7428
|
+
text: line.slice(0, titleEnd),
|
|
7429
|
+
color: COLORS.strong,
|
|
7430
|
+
bold: true
|
|
7431
|
+
},
|
|
7432
|
+
{ text: line.slice(titleEnd), color: COLORS.muted }
|
|
7433
|
+
]
|
|
7434
|
+
});
|
|
7435
|
+
});
|
|
7436
|
+
}
|
|
7437
|
+
const inner = Math.max(width - 2, 0);
|
|
7438
|
+
rows.push(BLANK3);
|
|
7439
|
+
rows.push({
|
|
7440
|
+
parts: [{ text: `\u256D${"\u2500".repeat(inner)}\u256E`, color: COLORS.danger }]
|
|
7441
|
+
});
|
|
7442
|
+
rows.push(neverRow(width));
|
|
7443
|
+
rows.push(
|
|
7444
|
+
neverRow(width, [{ text: "I NEVER", color: COLORS.danger, bold: true }])
|
|
7445
|
+
);
|
|
7446
|
+
for (const item of neverItems) {
|
|
7447
|
+
rows.push(neverRow(width));
|
|
7448
|
+
const marker = "\u2715 ";
|
|
7449
|
+
const bodyWidth = Math.max(width - 2 - NEVER_BOX_PAD_X - marker.length, 1);
|
|
7450
|
+
const lines = wrapText(item, bodyWidth);
|
|
7451
|
+
lines.forEach((line, i) => {
|
|
7452
|
+
rows.push(
|
|
7453
|
+
neverRow(
|
|
7454
|
+
width,
|
|
7455
|
+
i === 0 ? [
|
|
7456
|
+
{ text: "\u2715", color: COLORS.danger },
|
|
7457
|
+
{ text: " " },
|
|
7458
|
+
{ text: line, color: COLORS.primary }
|
|
7459
|
+
] : [
|
|
7460
|
+
{ text: " ".repeat(marker.length) },
|
|
7461
|
+
{ text: line, color: COLORS.primary }
|
|
7462
|
+
]
|
|
7463
|
+
)
|
|
7464
|
+
);
|
|
7465
|
+
});
|
|
7466
|
+
}
|
|
7467
|
+
rows.push(neverRow(width));
|
|
7468
|
+
rows.push({
|
|
7469
|
+
parts: [{ text: `\u2570${"\u2500".repeat(inner)}\u256F`, color: COLORS.danger }]
|
|
7470
|
+
});
|
|
7471
|
+
rows.push(BLANK3);
|
|
7472
|
+
for (const link of policyLinks) {
|
|
7473
|
+
const prefix = `${link.label}: `;
|
|
7474
|
+
const urlLines = wrapText(link.url, Math.max(width - prefix.length, 1));
|
|
7475
|
+
urlLines.forEach((line, i) => {
|
|
7476
|
+
rows.push({
|
|
7477
|
+
parts: i === 0 ? [
|
|
7478
|
+
{ text: prefix, color: COLORS.strong, bold: true },
|
|
7479
|
+
{ text: line, color: COLORS.accent }
|
|
7480
|
+
] : [{ text: `${" ".repeat(prefix.length)}${line}`, color: COLORS.accent }]
|
|
7481
|
+
});
|
|
7482
|
+
});
|
|
7483
|
+
}
|
|
7484
|
+
return rows;
|
|
7207
7485
|
}
|
|
7208
7486
|
function LearnMore() {
|
|
7209
7487
|
const confirmStart = useWizard((s) => s.confirmStart);
|
|
7210
7488
|
const backToHome = useWizard((s) => s.backToHome);
|
|
7211
|
-
const { columns } =
|
|
7212
|
-
const
|
|
7213
|
-
|
|
7489
|
+
const { columns } = useWindowSize7();
|
|
7490
|
+
const contentWidth = Math.max(columns - PADDING_X * 2, 1);
|
|
7491
|
+
const rows = buildLearnMoreRows(contentWidth);
|
|
7492
|
+
const scroll = useScrollWindow({ itemCount: rows.length });
|
|
7493
|
+
const scrollable = scroll.maxOffset > 0;
|
|
7494
|
+
useInput7((input, key) => {
|
|
7214
7495
|
if (key.escape) backToHome();
|
|
7215
7496
|
else if (key.return) confirmStart();
|
|
7497
|
+
else if (scrollable && (input === "k" || key.upArrow)) scroll.scrollBy(-1);
|
|
7498
|
+
else if (scrollable && (input === "j" || key.downArrow)) scroll.scrollBy(1);
|
|
7216
7499
|
});
|
|
7217
|
-
|
|
7218
|
-
|
|
7500
|
+
const visible = rows.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
7501
|
+
return /* @__PURE__ */ jsxs13(
|
|
7502
|
+
Box13,
|
|
7219
7503
|
{
|
|
7220
7504
|
flexDirection: "column",
|
|
7221
7505
|
paddingX: PADDING_X,
|
|
7222
7506
|
paddingY: 2,
|
|
7223
7507
|
width: "100%",
|
|
7224
|
-
|
|
7508
|
+
flexGrow: 1,
|
|
7225
7509
|
children: [
|
|
7226
|
-
/* @__PURE__ */
|
|
7227
|
-
/* @__PURE__ */
|
|
7228
|
-
|
|
7229
|
-
/* @__PURE__ */
|
|
7230
|
-
/* @__PURE__ */
|
|
7231
|
-
/* @__PURE__ */ jsx11(Box12, { width: TAG_COLUMN_WIDTH, flexShrink: 0, children: /* @__PURE__ */ jsx11(Text13, { color: TAG_COLORS[item.tag], bold: true, children: `[${item.tag}]` }) }),
|
|
7232
|
-
/* @__PURE__ */ jsx11(Box12, { flexDirection: "column", children: /* @__PURE__ */ jsxs12(Text13, { color: COLORS.primary, children: [
|
|
7233
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.strong, bold: true, children: item.title }),
|
|
7234
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: ` \u2014 ${item.description}` })
|
|
7235
|
-
] }) })
|
|
7236
|
-
] })
|
|
7237
|
-
] }, item.tag)) }),
|
|
7238
|
-
/* @__PURE__ */ jsxs12(Box12, { marginTop: 1, flexDirection: "column", children: [
|
|
7239
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.danger, children: `\u256D${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256E` }),
|
|
7240
|
-
/* @__PURE__ */ jsx11(NeverLine, { width: dividerWidth }),
|
|
7241
|
-
/* @__PURE__ */ jsx11(
|
|
7242
|
-
NeverLine,
|
|
7243
|
-
{
|
|
7244
|
-
width: dividerWidth,
|
|
7245
|
-
segments: [{ text: "I NEVER", color: COLORS.danger, bold: true }]
|
|
7246
|
-
}
|
|
7247
|
-
),
|
|
7248
|
-
neverItems.map((item) => /* @__PURE__ */ jsxs12(Fragment, { children: [
|
|
7249
|
-
/* @__PURE__ */ jsx11(NeverLine, { width: dividerWidth }),
|
|
7250
|
-
/* @__PURE__ */ jsx11(
|
|
7251
|
-
NeverLine,
|
|
7252
|
-
{
|
|
7253
|
-
width: dividerWidth,
|
|
7254
|
-
segments: [
|
|
7255
|
-
{ text: "\u2715", color: COLORS.danger },
|
|
7256
|
-
{ text: " " },
|
|
7257
|
-
{ text: item, color: COLORS.primary }
|
|
7258
|
-
]
|
|
7259
|
-
}
|
|
7260
|
-
)
|
|
7261
|
-
] }, item)),
|
|
7262
|
-
/* @__PURE__ */ jsx11(NeverLine, { width: dividerWidth }),
|
|
7263
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.danger, children: `\u2570${"\u2500".repeat(Math.max(0, dividerWidth - 2))}\u256F` })
|
|
7510
|
+
/* @__PURE__ */ jsx12(ResizeNotice, {}),
|
|
7511
|
+
/* @__PURE__ */ jsx12(ScrollView, { scroll, children: visible.map((row, i) => /* @__PURE__ */ jsx12(Text14, { wrap: "truncate", children: row.parts.map((part, j) => /* @__PURE__ */ jsx12(Text14, { color: part.color, bold: part.bold, children: part.text }, j)) }, `learn-more-${scroll.offset}-${i}`)) }),
|
|
7512
|
+
scrollable && /* @__PURE__ */ jsxs13(Text14, { children: [
|
|
7513
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.primary, children: "[j] [k]" }),
|
|
7514
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.dim, children: " scroll" })
|
|
7264
7515
|
] }),
|
|
7265
|
-
/* @__PURE__ */
|
|
7266
|
-
/* @__PURE__ */
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", gap: 1, children: [
|
|
7271
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "[" }),
|
|
7272
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.primary, children: "esc" }),
|
|
7273
|
-
/* @__PURE__ */ jsx11(Text13, { color: COLORS.muted, children: "] back" })
|
|
7516
|
+
/* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 3, children: [
|
|
7517
|
+
/* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 1, children: [
|
|
7518
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "[" }),
|
|
7519
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.primary, children: "esc" }),
|
|
7520
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "] back" })
|
|
7274
7521
|
] }),
|
|
7275
|
-
/* @__PURE__ */
|
|
7276
|
-
/* @__PURE__ */
|
|
7277
|
-
/* @__PURE__ */
|
|
7278
|
-
/* @__PURE__ */
|
|
7279
|
-
/* @__PURE__ */
|
|
7522
|
+
/* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", gap: 1, children: [
|
|
7523
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "[" }),
|
|
7524
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.primary, children: "enter" }),
|
|
7525
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.muted, children: "]" }),
|
|
7526
|
+
/* @__PURE__ */ jsx12(Text14, { color: COLORS.success, bold: true, children: "start wizard" })
|
|
7280
7527
|
] })
|
|
7281
7528
|
] })
|
|
7282
7529
|
]
|
|
@@ -7285,17 +7532,17 @@ function LearnMore() {
|
|
|
7285
7532
|
}
|
|
7286
7533
|
|
|
7287
7534
|
// src/ui/Sidebar.tsx
|
|
7288
|
-
import { Box as
|
|
7535
|
+
import { Box as Box16, Text as Text17 } from "ink";
|
|
7289
7536
|
|
|
7290
7537
|
// src/ui/Steps.tsx
|
|
7291
|
-
import { Box as
|
|
7538
|
+
import { Box as Box14, Text as Text15 } from "ink";
|
|
7292
7539
|
import Spinner2 from "ink-spinner";
|
|
7293
|
-
import { jsx as
|
|
7540
|
+
import { jsx as jsx13, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
7294
7541
|
function Steps() {
|
|
7295
7542
|
const { steps } = useWizard();
|
|
7296
7543
|
const visibleSteps = steps.filter(isStepVisible);
|
|
7297
|
-
return /* @__PURE__ */
|
|
7298
|
-
s.status === "running" ? /* @__PURE__ */
|
|
7544
|
+
return /* @__PURE__ */ jsx13(Box14, { flexDirection: "column", gap: 1, children: visibleSteps.map((s) => /* @__PURE__ */ jsx13(Box14, { flexDirection: "column", children: /* @__PURE__ */ jsxs14(Text15, { color: COLORS.status[s.status], children: [
|
|
7545
|
+
s.status === "running" ? /* @__PURE__ */ jsx13(Spinner2, { type: "dots" }) : MARKER[s.status],
|
|
7299
7546
|
" ",
|
|
7300
7547
|
s.title
|
|
7301
7548
|
] }) }, s.id)) });
|
|
@@ -7304,27 +7551,27 @@ function CurrentStep() {
|
|
|
7304
7551
|
const { steps } = useWizard();
|
|
7305
7552
|
const currentStep = steps.filter(isStepVisible).find((s) => s.status === "running");
|
|
7306
7553
|
if (!currentStep) return null;
|
|
7307
|
-
return /* @__PURE__ */
|
|
7308
|
-
/* @__PURE__ */
|
|
7554
|
+
return /* @__PURE__ */ jsxs14(Text15, { color: COLORS.status.running, children: [
|
|
7555
|
+
/* @__PURE__ */ jsx13(Spinner2, { type: "dots" }),
|
|
7309
7556
|
" ",
|
|
7310
7557
|
` ${currentStep.title}`
|
|
7311
7558
|
] });
|
|
7312
7559
|
}
|
|
7313
7560
|
|
|
7314
7561
|
// src/ui/Progress.tsx
|
|
7315
|
-
import { Box as
|
|
7316
|
-
import { jsx as
|
|
7562
|
+
import { Box as Box15, Text as Text16 } from "ink";
|
|
7563
|
+
import { jsx as jsx14, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
7317
7564
|
function Progress() {
|
|
7318
7565
|
const { steps, currentStepIndex } = useWizard();
|
|
7319
7566
|
const visibleSteps = steps.filter(isStepVisible);
|
|
7320
7567
|
if (visibleSteps.length === 0) return null;
|
|
7321
7568
|
const visibleCountThroughCurrent = steps.slice(0, currentStepIndex + 1).filter(isStepVisible).length;
|
|
7322
7569
|
const activeStepNumber = Math.max(1, visibleCountThroughCurrent);
|
|
7323
|
-
return /* @__PURE__ */
|
|
7324
|
-
/* @__PURE__ */
|
|
7325
|
-
/* @__PURE__ */
|
|
7326
|
-
/* @__PURE__ */
|
|
7327
|
-
/* @__PURE__ */
|
|
7570
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "row", gap: 1, children: [
|
|
7571
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.muted, children: "STEP" }),
|
|
7572
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.strong, bold: true, children: activeStepNumber }),
|
|
7573
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.strong, bold: true, children: "/" }),
|
|
7574
|
+
/* @__PURE__ */ jsx14(Text16, { color: COLORS.strong, bold: true, children: visibleSteps.length })
|
|
7328
7575
|
] });
|
|
7329
7576
|
}
|
|
7330
7577
|
|
|
@@ -7335,10 +7582,10 @@ var sidebarCommands = [
|
|
|
7335
7582
|
];
|
|
7336
7583
|
|
|
7337
7584
|
// src/ui/Sidebar.tsx
|
|
7338
|
-
import { jsx as
|
|
7585
|
+
import { jsx as jsx15, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
7339
7586
|
function Sidebar() {
|
|
7340
|
-
return /* @__PURE__ */
|
|
7341
|
-
|
|
7587
|
+
return /* @__PURE__ */ jsxs16(
|
|
7588
|
+
Box16,
|
|
7342
7589
|
{
|
|
7343
7590
|
backgroundColor: "#14171E",
|
|
7344
7591
|
width: 30,
|
|
@@ -7347,16 +7594,16 @@ function Sidebar() {
|
|
|
7347
7594
|
flexDirection: "column",
|
|
7348
7595
|
justifyContent: "space-between",
|
|
7349
7596
|
children: [
|
|
7350
|
-
/* @__PURE__ */
|
|
7351
|
-
/* @__PURE__ */
|
|
7352
|
-
/* @__PURE__ */
|
|
7597
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", gap: 1, children: [
|
|
7598
|
+
/* @__PURE__ */ jsx15(Text17, { color: COLORS.muted, children: "PROGRESS" }),
|
|
7599
|
+
/* @__PURE__ */ jsx15(Steps, {})
|
|
7353
7600
|
] }),
|
|
7354
|
-
/* @__PURE__ */
|
|
7355
|
-
/* @__PURE__ */
|
|
7356
|
-
/* @__PURE__ */
|
|
7357
|
-
return /* @__PURE__ */
|
|
7358
|
-
/* @__PURE__ */
|
|
7359
|
-
/* @__PURE__ */
|
|
7601
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", gap: 1, children: [
|
|
7602
|
+
/* @__PURE__ */ jsx15(Progress, {}),
|
|
7603
|
+
/* @__PURE__ */ jsx15(Box16, { flexDirection: "column", children: sidebarCommands.map((c) => {
|
|
7604
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "row", gap: 1, children: [
|
|
7605
|
+
/* @__PURE__ */ jsx15(Text17, { color: COLORS.primary, children: `[${c.keyHint}]` }),
|
|
7606
|
+
/* @__PURE__ */ jsx15(Text17, { color: COLORS.muted, children: c.description })
|
|
7360
7607
|
] }, c.keyHint);
|
|
7361
7608
|
}) })
|
|
7362
7609
|
] })
|
|
@@ -7366,12 +7613,12 @@ function Sidebar() {
|
|
|
7366
7613
|
}
|
|
7367
7614
|
|
|
7368
7615
|
// src/ui/Ribbon.tsx
|
|
7369
|
-
import { Box as
|
|
7370
|
-
import { jsx as
|
|
7616
|
+
import { Box as Box17, Text as Text18 } from "ink";
|
|
7617
|
+
import { jsx as jsx16, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
7371
7618
|
function Ribbon() {
|
|
7372
7619
|
const firstCommand = sidebarCommands[0];
|
|
7373
|
-
return /* @__PURE__ */
|
|
7374
|
-
|
|
7620
|
+
return /* @__PURE__ */ jsxs17(
|
|
7621
|
+
Box17,
|
|
7375
7622
|
{
|
|
7376
7623
|
backgroundColor: "#14171E",
|
|
7377
7624
|
flexDirection: "row",
|
|
@@ -7379,11 +7626,11 @@ function Ribbon() {
|
|
|
7379
7626
|
paddingX: 2,
|
|
7380
7627
|
paddingY: 1,
|
|
7381
7628
|
children: [
|
|
7382
|
-
/* @__PURE__ */
|
|
7383
|
-
/* @__PURE__ */
|
|
7384
|
-
/* @__PURE__ */
|
|
7385
|
-
/* @__PURE__ */
|
|
7386
|
-
/* @__PURE__ */
|
|
7629
|
+
/* @__PURE__ */ jsx16(Progress, {}),
|
|
7630
|
+
/* @__PURE__ */ jsx16(CurrentStep, {}),
|
|
7631
|
+
/* @__PURE__ */ jsxs17(Box17, { flexDirection: "row", gap: 1, children: [
|
|
7632
|
+
/* @__PURE__ */ jsx16(Text18, { color: COLORS.primary, children: `[${firstCommand.keyHint}]` }),
|
|
7633
|
+
/* @__PURE__ */ jsx16(Text18, { color: COLORS.muted, children: firstCommand.description })
|
|
7387
7634
|
] })
|
|
7388
7635
|
]
|
|
7389
7636
|
}
|
|
@@ -7394,8 +7641,8 @@ function Ribbon() {
|
|
|
7394
7641
|
import { useState as useState12 } from "react";
|
|
7395
7642
|
|
|
7396
7643
|
// src/ui/Logs.tsx
|
|
7397
|
-
import { Box as
|
|
7398
|
-
import { jsx as
|
|
7644
|
+
import { Box as Box18, Text as Text19, useInput as useInput8 } from "ink";
|
|
7645
|
+
import { jsx as jsx17, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
7399
7646
|
var KIND_COLOR = {
|
|
7400
7647
|
tool: COLORS.primary,
|
|
7401
7648
|
prompt: COLORS.badge
|
|
@@ -7431,9 +7678,9 @@ function Logs() {
|
|
|
7431
7678
|
else if (input === "j" || key.downArrow) scroll.scrollBy(1);
|
|
7432
7679
|
});
|
|
7433
7680
|
const visible = logs.slice(scroll.offset, scroll.offset + scroll.capacity);
|
|
7434
|
-
return /* @__PURE__ */
|
|
7435
|
-
logs.length === 0 && /* @__PURE__ */
|
|
7436
|
-
/* @__PURE__ */
|
|
7681
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", paddingX: 4, paddingY: 2, flexGrow: 1, children: [
|
|
7682
|
+
logs.length === 0 && /* @__PURE__ */ jsx17(Text19, { color: COLORS.dim, children: "No logs yet." }),
|
|
7683
|
+
/* @__PURE__ */ jsx17(ScrollView, { scroll, children: visible.map((entry) => {
|
|
7437
7684
|
const timestamp = `[${formatTimestamp(entry.startedAt)}]`;
|
|
7438
7685
|
const durationText = entry.kind === "tool" && entry.durationMs !== void 0 ? `${entry.durationMs}ms` : "";
|
|
7439
7686
|
const rawPreview = rawInputText(entry.input);
|
|
@@ -7443,28 +7690,28 @@ function Logs() {
|
|
|
7443
7690
|
const name = truncate3(entry.name, budget);
|
|
7444
7691
|
budget -= name.length;
|
|
7445
7692
|
const preview = rawPreview ? truncate3(rawPreview, budget) : "";
|
|
7446
|
-
return /* @__PURE__ */
|
|
7447
|
-
/* @__PURE__ */
|
|
7448
|
-
/* @__PURE__ */
|
|
7449
|
-
preview && /* @__PURE__ */
|
|
7450
|
-
durationText && /* @__PURE__ */
|
|
7693
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "row", gap: ROW_GAP, children: [
|
|
7694
|
+
/* @__PURE__ */ jsx17(Text19, { color: COLORS.dim, children: timestamp }),
|
|
7695
|
+
/* @__PURE__ */ jsx17(Text19, { color: logNameColor(entry), wrap: "truncate", children: name }),
|
|
7696
|
+
preview && /* @__PURE__ */ jsx17(Text19, { color: COLORS.dim, wrap: "truncate", children: preview }),
|
|
7697
|
+
durationText && /* @__PURE__ */ jsx17(Text19, { color: COLORS.dim, children: durationText })
|
|
7451
7698
|
] }, entry.id);
|
|
7452
7699
|
}) }),
|
|
7453
|
-
/* @__PURE__ */
|
|
7454
|
-
/* @__PURE__ */
|
|
7455
|
-
/* @__PURE__ */
|
|
7700
|
+
/* @__PURE__ */ jsxs18(Text19, { children: [
|
|
7701
|
+
/* @__PURE__ */ jsx17(Text19, { color: COLORS.primary, children: "[j] [k]" }),
|
|
7702
|
+
/* @__PURE__ */ jsx17(Text19, { color: COLORS.dim, children: " scroll" })
|
|
7456
7703
|
] })
|
|
7457
7704
|
] });
|
|
7458
7705
|
}
|
|
7459
7706
|
|
|
7460
7707
|
// src/ui/Tips.tsx
|
|
7461
7708
|
import { useEffect as useEffect3, useRef as useRef4, useState as useState11 } from "react";
|
|
7462
|
-
import { Box as
|
|
7709
|
+
import { Box as Box20, Text as Text21 } from "ink";
|
|
7463
7710
|
import terminalLink from "terminal-link";
|
|
7464
7711
|
|
|
7465
7712
|
// src/ui/Code.tsx
|
|
7466
|
-
import { Box as
|
|
7467
|
-
import { jsx as
|
|
7713
|
+
import { Box as Box19, Text as Text20 } from "ink";
|
|
7714
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
7468
7715
|
var TOKEN_RE = /("(?:\\.|[^"\\])*"|\btrue\b|\bfalse\b|\bnull\b|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[{}[\]:,])/g;
|
|
7469
7716
|
function highlightJson(json) {
|
|
7470
7717
|
const parts = json.split(TOKEN_RE);
|
|
@@ -7473,22 +7720,22 @@ function highlightJson(json) {
|
|
|
7473
7720
|
if (part[0] === '"') {
|
|
7474
7721
|
const next = parts.slice(i + 1).find((p) => p.trim());
|
|
7475
7722
|
const isKey = next?.trimStart().startsWith(":");
|
|
7476
|
-
return /* @__PURE__ */
|
|
7723
|
+
return /* @__PURE__ */ jsx18(Text20, { color: isKey ? "cyan" : "green", children: part }, i);
|
|
7477
7724
|
}
|
|
7478
7725
|
if (part === "true" || part === "false" || part === "null") {
|
|
7479
|
-
return /* @__PURE__ */
|
|
7726
|
+
return /* @__PURE__ */ jsx18(Text20, { color: "magenta", children: part }, i);
|
|
7480
7727
|
}
|
|
7481
7728
|
if (/^-?\d/.test(part)) {
|
|
7482
|
-
return /* @__PURE__ */
|
|
7729
|
+
return /* @__PURE__ */ jsx18(Text20, { color: "yellow", children: part }, i);
|
|
7483
7730
|
}
|
|
7484
7731
|
if (/^[{}[\]:,]$/.test(part)) {
|
|
7485
|
-
return /* @__PURE__ */
|
|
7732
|
+
return /* @__PURE__ */ jsx18(Text20, { color: COLORS.dim, children: part }, i);
|
|
7486
7733
|
}
|
|
7487
|
-
return /* @__PURE__ */
|
|
7734
|
+
return /* @__PURE__ */ jsx18(Text20, { children: part }, i);
|
|
7488
7735
|
});
|
|
7489
7736
|
}
|
|
7490
7737
|
function Code({ children }) {
|
|
7491
|
-
return /* @__PURE__ */
|
|
7738
|
+
return /* @__PURE__ */ jsx18(Box19, { children: /* @__PURE__ */ jsx18(Text20, { children: highlightJson(children) }) });
|
|
7492
7739
|
}
|
|
7493
7740
|
|
|
7494
7741
|
// src/ui/copy/tips.ts
|
|
@@ -7702,26 +7949,26 @@ function tipsByIds(ids) {
|
|
|
7702
7949
|
}
|
|
7703
7950
|
|
|
7704
7951
|
// src/ui/Tips.tsx
|
|
7705
|
-
import { jsx as
|
|
7952
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
7706
7953
|
var TICK_MS = 16;
|
|
7707
7954
|
var CHUNK_HOLD_MS = 2e3;
|
|
7708
7955
|
var HOLD_MS = 12e3;
|
|
7709
7956
|
function TipTitle({ children }) {
|
|
7710
|
-
return /* @__PURE__ */
|
|
7711
|
-
/* @__PURE__ */
|
|
7712
|
-
/* @__PURE__ */
|
|
7957
|
+
return /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
7958
|
+
/* @__PURE__ */ jsx19(Text21, { color: "cyan", children: "\u2726" }),
|
|
7959
|
+
/* @__PURE__ */ jsx19(Text21, { color: "white", bold: true, children })
|
|
7713
7960
|
] });
|
|
7714
7961
|
}
|
|
7715
7962
|
function InlineSegment({ segment }) {
|
|
7716
7963
|
switch (segment.type) {
|
|
7717
7964
|
case "highlight":
|
|
7718
|
-
return /* @__PURE__ */
|
|
7965
|
+
return /* @__PURE__ */ jsx19(Text21, { color: COLORS.success, children: segment.value });
|
|
7719
7966
|
case "link":
|
|
7720
|
-
return /* @__PURE__ */
|
|
7967
|
+
return /* @__PURE__ */ jsx19(Text21, { color: "cyan", underline: true, children: segment.href ? terminalLink(segment.value, segment.href) : segment.value });
|
|
7721
7968
|
case "codeword":
|
|
7722
|
-
return /* @__PURE__ */
|
|
7969
|
+
return /* @__PURE__ */ jsx19(Text21, { color: COLORS.highlight.fg, backgroundColor: COLORS.highlight.bg, children: segment.value });
|
|
7723
7970
|
default:
|
|
7724
|
-
return /* @__PURE__ */
|
|
7971
|
+
return /* @__PURE__ */ jsx19(Text21, { color: COLORS.muted, children: segment.value });
|
|
7725
7972
|
}
|
|
7726
7973
|
}
|
|
7727
7974
|
function TipContent({
|
|
@@ -7755,10 +8002,10 @@ function TipContent({
|
|
|
7755
8002
|
blocks.push({ type: "inline", segments: [segment] });
|
|
7756
8003
|
}
|
|
7757
8004
|
}
|
|
7758
|
-
return /* @__PURE__ */
|
|
7759
|
-
(block, i) => block.type === "code" ? /* @__PURE__ */
|
|
8005
|
+
return /* @__PURE__ */ jsx19(Box20, { flexDirection: "column", marginLeft: 2, gap: 1, children: blocks.map(
|
|
8006
|
+
(block, i) => block.type === "code" ? /* @__PURE__ */ jsx19(Code, { children: block.segment.value }, i) : /* @__PURE__ */ jsx19(Text21, { children: block.segments.map((segment, j) => /* @__PURE__ */ jsxs19(Text21, { children: [
|
|
7760
8007
|
j > 0 && " ",
|
|
7761
|
-
/* @__PURE__ */
|
|
8008
|
+
/* @__PURE__ */ jsx19(InlineSegment, { segment })
|
|
7762
8009
|
] }, j)) }, i)
|
|
7763
8010
|
) });
|
|
7764
8011
|
}
|
|
@@ -7835,14 +8082,51 @@ function Tips({
|
|
|
7835
8082
|
if (!tip) return null;
|
|
7836
8083
|
const titleRevealed = tip.title.slice(0, revealed);
|
|
7837
8084
|
const contentRevealed = Math.max(0, revealed - tip.title.length);
|
|
7838
|
-
return /* @__PURE__ */
|
|
7839
|
-
/* @__PURE__ */
|
|
7840
|
-
/* @__PURE__ */
|
|
8085
|
+
return /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", marginBottom: 1, gap: 1, children: [
|
|
8086
|
+
/* @__PURE__ */ jsx19(TipTitle, { children: titleRevealed }),
|
|
8087
|
+
/* @__PURE__ */ jsx19(TipContent, { chunks: tip.chunks, revealed: contentRevealed })
|
|
7841
8088
|
] });
|
|
7842
8089
|
}
|
|
7843
8090
|
|
|
8091
|
+
// src/ui/useRepaintOnResize.ts
|
|
8092
|
+
import { useEffect as useEffect4 } from "react";
|
|
8093
|
+
import { useApp, useStdout } from "ink";
|
|
8094
|
+
var BEGIN_SYNC = "\x1B[?2026h";
|
|
8095
|
+
var END_SYNC = "\x1B[?2026l";
|
|
8096
|
+
var CLEAR_SCREEN_AND_SCROLLBACK = "\x1B[2J\x1B[3J\x1B[H";
|
|
8097
|
+
function useRepaintOnResize(debounceMs = 100) {
|
|
8098
|
+
const { stdout } = useStdout();
|
|
8099
|
+
const { suspendTerminal } = useApp();
|
|
8100
|
+
useEffect4(() => {
|
|
8101
|
+
if (!stdout.isTTY) return;
|
|
8102
|
+
let timer;
|
|
8103
|
+
let repaint = Promise.resolve();
|
|
8104
|
+
const onResize = () => {
|
|
8105
|
+
clearTimeout(timer);
|
|
8106
|
+
timer = setTimeout(() => {
|
|
8107
|
+
repaint = repaint.then(async () => {
|
|
8108
|
+
stdout.write(BEGIN_SYNC);
|
|
8109
|
+
try {
|
|
8110
|
+
await suspendTerminal(() => {
|
|
8111
|
+
stdout.write(CLEAR_SCREEN_AND_SCROLLBACK);
|
|
8112
|
+
});
|
|
8113
|
+
} finally {
|
|
8114
|
+
stdout.write(END_SYNC);
|
|
8115
|
+
}
|
|
8116
|
+
}).catch(() => {
|
|
8117
|
+
});
|
|
8118
|
+
}, debounceMs);
|
|
8119
|
+
};
|
|
8120
|
+
stdout.on("resize", onResize);
|
|
8121
|
+
return () => {
|
|
8122
|
+
clearTimeout(timer);
|
|
8123
|
+
stdout.off("resize", onResize);
|
|
8124
|
+
};
|
|
8125
|
+
}, [stdout, suspendTerminal, debounceMs]);
|
|
8126
|
+
}
|
|
8127
|
+
|
|
7844
8128
|
// src/ui/App.tsx
|
|
7845
|
-
import { jsx as
|
|
8129
|
+
import { jsx as jsx20, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
7846
8130
|
function App() {
|
|
7847
8131
|
const {
|
|
7848
8132
|
phase,
|
|
@@ -7857,8 +8141,10 @@ function App() {
|
|
|
7857
8141
|
loadingMessage,
|
|
7858
8142
|
review: review2
|
|
7859
8143
|
} = useWizard();
|
|
7860
|
-
const { exit } =
|
|
7861
|
-
const { columns, rows } =
|
|
8144
|
+
const { exit } = useApp2();
|
|
8145
|
+
const { columns, rows } = useWindowSize8();
|
|
8146
|
+
useRepaintOnResize();
|
|
8147
|
+
const compactRun = isCompactTerminal(columns, rows);
|
|
7862
8148
|
const [showLogs, setShowLogs] = useState12(false);
|
|
7863
8149
|
const [tipState, setTipState] = useState12("idle");
|
|
7864
8150
|
const finished = phase === "done" || phase === "error";
|
|
@@ -7869,10 +8155,10 @@ function App() {
|
|
|
7869
8155
|
const isAwaitingUserInput = phase === "awaitingInput" && !!inputReq;
|
|
7870
8156
|
const isCommandApprovalPrompt = isAwaitingUserInput && inputReq?.promptType === "commandApproval";
|
|
7871
8157
|
const promptPending = isAwaitingUserInput && !isCommandApprovalPrompt;
|
|
7872
|
-
const holdForTip = stepHasTips && promptPending && tipState === "revealing";
|
|
7873
|
-
const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" && !loadingMessage && !settingUpAppId || isCommandApprovalPrompt);
|
|
8158
|
+
const holdForTip = !compactRun && stepHasTips && promptPending && tipState === "revealing";
|
|
8159
|
+
const showTips = !compactRun && stepHasTips && (phase === "running" && currentStep?.status === "running" && !loadingMessage && !settingUpAppId || isCommandApprovalPrompt);
|
|
7874
8160
|
const showNoticesInMain = !stepHasTips;
|
|
7875
|
-
const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
|
|
8161
|
+
const showNotices = !compactRun && (!isAwaitingUserInput || holdForTip) && !review2;
|
|
7876
8162
|
useInput9(
|
|
7877
8163
|
(_input, key) => {
|
|
7878
8164
|
if (key.return) {
|
|
@@ -7905,32 +8191,31 @@ function App() {
|
|
|
7905
8191
|
}
|
|
7906
8192
|
});
|
|
7907
8193
|
const mainWindowVisible = phase === "authenticating" || phase === "preflight" || phase === "running" || phase === "awaitingInput" || phase === "error" || phase === "done";
|
|
7908
|
-
const flexDirection = columns >
|
|
8194
|
+
const flexDirection = columns > SIDEBAR_MIN_COLUMNS ? "row" : "column";
|
|
7909
8195
|
const showSidebar = flexDirection === "row";
|
|
7910
|
-
const scrollsPastViewport = phase === "idle" && homeScreen === "learnMore";
|
|
7911
8196
|
return (
|
|
7912
8197
|
/* Clamped to exactly the viewport: a taller frame makes Ink clear and repaint
|
|
7913
|
-
the whole screen, and the scrolling throws off its cursor arithmetic
|
|
7914
|
-
|
|
7915
|
-
/* @__PURE__ */
|
|
7916
|
-
|
|
8198
|
+
the whole screen, and the scrolling throws off its cursor arithmetic.
|
|
8199
|
+
Flicker and leftover rows. */
|
|
8200
|
+
/* @__PURE__ */ jsxs20(
|
|
8201
|
+
Box21,
|
|
7917
8202
|
{
|
|
7918
8203
|
backgroundColor: COLORS.bg.main,
|
|
7919
8204
|
flexDirection: "row",
|
|
7920
8205
|
width: columns,
|
|
7921
|
-
height:
|
|
7922
|
-
overflow:
|
|
8206
|
+
height: rows,
|
|
8207
|
+
overflow: "hidden",
|
|
7923
8208
|
children: [
|
|
7924
|
-
mainWindowVisible && /* @__PURE__ */
|
|
7925
|
-
|
|
8209
|
+
mainWindowVisible && /* @__PURE__ */ jsxs20(
|
|
8210
|
+
Box21,
|
|
7926
8211
|
{
|
|
7927
8212
|
flexDirection,
|
|
7928
8213
|
width: "100%",
|
|
7929
8214
|
maxHeight: rows,
|
|
7930
8215
|
justifyContent: "space-between",
|
|
7931
8216
|
children: [
|
|
7932
|
-
showLogs ? /* @__PURE__ */
|
|
7933
|
-
|
|
8217
|
+
showLogs ? /* @__PURE__ */ jsx20(Logs, {}) : /* @__PURE__ */ jsxs20(
|
|
8218
|
+
Box21,
|
|
7934
8219
|
{
|
|
7935
8220
|
flexDirection: "column",
|
|
7936
8221
|
paddingX: 4,
|
|
@@ -7939,35 +8224,35 @@ function App() {
|
|
|
7939
8224
|
flexGrow: 1,
|
|
7940
8225
|
gap: 1,
|
|
7941
8226
|
children: [
|
|
7942
|
-
/* @__PURE__ */
|
|
7943
|
-
phase === "preflight" && !user && /* @__PURE__ */
|
|
7944
|
-
/* @__PURE__ */
|
|
8227
|
+
/* @__PURE__ */ jsxs20(Box21, { flexGrow: 2, flexDirection: "column", children: [
|
|
8228
|
+
phase === "preflight" && !user && /* @__PURE__ */ jsx20(Box21, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs20(Text22, { color: COLORS.strong, bold: true, children: [
|
|
8229
|
+
/* @__PURE__ */ jsx20(Spinner3, { type: "dots" }),
|
|
7945
8230
|
" Signing in to Algolia"
|
|
7946
8231
|
] }) }),
|
|
7947
|
-
phase === "preflight" && user && /* @__PURE__ */
|
|
7948
|
-
/* @__PURE__ */
|
|
8232
|
+
phase === "preflight" && user && /* @__PURE__ */ jsx20(Box21, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs20(Text22, { color: COLORS.strong, bold: true, children: [
|
|
8233
|
+
/* @__PURE__ */ jsx20(Spinner3, { type: "dots" }),
|
|
7949
8234
|
" Getting things ready"
|
|
7950
8235
|
] }) }),
|
|
7951
|
-
phase === "authenticating" && /* @__PURE__ */
|
|
7952
|
-
/* @__PURE__ */
|
|
7953
|
-
/* @__PURE__ */
|
|
8236
|
+
phase === "authenticating" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", marginBottom: 1, children: [
|
|
8237
|
+
/* @__PURE__ */ jsxs20(Text22, { color: COLORS.strong, bold: true, children: [
|
|
8238
|
+
/* @__PURE__ */ jsx20(Spinner3, { type: "dots" }),
|
|
7954
8239
|
" Signing in to Algolia"
|
|
7955
8240
|
] }),
|
|
7956
|
-
/* @__PURE__ */
|
|
8241
|
+
/* @__PURE__ */ jsx20(Text22, { color: COLORS.muted, children: "A browser window will open \u2014 complete sign-in there." })
|
|
7957
8242
|
] }),
|
|
7958
|
-
settingUpAppId && /* @__PURE__ */
|
|
7959
|
-
/* @__PURE__ */
|
|
8243
|
+
settingUpAppId && /* @__PURE__ */ jsx20(Box21, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs20(Text22, { color: COLORS.strong, bold: true, children: [
|
|
8244
|
+
/* @__PURE__ */ jsx20(Spinner3, { type: "dots" }),
|
|
7960
8245
|
" Setting up Wizard using app",
|
|
7961
8246
|
" ",
|
|
7962
8247
|
settingUpAppId
|
|
7963
8248
|
] }) }),
|
|
7964
|
-
phase === "running" && !settingUpAppId && loadingMessage && /* @__PURE__ */
|
|
7965
|
-
/* @__PURE__ */
|
|
8249
|
+
phase === "running" && !settingUpAppId && loadingMessage && /* @__PURE__ */ jsx20(Box21, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs20(Text22, { color: COLORS.strong, bold: true, children: [
|
|
8250
|
+
/* @__PURE__ */ jsx20(Spinner3, { type: "dots" }),
|
|
7966
8251
|
" ",
|
|
7967
8252
|
loadingMessage
|
|
7968
8253
|
] }) }),
|
|
7969
|
-
/* @__PURE__ */
|
|
7970
|
-
showTips && currentStep && /* @__PURE__ */
|
|
8254
|
+
/* @__PURE__ */ jsx20(CliOutput, {}),
|
|
8255
|
+
showTips && currentStep && /* @__PURE__ */ jsx20(
|
|
7971
8256
|
Tips,
|
|
7972
8257
|
{
|
|
7973
8258
|
stepId: currentStep.id,
|
|
@@ -7975,24 +8260,24 @@ function App() {
|
|
|
7975
8260
|
onRevealStateChange: setTipState
|
|
7976
8261
|
}
|
|
7977
8262
|
),
|
|
7978
|
-
showNoticesInMain && showNotices && /* @__PURE__ */
|
|
7979
|
-
/* @__PURE__ */
|
|
7980
|
-
!showTips && /* @__PURE__ */
|
|
7981
|
-
phase === "error" && error && /* @__PURE__ */
|
|
8263
|
+
showNoticesInMain && showNotices && /* @__PURE__ */ jsx20(Notices, { showAll: true, border: false }),
|
|
8264
|
+
/* @__PURE__ */ jsx20(Review, {}),
|
|
8265
|
+
!showTips && /* @__PURE__ */ jsx20(PromptInput, {}),
|
|
8266
|
+
phase === "error" && error && /* @__PURE__ */ jsx20(Box21, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text22, { color: COLORS.status.error, children: [
|
|
7982
8267
|
"\u2716 ",
|
|
7983
8268
|
error
|
|
7984
8269
|
] }) })
|
|
7985
8270
|
] }),
|
|
7986
|
-
!showNoticesInMain && showNotices && /* @__PURE__ */
|
|
7987
|
-
showTips && !holdForTip && /* @__PURE__ */
|
|
8271
|
+
!showNoticesInMain && showNotices && /* @__PURE__ */ jsx20(Notices, {}),
|
|
8272
|
+
showTips && !holdForTip && /* @__PURE__ */ jsx20(PromptInput, {})
|
|
7988
8273
|
]
|
|
7989
8274
|
}
|
|
7990
8275
|
),
|
|
7991
|
-
showSidebar ? /* @__PURE__ */
|
|
8276
|
+
showSidebar ? /* @__PURE__ */ jsx20(Sidebar, {}) : /* @__PURE__ */ jsx20(Ribbon, {})
|
|
7992
8277
|
]
|
|
7993
8278
|
}
|
|
7994
8279
|
),
|
|
7995
|
-
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */
|
|
8280
|
+
phase === "idle" && (homeScreen === "learnMore" ? /* @__PURE__ */ jsx20(LearnMore, {}) : /* @__PURE__ */ jsx20(Welcome, {}))
|
|
7996
8281
|
]
|
|
7997
8282
|
}
|
|
7998
8283
|
)
|
|
@@ -8228,49 +8513,10 @@ async function resetProjectState() {
|
|
|
8228
8513
|
return { dir, removed: targets };
|
|
8229
8514
|
}
|
|
8230
8515
|
|
|
8231
|
-
// src/lib/terminalSize.ts
|
|
8232
|
-
var MIN_ROWS = 30;
|
|
8233
|
-
var MIN_COLUMNS = 100;
|
|
8234
|
-
async function requestTerminalSize(stdout = process.stdout, {
|
|
8235
|
-
rows = MIN_ROWS,
|
|
8236
|
-
columns = MIN_COLUMNS,
|
|
8237
|
-
timeoutMs = 150,
|
|
8238
|
-
settleMs = 120
|
|
8239
|
-
} = {}) {
|
|
8240
|
-
if (!stdout.isTTY) return;
|
|
8241
|
-
const currentRows = stdout.rows ?? 0;
|
|
8242
|
-
const currentColumns = stdout.columns ?? 0;
|
|
8243
|
-
if (currentRows >= rows && currentColumns >= columns) return;
|
|
8244
|
-
stdout.write(
|
|
8245
|
-
`\x1B[8;${Math.max(currentRows, rows)};${Math.max(currentColumns, columns)}t`
|
|
8246
|
-
);
|
|
8247
|
-
const resized = await waitForResize(stdout, timeoutMs);
|
|
8248
|
-
if (!resized) return;
|
|
8249
|
-
await delay(settleMs);
|
|
8250
|
-
stdout.write("\x1B[2J\x1B[H");
|
|
8251
|
-
}
|
|
8252
|
-
function waitForResize(stdout, timeoutMs) {
|
|
8253
|
-
return new Promise((resolve5) => {
|
|
8254
|
-
const finish = (didResize) => () => {
|
|
8255
|
-
clearTimeout(timer);
|
|
8256
|
-
stdout.off("resize", onResize);
|
|
8257
|
-
resolve5(didResize);
|
|
8258
|
-
};
|
|
8259
|
-
const onResize = finish(true);
|
|
8260
|
-
const timer = setTimeout(finish(false), timeoutMs);
|
|
8261
|
-
stdout.once("resize", onResize);
|
|
8262
|
-
});
|
|
8263
|
-
}
|
|
8264
|
-
function delay(ms) {
|
|
8265
|
-
return new Promise((resolve5) => {
|
|
8266
|
-
setTimeout(resolve5, ms);
|
|
8267
|
-
});
|
|
8268
|
-
}
|
|
8269
|
-
|
|
8270
8516
|
// package.json with { type: 'json' }
|
|
8271
8517
|
var package_default2 = {
|
|
8272
8518
|
name: "@algolia/wizard",
|
|
8273
|
-
version: "0.
|
|
8519
|
+
version: "0.77.0",
|
|
8274
8520
|
description: "Magically implement Algolia functionality in your codebase",
|
|
8275
8521
|
type: "module",
|
|
8276
8522
|
engines: {
|
|
@@ -8377,7 +8623,7 @@ async function checkVersion() {
|
|
|
8377
8623
|
}
|
|
8378
8624
|
|
|
8379
8625
|
// src/main.tsx
|
|
8380
|
-
import { jsx as
|
|
8626
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
8381
8627
|
var FAILURE_EXIT_CODE = 1;
|
|
8382
8628
|
async function exitProcessWithError(store, instance, message) {
|
|
8383
8629
|
store.setError(message);
|
|
@@ -8440,7 +8686,7 @@ ${formatStepList(workflow)}`);
|
|
|
8440
8686
|
async function run(opts) {
|
|
8441
8687
|
const { workflow, skipResumePrompt } = opts;
|
|
8442
8688
|
const store = useWizard.getState();
|
|
8443
|
-
const instance = render(/* @__PURE__ */
|
|
8689
|
+
const instance = render(/* @__PURE__ */ jsx21(App, {}), { incrementalRendering: true });
|
|
8444
8690
|
await store.waitForStart();
|
|
8445
8691
|
store.syncSteps(
|
|
8446
8692
|
workflow.steps.map((s) => ({
|