@tolkbot/cli 0.1.0 → 0.2.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/index.js +823 -758
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5787,7 +5787,7 @@ var require_out4 = __commonJS({
|
|
|
5787
5787
|
import { Command as Command6 } from "commander";
|
|
5788
5788
|
|
|
5789
5789
|
// package.json
|
|
5790
|
-
var version = "0.
|
|
5790
|
+
var version = "0.2.0";
|
|
5791
5791
|
|
|
5792
5792
|
// src/commands/auth/index.ts
|
|
5793
5793
|
import { Command } from "commander";
|
|
@@ -6001,6 +6001,26 @@ function isTokenExpired(resolved, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
|
6001
6001
|
if (resolved.expiresAt === null) return false;
|
|
6002
6002
|
return resolved.expiresAt <= nowSeconds + EXPIRY_SKEW_SECONDS;
|
|
6003
6003
|
}
|
|
6004
|
+
var EXPIRY_WARNING_SECONDS = 3 * 24 * 60 * 60;
|
|
6005
|
+
function expiresInSeconds(resolved, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
6006
|
+
if (resolved.expiresAt === null) return null;
|
|
6007
|
+
return resolved.expiresAt - nowSeconds;
|
|
6008
|
+
}
|
|
6009
|
+
function describeTimeLeft(seconds) {
|
|
6010
|
+
const plural2 = (n, unit) => `in ${n} ${unit}${n === 1 ? "" : "s"}`;
|
|
6011
|
+
if (seconds >= 2 * 24 * 60 * 60) {
|
|
6012
|
+
return plural2(Math.floor(seconds / 86400), "day");
|
|
6013
|
+
}
|
|
6014
|
+
if (seconds >= 2 * 60 * 60) {
|
|
6015
|
+
return plural2(Math.floor(seconds / 3600), "hour");
|
|
6016
|
+
}
|
|
6017
|
+
return plural2(Math.max(0, Math.floor(seconds / 60)), "minute");
|
|
6018
|
+
}
|
|
6019
|
+
function expiryWarning(resolved, nowSeconds = Math.floor(Date.now() / 1e3)) {
|
|
6020
|
+
const left = expiresInSeconds(resolved, nowSeconds);
|
|
6021
|
+
if (left === null || left > EXPIRY_WARNING_SECONDS) return null;
|
|
6022
|
+
return `\u26A0 Your token (from ${describeTokenSource(resolved.source)}) expires ${describeTimeLeft(left)}. ${reauthHint(resolved.source)}`;
|
|
6023
|
+
}
|
|
6004
6024
|
function describeTokenSource(source) {
|
|
6005
6025
|
switch (source) {
|
|
6006
6026
|
case "flag":
|
|
@@ -6242,8 +6262,8 @@ var env = createEnv({
|
|
|
6242
6262
|
function requireConvexUrl() {
|
|
6243
6263
|
if (!env.CONVEX_URL) {
|
|
6244
6264
|
throw new CliError(
|
|
6245
|
-
"CONVEX_URL is not set, so the CLI cannot reach the
|
|
6246
|
-
"Set CONVEX_URL to your
|
|
6265
|
+
"CONVEX_URL is not set, so the CLI cannot reach the TolkBot backend.",
|
|
6266
|
+
"Set CONVEX_URL to your TolkBot deployment URL."
|
|
6247
6267
|
);
|
|
6248
6268
|
}
|
|
6249
6269
|
return env.CONVEX_URL;
|
|
@@ -6355,6 +6375,10 @@ async function listenOnFreePort(server, ports) {
|
|
|
6355
6375
|
"Free one of these ports and try again."
|
|
6356
6376
|
);
|
|
6357
6377
|
}
|
|
6378
|
+
function validityNote(expiresAt) {
|
|
6379
|
+
const until = expiresAt === null ? "" : `, valid until ${new Date(expiresAt * 1e3).toLocaleString()}`;
|
|
6380
|
+
return `It is a session for you${until}. For CI, copy it into $${TOKEN_ENV_VAR}. If it leaks, run 'tolkbot auth logout --all'.`;
|
|
6381
|
+
}
|
|
6358
6382
|
function LoginUI({ state }) {
|
|
6359
6383
|
if (state.type === "opening") {
|
|
6360
6384
|
return /* @__PURE__ */ jsxs(Box, { children: [
|
|
@@ -6390,11 +6414,7 @@ function LoginUI({ state }) {
|
|
|
6390
6414
|
"Token saved to ",
|
|
6391
6415
|
getTokenPath()
|
|
6392
6416
|
] }) }),
|
|
6393
|
-
/* @__PURE__ */
|
|
6394
|
-
"For CI, copy it into $",
|
|
6395
|
-
TOKEN_ENV_VAR,
|
|
6396
|
-
" instead."
|
|
6397
|
-
] })
|
|
6417
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: validityNote(state.expiresAt) })
|
|
6398
6418
|
] });
|
|
6399
6419
|
}
|
|
6400
6420
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
@@ -6402,13 +6422,43 @@ function LoginUI({ state }) {
|
|
|
6402
6422
|
/* @__PURE__ */ jsx(Text, { dimColor: true, children: state.message })
|
|
6403
6423
|
] });
|
|
6404
6424
|
}
|
|
6425
|
+
async function runPlainLogin(opts, verificationCode) {
|
|
6426
|
+
let server = null;
|
|
6427
|
+
try {
|
|
6428
|
+
server = await startCallbackServer(verificationCode);
|
|
6429
|
+
const authUrl = loginUrl(server.port, verificationCode);
|
|
6430
|
+
if (!opts.noBrowser) await open(authUrl);
|
|
6431
|
+
console.log(`Open this URL in a browser to log in: ${authUrl}`);
|
|
6432
|
+
console.log(`Verification code: ${verificationCode}`);
|
|
6433
|
+
console.log(
|
|
6434
|
+
"The browser must reach this machine on localhost; forward the port if it runs elsewhere."
|
|
6435
|
+
);
|
|
6436
|
+
console.log("Waiting for authentication\u2026");
|
|
6437
|
+
const token = await server.token;
|
|
6438
|
+
await saveToken(token);
|
|
6439
|
+
console.log(`Authenticated. Token saved to ${getTokenPath()}.`);
|
|
6440
|
+
console.log(validityNote(decodeTokenExpiry(token)));
|
|
6441
|
+
} catch (error62) {
|
|
6442
|
+
server?.close();
|
|
6443
|
+
console.error(
|
|
6444
|
+
`Authentication failed: ${error62 instanceof Error ? error62.message : String(error62)}`
|
|
6445
|
+
);
|
|
6446
|
+
return exitAfterFlush(1);
|
|
6447
|
+
}
|
|
6448
|
+
}
|
|
6449
|
+
function loginUrl(port, verificationCode) {
|
|
6450
|
+
return `${env.TOLKBOT_WEB_URL}/cli/login/confirm?port=${port}&code=${verificationCode}`;
|
|
6451
|
+
}
|
|
6405
6452
|
async function runAuthLogin(opts = {}) {
|
|
6406
6453
|
const verificationCode = generateVerificationCode();
|
|
6454
|
+
if (!process.stdout.isTTY) {
|
|
6455
|
+
return runPlainLogin(opts, verificationCode);
|
|
6456
|
+
}
|
|
6407
6457
|
let { unmount } = render(/* @__PURE__ */ jsx(LoginUI, { state: { type: "opening" } }));
|
|
6408
6458
|
let server = null;
|
|
6409
6459
|
try {
|
|
6410
6460
|
server = await startCallbackServer(verificationCode);
|
|
6411
|
-
const authUrl =
|
|
6461
|
+
const authUrl = loginUrl(server.port, verificationCode);
|
|
6412
6462
|
if (!opts.noBrowser) {
|
|
6413
6463
|
await open(authUrl);
|
|
6414
6464
|
}
|
|
@@ -6430,7 +6480,14 @@ async function runAuthLogin(opts = {}) {
|
|
|
6430
6480
|
const token = await server.token;
|
|
6431
6481
|
await saveToken(token);
|
|
6432
6482
|
unmount();
|
|
6433
|
-
const successUi = render(
|
|
6483
|
+
const successUi = render(
|
|
6484
|
+
/* @__PURE__ */ jsx(
|
|
6485
|
+
LoginUI,
|
|
6486
|
+
{
|
|
6487
|
+
state: { type: "success", expiresAt: decodeTokenExpiry(token) }
|
|
6488
|
+
}
|
|
6489
|
+
)
|
|
6490
|
+
);
|
|
6434
6491
|
unmount = successUi.unmount;
|
|
6435
6492
|
await successUi.waitUntilExit();
|
|
6436
6493
|
} catch (error62) {
|
|
@@ -6452,9 +6509,107 @@ async function runAuthLogin(opts = {}) {
|
|
|
6452
6509
|
}
|
|
6453
6510
|
}
|
|
6454
6511
|
|
|
6512
|
+
// ../backend/convex/_generated/api.js
|
|
6513
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
6514
|
+
var api = anyApi;
|
|
6515
|
+
var components = componentsGeneric();
|
|
6516
|
+
|
|
6455
6517
|
// src/commands/auth/logout.tsx
|
|
6456
6518
|
import { Box as Box2, render as render2, Text as Text2 } from "ink";
|
|
6457
6519
|
|
|
6520
|
+
// ../shared/src/auth/index.ts
|
|
6521
|
+
var CLI_SIGNED_OUT = "CLI_SIGNED_OUT";
|
|
6522
|
+
function findCliSignedOut(error62) {
|
|
6523
|
+
return readPayload(error62) ?? readPayload(readProperty(error62, "data"));
|
|
6524
|
+
}
|
|
6525
|
+
function readPayload(candidate) {
|
|
6526
|
+
const code = readProperty(candidate, "code");
|
|
6527
|
+
const message = readProperty(candidate, "message");
|
|
6528
|
+
const signedOutAt = readProperty(candidate, "signedOutAt");
|
|
6529
|
+
if (code !== CLI_SIGNED_OUT || typeof message !== "string" || typeof signedOutAt !== "number") {
|
|
6530
|
+
return null;
|
|
6531
|
+
}
|
|
6532
|
+
return { code: CLI_SIGNED_OUT, message, signedOutAt };
|
|
6533
|
+
}
|
|
6534
|
+
function readProperty(candidate, key) {
|
|
6535
|
+
if (typeof candidate !== "object" || candidate === null) {
|
|
6536
|
+
return void 0;
|
|
6537
|
+
}
|
|
6538
|
+
return candidate[key];
|
|
6539
|
+
}
|
|
6540
|
+
|
|
6541
|
+
// src/lib/convex-client.ts
|
|
6542
|
+
import { ConvexHttpClient } from "convex/browser";
|
|
6543
|
+
var BACKEND_METHODS = /* @__PURE__ */ new Set(["query", "mutation", "action"]);
|
|
6544
|
+
var client2 = null;
|
|
6545
|
+
function getConvexClient() {
|
|
6546
|
+
client2 ??= new ConvexHttpClient(requireConvexUrl());
|
|
6547
|
+
return client2;
|
|
6548
|
+
}
|
|
6549
|
+
function translateAuthError(error62, resolved) {
|
|
6550
|
+
const signedOut = findCliSignedOut(error62);
|
|
6551
|
+
if (signedOut) {
|
|
6552
|
+
const at = new Date(signedOut.signedOutAt).toLocaleString();
|
|
6553
|
+
return new AuthError(
|
|
6554
|
+
`These credentials were signed out on ${at} (from ${describeTokenSource(resolved.source)}).`,
|
|
6555
|
+
reauthHint(resolved.source)
|
|
6556
|
+
);
|
|
6557
|
+
}
|
|
6558
|
+
if (!isUnauthenticatedError(error62)) return error62;
|
|
6559
|
+
return new AuthError(
|
|
6560
|
+
`Your token was rejected (from ${describeTokenSource(resolved.source)}). It may be revoked, malformed, or issued for a different deployment.`,
|
|
6561
|
+
reauthHint(resolved.source)
|
|
6562
|
+
);
|
|
6563
|
+
}
|
|
6564
|
+
function withAuthErrors(target, resolved) {
|
|
6565
|
+
return new Proxy(target, {
|
|
6566
|
+
get(obj, prop, receiver) {
|
|
6567
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
6568
|
+
if (typeof value !== "function" || !BACKEND_METHODS.has(String(prop))) {
|
|
6569
|
+
return value;
|
|
6570
|
+
}
|
|
6571
|
+
const method = value;
|
|
6572
|
+
return (...args) => {
|
|
6573
|
+
const result = method.apply(obj, args);
|
|
6574
|
+
if (result instanceof Promise) {
|
|
6575
|
+
return result.catch((error62) => {
|
|
6576
|
+
throw translateAuthError(error62, resolved);
|
|
6577
|
+
});
|
|
6578
|
+
}
|
|
6579
|
+
return result;
|
|
6580
|
+
};
|
|
6581
|
+
}
|
|
6582
|
+
});
|
|
6583
|
+
}
|
|
6584
|
+
var warnedAboutExpiry = false;
|
|
6585
|
+
function warnOnceIfExpiringSoon(resolved) {
|
|
6586
|
+
if (warnedAboutExpiry) return;
|
|
6587
|
+
const warning = expiryWarning(resolved);
|
|
6588
|
+
if (!warning) return;
|
|
6589
|
+
warnedAboutExpiry = true;
|
|
6590
|
+
console.error(warning);
|
|
6591
|
+
}
|
|
6592
|
+
async function getAuthenticatedConvexClient() {
|
|
6593
|
+
const convexClient = getConvexClient();
|
|
6594
|
+
const resolved = await resolveToken();
|
|
6595
|
+
if (!resolved) {
|
|
6596
|
+
throw new AuthError(
|
|
6597
|
+
"Not authenticated.",
|
|
6598
|
+
`Run 'tolkbot auth login', or set $${TOKEN_ENV_VAR} for CI and headless environments.`
|
|
6599
|
+
);
|
|
6600
|
+
}
|
|
6601
|
+
if (isTokenExpired(resolved)) {
|
|
6602
|
+
const expiredAt = resolved.expiresAt ? new Date(resolved.expiresAt * 1e3).toLocaleString() : "an unknown time";
|
|
6603
|
+
throw new AuthError(
|
|
6604
|
+
`Your token expired at ${expiredAt} (from ${describeTokenSource(resolved.source)}).`,
|
|
6605
|
+
reauthHint(resolved.source)
|
|
6606
|
+
);
|
|
6607
|
+
}
|
|
6608
|
+
warnOnceIfExpiringSoon(resolved);
|
|
6609
|
+
convexClient.setAuth(resolved.token);
|
|
6610
|
+
return withAuthErrors(convexClient, resolved);
|
|
6611
|
+
}
|
|
6612
|
+
|
|
6458
6613
|
// src/utils/exit.ts
|
|
6459
6614
|
var CliExit = class extends Error {
|
|
6460
6615
|
constructor(code) {
|
|
@@ -6494,52 +6649,88 @@ function jsonResult(data, exitCode) {
|
|
|
6494
6649
|
|
|
6495
6650
|
// src/commands/auth/logout.tsx
|
|
6496
6651
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
6652
|
+
function formatSeconds(seconds) {
|
|
6653
|
+
return new Date(seconds * 1e3).toLocaleString();
|
|
6654
|
+
}
|
|
6655
|
+
function stillValidNote(expiresAt) {
|
|
6656
|
+
const until = expiresAt === null ? "until it expires" : `until ${formatSeconds(expiresAt)}`;
|
|
6657
|
+
return `The token stays valid anywhere else it was copied ${until}. Run 'tolkbot auth logout --all' to sign out every CLI session.`;
|
|
6658
|
+
}
|
|
6497
6659
|
function LogoutUI({ state }) {
|
|
6498
|
-
if (state.type === "
|
|
6660
|
+
if (state.type === "error") {
|
|
6499
6661
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
6500
|
-
/* @__PURE__ */
|
|
6501
|
-
|
|
6502
|
-
/* @__PURE__ */ jsx2(Text2, { children: state.hadToken ? " Successfully logged out!" : " Already logged out." })
|
|
6503
|
-
] }),
|
|
6504
|
-
state.envTokenStillSet && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
6505
|
-
/* @__PURE__ */ jsxs2(Text2, { color: "yellow", children: [
|
|
6506
|
-
"\u26A0 $",
|
|
6507
|
-
TOKEN_ENV_VAR,
|
|
6508
|
-
" is still set in your environment"
|
|
6509
|
-
] }),
|
|
6510
|
-
/* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
6511
|
-
"It takes precedence over ",
|
|
6512
|
-
getTokenPath(),
|
|
6513
|
-
", so the CLI remains authenticated. Unset it to fully log out."
|
|
6514
|
-
] })
|
|
6515
|
-
] })
|
|
6662
|
+
/* @__PURE__ */ jsx2(Text2, { color: "red", children: "\u2717 Logout failed" }),
|
|
6663
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: state.message })
|
|
6516
6664
|
] });
|
|
6517
6665
|
}
|
|
6666
|
+
const signedOutAll = state.signedOutAt !== null;
|
|
6667
|
+
let headline = state.hadToken ? " Successfully logged out!" : " Already logged out.";
|
|
6668
|
+
if (signedOutAll) headline = " Signed out every CLI session.";
|
|
6518
6669
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
6519
|
-
/* @__PURE__ */
|
|
6520
|
-
|
|
6670
|
+
/* @__PURE__ */ jsxs2(Box2, { children: [
|
|
6671
|
+
/* @__PURE__ */ jsx2(Text2, { color: "green", children: "\u2713" }),
|
|
6672
|
+
/* @__PURE__ */ jsx2(Text2, { children: headline })
|
|
6673
|
+
] }),
|
|
6674
|
+
signedOutAll && /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
6675
|
+
"Every CLI token issued before",
|
|
6676
|
+
" ",
|
|
6677
|
+
new Date(state.signedOutAt ?? 0).toLocaleString(),
|
|
6678
|
+
" is refused, on every machine. Your dashboard session is not affected."
|
|
6679
|
+
] }),
|
|
6680
|
+
!signedOutAll && state.hadToken && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: stillValidNote(state.removedTokenExpiresAt) }),
|
|
6681
|
+
state.envTokenStillSet && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
|
|
6682
|
+
/* @__PURE__ */ jsxs2(Text2, { color: "yellow", children: [
|
|
6683
|
+
"\u26A0 $",
|
|
6684
|
+
TOKEN_ENV_VAR,
|
|
6685
|
+
" is still set in your environment"
|
|
6686
|
+
] }),
|
|
6687
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: signedOutAll ? "It was signed out too, so remove it." : `It takes precedence over ${getTokenPath()}, so the CLI remains authenticated. Unset it to fully log out.` })
|
|
6688
|
+
] })
|
|
6521
6689
|
] });
|
|
6522
6690
|
}
|
|
6691
|
+
async function signOutAllCliSessions() {
|
|
6692
|
+
const client3 = await getAuthenticatedConvexClient();
|
|
6693
|
+
const { signedOutAt } = await client3.action(
|
|
6694
|
+
api.actions.cliSessions.signOutAll,
|
|
6695
|
+
{}
|
|
6696
|
+
);
|
|
6697
|
+
return signedOutAt;
|
|
6698
|
+
}
|
|
6523
6699
|
async function runAuthLogout(opts = {}) {
|
|
6524
6700
|
try {
|
|
6525
|
-
const
|
|
6701
|
+
const signedOutAt = opts.all ? await signOutAllCliSessions() : null;
|
|
6702
|
+
const stored = await loadToken();
|
|
6703
|
+
const hadToken = stored !== null;
|
|
6704
|
+
const removedTokenExpiresAt = stored ? decodeTokenExpiry(stored) : null;
|
|
6526
6705
|
await deleteToken();
|
|
6527
6706
|
const envTokenStillSet = hasEnvToken();
|
|
6528
6707
|
if (opts.json) {
|
|
6708
|
+
const warnings = [
|
|
6709
|
+
...signedOutAt === null && hadToken ? [stillValidNote(removedTokenExpiresAt)] : [],
|
|
6710
|
+
...envTokenStillSet ? [
|
|
6711
|
+
signedOutAt === null ? `$${TOKEN_ENV_VAR} is still set and takes precedence over ${getTokenPath()}.` : `$${TOKEN_ENV_VAR} is still set; it was signed out too, so remove it.`
|
|
6712
|
+
] : []
|
|
6713
|
+
];
|
|
6529
6714
|
jsonSuccess({
|
|
6530
6715
|
loggedOut: true,
|
|
6531
6716
|
hadStoredToken: hadToken,
|
|
6532
6717
|
envTokenStillSet,
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
} : {}
|
|
6718
|
+
signedOutAllCliSessions: signedOutAt !== null,
|
|
6719
|
+
...signedOutAt !== null ? { signedOutAt: new Date(signedOutAt).toISOString() } : {},
|
|
6720
|
+
...warnings.length > 0 ? { warning: warnings.join(" ") } : {}
|
|
6536
6721
|
});
|
|
6537
6722
|
}
|
|
6538
6723
|
const ui = render2(
|
|
6539
6724
|
/* @__PURE__ */ jsx2(
|
|
6540
6725
|
LogoutUI,
|
|
6541
6726
|
{
|
|
6542
|
-
state: {
|
|
6727
|
+
state: {
|
|
6728
|
+
type: "success",
|
|
6729
|
+
hadToken,
|
|
6730
|
+
envTokenStillSet,
|
|
6731
|
+
removedTokenExpiresAt,
|
|
6732
|
+
signedOutAt
|
|
6733
|
+
}
|
|
6543
6734
|
}
|
|
6544
6735
|
)
|
|
6545
6736
|
);
|
|
@@ -6557,76 +6748,17 @@ async function runAuthLogout(opts = {}) {
|
|
|
6557
6748
|
|
|
6558
6749
|
// src/commands/auth/whoami.tsx
|
|
6559
6750
|
import { Spinner as Spinner2 } from "@inkjs/ui";
|
|
6560
|
-
|
|
6561
|
-
// ../backend/convex/_generated/api.js
|
|
6562
|
-
import { anyApi, componentsGeneric } from "convex/server";
|
|
6563
|
-
var api = anyApi;
|
|
6564
|
-
var components = componentsGeneric();
|
|
6565
|
-
|
|
6566
|
-
// src/commands/auth/whoami.tsx
|
|
6567
6751
|
import { Box as Box3, render as render3, Text as Text3 } from "ink";
|
|
6568
|
-
|
|
6569
|
-
// src/lib/convex-client.ts
|
|
6570
|
-
import { ConvexHttpClient } from "convex/browser";
|
|
6571
|
-
var BACKEND_METHODS = /* @__PURE__ */ new Set(["query", "mutation", "action"]);
|
|
6572
|
-
var client2 = null;
|
|
6573
|
-
function getConvexClient() {
|
|
6574
|
-
client2 ??= new ConvexHttpClient(requireConvexUrl());
|
|
6575
|
-
return client2;
|
|
6576
|
-
}
|
|
6577
|
-
function translateAuthError(error62, resolved) {
|
|
6578
|
-
if (!isUnauthenticatedError(error62)) return error62;
|
|
6579
|
-
return new AuthError(
|
|
6580
|
-
`Your token was rejected (from ${describeTokenSource(resolved.source)}). It may be revoked, malformed, or issued for a different deployment.`,
|
|
6581
|
-
reauthHint(resolved.source)
|
|
6582
|
-
);
|
|
6583
|
-
}
|
|
6584
|
-
function withAuthErrors(target, resolved) {
|
|
6585
|
-
return new Proxy(target, {
|
|
6586
|
-
get(obj, prop, receiver) {
|
|
6587
|
-
const value = Reflect.get(obj, prop, receiver);
|
|
6588
|
-
if (typeof value !== "function" || !BACKEND_METHODS.has(String(prop))) {
|
|
6589
|
-
return value;
|
|
6590
|
-
}
|
|
6591
|
-
const method = value;
|
|
6592
|
-
return (...args) => {
|
|
6593
|
-
const result = method.apply(obj, args);
|
|
6594
|
-
if (result instanceof Promise) {
|
|
6595
|
-
return result.catch((error62) => {
|
|
6596
|
-
throw translateAuthError(error62, resolved);
|
|
6597
|
-
});
|
|
6598
|
-
}
|
|
6599
|
-
return result;
|
|
6600
|
-
};
|
|
6601
|
-
}
|
|
6602
|
-
});
|
|
6603
|
-
}
|
|
6604
|
-
async function getAuthenticatedConvexClient() {
|
|
6605
|
-
const convexClient = getConvexClient();
|
|
6606
|
-
const resolved = await resolveToken();
|
|
6607
|
-
if (!resolved) {
|
|
6608
|
-
throw new AuthError(
|
|
6609
|
-
"Not authenticated.",
|
|
6610
|
-
`Run 'tolkbot auth login', or set $${TOKEN_ENV_VAR} for CI and headless environments.`
|
|
6611
|
-
);
|
|
6612
|
-
}
|
|
6613
|
-
if (isTokenExpired(resolved)) {
|
|
6614
|
-
const expiredAt = resolved.expiresAt ? new Date(resolved.expiresAt * 1e3).toLocaleString() : "an unknown time";
|
|
6615
|
-
throw new AuthError(
|
|
6616
|
-
`Your token expired at ${expiredAt} (from ${describeTokenSource(resolved.source)}).`,
|
|
6617
|
-
reauthHint(resolved.source)
|
|
6618
|
-
);
|
|
6619
|
-
}
|
|
6620
|
-
convexClient.setAuth(resolved.token);
|
|
6621
|
-
return withAuthErrors(convexClient, resolved);
|
|
6622
|
-
}
|
|
6623
|
-
|
|
6624
|
-
// src/commands/auth/whoami.tsx
|
|
6625
6752
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
6626
6753
|
function formatExpiry(expiresAt) {
|
|
6627
6754
|
if (expiresAt === null) return "unknown";
|
|
6628
6755
|
return new Date(expiresAt * 1e3).toLocaleString();
|
|
6629
6756
|
}
|
|
6757
|
+
function describeExpiry(resolved) {
|
|
6758
|
+
const left = expiresInSeconds(resolved);
|
|
6759
|
+
if (left === null) return "Expiry unknown";
|
|
6760
|
+
return `Expires ${describeTimeLeft(left)} (${formatExpiry(resolved.expiresAt)})`;
|
|
6761
|
+
}
|
|
6630
6762
|
function WhoamiUI({ state }) {
|
|
6631
6763
|
if (state.type === "loading") {
|
|
6632
6764
|
return /* @__PURE__ */ jsxs3(Box3, { children: [
|
|
@@ -6651,8 +6783,7 @@ function WhoamiUI({ state }) {
|
|
|
6651
6783
|
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2502 " }),
|
|
6652
6784
|
/* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
6653
6785
|
" ",
|
|
6654
|
-
|
|
6655
|
-
formatExpiry(state.resolved.expiresAt)
|
|
6786
|
+
describeExpiry(state.resolved)
|
|
6656
6787
|
] })
|
|
6657
6788
|
] }),
|
|
6658
6789
|
/* @__PURE__ */ jsxs3(Box3, { children: [
|
|
@@ -6731,7 +6862,8 @@ async function runAuthWhoami(opts = {}) {
|
|
|
6731
6862
|
email: user.email,
|
|
6732
6863
|
tokenSource: resolved.source,
|
|
6733
6864
|
tokenPath: getTokenPath(),
|
|
6734
|
-
expiresAt: resolved.expiresAt ? new Date(resolved.expiresAt * 1e3).toISOString() : null
|
|
6865
|
+
expiresAt: resolved.expiresAt ? new Date(resolved.expiresAt * 1e3).toISOString() : null,
|
|
6866
|
+
expiresInSeconds: expiresInSeconds(resolved)
|
|
6735
6867
|
});
|
|
6736
6868
|
}
|
|
6737
6869
|
return renderAndExit(
|
|
@@ -6750,9 +6882,9 @@ async function runAuthWhoami(opts = {}) {
|
|
|
6750
6882
|
|
|
6751
6883
|
// src/commands/auth/index.ts
|
|
6752
6884
|
var authCommand = new Command("auth").description(
|
|
6753
|
-
"Authenticate with
|
|
6885
|
+
"Authenticate with TolkBot"
|
|
6754
6886
|
);
|
|
6755
|
-
authCommand.command("login").description("Log in to
|
|
6887
|
+
authCommand.command("login").description("Log in to TolkBot").option(
|
|
6756
6888
|
"--no-browser",
|
|
6757
6889
|
"Print the login URL instead of opening a browser (for headless hosts)"
|
|
6758
6890
|
).action(async (opts) => {
|
|
@@ -6763,8 +6895,14 @@ authCommand.command("login").description("Log in to Tolkbot").option(
|
|
|
6763
6895
|
const parsed = validateOrExit(schema, opts);
|
|
6764
6896
|
await runAuthLogin({ noBrowser: !parsed.browser });
|
|
6765
6897
|
});
|
|
6766
|
-
authCommand.command("logout").description("Log out of
|
|
6767
|
-
|
|
6898
|
+
authCommand.command("logout").description("Log out of TolkBot").option(
|
|
6899
|
+
"--all",
|
|
6900
|
+
"Sign out every CLI session on every machine, then remove the local token"
|
|
6901
|
+
).option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
6902
|
+
const schema = z2.object({
|
|
6903
|
+
json: z2.boolean().optional(),
|
|
6904
|
+
all: z2.boolean().optional()
|
|
6905
|
+
});
|
|
6768
6906
|
const parsed = validateOrExit(schema, opts);
|
|
6769
6907
|
await runAuthLogout(parsed);
|
|
6770
6908
|
});
|
|
@@ -26990,8 +27128,11 @@ var DEFAULT_BEHAVIORAL_SETTINGS = {
|
|
|
26990
27128
|
tonePreset: "formal",
|
|
26991
27129
|
toneInstructions: "Use a formal, professional tone. Avoid slang.",
|
|
26992
27130
|
workflow: {
|
|
27131
|
+
// What a project that never stored the field resolves to: every
|
|
27132
|
+
// project created before DUO-536. Those keep it off, so a project
|
|
27133
|
+
// nobody switched on does not start opening pull requests because a
|
|
27134
|
+
// default moved. New projects store `NEW_PROJECT_AUTO_CREATE_PR`.
|
|
26993
27135
|
autoCreatePR: false,
|
|
26994
|
-
// Opt-in feature - users must enable in dashboard
|
|
26995
27136
|
branchPattern: "tolkbot/{{projectName}}-i18n-{{lng}}",
|
|
26996
27137
|
baseBranches: void 0,
|
|
26997
27138
|
prTargetBranch: void 0,
|
|
@@ -27606,210 +27747,13 @@ glossaryCommand.command("remove").description("Remove a glossary term").required
|
|
|
27606
27747
|
await runGlossaryRemove(parsed);
|
|
27607
27748
|
});
|
|
27608
27749
|
|
|
27609
|
-
// src/commands/help.tsx
|
|
27610
|
-
import { Box as Box10, render as render9, Text as Text10 } from "ink";
|
|
27611
|
-
|
|
27612
|
-
// src/components/logo.tsx
|
|
27613
|
-
import { Box as Box9, Text as Text9 } from "ink";
|
|
27614
|
-
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
27615
|
-
var logoText = `
|
|
27616
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
27617
|
-
\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D
|
|
27618
|
-
\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
27619
|
-
\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
27620
|
-
\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551
|
|
27621
|
-
`;
|
|
27622
|
-
function Logo() {
|
|
27623
|
-
return /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: logoText }) });
|
|
27624
|
-
}
|
|
27625
|
-
var logo_default = Logo;
|
|
27626
|
-
|
|
27627
|
-
// src/commands/help.tsx
|
|
27628
|
-
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
27629
|
-
function HelpUI() {
|
|
27630
|
-
return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", paddingY: 1, children: [
|
|
27631
|
-
/* @__PURE__ */ jsx10(logo_default, {}),
|
|
27632
|
-
/* @__PURE__ */ jsx10(Box10, { children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "Localization workflow for your repo" }) }),
|
|
27633
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
27634
|
-
/* @__PURE__ */ jsx10(Text10, { bold: true, children: "Usage:" }),
|
|
27635
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27636
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27637
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot [command] [options]" })
|
|
27638
|
-
] })
|
|
27639
|
-
] }),
|
|
27640
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
27641
|
-
/* @__PURE__ */ jsx10(Text10, { bold: true, children: "Commands:" }),
|
|
27642
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, marginLeft: 2, flexDirection: "column", children: [
|
|
27643
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27644
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "init" }),
|
|
27645
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27646
|
-
" ",
|
|
27647
|
-
" "
|
|
27648
|
-
] }),
|
|
27649
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Initialize Tolkbot in the current repo" })
|
|
27650
|
-
] }),
|
|
27651
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, children: [
|
|
27652
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "auth" }),
|
|
27653
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27654
|
-
" ",
|
|
27655
|
-
" "
|
|
27656
|
-
] }),
|
|
27657
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Authenticate with Tolkbot" })
|
|
27658
|
-
] }),
|
|
27659
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27660
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27661
|
-
"\u2022 login ",
|
|
27662
|
-
" "
|
|
27663
|
-
] }),
|
|
27664
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Log in to Tolkbot" })
|
|
27665
|
-
] }),
|
|
27666
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27667
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27668
|
-
"\u2022 logout ",
|
|
27669
|
-
" "
|
|
27670
|
-
] }),
|
|
27671
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Log out of Tolkbot" })
|
|
27672
|
-
] }),
|
|
27673
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27674
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27675
|
-
"\u2022 whoami ",
|
|
27676
|
-
" "
|
|
27677
|
-
] }),
|
|
27678
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Show the current authenticated user" })
|
|
27679
|
-
] }),
|
|
27680
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, children: [
|
|
27681
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "validate" }),
|
|
27682
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27683
|
-
" ",
|
|
27684
|
-
" "
|
|
27685
|
-
] }),
|
|
27686
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Validate translation files and configuration" })
|
|
27687
|
-
] }),
|
|
27688
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, children: [
|
|
27689
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "translate" }),
|
|
27690
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27691
|
-
" ",
|
|
27692
|
-
" "
|
|
27693
|
-
] }),
|
|
27694
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Translate with Tolkbot" })
|
|
27695
|
-
] }),
|
|
27696
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27697
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27698
|
-
"\u2022 plan ",
|
|
27699
|
-
" "
|
|
27700
|
-
] }),
|
|
27701
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Generate translation plan" })
|
|
27702
|
-
] }),
|
|
27703
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27704
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27705
|
-
"\u2022 run ",
|
|
27706
|
-
" "
|
|
27707
|
-
] }),
|
|
27708
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Run translation job" })
|
|
27709
|
-
] }),
|
|
27710
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27711
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27712
|
-
"\u2022 apply ",
|
|
27713
|
-
" "
|
|
27714
|
-
] }),
|
|
27715
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Apply translation job results" })
|
|
27716
|
-
] }),
|
|
27717
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27718
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27719
|
-
"\u2022 status ",
|
|
27720
|
-
" "
|
|
27721
|
-
] }),
|
|
27722
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Check status of translation job" })
|
|
27723
|
-
] }),
|
|
27724
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, children: [
|
|
27725
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27726
|
-
"\u2022 cancel ",
|
|
27727
|
-
" "
|
|
27728
|
-
] }),
|
|
27729
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Cancel translation job" })
|
|
27730
|
-
] }),
|
|
27731
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, children: [
|
|
27732
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "telemetry" }),
|
|
27733
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27734
|
-
" ",
|
|
27735
|
-
" "
|
|
27736
|
-
] }),
|
|
27737
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Show or change anonymous usage reporting (status, on, off)" })
|
|
27738
|
-
] }),
|
|
27739
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, children: [
|
|
27740
|
-
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "help" }),
|
|
27741
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27742
|
-
" ",
|
|
27743
|
-
" "
|
|
27744
|
-
] }),
|
|
27745
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Show this help message" })
|
|
27746
|
-
] })
|
|
27747
|
-
] })
|
|
27748
|
-
] }),
|
|
27749
|
-
/* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "Telemetry: one event per command with its name, outcome and duration; never file paths or content. Opt out with `tolkbot telemetry off` or TOLKBOT_TELEMETRY=0." }) }),
|
|
27750
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
27751
|
-
/* @__PURE__ */ jsx10(Text10, { bold: true, children: "Options:" }),
|
|
27752
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, flexDirection: "column", children: [
|
|
27753
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27754
|
-
/* @__PURE__ */ jsx10(Text10, { color: "yellow", children: "-h, --help" }),
|
|
27755
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27756
|
-
" ",
|
|
27757
|
-
" "
|
|
27758
|
-
] }),
|
|
27759
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Show help for a command" })
|
|
27760
|
-
] }),
|
|
27761
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27762
|
-
/* @__PURE__ */ jsx10(Text10, { color: "yellow", children: "-v, --version" }),
|
|
27763
|
-
/* @__PURE__ */ jsxs9(Text10, { dimColor: true, children: [
|
|
27764
|
-
" ",
|
|
27765
|
-
" "
|
|
27766
|
-
] }),
|
|
27767
|
-
/* @__PURE__ */ jsx10(Text10, { children: "Show version number" })
|
|
27768
|
-
] })
|
|
27769
|
-
] })
|
|
27770
|
-
] }),
|
|
27771
|
-
/* @__PURE__ */ jsxs9(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
27772
|
-
/* @__PURE__ */ jsx10(Text10, { bold: true, children: "Examples:" }),
|
|
27773
|
-
/* @__PURE__ */ jsxs9(Box10, { marginLeft: 2, flexDirection: "column", children: [
|
|
27774
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27775
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27776
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot init" })
|
|
27777
|
-
] }),
|
|
27778
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27779
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27780
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot auth login" })
|
|
27781
|
-
] }),
|
|
27782
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27783
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27784
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot validate" })
|
|
27785
|
-
] }),
|
|
27786
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27787
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27788
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot translate plan --src en --dst es" })
|
|
27789
|
-
] }),
|
|
27790
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27791
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27792
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot translate run --dst es" })
|
|
27793
|
-
] }),
|
|
27794
|
-
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
27795
|
-
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "$ " }),
|
|
27796
|
-
/* @__PURE__ */ jsx10(Text10, { children: "tolkbot translate apply --job-id <id>" })
|
|
27797
|
-
] })
|
|
27798
|
-
] })
|
|
27799
|
-
] }),
|
|
27800
|
-
/* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "For more info on a specific command, use: tolkbot [command] --help" }) })
|
|
27801
|
-
] });
|
|
27802
|
-
}
|
|
27803
|
-
async function runHelp() {
|
|
27804
|
-
const { waitUntilExit } = render9(/* @__PURE__ */ jsx10(HelpUI, {}));
|
|
27805
|
-
await waitUntilExit();
|
|
27806
|
-
}
|
|
27807
|
-
|
|
27808
27750
|
// src/commands/init/index.tsx
|
|
27809
|
-
import { Box as
|
|
27751
|
+
import { Box as Box10, render as render9, Text as Text10 } from "ink";
|
|
27810
27752
|
|
|
27811
27753
|
// src/commands/init/core.ts
|
|
27812
27754
|
import { execSync as execSync2 } from "child_process";
|
|
27755
|
+
var DETECTION_TIMEOUT_MS = 3 * 6e4;
|
|
27756
|
+
var DETECTION_POLL_MS = 1e3;
|
|
27813
27757
|
function getRecommendedFramework(projectType) {
|
|
27814
27758
|
const map2 = {
|
|
27815
27759
|
"next-app": "next-intl",
|
|
@@ -27898,53 +27842,100 @@ async function linkRepository(cwd, plan) {
|
|
|
27898
27842
|
}
|
|
27899
27843
|
);
|
|
27900
27844
|
const existing = existingProjects[0];
|
|
27845
|
+
let projectId;
|
|
27846
|
+
let createdProject = false;
|
|
27901
27847
|
if (existing) {
|
|
27902
|
-
|
|
27903
|
-
|
|
27904
|
-
|
|
27905
|
-
|
|
27906
|
-
|
|
27907
|
-
|
|
27908
|
-
|
|
27909
|
-
|
|
27848
|
+
projectId = existing._id;
|
|
27849
|
+
} else {
|
|
27850
|
+
const [baseLanguage2] = assertSupportedLocales(
|
|
27851
|
+
[plan.baseLanguage],
|
|
27852
|
+
"base locale"
|
|
27853
|
+
);
|
|
27854
|
+
const targetLanguages = assertSupportedLocales(
|
|
27855
|
+
plan.targetLanguages,
|
|
27856
|
+
"target locale(s)"
|
|
27857
|
+
);
|
|
27858
|
+
if (!baseLanguage2) {
|
|
27859
|
+
throw new CliError("Could not resolve a base locale.");
|
|
27860
|
+
}
|
|
27861
|
+
const created = await convexClient.mutation(
|
|
27862
|
+
api.projects.createWithInitialization,
|
|
27863
|
+
{
|
|
27864
|
+
name,
|
|
27865
|
+
organizationId: repository.organizationId,
|
|
27866
|
+
repositoryId: repository._id,
|
|
27867
|
+
subpath: "",
|
|
27868
|
+
baseLanguage: baseLanguage2,
|
|
27869
|
+
targetLanguages,
|
|
27870
|
+
sourcePattern: "",
|
|
27871
|
+
outputPattern: "",
|
|
27872
|
+
useOrgSettings: true,
|
|
27873
|
+
hasPatternDetection: false
|
|
27874
|
+
}
|
|
27875
|
+
);
|
|
27876
|
+
projectId = created.projectId;
|
|
27877
|
+
createdProject = true;
|
|
27910
27878
|
}
|
|
27911
|
-
const
|
|
27912
|
-
|
|
27913
|
-
"base locale"
|
|
27914
|
-
);
|
|
27915
|
-
const targetLanguages = assertSupportedLocales(
|
|
27916
|
-
plan.targetLanguages,
|
|
27917
|
-
"target locale(s)"
|
|
27879
|
+
const project = await waitForDetection(
|
|
27880
|
+
() => convexClient.query(api.projects.getProjectForCli, { projectId })
|
|
27918
27881
|
);
|
|
27919
|
-
|
|
27920
|
-
throw new CliError("Could not resolve a base locale.");
|
|
27921
|
-
}
|
|
27922
|
-
const projectId = await convexClient.mutation(api.projects.create, {
|
|
27923
|
-
name,
|
|
27924
|
-
organizationId: repository.organizationId,
|
|
27925
|
-
repositoryId: repository._id,
|
|
27926
|
-
subpath: "",
|
|
27927
|
-
baseLanguage: baseLanguage2,
|
|
27928
|
-
targetLanguages,
|
|
27929
|
-
sourcePattern: "",
|
|
27930
|
-
outputPattern: "",
|
|
27931
|
-
useOrgSettings: true
|
|
27932
|
-
});
|
|
27882
|
+
requireSourcePattern(project, `${owner}/${name}`);
|
|
27933
27883
|
return {
|
|
27934
27884
|
projectId,
|
|
27935
27885
|
repositoryId: repository._id,
|
|
27936
27886
|
organizationId: repository.organizationId,
|
|
27937
27887
|
owner,
|
|
27938
27888
|
name,
|
|
27939
|
-
createdProject
|
|
27940
|
-
|
|
27889
|
+
createdProject,
|
|
27890
|
+
baseLanguage: project.baseLanguage,
|
|
27891
|
+
targetLanguages: project.targetLanguages,
|
|
27892
|
+
sourcePattern: project.sourcePattern
|
|
27893
|
+
};
|
|
27894
|
+
}
|
|
27895
|
+
function isDetecting(project) {
|
|
27896
|
+
return project.initializationStatus === "pending" || project.initializationStatus === "initializing";
|
|
27897
|
+
}
|
|
27898
|
+
async function waitForDetection(read, opts = {}) {
|
|
27899
|
+
const timeoutMs = opts.timeoutMs ?? DETECTION_TIMEOUT_MS;
|
|
27900
|
+
const pollMs = opts.pollMs ?? DETECTION_POLL_MS;
|
|
27901
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
27902
|
+
const now = opts.now ?? Date.now;
|
|
27903
|
+
const deadline = now() + timeoutMs;
|
|
27904
|
+
for (; ; ) {
|
|
27905
|
+
const project = await read();
|
|
27906
|
+
if (!project) {
|
|
27907
|
+
throw new CliError(
|
|
27908
|
+
"The project disappeared while TolkBot was detecting its files.",
|
|
27909
|
+
"Run 'tolkbot init' again."
|
|
27910
|
+
);
|
|
27911
|
+
}
|
|
27912
|
+
if (!isDetecting(project)) return project;
|
|
27913
|
+
if (now() >= deadline) {
|
|
27914
|
+
throw new CliError(
|
|
27915
|
+
`TolkBot is still detecting the project's translation files after ${Math.round(timeoutMs / 1e3)} seconds.`,
|
|
27916
|
+
"Run 'tolkbot init' again in a minute; it picks up the same project."
|
|
27917
|
+
);
|
|
27918
|
+
}
|
|
27919
|
+
await sleep(pollMs);
|
|
27920
|
+
}
|
|
27921
|
+
}
|
|
27922
|
+
function patternSettingsUrl(slug) {
|
|
27923
|
+
return `${env.TOLKBOT_WEB_URL}/projects/${slug}/settings/languages`;
|
|
27924
|
+
}
|
|
27925
|
+
function requireSourcePattern(project, repository) {
|
|
27926
|
+
if (project.sourcePattern.trim() !== "") return;
|
|
27927
|
+
const reason = project.initializationStatus === "failed" && project.initializationError ? ` Detection failed: ${project.initializationError}` : "";
|
|
27928
|
+
throw new CliError(
|
|
27929
|
+
`TolkBot found no translation files in ${repository}.${reason}`,
|
|
27930
|
+
`Set the file pattern in the project's settings at ${patternSettingsUrl(project.slug)}, then run 'tolkbot init' again.`
|
|
27931
|
+
);
|
|
27941
27932
|
}
|
|
27942
27933
|
|
|
27943
27934
|
// src/commands/init/wizard.tsx
|
|
27944
27935
|
import * as React from "react";
|
|
27945
27936
|
import { Select, Spinner as Spinner8, TextInput } from "@inkjs/ui";
|
|
27946
|
-
import { Box as
|
|
27947
|
-
import { jsx as
|
|
27937
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
27938
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
27948
27939
|
function friendlyFramework(f) {
|
|
27949
27940
|
const map2 = {
|
|
27950
27941
|
"next-intl": "Next.js with next-intl",
|
|
@@ -28006,6 +27997,9 @@ function InitWizard({
|
|
|
28006
27997
|
});
|
|
28007
27998
|
setSetupData((prev) => ({
|
|
28008
27999
|
...prev,
|
|
28000
|
+
// What detection settled on, for the next-step hint.
|
|
28001
|
+
baseLanguage: result.baseLanguage,
|
|
28002
|
+
targetLanguages: result.targetLanguages,
|
|
28009
28003
|
projectId: result.projectId,
|
|
28010
28004
|
repositoryId: result.repositoryId,
|
|
28011
28005
|
owner: result.owner,
|
|
@@ -28071,30 +28065,30 @@ function InitWizard({
|
|
|
28071
28065
|
}
|
|
28072
28066
|
}, [step, error62, setupData.projectId, onFailure]);
|
|
28073
28067
|
if (step === "detecting") {
|
|
28074
|
-
return /* @__PURE__ */
|
|
28075
|
-
/* @__PURE__ */
|
|
28076
|
-
/* @__PURE__ */
|
|
28077
|
-
/* @__PURE__ */
|
|
28068
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28069
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
28070
|
+
/* @__PURE__ */ jsx9(Spinner8, {}),
|
|
28071
|
+
/* @__PURE__ */ jsx9(Text9, { children: " Detecting project setup..." })
|
|
28078
28072
|
] }),
|
|
28079
|
-
/* @__PURE__ */
|
|
28073
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28080
28074
|
"Project: ",
|
|
28081
28075
|
friendlyProjectType(detected.projectType)
|
|
28082
28076
|
] }) }),
|
|
28083
|
-
detected.framework && /* @__PURE__ */
|
|
28077
|
+
detected.framework && /* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28084
28078
|
"Framework: ",
|
|
28085
28079
|
friendlyFramework(detected.framework)
|
|
28086
28080
|
] }) })
|
|
28087
28081
|
] });
|
|
28088
28082
|
}
|
|
28089
28083
|
if (step === "setupChoice") {
|
|
28090
|
-
return /* @__PURE__ */
|
|
28091
|
-
/* @__PURE__ */
|
|
28092
|
-
/* @__PURE__ */
|
|
28084
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28085
|
+
/* @__PURE__ */ jsx9(Text9, { children: "\u26A0\uFE0F No i18n library detected" }),
|
|
28086
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28093
28087
|
"Detected: ",
|
|
28094
28088
|
friendlyProjectType(detected.projectType)
|
|
28095
28089
|
] }) }),
|
|
28096
|
-
/* @__PURE__ */
|
|
28097
|
-
/* @__PURE__ */
|
|
28090
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { children: "Would you like to set up internationalization?" }) }),
|
|
28091
|
+
/* @__PURE__ */ jsx9(
|
|
28098
28092
|
Select,
|
|
28099
28093
|
{
|
|
28100
28094
|
options: [
|
|
@@ -28120,9 +28114,9 @@ function InitWizard({
|
|
|
28120
28114
|
] });
|
|
28121
28115
|
}
|
|
28122
28116
|
if (step === "frameworkSelect") {
|
|
28123
|
-
return /* @__PURE__ */
|
|
28124
|
-
/* @__PURE__ */
|
|
28125
|
-
/* @__PURE__ */
|
|
28117
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28118
|
+
/* @__PURE__ */ jsx9(Text9, { children: "Select i18n framework:" }),
|
|
28119
|
+
/* @__PURE__ */ jsx9(
|
|
28126
28120
|
Select,
|
|
28127
28121
|
{
|
|
28128
28122
|
options: [
|
|
@@ -28150,9 +28144,9 @@ function InitWizard({
|
|
|
28150
28144
|
if (step === "languageInput") {
|
|
28151
28145
|
const subStep = !setupData.baseLanguage ? "base" : setupData.targetLanguages.length === 0 ? "targets" : "confirm";
|
|
28152
28146
|
if (subStep === "base") {
|
|
28153
|
-
return /* @__PURE__ */
|
|
28154
|
-
/* @__PURE__ */
|
|
28155
|
-
/* @__PURE__ */
|
|
28147
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28148
|
+
/* @__PURE__ */ jsx9(Text9, { children: "Base language (source):" }),
|
|
28149
|
+
/* @__PURE__ */ jsx9(
|
|
28156
28150
|
TextInput,
|
|
28157
28151
|
{
|
|
28158
28152
|
placeholder: "en",
|
|
@@ -28167,9 +28161,9 @@ function InitWizard({
|
|
|
28167
28161
|
] });
|
|
28168
28162
|
}
|
|
28169
28163
|
if (subStep === "targets") {
|
|
28170
|
-
return /* @__PURE__ */
|
|
28171
|
-
/* @__PURE__ */
|
|
28172
|
-
/* @__PURE__ */
|
|
28164
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28165
|
+
/* @__PURE__ */ jsx9(Text9, { children: "Target languages (comma-separated, e.g. no,sv,da):" }),
|
|
28166
|
+
/* @__PURE__ */ jsx9(
|
|
28173
28167
|
TextInput,
|
|
28174
28168
|
{
|
|
28175
28169
|
placeholder: "no,sv",
|
|
@@ -28185,26 +28179,26 @@ function InitWizard({
|
|
|
28185
28179
|
] });
|
|
28186
28180
|
}
|
|
28187
28181
|
const setup = getFrameworkSetup(setupData.framework);
|
|
28188
|
-
return /* @__PURE__ */
|
|
28189
|
-
/* @__PURE__ */
|
|
28190
|
-
/* @__PURE__ */
|
|
28182
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28183
|
+
/* @__PURE__ */ jsx9(Text9, { children: "Ready to set up:" }),
|
|
28184
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28191
28185
|
"Framework: ",
|
|
28192
28186
|
friendlyFramework(setupData.framework)
|
|
28193
28187
|
] }) }),
|
|
28194
|
-
/* @__PURE__ */
|
|
28188
|
+
/* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28195
28189
|
"Base: ",
|
|
28196
28190
|
setupData.baseLanguage
|
|
28197
28191
|
] }) }),
|
|
28198
|
-
/* @__PURE__ */
|
|
28192
|
+
/* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28199
28193
|
"Targets: ",
|
|
28200
28194
|
setupData.targetLanguages.join(", ")
|
|
28201
28195
|
] }) }),
|
|
28202
|
-
/* @__PURE__ */
|
|
28203
|
-
setup.dependencies.map((dep) => /* @__PURE__ */
|
|
28196
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Will install:" }) }),
|
|
28197
|
+
setup.dependencies.map((dep) => /* @__PURE__ */ jsx9(Box9, { paddingLeft: 2, children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28204
28198
|
"- ",
|
|
28205
28199
|
dep
|
|
28206
28200
|
] }) }, dep)),
|
|
28207
|
-
/* @__PURE__ */
|
|
28201
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(
|
|
28208
28202
|
Select,
|
|
28209
28203
|
{
|
|
28210
28204
|
options: [
|
|
@@ -28223,56 +28217,59 @@ function InitWizard({
|
|
|
28223
28217
|
] });
|
|
28224
28218
|
}
|
|
28225
28219
|
if (step === "installing") {
|
|
28226
|
-
return /* @__PURE__ */
|
|
28227
|
-
/* @__PURE__ */
|
|
28228
|
-
/* @__PURE__ */
|
|
28229
|
-
/* @__PURE__ */
|
|
28220
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28221
|
+
/* @__PURE__ */ jsxs9(Box9, { children: [
|
|
28222
|
+
/* @__PURE__ */ jsx9(Spinner8, {}),
|
|
28223
|
+
/* @__PURE__ */ jsx9(Text9, { children: " Installing dependencies..." })
|
|
28230
28224
|
] }),
|
|
28231
|
-
/* @__PURE__ */
|
|
28225
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28232
28226
|
"Using ",
|
|
28233
28227
|
detected.packageManager
|
|
28234
28228
|
] }) })
|
|
28235
28229
|
] });
|
|
28236
28230
|
}
|
|
28237
28231
|
if (step === "linkingRepository") {
|
|
28238
|
-
return /* @__PURE__ */
|
|
28239
|
-
/* @__PURE__ */
|
|
28240
|
-
/* @__PURE__ */
|
|
28232
|
+
return /* @__PURE__ */ jsx9(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsxs9(Box9, { children: [
|
|
28233
|
+
/* @__PURE__ */ jsx9(Spinner8, {}),
|
|
28234
|
+
/* @__PURE__ */ jsxs9(Text9, { children: [
|
|
28235
|
+
" ",
|
|
28236
|
+
"Linking to TolkBot and finding your translation files\u2026"
|
|
28237
|
+
] })
|
|
28241
28238
|
] }) });
|
|
28242
28239
|
}
|
|
28243
28240
|
if (step === "done") {
|
|
28244
28241
|
if (error62) {
|
|
28245
|
-
return /* @__PURE__ */
|
|
28246
|
-
/* @__PURE__ */
|
|
28247
|
-
/* @__PURE__ */
|
|
28242
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28243
|
+
/* @__PURE__ */ jsx9(Text9, { color: "red", children: "\u2717 Setup failed" }),
|
|
28244
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { children: error62 }) })
|
|
28248
28245
|
] });
|
|
28249
28246
|
}
|
|
28250
|
-
return /* @__PURE__ */
|
|
28251
|
-
/* @__PURE__ */
|
|
28252
|
-
/* @__PURE__ */
|
|
28247
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
28248
|
+
/* @__PURE__ */ jsx9(Text9, { color: "green", children: "\u2713 Setup complete!" }),
|
|
28249
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28253
28250
|
"Repository: ",
|
|
28254
28251
|
setupData.owner,
|
|
28255
28252
|
"/",
|
|
28256
28253
|
setupData.name
|
|
28257
28254
|
] }) }),
|
|
28258
|
-
/* @__PURE__ */
|
|
28255
|
+
/* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28259
28256
|
"Framework: ",
|
|
28260
28257
|
friendlyFramework(setupData.framework)
|
|
28261
28258
|
] }) }),
|
|
28262
|
-
/* @__PURE__ */
|
|
28259
|
+
/* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28263
28260
|
"Project ID: ",
|
|
28264
28261
|
setupData.projectId
|
|
28265
28262
|
] }) }),
|
|
28266
|
-
/* @__PURE__ */
|
|
28267
|
-
setupData.shouldInstall && /* @__PURE__ */
|
|
28268
|
-
/* @__PURE__ */
|
|
28269
|
-
/* @__PURE__ */
|
|
28270
|
-
/* @__PURE__ */
|
|
28263
|
+
/* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { children: "Created tolkbot.json" }) }),
|
|
28264
|
+
setupData.shouldInstall && /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, flexDirection: "column", children: [
|
|
28265
|
+
/* @__PURE__ */ jsx9(Text9, { children: "Next steps:" }),
|
|
28266
|
+
/* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "1. Import i18n in your app - see docs" }),
|
|
28267
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28271
28268
|
"2. Add translations to ",
|
|
28272
28269
|
setupData.baseLanguage,
|
|
28273
28270
|
".json"
|
|
28274
28271
|
] }),
|
|
28275
|
-
/* @__PURE__ */
|
|
28272
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28276
28273
|
"3. Run: tolkbot translate run --src",
|
|
28277
28274
|
" ",
|
|
28278
28275
|
setupData.baseLanguage,
|
|
@@ -28281,9 +28278,9 @@ function InitWizard({
|
|
|
28281
28278
|
setupData.targetLanguages[0] ?? "no"
|
|
28282
28279
|
] })
|
|
28283
28280
|
] }),
|
|
28284
|
-
!setupData.shouldInstall && /* @__PURE__ */
|
|
28285
|
-
/* @__PURE__ */
|
|
28286
|
-
/* @__PURE__ */
|
|
28281
|
+
!setupData.shouldInstall && /* @__PURE__ */ jsxs9(Box9, { marginTop: 1, flexDirection: "column", children: [
|
|
28282
|
+
/* @__PURE__ */ jsx9(Text9, { children: "Next steps:" }),
|
|
28283
|
+
/* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
|
|
28287
28284
|
"Run: tolkbot translate plan --src",
|
|
28288
28285
|
" ",
|
|
28289
28286
|
setupData.baseLanguage,
|
|
@@ -28294,11 +28291,11 @@ function InitWizard({
|
|
|
28294
28291
|
] })
|
|
28295
28292
|
] });
|
|
28296
28293
|
}
|
|
28297
|
-
return /* @__PURE__ */
|
|
28294
|
+
return /* @__PURE__ */ jsx9(Text9, { children: "Unknown step" });
|
|
28298
28295
|
}
|
|
28299
28296
|
|
|
28300
28297
|
// src/commands/init/index.tsx
|
|
28301
|
-
import { jsx as
|
|
28298
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
28302
28299
|
var FRAMEWORKS = [
|
|
28303
28300
|
"next-intl",
|
|
28304
28301
|
"react-i18next",
|
|
@@ -28340,38 +28337,42 @@ function SummaryUI({
|
|
|
28340
28337
|
plan,
|
|
28341
28338
|
result
|
|
28342
28339
|
}) {
|
|
28343
|
-
return /* @__PURE__ */
|
|
28344
|
-
/* @__PURE__ */
|
|
28345
|
-
/* @__PURE__ */
|
|
28346
|
-
/* @__PURE__ */
|
|
28340
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
28341
|
+
/* @__PURE__ */ jsxs10(Box10, { children: [
|
|
28342
|
+
/* @__PURE__ */ jsx10(Text10, { color: "green", children: "\u2713" }),
|
|
28343
|
+
/* @__PURE__ */ jsx10(Text10, { children: " Setup complete" })
|
|
28347
28344
|
] }),
|
|
28348
|
-
/* @__PURE__ */
|
|
28349
|
-
/* @__PURE__ */
|
|
28345
|
+
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, flexDirection: "column", children: [
|
|
28346
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
28350
28347
|
"Repository: ",
|
|
28351
28348
|
result.owner,
|
|
28352
28349
|
"/",
|
|
28353
28350
|
result.name
|
|
28354
28351
|
] }),
|
|
28355
|
-
/* @__PURE__ */
|
|
28352
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
28356
28353
|
"Framework: ",
|
|
28357
28354
|
plan.framework
|
|
28358
28355
|
] }),
|
|
28359
|
-
/* @__PURE__ */
|
|
28356
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
28357
|
+
"Files: ",
|
|
28358
|
+
result.sourcePattern
|
|
28359
|
+
] }),
|
|
28360
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
28360
28361
|
"Base locale: ",
|
|
28361
|
-
|
|
28362
|
+
result.baseLanguage
|
|
28362
28363
|
] }),
|
|
28363
|
-
/* @__PURE__ */
|
|
28364
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
28364
28365
|
"Targets:",
|
|
28365
28366
|
" ",
|
|
28366
|
-
|
|
28367
|
+
result.targetLanguages.length > 0 ? result.targetLanguages.join(", ") : "none configured"
|
|
28367
28368
|
] }),
|
|
28368
|
-
/* @__PURE__ */
|
|
28369
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
28369
28370
|
"Project: ",
|
|
28370
28371
|
result.projectId,
|
|
28371
28372
|
result.createdProject ? " (created)" : " (existing)"
|
|
28372
28373
|
] })
|
|
28373
28374
|
] }),
|
|
28374
|
-
/* @__PURE__ */
|
|
28375
|
+
/* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text10, { children: "Wrote tolkbot.json" }) })
|
|
28375
28376
|
] });
|
|
28376
28377
|
}
|
|
28377
28378
|
async function runHeadless(cwd, opts) {
|
|
@@ -28410,8 +28411,9 @@ async function runHeadless(cwd, opts) {
|
|
|
28410
28411
|
repositoryId: result.repositoryId,
|
|
28411
28412
|
repository: `${result.owner}/${result.name}`,
|
|
28412
28413
|
framework: plan.framework,
|
|
28413
|
-
|
|
28414
|
-
|
|
28414
|
+
sourcePattern: result.sourcePattern,
|
|
28415
|
+
baseLocale: result.baseLanguage,
|
|
28416
|
+
targets: result.targetLanguages,
|
|
28415
28417
|
createdProject: result.createdProject,
|
|
28416
28418
|
installed: plan.install
|
|
28417
28419
|
},
|
|
@@ -28419,7 +28421,7 @@ async function runHeadless(cwd, opts) {
|
|
|
28419
28421
|
);
|
|
28420
28422
|
return;
|
|
28421
28423
|
}
|
|
28422
|
-
|
|
28424
|
+
render9(/* @__PURE__ */ jsx10(SummaryUI, { plan, result })).unmount();
|
|
28423
28425
|
}
|
|
28424
28426
|
function canPrompt() {
|
|
28425
28427
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
@@ -28449,8 +28451,8 @@ async function runInit(opts = {}) {
|
|
|
28449
28451
|
}
|
|
28450
28452
|
async function runInteractive(opts) {
|
|
28451
28453
|
const outcome = { failed: false };
|
|
28452
|
-
const { unmount, waitUntilExit } =
|
|
28453
|
-
/* @__PURE__ */
|
|
28454
|
+
const { unmount, waitUntilExit } = render9(
|
|
28455
|
+
/* @__PURE__ */ jsx10(
|
|
28454
28456
|
InitWizard,
|
|
28455
28457
|
{
|
|
28456
28458
|
force: opts.force,
|
|
@@ -28485,24 +28487,24 @@ import { z as z5 } from "zod/v4";
|
|
|
28485
28487
|
|
|
28486
28488
|
// src/commands/learnings/archive.tsx
|
|
28487
28489
|
import { Spinner as Spinner9 } from "@inkjs/ui";
|
|
28488
|
-
import { Box as
|
|
28489
|
-
import { jsx as
|
|
28490
|
+
import { Box as Box11, render as render10, Text as Text11 } from "ink";
|
|
28491
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
28490
28492
|
function ArchiveUI({ state }) {
|
|
28491
28493
|
if (state.type === "archiving") {
|
|
28492
|
-
return /* @__PURE__ */
|
|
28493
|
-
/* @__PURE__ */
|
|
28494
|
-
/* @__PURE__ */
|
|
28494
|
+
return /* @__PURE__ */ jsxs11(Box11, { children: [
|
|
28495
|
+
/* @__PURE__ */ jsx11(Spinner9, {}),
|
|
28496
|
+
/* @__PURE__ */ jsx11(Text11, { children: " Archiving learning\u2026" })
|
|
28495
28497
|
] });
|
|
28496
28498
|
}
|
|
28497
28499
|
if (state.type === "success") {
|
|
28498
|
-
return /* @__PURE__ */
|
|
28499
|
-
/* @__PURE__ */
|
|
28500
|
-
/* @__PURE__ */
|
|
28500
|
+
return /* @__PURE__ */ jsxs11(Box11, { children: [
|
|
28501
|
+
/* @__PURE__ */ jsx11(Text11, { color: "green", children: "\u2713" }),
|
|
28502
|
+
/* @__PURE__ */ jsx11(Text11, { children: " Learning archived" })
|
|
28501
28503
|
] });
|
|
28502
28504
|
}
|
|
28503
|
-
return /* @__PURE__ */
|
|
28504
|
-
/* @__PURE__ */
|
|
28505
|
-
/* @__PURE__ */
|
|
28505
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
28506
|
+
/* @__PURE__ */ jsx11(Text11, { color: "red", children: "\u2717 Failed to archive learning" }),
|
|
28507
|
+
/* @__PURE__ */ jsx11(Text11, { dimColor: true, children: state.message })
|
|
28506
28508
|
] });
|
|
28507
28509
|
}
|
|
28508
28510
|
async function runLearningsArchive(opts) {
|
|
@@ -28519,7 +28521,7 @@ async function runLearningsArchive(opts) {
|
|
|
28519
28521
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
28520
28522
|
}
|
|
28521
28523
|
}
|
|
28522
|
-
let { unmount } =
|
|
28524
|
+
let { unmount } = render10(/* @__PURE__ */ jsx11(ArchiveUI, { state: { type: "archiving" } }));
|
|
28523
28525
|
try {
|
|
28524
28526
|
const convexClient = await getAuthenticatedConvexClient();
|
|
28525
28527
|
const { organizationId: organizationId2 } = await getProjectContext(convexClient);
|
|
@@ -28528,13 +28530,13 @@ async function runLearningsArchive(opts) {
|
|
|
28528
28530
|
learningId: opts.id
|
|
28529
28531
|
});
|
|
28530
28532
|
unmount();
|
|
28531
|
-
const ui =
|
|
28533
|
+
const ui = render10(/* @__PURE__ */ jsx11(ArchiveUI, { state: { type: "success" } }));
|
|
28532
28534
|
unmount = ui.unmount;
|
|
28533
28535
|
await ui.waitUntilExit();
|
|
28534
28536
|
} catch (error62) {
|
|
28535
28537
|
unmount();
|
|
28536
|
-
const ui =
|
|
28537
|
-
/* @__PURE__ */
|
|
28538
|
+
const ui = render10(
|
|
28539
|
+
/* @__PURE__ */ jsx11(
|
|
28538
28540
|
ArchiveUI,
|
|
28539
28541
|
{
|
|
28540
28542
|
state: {
|
|
@@ -28551,8 +28553,8 @@ async function runLearningsArchive(opts) {
|
|
|
28551
28553
|
|
|
28552
28554
|
// src/commands/learnings/list.tsx
|
|
28553
28555
|
import { Spinner as Spinner10 } from "@inkjs/ui";
|
|
28554
|
-
import { Box as
|
|
28555
|
-
import { jsx as
|
|
28556
|
+
import { Box as Box12, render as render11, Text as Text12 } from "ink";
|
|
28557
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
28556
28558
|
var feedbackLabels = {
|
|
28557
28559
|
"incorrect-term": "Incorrect term",
|
|
28558
28560
|
"wrong-tone": "Wrong tone",
|
|
@@ -28562,53 +28564,53 @@ var feedbackLabels = {
|
|
|
28562
28564
|
};
|
|
28563
28565
|
function LearningsListUI({ state }) {
|
|
28564
28566
|
if (state.type === "loading") {
|
|
28565
|
-
return /* @__PURE__ */
|
|
28566
|
-
/* @__PURE__ */
|
|
28567
|
-
/* @__PURE__ */
|
|
28567
|
+
return /* @__PURE__ */ jsxs12(Box12, { children: [
|
|
28568
|
+
/* @__PURE__ */ jsx12(Spinner10, {}),
|
|
28569
|
+
/* @__PURE__ */ jsx12(Text12, { children: " Loading learnings\u2026" })
|
|
28568
28570
|
] });
|
|
28569
28571
|
}
|
|
28570
28572
|
if (state.type === "error") {
|
|
28571
|
-
return /* @__PURE__ */
|
|
28572
|
-
/* @__PURE__ */
|
|
28573
|
-
/* @__PURE__ */
|
|
28573
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
28574
|
+
/* @__PURE__ */ jsx12(Text12, { color: "red", children: "\u2717 Error" }),
|
|
28575
|
+
/* @__PURE__ */ jsx12(Text12, { dimColor: true, children: state.message })
|
|
28574
28576
|
] });
|
|
28575
28577
|
}
|
|
28576
28578
|
const { learnings } = state;
|
|
28577
28579
|
if (learnings.length === 0) {
|
|
28578
|
-
return /* @__PURE__ */
|
|
28580
|
+
return /* @__PURE__ */ jsx12(Box12, { children: /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "No learnings found." }) });
|
|
28579
28581
|
}
|
|
28580
|
-
return /* @__PURE__ */
|
|
28581
|
-
/* @__PURE__ */
|
|
28582
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
28583
|
+
/* @__PURE__ */ jsx12(Box12, { marginBottom: 1, children: /* @__PURE__ */ jsxs12(Text12, { bold: true, children: [
|
|
28582
28584
|
learnings.length,
|
|
28583
28585
|
" learning",
|
|
28584
28586
|
learnings.length === 1 ? "" : "s"
|
|
28585
28587
|
] }) }),
|
|
28586
|
-
learnings.map((l) => /* @__PURE__ */
|
|
28587
|
-
/* @__PURE__ */
|
|
28588
|
-
/* @__PURE__ */
|
|
28588
|
+
learnings.map((l) => /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", marginBottom: 1, children: [
|
|
28589
|
+
/* @__PURE__ */ jsxs12(Box12, { gap: 1, children: [
|
|
28590
|
+
/* @__PURE__ */ jsxs12(Text12, { bold: true, children: [
|
|
28589
28591
|
l.srcLocale,
|
|
28590
28592
|
" \u2192 ",
|
|
28591
28593
|
l.dstLocale
|
|
28592
28594
|
] }),
|
|
28593
|
-
/* @__PURE__ */
|
|
28595
|
+
/* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
28594
28596
|
"[",
|
|
28595
28597
|
feedbackLabels[l.feedbackType] ?? l.feedbackType,
|
|
28596
28598
|
"]"
|
|
28597
28599
|
] }),
|
|
28598
|
-
l.status === "archived" && /* @__PURE__ */
|
|
28600
|
+
l.status === "archived" && /* @__PURE__ */ jsx12(Text12, { color: "yellow", children: "[archived]" })
|
|
28599
28601
|
] }),
|
|
28600
|
-
/* @__PURE__ */
|
|
28602
|
+
/* @__PURE__ */ jsx12(Box12, { paddingLeft: 2, children: /* @__PURE__ */ jsxs12(Text12, { children: [
|
|
28601
28603
|
'"',
|
|
28602
28604
|
l.sourceText,
|
|
28603
28605
|
'" \u2192 "',
|
|
28604
28606
|
l.suggestedTranslation,
|
|
28605
28607
|
'"'
|
|
28606
28608
|
] }) }),
|
|
28607
|
-
l.reasoning && /* @__PURE__ */
|
|
28609
|
+
l.reasoning && /* @__PURE__ */ jsx12(Box12, { paddingLeft: 2, children: /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
28608
28610
|
"Reason: ",
|
|
28609
28611
|
l.reasoning
|
|
28610
28612
|
] }) }),
|
|
28611
|
-
/* @__PURE__ */
|
|
28613
|
+
/* @__PURE__ */ jsx12(Box12, { paddingLeft: 2, children: /* @__PURE__ */ jsxs12(Text12, { dimColor: true, children: [
|
|
28612
28614
|
"ID: ",
|
|
28613
28615
|
l._id
|
|
28614
28616
|
] }) })
|
|
@@ -28646,7 +28648,7 @@ async function runLearningsList(opts) {
|
|
|
28646
28648
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
28647
28649
|
}
|
|
28648
28650
|
}
|
|
28649
|
-
let { unmount } =
|
|
28651
|
+
let { unmount } = render11(/* @__PURE__ */ jsx12(LearningsListUI, { state: { type: "loading" } }));
|
|
28650
28652
|
try {
|
|
28651
28653
|
const convexClient = await getAuthenticatedConvexClient();
|
|
28652
28654
|
const { projectId, organizationId: organizationId2 } = await getProjectContext(convexClient);
|
|
@@ -28660,15 +28662,15 @@ async function runLearningsList(opts) {
|
|
|
28660
28662
|
}
|
|
28661
28663
|
);
|
|
28662
28664
|
unmount();
|
|
28663
|
-
const ui =
|
|
28664
|
-
/* @__PURE__ */
|
|
28665
|
+
const ui = render11(
|
|
28666
|
+
/* @__PURE__ */ jsx12(LearningsListUI, { state: { type: "success", learnings } })
|
|
28665
28667
|
);
|
|
28666
28668
|
unmount = ui.unmount;
|
|
28667
28669
|
await ui.waitUntilExit();
|
|
28668
28670
|
} catch (error62) {
|
|
28669
28671
|
unmount();
|
|
28670
|
-
const ui =
|
|
28671
|
-
/* @__PURE__ */
|
|
28672
|
+
const ui = render11(
|
|
28673
|
+
/* @__PURE__ */ jsx12(
|
|
28672
28674
|
LearningsListUI,
|
|
28673
28675
|
{
|
|
28674
28676
|
state: {
|
|
@@ -28685,24 +28687,24 @@ async function runLearningsList(opts) {
|
|
|
28685
28687
|
|
|
28686
28688
|
// src/commands/learnings/remove.tsx
|
|
28687
28689
|
import { Spinner as Spinner11 } from "@inkjs/ui";
|
|
28688
|
-
import { Box as
|
|
28689
|
-
import { jsx as
|
|
28690
|
+
import { Box as Box13, render as render12, Text as Text13 } from "ink";
|
|
28691
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
28690
28692
|
function RemoveUI2({ state }) {
|
|
28691
28693
|
if (state.type === "removing") {
|
|
28692
|
-
return /* @__PURE__ */
|
|
28693
|
-
/* @__PURE__ */
|
|
28694
|
-
/* @__PURE__ */
|
|
28694
|
+
return /* @__PURE__ */ jsxs13(Box13, { children: [
|
|
28695
|
+
/* @__PURE__ */ jsx13(Spinner11, {}),
|
|
28696
|
+
/* @__PURE__ */ jsx13(Text13, { children: " Removing learning\u2026" })
|
|
28695
28697
|
] });
|
|
28696
28698
|
}
|
|
28697
28699
|
if (state.type === "success") {
|
|
28698
|
-
return /* @__PURE__ */
|
|
28699
|
-
/* @__PURE__ */
|
|
28700
|
-
/* @__PURE__ */
|
|
28700
|
+
return /* @__PURE__ */ jsxs13(Box13, { children: [
|
|
28701
|
+
/* @__PURE__ */ jsx13(Text13, { color: "green", children: "\u2713" }),
|
|
28702
|
+
/* @__PURE__ */ jsx13(Text13, { children: " Learning removed" })
|
|
28701
28703
|
] });
|
|
28702
28704
|
}
|
|
28703
|
-
return /* @__PURE__ */
|
|
28704
|
-
/* @__PURE__ */
|
|
28705
|
-
/* @__PURE__ */
|
|
28705
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
|
|
28706
|
+
/* @__PURE__ */ jsx13(Text13, { color: "red", children: "\u2717 Failed to remove learning" }),
|
|
28707
|
+
/* @__PURE__ */ jsx13(Text13, { dimColor: true, children: state.message })
|
|
28706
28708
|
] });
|
|
28707
28709
|
}
|
|
28708
28710
|
async function runLearningsRemove(opts) {
|
|
@@ -28719,7 +28721,7 @@ async function runLearningsRemove(opts) {
|
|
|
28719
28721
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
28720
28722
|
}
|
|
28721
28723
|
}
|
|
28722
|
-
let { unmount } =
|
|
28724
|
+
let { unmount } = render12(/* @__PURE__ */ jsx13(RemoveUI2, { state: { type: "removing" } }));
|
|
28723
28725
|
try {
|
|
28724
28726
|
const convexClient = await getAuthenticatedConvexClient();
|
|
28725
28727
|
const { organizationId: organizationId2 } = await getProjectContext(convexClient);
|
|
@@ -28728,13 +28730,13 @@ async function runLearningsRemove(opts) {
|
|
|
28728
28730
|
learningId: opts.id
|
|
28729
28731
|
});
|
|
28730
28732
|
unmount();
|
|
28731
|
-
const ui =
|
|
28733
|
+
const ui = render12(/* @__PURE__ */ jsx13(RemoveUI2, { state: { type: "success" } }));
|
|
28732
28734
|
unmount = ui.unmount;
|
|
28733
28735
|
await ui.waitUntilExit();
|
|
28734
28736
|
} catch (error62) {
|
|
28735
28737
|
unmount();
|
|
28736
|
-
const ui =
|
|
28737
|
-
/* @__PURE__ */
|
|
28738
|
+
const ui = render12(
|
|
28739
|
+
/* @__PURE__ */ jsx13(
|
|
28738
28740
|
RemoveUI2,
|
|
28739
28741
|
{
|
|
28740
28742
|
state: {
|
|
@@ -28751,59 +28753,59 @@ async function runLearningsRemove(opts) {
|
|
|
28751
28753
|
|
|
28752
28754
|
// src/commands/learnings/show.tsx
|
|
28753
28755
|
import { Spinner as Spinner12 } from "@inkjs/ui";
|
|
28754
|
-
import { Box as
|
|
28755
|
-
import { jsx as
|
|
28756
|
+
import { Box as Box14, render as render13, Text as Text14 } from "ink";
|
|
28757
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
28756
28758
|
function LearningShowUI({ state }) {
|
|
28757
28759
|
if (state.type === "loading") {
|
|
28758
|
-
return /* @__PURE__ */
|
|
28759
|
-
/* @__PURE__ */
|
|
28760
|
-
/* @__PURE__ */
|
|
28760
|
+
return /* @__PURE__ */ jsxs14(Box14, { children: [
|
|
28761
|
+
/* @__PURE__ */ jsx14(Spinner12, {}),
|
|
28762
|
+
/* @__PURE__ */ jsx14(Text14, { children: " Loading learning\u2026" })
|
|
28761
28763
|
] });
|
|
28762
28764
|
}
|
|
28763
28765
|
if (state.type === "not-found") {
|
|
28764
|
-
return /* @__PURE__ */
|
|
28766
|
+
return /* @__PURE__ */ jsx14(Box14, { children: /* @__PURE__ */ jsx14(Text14, { color: "red", children: "\u2717 Learning not found" }) });
|
|
28765
28767
|
}
|
|
28766
28768
|
if (state.type === "error") {
|
|
28767
|
-
return /* @__PURE__ */
|
|
28768
|
-
/* @__PURE__ */
|
|
28769
|
-
/* @__PURE__ */
|
|
28769
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
28770
|
+
/* @__PURE__ */ jsx14(Text14, { color: "red", children: "\u2717 Error" }),
|
|
28771
|
+
/* @__PURE__ */ jsx14(Text14, { dimColor: true, children: state.message })
|
|
28770
28772
|
] });
|
|
28771
28773
|
}
|
|
28772
28774
|
const { learning } = state;
|
|
28773
|
-
return /* @__PURE__ */
|
|
28774
|
-
/* @__PURE__ */
|
|
28775
|
-
/* @__PURE__ */
|
|
28776
|
-
/* @__PURE__ */
|
|
28775
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
28776
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28777
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Source text:" }),
|
|
28778
|
+
/* @__PURE__ */ jsx14(Text14, { children: learning.sourceText })
|
|
28777
28779
|
] }),
|
|
28778
|
-
/* @__PURE__ */
|
|
28779
|
-
/* @__PURE__ */
|
|
28780
|
-
/* @__PURE__ */
|
|
28780
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28781
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Suggested translation:" }),
|
|
28782
|
+
/* @__PURE__ */ jsx14(Text14, { children: learning.suggestedTranslation })
|
|
28781
28783
|
] }),
|
|
28782
|
-
/* @__PURE__ */
|
|
28783
|
-
/* @__PURE__ */
|
|
28784
|
-
/* @__PURE__ */
|
|
28784
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28785
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Locales:" }),
|
|
28786
|
+
/* @__PURE__ */ jsxs14(Text14, { children: [
|
|
28785
28787
|
learning.srcLocale,
|
|
28786
28788
|
" \u2192 ",
|
|
28787
28789
|
learning.dstLocale
|
|
28788
28790
|
] })
|
|
28789
28791
|
] }),
|
|
28790
|
-
/* @__PURE__ */
|
|
28791
|
-
/* @__PURE__ */
|
|
28792
|
-
/* @__PURE__ */
|
|
28792
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28793
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Feedback type:" }),
|
|
28794
|
+
/* @__PURE__ */ jsx14(Text14, { children: learning.feedbackType })
|
|
28793
28795
|
] }),
|
|
28794
|
-
/* @__PURE__ */
|
|
28795
|
-
/* @__PURE__ */
|
|
28796
|
-
/* @__PURE__ */
|
|
28796
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28797
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Reasoning:" }),
|
|
28798
|
+
/* @__PURE__ */ jsx14(Text14, { children: learning.reasoning })
|
|
28797
28799
|
] }),
|
|
28798
|
-
/* @__PURE__ */
|
|
28799
|
-
/* @__PURE__ */
|
|
28800
|
-
/* @__PURE__ */
|
|
28800
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28801
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Status:" }),
|
|
28802
|
+
/* @__PURE__ */ jsx14(Text14, { color: learning.status === "active" ? "green" : "yellow", children: learning.status })
|
|
28801
28803
|
] }),
|
|
28802
|
-
/* @__PURE__ */
|
|
28803
|
-
/* @__PURE__ */
|
|
28804
|
-
/* @__PURE__ */
|
|
28804
|
+
/* @__PURE__ */ jsxs14(Box14, { gap: 1, children: [
|
|
28805
|
+
/* @__PURE__ */ jsx14(Text14, { bold: true, children: "Source:" }),
|
|
28806
|
+
/* @__PURE__ */ jsx14(Text14, { children: learning.source })
|
|
28805
28807
|
] }),
|
|
28806
|
-
/* @__PURE__ */
|
|
28808
|
+
/* @__PURE__ */ jsx14(Box14, { marginTop: 1, children: /* @__PURE__ */ jsxs14(Text14, { dimColor: true, children: [
|
|
28807
28809
|
"ID: ",
|
|
28808
28810
|
learning._id
|
|
28809
28811
|
] }) })
|
|
@@ -28836,7 +28838,7 @@ async function runLearningsShow(opts) {
|
|
|
28836
28838
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
28837
28839
|
}
|
|
28838
28840
|
}
|
|
28839
|
-
let { unmount } =
|
|
28841
|
+
let { unmount } = render13(/* @__PURE__ */ jsx14(LearningShowUI, { state: { type: "loading" } }));
|
|
28840
28842
|
try {
|
|
28841
28843
|
const convexClient = await getAuthenticatedConvexClient();
|
|
28842
28844
|
const { organizationId: organizationId2 } = await getProjectContext(convexClient);
|
|
@@ -28846,21 +28848,21 @@ async function runLearningsShow(opts) {
|
|
|
28846
28848
|
});
|
|
28847
28849
|
if (!learning) {
|
|
28848
28850
|
unmount();
|
|
28849
|
-
const ui2 =
|
|
28851
|
+
const ui2 = render13(/* @__PURE__ */ jsx14(LearningShowUI, { state: { type: "not-found" } }));
|
|
28850
28852
|
unmount = ui2.unmount;
|
|
28851
28853
|
await ui2.waitUntilExit();
|
|
28852
28854
|
return exitAfterFlush(1);
|
|
28853
28855
|
}
|
|
28854
28856
|
unmount();
|
|
28855
|
-
const ui =
|
|
28856
|
-
/* @__PURE__ */
|
|
28857
|
+
const ui = render13(
|
|
28858
|
+
/* @__PURE__ */ jsx14(LearningShowUI, { state: { type: "success", learning } })
|
|
28857
28859
|
);
|
|
28858
28860
|
unmount = ui.unmount;
|
|
28859
28861
|
await ui.waitUntilExit();
|
|
28860
28862
|
} catch (error62) {
|
|
28861
28863
|
unmount();
|
|
28862
|
-
const ui =
|
|
28863
|
-
/* @__PURE__ */
|
|
28864
|
+
const ui = render13(
|
|
28865
|
+
/* @__PURE__ */ jsx14(
|
|
28864
28866
|
LearningShowUI,
|
|
28865
28867
|
{
|
|
28866
28868
|
state: {
|
|
@@ -28965,7 +28967,7 @@ import { z as z7 } from "zod/v4";
|
|
|
28965
28967
|
import fs7 from "fs/promises";
|
|
28966
28968
|
import path8 from "path";
|
|
28967
28969
|
import { Spinner as Spinner13 } from "@inkjs/ui";
|
|
28968
|
-
import { Box as
|
|
28970
|
+
import { Box as Box15, render as render14, Text as Text15 } from "ink";
|
|
28969
28971
|
|
|
28970
28972
|
// src/commands/translate/task-generator.ts
|
|
28971
28973
|
import fs6 from "fs/promises";
|
|
@@ -31448,7 +31450,7 @@ async function generateTasks(ctx, srcLocale, dstLocale, opts = {}) {
|
|
|
31448
31450
|
}
|
|
31449
31451
|
|
|
31450
31452
|
// src/commands/translate/plan.tsx
|
|
31451
|
-
import { jsx as
|
|
31453
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
31452
31454
|
async function loadPlanContext(cwd) {
|
|
31453
31455
|
const config3 = readConfig(cwd);
|
|
31454
31456
|
if (!config3) {
|
|
@@ -31505,18 +31507,18 @@ function PlanUI({
|
|
|
31505
31507
|
dst
|
|
31506
31508
|
}) {
|
|
31507
31509
|
if (state.type === "loading") {
|
|
31508
|
-
return /* @__PURE__ */
|
|
31509
|
-
/* @__PURE__ */
|
|
31510
|
-
/* @__PURE__ */
|
|
31510
|
+
return /* @__PURE__ */ jsxs15(Box15, { children: [
|
|
31511
|
+
/* @__PURE__ */ jsx15(Spinner13, {}),
|
|
31512
|
+
/* @__PURE__ */ jsx15(Text15, { children: " Loading configuration\u2026" })
|
|
31511
31513
|
] });
|
|
31512
31514
|
}
|
|
31513
31515
|
if (state.type === "planning") {
|
|
31514
|
-
return /* @__PURE__ */
|
|
31515
|
-
/* @__PURE__ */
|
|
31516
|
-
/* @__PURE__ */
|
|
31517
|
-
/* @__PURE__ */
|
|
31516
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
31517
|
+
/* @__PURE__ */ jsxs15(Box15, { children: [
|
|
31518
|
+
/* @__PURE__ */ jsx15(Spinner13, {}),
|
|
31519
|
+
/* @__PURE__ */ jsx15(Text15, { children: " Analyzing translation needs\u2026" })
|
|
31518
31520
|
] }),
|
|
31519
|
-
/* @__PURE__ */
|
|
31521
|
+
/* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
31520
31522
|
src,
|
|
31521
31523
|
" \u2192 ",
|
|
31522
31524
|
dst
|
|
@@ -31525,12 +31527,12 @@ function PlanUI({
|
|
|
31525
31527
|
}
|
|
31526
31528
|
if (state.type === "success") {
|
|
31527
31529
|
const { plan } = state;
|
|
31528
|
-
return /* @__PURE__ */
|
|
31529
|
-
/* @__PURE__ */
|
|
31530
|
-
/* @__PURE__ */
|
|
31531
|
-
/* @__PURE__ */
|
|
31530
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
31531
|
+
/* @__PURE__ */ jsxs15(Box15, { children: [
|
|
31532
|
+
/* @__PURE__ */ jsx15(Text15, { color: "green", children: "\u2713" }),
|
|
31533
|
+
/* @__PURE__ */ jsx15(Text15, { children: " Translation plan generated" })
|
|
31532
31534
|
] }),
|
|
31533
|
-
/* @__PURE__ */
|
|
31535
|
+
/* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text15, { dimColor: true, children: [
|
|
31534
31536
|
src,
|
|
31535
31537
|
" \u2192 ",
|
|
31536
31538
|
dst,
|
|
@@ -31538,17 +31540,17 @@ function PlanUI({
|
|
|
31538
31540
|
plan.tasks.length,
|
|
31539
31541
|
" task(s)"
|
|
31540
31542
|
] }) }),
|
|
31541
|
-
describePlan(plan).map((line) => /* @__PURE__ */
|
|
31542
|
-
plan.tasks.length === 0 && /* @__PURE__ */
|
|
31543
|
+
describePlan(plan).map((line) => /* @__PURE__ */ jsx15(Box15, { children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, children: line }) }, line)),
|
|
31544
|
+
plan.tasks.length === 0 && /* @__PURE__ */ jsx15(Box15, { marginTop: 1, children: /* @__PURE__ */ jsxs15(Text15, { color: "yellow", children: [
|
|
31543
31545
|
"No translations needed - ",
|
|
31544
31546
|
dst,
|
|
31545
31547
|
" is up to date."
|
|
31546
31548
|
] }) })
|
|
31547
31549
|
] });
|
|
31548
31550
|
}
|
|
31549
|
-
return /* @__PURE__ */
|
|
31550
|
-
/* @__PURE__ */
|
|
31551
|
-
/* @__PURE__ */
|
|
31551
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
31552
|
+
/* @__PURE__ */ jsx15(Text15, { color: "red", children: "\u2717 Planning failed" }),
|
|
31553
|
+
/* @__PURE__ */ jsx15(Text15, { dimColor: true, children: state.message })
|
|
31552
31554
|
] });
|
|
31553
31555
|
}
|
|
31554
31556
|
function planOutput(plan) {
|
|
@@ -31582,23 +31584,23 @@ async function runPlan(opts) {
|
|
|
31582
31584
|
}
|
|
31583
31585
|
}
|
|
31584
31586
|
let src = opts.src ?? "";
|
|
31585
|
-
let { unmount } =
|
|
31586
|
-
/* @__PURE__ */
|
|
31587
|
+
let { unmount } = render14(
|
|
31588
|
+
/* @__PURE__ */ jsx15(PlanUI, { state: { type: "loading" }, src, dst: opts.dst })
|
|
31587
31589
|
);
|
|
31588
31590
|
try {
|
|
31589
31591
|
const ctx = await loadPlanContext(cwd);
|
|
31590
31592
|
src = opts.src ?? ctx.project.baseLanguage;
|
|
31591
31593
|
unmount();
|
|
31592
|
-
const planningUi =
|
|
31593
|
-
/* @__PURE__ */
|
|
31594
|
+
const planningUi = render14(
|
|
31595
|
+
/* @__PURE__ */ jsx15(PlanUI, { state: { type: "planning" }, src, dst: opts.dst })
|
|
31594
31596
|
);
|
|
31595
31597
|
unmount = planningUi.unmount;
|
|
31596
31598
|
const plan = await planForLocale(ctx, src, opts.dst, {
|
|
31597
31599
|
retranslateUntracked: opts.retranslateUntracked
|
|
31598
31600
|
});
|
|
31599
31601
|
unmount();
|
|
31600
|
-
const successUi =
|
|
31601
|
-
/* @__PURE__ */
|
|
31602
|
+
const successUi = render14(
|
|
31603
|
+
/* @__PURE__ */ jsx15(
|
|
31602
31604
|
PlanUI,
|
|
31603
31605
|
{
|
|
31604
31606
|
state: { type: "success", plan },
|
|
@@ -31628,8 +31630,8 @@ Tasks written to: ${outputPath}`);
|
|
|
31628
31630
|
}
|
|
31629
31631
|
} catch (error62) {
|
|
31630
31632
|
unmount();
|
|
31631
|
-
const errorUi =
|
|
31632
|
-
/* @__PURE__ */
|
|
31633
|
+
const errorUi = render14(
|
|
31634
|
+
/* @__PURE__ */ jsx15(
|
|
31633
31635
|
PlanUI,
|
|
31634
31636
|
{
|
|
31635
31637
|
state: {
|
|
@@ -31733,7 +31735,7 @@ async function runAdopt(opts) {
|
|
|
31733
31735
|
// src/commands/translate/apply.tsx
|
|
31734
31736
|
import { useState as useState2 } from "react";
|
|
31735
31737
|
import { MultiSelect, Spinner as Spinner14 } from "@inkjs/ui";
|
|
31736
|
-
import { Box as
|
|
31738
|
+
import { Box as Box16, render as render15, Text as Text16 } from "ink";
|
|
31737
31739
|
|
|
31738
31740
|
// src/commands/translate/apply-core.ts
|
|
31739
31741
|
import fs8 from "fs/promises";
|
|
@@ -31839,7 +31841,7 @@ async function writeTranslationFile(input2) {
|
|
|
31839
31841
|
}
|
|
31840
31842
|
|
|
31841
31843
|
// src/commands/translate/apply.tsx
|
|
31842
|
-
import { jsx as
|
|
31844
|
+
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
31843
31845
|
function ApplyUI({
|
|
31844
31846
|
jobs,
|
|
31845
31847
|
state,
|
|
@@ -31847,10 +31849,10 @@ function ApplyUI({
|
|
|
31847
31849
|
}) {
|
|
31848
31850
|
const [selectedValues, setSelectedValues] = useState2([]);
|
|
31849
31851
|
if (state.status === "selecting") {
|
|
31850
|
-
return /* @__PURE__ */
|
|
31851
|
-
/* @__PURE__ */
|
|
31852
|
-
/* @__PURE__ */
|
|
31853
|
-
/* @__PURE__ */
|
|
31852
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
31853
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, children: "Select translation jobs to apply:" }),
|
|
31854
|
+
/* @__PURE__ */ jsx16(Text16, { dimColor: true, children: "Space to select, Enter to confirm, Ctrl+C to cancel" }),
|
|
31855
|
+
/* @__PURE__ */ jsx16(Box16, { marginTop: 1, children: /* @__PURE__ */ jsx16(
|
|
31854
31856
|
MultiSelect,
|
|
31855
31857
|
{
|
|
31856
31858
|
options: jobs,
|
|
@@ -31861,19 +31863,19 @@ function ApplyUI({
|
|
|
31861
31863
|
] });
|
|
31862
31864
|
}
|
|
31863
31865
|
if (state.status === "applying") {
|
|
31864
|
-
return /* @__PURE__ */
|
|
31865
|
-
/* @__PURE__ */
|
|
31866
|
-
/* @__PURE__ */
|
|
31866
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
31867
|
+
/* @__PURE__ */ jsx16(Spinner14, {}),
|
|
31868
|
+
/* @__PURE__ */ jsxs16(Text16, { children: [
|
|
31867
31869
|
"Applying job ",
|
|
31868
31870
|
state.currentJobIndex,
|
|
31869
31871
|
"/",
|
|
31870
31872
|
state.totalJobs
|
|
31871
31873
|
] }),
|
|
31872
|
-
state.currentJob && /* @__PURE__ */
|
|
31874
|
+
state.currentJob && /* @__PURE__ */ jsx16(Text16, { dimColor: true, children: state.currentJob })
|
|
31873
31875
|
] });
|
|
31874
31876
|
}
|
|
31875
31877
|
if (state.status === "success") {
|
|
31876
|
-
return /* @__PURE__ */
|
|
31878
|
+
return /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", children: /* @__PURE__ */ jsxs16(Text16, { color: "green", children: [
|
|
31877
31879
|
"\u2713 Applied ",
|
|
31878
31880
|
state.keys,
|
|
31879
31881
|
" keys to ",
|
|
@@ -31885,7 +31887,7 @@ function ApplyUI({
|
|
|
31885
31887
|
state.refused ? `, ${state.refused} not applied` : ""
|
|
31886
31888
|
] }) });
|
|
31887
31889
|
}
|
|
31888
|
-
return /* @__PURE__ */
|
|
31890
|
+
return /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", children: /* @__PURE__ */ jsxs16(Text16, { color: "red", children: [
|
|
31889
31891
|
"\u2717 Error: ",
|
|
31890
31892
|
state.message
|
|
31891
31893
|
] }) });
|
|
@@ -32030,8 +32032,8 @@ async function runApply(opts) {
|
|
|
32030
32032
|
}));
|
|
32031
32033
|
let state = { status: "selecting" };
|
|
32032
32034
|
let selectedJobIds = [];
|
|
32033
|
-
const { rerender, unmount } =
|
|
32034
|
-
/* @__PURE__ */
|
|
32035
|
+
const { rerender, unmount } = render15(
|
|
32036
|
+
/* @__PURE__ */ jsx16(
|
|
32035
32037
|
ApplyUI,
|
|
32036
32038
|
{
|
|
32037
32039
|
jobs: jobOptions,
|
|
@@ -32045,7 +32047,7 @@ async function runApply(opts) {
|
|
|
32045
32047
|
const updateState = (newState) => {
|
|
32046
32048
|
state = { ...state, ...newState };
|
|
32047
32049
|
rerender(
|
|
32048
|
-
/* @__PURE__ */
|
|
32050
|
+
/* @__PURE__ */ jsx16(
|
|
32049
32051
|
ApplyUI,
|
|
32050
32052
|
{
|
|
32051
32053
|
jobs: jobOptions,
|
|
@@ -32121,30 +32123,30 @@ async function runApply(opts) {
|
|
|
32121
32123
|
|
|
32122
32124
|
// src/commands/translate/cancel.tsx
|
|
32123
32125
|
import { Spinner as Spinner15 } from "@inkjs/ui";
|
|
32124
|
-
import { Box as
|
|
32125
|
-
import { jsx as
|
|
32126
|
+
import { Box as Box17, render as render16, Text as Text17 } from "ink";
|
|
32127
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
32126
32128
|
function CancelUI({ state }) {
|
|
32127
32129
|
if (state.type === "cancelling") {
|
|
32128
|
-
return /* @__PURE__ */
|
|
32129
|
-
/* @__PURE__ */
|
|
32130
|
-
/* @__PURE__ */
|
|
32130
|
+
return /* @__PURE__ */ jsxs17(Box17, { children: [
|
|
32131
|
+
/* @__PURE__ */ jsx17(Spinner15, {}),
|
|
32132
|
+
/* @__PURE__ */ jsx17(Text17, { children: " Cancelling job\u2026" })
|
|
32131
32133
|
] });
|
|
32132
32134
|
}
|
|
32133
32135
|
if (state.type === "success") {
|
|
32134
|
-
return /* @__PURE__ */
|
|
32135
|
-
/* @__PURE__ */
|
|
32136
|
-
/* @__PURE__ */
|
|
32137
|
-
/* @__PURE__ */
|
|
32136
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
32137
|
+
/* @__PURE__ */ jsxs17(Box17, { children: [
|
|
32138
|
+
/* @__PURE__ */ jsx17(Text17, { color: "green", children: "\u2713" }),
|
|
32139
|
+
/* @__PURE__ */ jsx17(Text17, { children: " Job cancelled successfully" })
|
|
32138
32140
|
] }),
|
|
32139
|
-
/* @__PURE__ */
|
|
32141
|
+
/* @__PURE__ */ jsx17(Box17, { marginTop: 1, children: /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
32140
32142
|
"Job ID: ",
|
|
32141
32143
|
state.jobId
|
|
32142
32144
|
] }) })
|
|
32143
32145
|
] });
|
|
32144
32146
|
}
|
|
32145
|
-
return /* @__PURE__ */
|
|
32146
|
-
/* @__PURE__ */
|
|
32147
|
-
/* @__PURE__ */
|
|
32147
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
32148
|
+
/* @__PURE__ */ jsx17(Text17, { color: "red", children: "\u2717 Failed to cancel job" }),
|
|
32149
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: state.message })
|
|
32148
32150
|
] });
|
|
32149
32151
|
}
|
|
32150
32152
|
async function runCancel(opts) {
|
|
@@ -32180,7 +32182,7 @@ async function runCancel(opts) {
|
|
|
32180
32182
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
32181
32183
|
}
|
|
32182
32184
|
}
|
|
32183
|
-
let { unmount } =
|
|
32185
|
+
let { unmount } = render16(/* @__PURE__ */ jsx17(CancelUI, { state: { type: "cancelling" } }));
|
|
32184
32186
|
try {
|
|
32185
32187
|
if (!opts.jobId) {
|
|
32186
32188
|
throw new Error("--job-id is required");
|
|
@@ -32210,15 +32212,15 @@ async function runCancel(opts) {
|
|
|
32210
32212
|
jobId: opts.jobId
|
|
32211
32213
|
});
|
|
32212
32214
|
unmount();
|
|
32213
|
-
const successUi =
|
|
32214
|
-
/* @__PURE__ */
|
|
32215
|
+
const successUi = render16(
|
|
32216
|
+
/* @__PURE__ */ jsx17(CancelUI, { state: { type: "success", jobId: opts.jobId } })
|
|
32215
32217
|
);
|
|
32216
32218
|
unmount = successUi.unmount;
|
|
32217
32219
|
await successUi.waitUntilExit();
|
|
32218
32220
|
} catch (error62) {
|
|
32219
32221
|
unmount();
|
|
32220
|
-
const errorUi =
|
|
32221
|
-
/* @__PURE__ */
|
|
32222
|
+
const errorUi = render16(
|
|
32223
|
+
/* @__PURE__ */ jsx17(
|
|
32222
32224
|
CancelUI,
|
|
32223
32225
|
{
|
|
32224
32226
|
state: {
|
|
@@ -32236,7 +32238,7 @@ async function runCancel(opts) {
|
|
|
32236
32238
|
// src/commands/translate/edit.tsx
|
|
32237
32239
|
import path11 from "path";
|
|
32238
32240
|
import { Spinner as Spinner16 } from "@inkjs/ui";
|
|
32239
|
-
import { Box as
|
|
32241
|
+
import { Box as Box18, render as render17, Text as Text18 } from "ink";
|
|
32240
32242
|
|
|
32241
32243
|
// src/utils/locale-files.ts
|
|
32242
32244
|
import path10 from "path";
|
|
@@ -32274,34 +32276,34 @@ function resolveKeyInFile(key, targetFile, fileCount, namespace) {
|
|
|
32274
32276
|
}
|
|
32275
32277
|
|
|
32276
32278
|
// src/commands/translate/edit.tsx
|
|
32277
|
-
import { jsx as
|
|
32279
|
+
import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
32278
32280
|
function EditUI({ state }) {
|
|
32279
32281
|
if (state.type === "editing") {
|
|
32280
|
-
return /* @__PURE__ */
|
|
32281
|
-
/* @__PURE__ */
|
|
32282
|
-
/* @__PURE__ */
|
|
32282
|
+
return /* @__PURE__ */ jsxs18(Box18, { children: [
|
|
32283
|
+
/* @__PURE__ */ jsx18(Spinner16, {}),
|
|
32284
|
+
/* @__PURE__ */ jsx18(Text18, { children: " Editing translation\u2026" })
|
|
32283
32285
|
] });
|
|
32284
32286
|
}
|
|
32285
32287
|
if (state.type === "success") {
|
|
32286
|
-
return /* @__PURE__ */
|
|
32287
|
-
/* @__PURE__ */
|
|
32288
|
-
/* @__PURE__ */
|
|
32289
|
-
/* @__PURE__ */
|
|
32288
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
32289
|
+
/* @__PURE__ */ jsxs18(Box18, { children: [
|
|
32290
|
+
/* @__PURE__ */ jsx18(Text18, { color: "green", children: "\u2713" }),
|
|
32291
|
+
/* @__PURE__ */ jsxs18(Text18, { children: [
|
|
32290
32292
|
" ",
|
|
32291
32293
|
"Updated ",
|
|
32292
|
-
/* @__PURE__ */
|
|
32294
|
+
/* @__PURE__ */ jsx18(Text18, { bold: true, children: state.key })
|
|
32293
32295
|
] })
|
|
32294
32296
|
] }),
|
|
32295
|
-
/* @__PURE__ */
|
|
32296
|
-
/* @__PURE__ */
|
|
32297
|
+
/* @__PURE__ */ jsx18(Box18, { paddingLeft: 2, children: /* @__PURE__ */ jsx18(Text18, { dimColor: true, children: state.value }) }),
|
|
32298
|
+
/* @__PURE__ */ jsx18(Box18, { marginTop: 1, children: /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
32297
32299
|
"File: ",
|
|
32298
32300
|
state.filePath
|
|
32299
32301
|
] }) })
|
|
32300
32302
|
] });
|
|
32301
32303
|
}
|
|
32302
|
-
return /* @__PURE__ */
|
|
32303
|
-
/* @__PURE__ */
|
|
32304
|
-
/* @__PURE__ */
|
|
32304
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
32305
|
+
/* @__PURE__ */ jsx18(Text18, { color: "red", children: "\u2717 Failed to edit translation" }),
|
|
32306
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: state.message })
|
|
32305
32307
|
] });
|
|
32306
32308
|
}
|
|
32307
32309
|
async function performEdit(opts) {
|
|
@@ -32360,17 +32362,17 @@ async function runEdit(opts) {
|
|
|
32360
32362
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
32361
32363
|
}
|
|
32362
32364
|
}
|
|
32363
|
-
let { unmount } =
|
|
32365
|
+
let { unmount } = render17(/* @__PURE__ */ jsx18(EditUI, { state: { type: "editing" } }));
|
|
32364
32366
|
try {
|
|
32365
32367
|
const result = await performEdit(opts);
|
|
32366
32368
|
unmount();
|
|
32367
|
-
const ui =
|
|
32369
|
+
const ui = render17(/* @__PURE__ */ jsx18(EditUI, { state: { type: "success", ...result } }));
|
|
32368
32370
|
unmount = ui.unmount;
|
|
32369
32371
|
await ui.waitUntilExit();
|
|
32370
32372
|
} catch (error62) {
|
|
32371
32373
|
unmount();
|
|
32372
|
-
const ui =
|
|
32373
|
-
/* @__PURE__ */
|
|
32374
|
+
const ui = render17(
|
|
32375
|
+
/* @__PURE__ */ jsx18(
|
|
32374
32376
|
EditUI,
|
|
32375
32377
|
{
|
|
32376
32378
|
state: {
|
|
@@ -32386,30 +32388,30 @@ async function runEdit(opts) {
|
|
|
32386
32388
|
}
|
|
32387
32389
|
|
|
32388
32390
|
// src/commands/translate/run.tsx
|
|
32389
|
-
import { render as
|
|
32391
|
+
import { render as render18 } from "ink";
|
|
32390
32392
|
|
|
32391
32393
|
// src/commands/translate/run-ui.tsx
|
|
32392
32394
|
import { Spinner as Spinner17 } from "@inkjs/ui";
|
|
32393
|
-
import { Box as
|
|
32394
|
-
import { jsx as
|
|
32395
|
+
import { Box as Box19, Text as Text19 } from "ink";
|
|
32396
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
32395
32397
|
function JobLink({ jobId }) {
|
|
32396
32398
|
const url2 = `${env.TOLKBOT_WEB_URL}/translation-jobs/${jobId}`;
|
|
32397
|
-
return /* @__PURE__ */
|
|
32399
|
+
return /* @__PURE__ */ jsxs19(Text19, { dimColor: true, children: [
|
|
32398
32400
|
"Job:",
|
|
32399
32401
|
" ",
|
|
32400
|
-
/* @__PURE__ */
|
|
32402
|
+
/* @__PURE__ */ jsx19(Text19, { color: "blue", underline: true, children: url2 })
|
|
32401
32403
|
] });
|
|
32402
32404
|
}
|
|
32403
32405
|
function PlanNotes({ notes }) {
|
|
32404
32406
|
if (!notes || notes.length === 0) return null;
|
|
32405
|
-
return /* @__PURE__ */
|
|
32407
|
+
return /* @__PURE__ */ jsx19(Box19, { flexDirection: "column", paddingLeft: 2, children: notes.map((note) => /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: note }, note)) });
|
|
32406
32408
|
}
|
|
32407
32409
|
function JobRow({ srcLocale, job }) {
|
|
32408
32410
|
const { dstLocale, status, taskCount, progress, jobId, error: error62, notes } = job;
|
|
32409
32411
|
if (status === "waiting") {
|
|
32410
|
-
return /* @__PURE__ */
|
|
32411
|
-
/* @__PURE__ */
|
|
32412
|
-
/* @__PURE__ */
|
|
32412
|
+
return /* @__PURE__ */ jsxs19(Box19, { children: [
|
|
32413
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "\u23F8 " }),
|
|
32414
|
+
/* @__PURE__ */ jsxs19(Text19, { dimColor: true, children: [
|
|
32413
32415
|
srcLocale,
|
|
32414
32416
|
" \u2192 ",
|
|
32415
32417
|
dstLocale,
|
|
@@ -32418,9 +32420,9 @@ function JobRow({ srcLocale, job }) {
|
|
|
32418
32420
|
] });
|
|
32419
32421
|
}
|
|
32420
32422
|
if (status === "generating") {
|
|
32421
|
-
return /* @__PURE__ */
|
|
32422
|
-
/* @__PURE__ */
|
|
32423
|
-
/* @__PURE__ */
|
|
32423
|
+
return /* @__PURE__ */ jsxs19(Box19, { children: [
|
|
32424
|
+
/* @__PURE__ */ jsx19(Spinner17, {}),
|
|
32425
|
+
/* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32424
32426
|
" ",
|
|
32425
32427
|
srcLocale,
|
|
32426
32428
|
" \u2192 ",
|
|
@@ -32432,10 +32434,10 @@ function JobRow({ srcLocale, job }) {
|
|
|
32432
32434
|
if (status === "translating" && progress) {
|
|
32433
32435
|
const processed = progress.completed + progress.failed;
|
|
32434
32436
|
const percent = progress.total > 0 ? Math.round(processed / progress.total * 100) : 0;
|
|
32435
|
-
return /* @__PURE__ */
|
|
32436
|
-
/* @__PURE__ */
|
|
32437
|
-
/* @__PURE__ */
|
|
32438
|
-
/* @__PURE__ */
|
|
32437
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
32438
|
+
/* @__PURE__ */ jsxs19(Box19, { children: [
|
|
32439
|
+
/* @__PURE__ */ jsx19(Spinner17, {}),
|
|
32440
|
+
/* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32439
32441
|
" ",
|
|
32440
32442
|
srcLocale,
|
|
32441
32443
|
" \u2192 ",
|
|
@@ -32449,16 +32451,16 @@ function JobRow({ srcLocale, job }) {
|
|
|
32449
32451
|
"%)"
|
|
32450
32452
|
] })
|
|
32451
32453
|
] }),
|
|
32452
|
-
jobId && /* @__PURE__ */
|
|
32454
|
+
jobId && /* @__PURE__ */ jsx19(Box19, { paddingLeft: 2, children: /* @__PURE__ */ jsx19(JobLink, { jobId }) })
|
|
32453
32455
|
] });
|
|
32454
32456
|
}
|
|
32455
32457
|
if (status === "completed" && progress) {
|
|
32456
32458
|
const icon = progress.status === "succeeded" ? "\u2713" : progress.status === "partial" ? "\u26A0" : "\u2717";
|
|
32457
32459
|
const color = progress.status === "succeeded" ? "green" : progress.status === "partial" ? "yellow" : "red";
|
|
32458
|
-
return /* @__PURE__ */
|
|
32459
|
-
/* @__PURE__ */
|
|
32460
|
-
/* @__PURE__ */
|
|
32461
|
-
/* @__PURE__ */
|
|
32460
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
32461
|
+
/* @__PURE__ */ jsxs19(Box19, { children: [
|
|
32462
|
+
/* @__PURE__ */ jsx19(Text19, { color, children: icon }),
|
|
32463
|
+
/* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32462
32464
|
" ",
|
|
32463
32465
|
srcLocale,
|
|
32464
32466
|
" \u2192 ",
|
|
@@ -32471,36 +32473,37 @@ function JobRow({ srcLocale, job }) {
|
|
|
32471
32473
|
progress.failed > 0 && ` (${progress.failed} failed)`
|
|
32472
32474
|
] })
|
|
32473
32475
|
] }),
|
|
32474
|
-
jobId && /* @__PURE__ */
|
|
32475
|
-
/* @__PURE__ */
|
|
32476
|
+
jobId && /* @__PURE__ */ jsx19(Box19, { paddingLeft: 2, children: /* @__PURE__ */ jsx19(JobLink, { jobId }) }),
|
|
32477
|
+
/* @__PURE__ */ jsx19(PlanNotes, { notes })
|
|
32476
32478
|
] });
|
|
32477
32479
|
}
|
|
32478
32480
|
if (status === "error") {
|
|
32479
|
-
return /* @__PURE__ */
|
|
32480
|
-
/* @__PURE__ */
|
|
32481
|
-
/* @__PURE__ */
|
|
32482
|
-
/* @__PURE__ */
|
|
32481
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
32482
|
+
/* @__PURE__ */ jsxs19(Box19, { children: [
|
|
32483
|
+
/* @__PURE__ */ jsx19(Text19, { color: "red", children: "\u2717 " }),
|
|
32484
|
+
/* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32483
32485
|
srcLocale,
|
|
32484
32486
|
" \u2192 ",
|
|
32485
32487
|
dstLocale,
|
|
32486
32488
|
": Failed"
|
|
32487
32489
|
] })
|
|
32488
32490
|
] }),
|
|
32489
|
-
error62 && /* @__PURE__ */
|
|
32491
|
+
error62 && /* @__PURE__ */ jsx19(Box19, { paddingLeft: 2, children: /* @__PURE__ */ jsx19(Text19, { dimColor: true, children: error62 }) }),
|
|
32492
|
+
jobId && /* @__PURE__ */ jsx19(Box19, { paddingLeft: 2, children: /* @__PURE__ */ jsx19(JobLink, { jobId }) })
|
|
32490
32493
|
] });
|
|
32491
32494
|
}
|
|
32492
32495
|
if (status === "completed" && !progress && taskCount === 0) {
|
|
32493
|
-
return /* @__PURE__ */
|
|
32494
|
-
/* @__PURE__ */
|
|
32495
|
-
/* @__PURE__ */
|
|
32496
|
-
/* @__PURE__ */
|
|
32496
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
32497
|
+
/* @__PURE__ */ jsxs19(Box19, { children: [
|
|
32498
|
+
/* @__PURE__ */ jsx19(Text19, { color: "green", children: "\u2713 " }),
|
|
32499
|
+
/* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32497
32500
|
srcLocale,
|
|
32498
32501
|
" \u2192 ",
|
|
32499
32502
|
dstLocale,
|
|
32500
32503
|
": Up to date (no translations needed)"
|
|
32501
32504
|
] })
|
|
32502
32505
|
] }),
|
|
32503
|
-
/* @__PURE__ */
|
|
32506
|
+
/* @__PURE__ */ jsx19(PlanNotes, { notes })
|
|
32504
32507
|
] });
|
|
32505
32508
|
}
|
|
32506
32509
|
return null;
|
|
@@ -32510,8 +32513,8 @@ function RunUI({ srcLocale, jobs }) {
|
|
|
32510
32513
|
const allCompleted = jobs.every(
|
|
32511
32514
|
(j) => j.status === "completed" || j.status === "error"
|
|
32512
32515
|
);
|
|
32513
|
-
return /* @__PURE__ */
|
|
32514
|
-
hasMultiple && /* @__PURE__ */
|
|
32516
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
32517
|
+
hasMultiple && /* @__PURE__ */ jsx19(Box19, { marginBottom: 1, children: /* @__PURE__ */ jsxs19(Text19, { bold: true, children: [
|
|
32515
32518
|
"\u{1F30D} Translating from ",
|
|
32516
32519
|
srcLocale,
|
|
32517
32520
|
" to ",
|
|
@@ -32519,14 +32522,14 @@ function RunUI({ srcLocale, jobs }) {
|
|
|
32519
32522
|
" ",
|
|
32520
32523
|
"languages"
|
|
32521
32524
|
] }) }),
|
|
32522
|
-
jobs.map((job) => /* @__PURE__ */
|
|
32523
|
-
hasMultiple && allCompleted && /* @__PURE__ */
|
|
32524
|
-
/* @__PURE__ */
|
|
32525
|
-
/* @__PURE__ */
|
|
32525
|
+
jobs.map((job) => /* @__PURE__ */ jsx19(JobRow, { srcLocale, job }, job.dstLocale)),
|
|
32526
|
+
hasMultiple && allCompleted && /* @__PURE__ */ jsxs19(Box19, { marginTop: 1, flexDirection: "column", children: [
|
|
32527
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "\u2500".repeat(60) }),
|
|
32528
|
+
/* @__PURE__ */ jsx19(Box19, { children: /* @__PURE__ */ jsx19(Text19, { bold: true, children: "\u{1F4CA} Summary" }) }),
|
|
32526
32529
|
jobs.map((job) => {
|
|
32527
32530
|
if (!job.progress) return null;
|
|
32528
32531
|
const icon = job.progress.status === "succeeded" ? "\u2713" : job.progress.status === "partial" ? "\u26A0" : "\u2717";
|
|
32529
|
-
return /* @__PURE__ */
|
|
32532
|
+
return /* @__PURE__ */ jsx19(Box19, { children: /* @__PURE__ */ jsxs19(Text19, { children: [
|
|
32530
32533
|
icon,
|
|
32531
32534
|
" ",
|
|
32532
32535
|
srcLocale,
|
|
@@ -32540,14 +32543,55 @@ function RunUI({ srcLocale, jobs }) {
|
|
|
32540
32543
|
job.progress.failed > 0 && ` (${job.progress.failed} failed)`
|
|
32541
32544
|
] }) }, job.dstLocale);
|
|
32542
32545
|
}),
|
|
32543
|
-
/* @__PURE__ */
|
|
32546
|
+
/* @__PURE__ */ jsx19(Text19, { dimColor: true, children: "\u2500".repeat(60) })
|
|
32544
32547
|
] })
|
|
32545
32548
|
] });
|
|
32546
32549
|
}
|
|
32547
32550
|
|
|
32548
32551
|
// src/commands/translate/translate-job.ts
|
|
32549
|
-
|
|
32550
|
-
|
|
32552
|
+
var FINISHED_STATUSES = /* @__PURE__ */ new Set([
|
|
32553
|
+
"succeeded",
|
|
32554
|
+
"partial",
|
|
32555
|
+
"failed",
|
|
32556
|
+
"cancelled"
|
|
32557
|
+
]);
|
|
32558
|
+
function isJobFinished(status) {
|
|
32559
|
+
return FINISHED_STATUSES.has(status);
|
|
32560
|
+
}
|
|
32561
|
+
function isJobUnsuccessful(status) {
|
|
32562
|
+
return status === "failed" || status === "cancelled";
|
|
32563
|
+
}
|
|
32564
|
+
var JOB_WAIT_TIMEOUT_MS = 60 * 6e4;
|
|
32565
|
+
var JOB_POLL_MS = 500;
|
|
32566
|
+
var JobWaitTimeoutError = class extends CliError {
|
|
32567
|
+
constructor(jobId, timeoutMs) {
|
|
32568
|
+
super(
|
|
32569
|
+
`Translation job ${jobId} was still running after ${Math.round(timeoutMs / 6e4)} minutes, so the CLI stopped waiting.`,
|
|
32570
|
+
`The job keeps running. Check it with 'tolkbot translate status --job-id ${jobId}' and apply it with 'tolkbot translate apply --job-id ${jobId}' once it finishes.`
|
|
32571
|
+
);
|
|
32572
|
+
this.jobId = jobId;
|
|
32573
|
+
this.name = "JobWaitTimeoutError";
|
|
32574
|
+
}
|
|
32575
|
+
jobId;
|
|
32576
|
+
};
|
|
32577
|
+
async function waitForJob(jobId, read, opts = {}) {
|
|
32578
|
+
const timeoutMs = opts.timeoutMs ?? JOB_WAIT_TIMEOUT_MS;
|
|
32579
|
+
const pollMs = opts.pollMs ?? JOB_POLL_MS;
|
|
32580
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
32581
|
+
const now = opts.now ?? Date.now;
|
|
32582
|
+
const deadline = now() + timeoutMs;
|
|
32583
|
+
for (; ; ) {
|
|
32584
|
+
const summary = await read();
|
|
32585
|
+
if (!summary) {
|
|
32586
|
+
throw new CliError(`Translation job ${jobId} was not found.`);
|
|
32587
|
+
}
|
|
32588
|
+
opts.onProgress?.(summary);
|
|
32589
|
+
if (isJobFinished(summary.status)) return summary;
|
|
32590
|
+
if (now() >= deadline) {
|
|
32591
|
+
throw new JobWaitTimeoutError(jobId, timeoutMs);
|
|
32592
|
+
}
|
|
32593
|
+
await sleep(pollMs);
|
|
32594
|
+
}
|
|
32551
32595
|
}
|
|
32552
32596
|
async function runTranslationJob(params) {
|
|
32553
32597
|
const {
|
|
@@ -32575,35 +32619,20 @@ async function runTranslationJob(params) {
|
|
|
32575
32619
|
context: t.context
|
|
32576
32620
|
}))
|
|
32577
32621
|
});
|
|
32578
|
-
|
|
32579
|
-
|
|
32580
|
-
|
|
32581
|
-
|
|
32582
|
-
|
|
32583
|
-
|
|
32584
|
-
|
|
32585
|
-
|
|
32586
|
-
);
|
|
32587
|
-
if (!result) {
|
|
32588
|
-
throw new Error("Job not found");
|
|
32589
|
-
}
|
|
32590
|
-
if (onProgress) {
|
|
32591
|
-
onProgress(result);
|
|
32592
|
-
}
|
|
32593
|
-
if (result.status === "succeeded" || result.status === "partial" || result.status === "failed") {
|
|
32594
|
-
summary = result;
|
|
32595
|
-
break;
|
|
32596
|
-
}
|
|
32597
|
-
await sleep(500);
|
|
32598
|
-
}
|
|
32622
|
+
const summary = await waitForJob(
|
|
32623
|
+
jobId,
|
|
32624
|
+
() => convexClient.query(api.translations.getJobSummary, {
|
|
32625
|
+
organizationId: organizationId2,
|
|
32626
|
+
jobId
|
|
32627
|
+
}),
|
|
32628
|
+
{ onProgress }
|
|
32629
|
+
);
|
|
32599
32630
|
return { jobId, summary };
|
|
32600
32631
|
}
|
|
32601
32632
|
|
|
32602
32633
|
// src/commands/translate/run.tsx
|
|
32603
|
-
import { jsx as
|
|
32634
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
32604
32635
|
async function runTranslate(opts) {
|
|
32605
|
-
const batchSize = opts.batchSize ?? 10;
|
|
32606
|
-
const concurrency = opts.concurrency ?? 3;
|
|
32607
32636
|
const ctx = await loadPlanContext(process.cwd());
|
|
32608
32637
|
const { project, framework } = ctx;
|
|
32609
32638
|
const projectId = project._id;
|
|
@@ -32626,8 +32655,8 @@ ${env.TOLKBOT_WEB_URL}/projects/${project.slug}/settings`
|
|
|
32626
32655
|
const planOpts = { retranslateUntracked: opts.retranslateUntracked };
|
|
32627
32656
|
const tasksFor = async (dstLocale) => opts.tasks ? { tasks: await loadTasksFromFile(opts.tasks), plan: void 0 } : await generateTasks(ctx, srcLocale, dstLocale, planOpts);
|
|
32628
32657
|
if (opts.json) {
|
|
32658
|
+
const results = [];
|
|
32629
32659
|
try {
|
|
32630
|
-
const results = [];
|
|
32631
32660
|
for (const dstLocale of dstLocales) {
|
|
32632
32661
|
const { tasks, plan } = await tasksFor(dstLocale);
|
|
32633
32662
|
const summary = plan ? summarize(plan) : void 0;
|
|
@@ -32639,28 +32668,15 @@ ${env.TOLKBOT_WEB_URL}/projects/${project.slug}/settings`
|
|
|
32639
32668
|
});
|
|
32640
32669
|
continue;
|
|
32641
32670
|
}
|
|
32642
|
-
|
|
32643
|
-
|
|
32644
|
-
|
|
32645
|
-
|
|
32646
|
-
|
|
32647
|
-
|
|
32648
|
-
tasks,
|
|
32649
|
-
batchSize,
|
|
32650
|
-
concurrency,
|
|
32651
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
32652
|
-
onProgress: () => {
|
|
32653
|
-
}
|
|
32654
|
-
});
|
|
32655
|
-
if (!job) {
|
|
32656
|
-
results.push({
|
|
32671
|
+
try {
|
|
32672
|
+
const { jobId, summary: job } = await runTranslationJob({
|
|
32673
|
+
projectId,
|
|
32674
|
+
organizationId: project.organizationId,
|
|
32675
|
+
framework,
|
|
32676
|
+
srcLocale,
|
|
32657
32677
|
dstLocale,
|
|
32658
|
-
|
|
32659
|
-
status: "error",
|
|
32660
|
-
error: "Job not found",
|
|
32661
|
-
plan: summary
|
|
32678
|
+
tasks
|
|
32662
32679
|
});
|
|
32663
|
-
} else {
|
|
32664
32680
|
results.push({
|
|
32665
32681
|
dstLocale,
|
|
32666
32682
|
jobId,
|
|
@@ -32668,28 +32684,45 @@ ${env.TOLKBOT_WEB_URL}/projects/${project.slug}/settings`
|
|
|
32668
32684
|
completed: job.completed,
|
|
32669
32685
|
failed: job.failed,
|
|
32670
32686
|
total: job.total,
|
|
32687
|
+
error: job.status === "cancelled" ? "The job was cancelled." : void 0,
|
|
32688
|
+
plan: summary
|
|
32689
|
+
});
|
|
32690
|
+
} catch (error62) {
|
|
32691
|
+
if (!(error62 instanceof JobWaitTimeoutError)) throw error62;
|
|
32692
|
+
results.push({
|
|
32693
|
+
dstLocale,
|
|
32694
|
+
jobId: error62.jobId,
|
|
32695
|
+
status: "timed-out",
|
|
32696
|
+
error: error62.message,
|
|
32671
32697
|
plan: summary
|
|
32672
32698
|
});
|
|
32699
|
+
break;
|
|
32673
32700
|
}
|
|
32701
|
+
if (results.at(-1)?.status === "cancelled") break;
|
|
32674
32702
|
}
|
|
32675
|
-
track("cli_translate_completed", {
|
|
32676
|
-
mode: "run",
|
|
32677
|
-
key_count: results.reduce((n, r) => n + (r.total ?? 0), 0),
|
|
32678
|
-
locale_count: results.length,
|
|
32679
|
-
job_count: results.filter((r) => r.jobId).length,
|
|
32680
|
-
json: true
|
|
32681
|
-
});
|
|
32682
|
-
jsonSuccess({ jobs: results });
|
|
32683
32703
|
} catch (error62) {
|
|
32684
32704
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
32685
32705
|
}
|
|
32706
|
+
track("cli_translate_completed", {
|
|
32707
|
+
mode: "run",
|
|
32708
|
+
key_count: results.reduce((n, r) => n + (r.total ?? 0), 0),
|
|
32709
|
+
locale_count: results.length,
|
|
32710
|
+
job_count: results.filter((r) => r.jobId).length,
|
|
32711
|
+
json: true
|
|
32712
|
+
});
|
|
32713
|
+
const ok = results.every(
|
|
32714
|
+
(r) => r.status !== "timed-out" && !isJobUnsuccessful(r.status)
|
|
32715
|
+
);
|
|
32716
|
+
if (ok) jsonSuccess({ jobs: results });
|
|
32717
|
+
jsonResult({ jobs: results }, 1);
|
|
32718
|
+
return;
|
|
32686
32719
|
}
|
|
32687
32720
|
const jobs = dstLocales.map((locale) => ({
|
|
32688
32721
|
dstLocale: locale,
|
|
32689
32722
|
status: "waiting"
|
|
32690
32723
|
}));
|
|
32691
|
-
const { rerender, unmount } =
|
|
32692
|
-
/* @__PURE__ */
|
|
32724
|
+
const { rerender, unmount } = render18(
|
|
32725
|
+
/* @__PURE__ */ jsx20(RunUI, { srcLocale, jobs })
|
|
32693
32726
|
);
|
|
32694
32727
|
const updateJob = (locale, update) => {
|
|
32695
32728
|
const index = jobs.findIndex((j) => j.dstLocale === locale);
|
|
@@ -32701,7 +32734,15 @@ ${env.TOLKBOT_WEB_URL}/projects/${project.slug}/settings`
|
|
|
32701
32734
|
dstLocale: currentJob.dstLocale,
|
|
32702
32735
|
status: update.status ?? currentJob.status
|
|
32703
32736
|
};
|
|
32704
|
-
rerender(/* @__PURE__ */
|
|
32737
|
+
rerender(/* @__PURE__ */ jsx20(RunUI, { srcLocale, jobs }));
|
|
32738
|
+
}
|
|
32739
|
+
};
|
|
32740
|
+
const skipRemaining = (locale, why) => {
|
|
32741
|
+
for (const later of dstLocales.slice(dstLocales.indexOf(locale) + 1)) {
|
|
32742
|
+
updateJob(later, {
|
|
32743
|
+
status: "error",
|
|
32744
|
+
error: `Not started, because ${why} the ${locale} job.`
|
|
32745
|
+
});
|
|
32705
32746
|
}
|
|
32706
32747
|
};
|
|
32707
32748
|
try {
|
|
@@ -32722,38 +32763,49 @@ ${env.TOLKBOT_WEB_URL}/projects/${project.slug}/settings`
|
|
|
32722
32763
|
taskCount: tasks.length,
|
|
32723
32764
|
notes
|
|
32724
32765
|
});
|
|
32725
|
-
|
|
32726
|
-
|
|
32727
|
-
|
|
32728
|
-
|
|
32729
|
-
|
|
32730
|
-
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32735
|
-
|
|
32736
|
-
|
|
32737
|
-
|
|
32738
|
-
|
|
32766
|
+
let outcome;
|
|
32767
|
+
try {
|
|
32768
|
+
outcome = await runTranslationJob({
|
|
32769
|
+
projectId,
|
|
32770
|
+
organizationId: project.organizationId,
|
|
32771
|
+
framework,
|
|
32772
|
+
srcLocale,
|
|
32773
|
+
dstLocale,
|
|
32774
|
+
tasks,
|
|
32775
|
+
onProgress: (progress) => {
|
|
32776
|
+
updateJob(dstLocale, { progress });
|
|
32777
|
+
}
|
|
32778
|
+
});
|
|
32779
|
+
} catch (error62) {
|
|
32780
|
+
if (!(error62 instanceof JobWaitTimeoutError)) throw error62;
|
|
32739
32781
|
updateJob(dstLocale, {
|
|
32740
32782
|
status: "error",
|
|
32741
|
-
|
|
32783
|
+
jobId: error62.jobId,
|
|
32784
|
+
error: error62.message
|
|
32742
32785
|
});
|
|
32743
|
-
|
|
32786
|
+
process.exitCode = 1;
|
|
32787
|
+
skipRemaining(dstLocale, "the CLI stopped waiting for");
|
|
32788
|
+
break;
|
|
32789
|
+
}
|
|
32790
|
+
const { jobId, summary } = outcome;
|
|
32791
|
+
if (summary.status === "failed") {
|
|
32744
32792
|
updateJob(dstLocale, {
|
|
32745
32793
|
status: "error",
|
|
32746
32794
|
progress: summary,
|
|
32747
32795
|
jobId,
|
|
32748
32796
|
error: "Translation failed"
|
|
32749
32797
|
});
|
|
32798
|
+
process.exitCode = 1;
|
|
32750
32799
|
} else if (summary.status === "cancelled") {
|
|
32751
32800
|
updateJob(dstLocale, {
|
|
32752
32801
|
status: "error",
|
|
32753
32802
|
progress: summary,
|
|
32754
32803
|
jobId,
|
|
32755
|
-
error: "
|
|
32804
|
+
error: "The job was cancelled."
|
|
32756
32805
|
});
|
|
32806
|
+
process.exitCode = 1;
|
|
32807
|
+
skipRemaining(dstLocale, "someone cancelled");
|
|
32808
|
+
break;
|
|
32757
32809
|
} else {
|
|
32758
32810
|
updateJob(dstLocale, {
|
|
32759
32811
|
status: "completed",
|
|
@@ -32785,34 +32837,34 @@ function summarize(plan) {
|
|
|
32785
32837
|
|
|
32786
32838
|
// src/commands/translate/status.tsx
|
|
32787
32839
|
import { Spinner as Spinner18 } from "@inkjs/ui";
|
|
32788
|
-
import { Box as
|
|
32789
|
-
import { jsx as
|
|
32840
|
+
import { Box as Box20, render as render19, Text as Text20 } from "ink";
|
|
32841
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
32790
32842
|
function StatusUI({ state }) {
|
|
32791
32843
|
if (state.type === "loading") {
|
|
32792
|
-
return /* @__PURE__ */
|
|
32793
|
-
/* @__PURE__ */
|
|
32794
|
-
/* @__PURE__ */
|
|
32844
|
+
return /* @__PURE__ */ jsxs20(Box20, { children: [
|
|
32845
|
+
/* @__PURE__ */ jsx21(Spinner18, {}),
|
|
32846
|
+
/* @__PURE__ */ jsx21(Text20, { children: " Loading job status\u2026" })
|
|
32795
32847
|
] });
|
|
32796
32848
|
}
|
|
32797
32849
|
if (state.type === "not-found") {
|
|
32798
|
-
return /* @__PURE__ */
|
|
32850
|
+
return /* @__PURE__ */ jsx21(Box20, { children: /* @__PURE__ */ jsx21(Text20, { color: "red", children: "\u2717 Job not found" }) });
|
|
32799
32851
|
}
|
|
32800
32852
|
if (state.type === "error") {
|
|
32801
|
-
return /* @__PURE__ */
|
|
32802
|
-
/* @__PURE__ */
|
|
32803
|
-
/* @__PURE__ */
|
|
32853
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
32854
|
+
/* @__PURE__ */ jsx21(Text20, { color: "red", children: "\u2717 Error fetching job status" }),
|
|
32855
|
+
/* @__PURE__ */ jsx21(Text20, { dimColor: true, children: state.message })
|
|
32804
32856
|
] });
|
|
32805
32857
|
}
|
|
32806
32858
|
const { summary } = state;
|
|
32807
32859
|
const processed = summary.completed + summary.failed;
|
|
32808
32860
|
const progress = summary.total > 0 ? Math.round(processed / summary.total * 100) : 0;
|
|
32809
32861
|
if (state.type === "running") {
|
|
32810
|
-
return /* @__PURE__ */
|
|
32811
|
-
/* @__PURE__ */
|
|
32812
|
-
/* @__PURE__ */
|
|
32813
|
-
/* @__PURE__ */
|
|
32862
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
32863
|
+
/* @__PURE__ */ jsxs20(Box20, { children: [
|
|
32864
|
+
/* @__PURE__ */ jsx21(Spinner18, {}),
|
|
32865
|
+
/* @__PURE__ */ jsx21(Text20, { children: " Job is running\u2026" })
|
|
32814
32866
|
] }),
|
|
32815
|
-
/* @__PURE__ */
|
|
32867
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text20, { children: [
|
|
32816
32868
|
"Progress: ",
|
|
32817
32869
|
processed,
|
|
32818
32870
|
"/",
|
|
@@ -32821,14 +32873,14 @@ function StatusUI({ state }) {
|
|
|
32821
32873
|
progress,
|
|
32822
32874
|
"%)"
|
|
32823
32875
|
] }) }),
|
|
32824
|
-
/* @__PURE__ */
|
|
32876
|
+
/* @__PURE__ */ jsx21(Box20, { children: /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
32825
32877
|
"Completed: ",
|
|
32826
32878
|
summary.completed,
|
|
32827
32879
|
" | Failed:",
|
|
32828
32880
|
" ",
|
|
32829
32881
|
summary.failed
|
|
32830
32882
|
] }) }),
|
|
32831
|
-
/* @__PURE__ */
|
|
32883
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
32832
32884
|
"Status: ",
|
|
32833
32885
|
summary.status
|
|
32834
32886
|
] }) })
|
|
@@ -32836,16 +32888,16 @@ function StatusUI({ state }) {
|
|
|
32836
32888
|
}
|
|
32837
32889
|
const statusColor = summary.status === "succeeded" ? "green" : summary.status === "partial" ? "yellow" : "red";
|
|
32838
32890
|
const statusIcon = summary.status === "succeeded" ? "\u2713" : summary.status === "partial" ? "\u26A0" : "\u2717";
|
|
32839
|
-
const statusText = summary.status === "succeeded" ? "completed successfully" : summary.status === "partial" ? "completed with some failures" : "failed";
|
|
32840
|
-
return /* @__PURE__ */
|
|
32841
|
-
/* @__PURE__ */
|
|
32842
|
-
/* @__PURE__ */
|
|
32843
|
-
/* @__PURE__ */
|
|
32891
|
+
const statusText = summary.status === "succeeded" ? "completed successfully" : summary.status === "partial" ? "completed with some failures" : summary.status === "cancelled" ? "was cancelled" : "failed";
|
|
32892
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
32893
|
+
/* @__PURE__ */ jsxs20(Box20, { children: [
|
|
32894
|
+
/* @__PURE__ */ jsx21(Text20, { color: statusColor, children: statusIcon }),
|
|
32895
|
+
/* @__PURE__ */ jsxs20(Text20, { children: [
|
|
32844
32896
|
" Job ",
|
|
32845
32897
|
statusText
|
|
32846
32898
|
] })
|
|
32847
32899
|
] }),
|
|
32848
|
-
/* @__PURE__ */
|
|
32900
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text20, { children: [
|
|
32849
32901
|
"Completed: ",
|
|
32850
32902
|
summary.completed,
|
|
32851
32903
|
" | Failed: ",
|
|
@@ -32853,7 +32905,7 @@ function StatusUI({ state }) {
|
|
|
32853
32905
|
" | Total: ",
|
|
32854
32906
|
summary.total
|
|
32855
32907
|
] }) }),
|
|
32856
|
-
/* @__PURE__ */
|
|
32908
|
+
/* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs20(Text20, { dimColor: true, children: [
|
|
32857
32909
|
"Status: ",
|
|
32858
32910
|
summary.status
|
|
32859
32911
|
] }) })
|
|
@@ -32902,7 +32954,7 @@ async function runStatus(opts) {
|
|
|
32902
32954
|
jsonError(error62 instanceof Error ? error62.message : String(error62));
|
|
32903
32955
|
}
|
|
32904
32956
|
}
|
|
32905
|
-
let { unmount } =
|
|
32957
|
+
let { unmount } = render19(/* @__PURE__ */ jsx21(StatusUI, { state: { type: "loading" } }));
|
|
32906
32958
|
try {
|
|
32907
32959
|
if (!opts.jobId) {
|
|
32908
32960
|
throw new Error("--job-id is required");
|
|
@@ -32910,17 +32962,17 @@ async function runStatus(opts) {
|
|
|
32910
32962
|
const summary = await fetchJobSummary(opts.jobId);
|
|
32911
32963
|
if (!summary) {
|
|
32912
32964
|
unmount();
|
|
32913
|
-
const notFoundUi =
|
|
32914
|
-
/* @__PURE__ */
|
|
32965
|
+
const notFoundUi = render19(
|
|
32966
|
+
/* @__PURE__ */ jsx21(StatusUI, { state: { type: "not-found" } })
|
|
32915
32967
|
);
|
|
32916
32968
|
unmount = notFoundUi.unmount;
|
|
32917
32969
|
await notFoundUi.waitUntilExit();
|
|
32918
32970
|
return exitAfterFlush(1);
|
|
32919
32971
|
}
|
|
32920
|
-
const isCompleted = summary.status
|
|
32972
|
+
const isCompleted = isJobFinished(summary.status);
|
|
32921
32973
|
unmount();
|
|
32922
|
-
const finalUi =
|
|
32923
|
-
/* @__PURE__ */
|
|
32974
|
+
const finalUi = render19(
|
|
32975
|
+
/* @__PURE__ */ jsx21(
|
|
32924
32976
|
StatusUI,
|
|
32925
32977
|
{
|
|
32926
32978
|
state: {
|
|
@@ -32932,13 +32984,13 @@ async function runStatus(opts) {
|
|
|
32932
32984
|
);
|
|
32933
32985
|
unmount = finalUi.unmount;
|
|
32934
32986
|
await finalUi.waitUntilExit();
|
|
32935
|
-
if (summary.status
|
|
32987
|
+
if (isJobUnsuccessful(summary.status)) {
|
|
32936
32988
|
return exitAfterFlush(1);
|
|
32937
32989
|
}
|
|
32938
32990
|
} catch (error62) {
|
|
32939
32991
|
unmount();
|
|
32940
|
-
const errorUi =
|
|
32941
|
-
/* @__PURE__ */
|
|
32992
|
+
const errorUi = render19(
|
|
32993
|
+
/* @__PURE__ */ jsx21(
|
|
32942
32994
|
StatusUI,
|
|
32943
32995
|
{
|
|
32944
32996
|
state: {
|
|
@@ -32955,7 +33007,7 @@ async function runStatus(opts) {
|
|
|
32955
33007
|
|
|
32956
33008
|
// src/commands/translate/index.ts
|
|
32957
33009
|
var translateCommand = new Command5("translate").description(
|
|
32958
|
-
"Translate with
|
|
33010
|
+
"Translate with TolkBot"
|
|
32959
33011
|
);
|
|
32960
33012
|
var RETRANSLATE_UNTRACKED_HELP = "Also retranslate translations TolkBot has no record of (kept by default)";
|
|
32961
33013
|
translateCommand.command("plan").description(
|
|
@@ -32977,14 +33029,12 @@ translateCommand.command("plan").description(
|
|
|
32977
33029
|
translateCommand.command("run").description("Run translation job (auto-generates tasks if not provided)").option(
|
|
32978
33030
|
"--src <locale>",
|
|
32979
33031
|
"Source locale (defaults to repository base language)"
|
|
32980
|
-
).option("--dst <locale>", "Destination locale").option("--all", "Translate to all target languages").option("--tasks <path>", "Path to tasks JSON array (optional)").option("--
|
|
33032
|
+
).option("--dst <locale>", "Destination locale").option("--all", "Translate to all target languages").option("--tasks <path>", "Path to tasks JSON array (optional)").option("--retranslate-untracked", RETRANSLATE_UNTRACKED_HELP).option("--json", "Output as JSON (machine-readable)").action(async (opts) => {
|
|
32981
33033
|
const schema = z7.object({
|
|
32982
33034
|
src: z7.string().optional(),
|
|
32983
33035
|
dst: z7.string().optional(),
|
|
32984
33036
|
all: z7.boolean().optional(),
|
|
32985
33037
|
tasks: z7.string().optional(),
|
|
32986
|
-
batchSize: z7.coerce.number().int().positive().default(10),
|
|
32987
|
-
concurrency: z7.coerce.number().int().positive().default(3),
|
|
32988
33038
|
retranslateUntracked: z7.boolean().optional(),
|
|
32989
33039
|
json: z7.boolean().optional()
|
|
32990
33040
|
});
|
|
@@ -33059,7 +33109,7 @@ translateCommand.command("status").description("Check status of translation job
|
|
|
33059
33109
|
});
|
|
33060
33110
|
|
|
33061
33111
|
// src/commands/validate.tsx
|
|
33062
|
-
import { Box as
|
|
33112
|
+
import { Box as Box21, render as render20, Text as Text21 } from "ink";
|
|
33063
33113
|
|
|
33064
33114
|
// ../ai/src/validators/placeholders.ts
|
|
33065
33115
|
var IDENTIFIER = /^[A-Za-z0-9_$][A-Za-z0-9_$.[\]-]*$/;
|
|
@@ -34152,7 +34202,7 @@ function finalize2(issues, stats, strict) {
|
|
|
34152
34202
|
}
|
|
34153
34203
|
|
|
34154
34204
|
// src/commands/validate.tsx
|
|
34155
|
-
import { jsx as
|
|
34205
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
34156
34206
|
var LEVEL_COLOR = {
|
|
34157
34207
|
error: "red",
|
|
34158
34208
|
warning: "yellow",
|
|
@@ -34161,12 +34211,12 @@ var LEVEL_COLOR = {
|
|
|
34161
34211
|
var GUTTER = 9;
|
|
34162
34212
|
function IssueLine({ issue: issue2 }) {
|
|
34163
34213
|
const location = [issue2.file, issue2.key].filter(Boolean).join(" \xB7 ");
|
|
34164
|
-
return /* @__PURE__ */
|
|
34165
|
-
/* @__PURE__ */
|
|
34166
|
-
/* @__PURE__ */
|
|
34167
|
-
/* @__PURE__ */
|
|
34214
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
34215
|
+
/* @__PURE__ */ jsxs21(Box21, { children: [
|
|
34216
|
+
/* @__PURE__ */ jsx22(Box21, { width: GUTTER, flexShrink: 0, children: /* @__PURE__ */ jsx22(Text21, { color: LEVEL_COLOR[issue2.level], children: issue2.level }) }),
|
|
34217
|
+
/* @__PURE__ */ jsx22(Box21, { flexGrow: 1, children: /* @__PURE__ */ jsx22(Text21, { children: issue2.message }) })
|
|
34168
34218
|
] }),
|
|
34169
|
-
/* @__PURE__ */
|
|
34219
|
+
/* @__PURE__ */ jsx22(Box21, { marginLeft: GUTTER, children: /* @__PURE__ */ jsxs21(Text21, { dimColor: true, children: [
|
|
34170
34220
|
issue2.rule,
|
|
34171
34221
|
location ? ` \u2014 ${location}` : ""
|
|
34172
34222
|
] }) })
|
|
@@ -34175,20 +34225,20 @@ function IssueLine({ issue: issue2 }) {
|
|
|
34175
34225
|
function ReportUI({ report }) {
|
|
34176
34226
|
const { counts, stats } = report;
|
|
34177
34227
|
const summary = ["error", "warning", "info"].filter((level) => counts[level] > 0).map((level) => `${counts[level]} ${level}(s)`).join(", ");
|
|
34178
|
-
return /* @__PURE__ */
|
|
34179
|
-
/* @__PURE__ */
|
|
34180
|
-
/* @__PURE__ */
|
|
34181
|
-
/* @__PURE__ */
|
|
34228
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
34229
|
+
/* @__PURE__ */ jsxs21(Box21, { children: [
|
|
34230
|
+
/* @__PURE__ */ jsx22(Text21, { color: report.valid ? "green" : "red", children: report.valid ? "\u2713" : "\u2717" }),
|
|
34231
|
+
/* @__PURE__ */ jsxs21(Text21, { children: [
|
|
34182
34232
|
" Validation ",
|
|
34183
34233
|
report.valid ? "passed" : "failed"
|
|
34184
34234
|
] }),
|
|
34185
|
-
summary ? /* @__PURE__ */
|
|
34235
|
+
summary ? /* @__PURE__ */ jsxs21(Text21, { dimColor: true, children: [
|
|
34186
34236
|
" \u2014 ",
|
|
34187
34237
|
summary
|
|
34188
34238
|
] }) : null
|
|
34189
34239
|
] }),
|
|
34190
|
-
stats.locales.length > 0 && /* @__PURE__ */
|
|
34191
|
-
/* @__PURE__ */
|
|
34240
|
+
stats.locales.length > 0 && /* @__PURE__ */ jsxs21(Box21, { marginTop: 1, flexDirection: "column", children: [
|
|
34241
|
+
/* @__PURE__ */ jsxs21(Text21, { dimColor: true, children: [
|
|
34192
34242
|
stats.filesChecked,
|
|
34193
34243
|
" ",
|
|
34194
34244
|
stats.format,
|
|
@@ -34197,18 +34247,18 @@ function ReportUI({ report }) {
|
|
|
34197
34247
|
stats.totalKeys,
|
|
34198
34248
|
" keys"
|
|
34199
34249
|
] }),
|
|
34200
|
-
/* @__PURE__ */
|
|
34250
|
+
/* @__PURE__ */ jsxs21(Text21, { dimColor: true, children: [
|
|
34201
34251
|
"Locales: ",
|
|
34202
34252
|
stats.locales.join(", "),
|
|
34203
34253
|
stats.baseLocale ? ` (base: ${stats.baseLocale})` : ""
|
|
34204
34254
|
] }),
|
|
34205
|
-
stats.pattern && /* @__PURE__ */
|
|
34255
|
+
stats.pattern && /* @__PURE__ */ jsxs21(Text21, { dimColor: true, children: [
|
|
34206
34256
|
"Pattern: ",
|
|
34207
34257
|
stats.pattern
|
|
34208
34258
|
] })
|
|
34209
34259
|
] }),
|
|
34210
|
-
report.issues.length > 0 && /* @__PURE__ */
|
|
34211
|
-
!report.strict && counts.warning > 0 && report.valid && /* @__PURE__ */
|
|
34260
|
+
report.issues.length > 0 && /* @__PURE__ */ jsx22(Box21, { marginTop: 1, flexDirection: "column", gap: 1, children: report.issues.map((issue2, idx) => /* @__PURE__ */ jsx22(IssueLine, { issue: issue2 }, idx)) }),
|
|
34261
|
+
!report.strict && counts.warning > 0 && report.valid && /* @__PURE__ */ jsx22(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx22(Text21, { dimColor: true, children: "Warnings did not fail this run. Use --strict to treat them as errors." }) })
|
|
34212
34262
|
] });
|
|
34213
34263
|
}
|
|
34214
34264
|
function emit(report, json2) {
|
|
@@ -34227,7 +34277,7 @@ function emit(report, json2) {
|
|
|
34227
34277
|
jsonResult(report, exitCode);
|
|
34228
34278
|
return;
|
|
34229
34279
|
}
|
|
34230
|
-
|
|
34280
|
+
render20(/* @__PURE__ */ jsx22(ReportUI, { report })).unmount();
|
|
34231
34281
|
process.exitCode = exitCode;
|
|
34232
34282
|
}
|
|
34233
34283
|
async function runValidate(opts = {}) {
|
|
@@ -34274,7 +34324,7 @@ function commandPath(command) {
|
|
|
34274
34324
|
return names.join(" ");
|
|
34275
34325
|
}
|
|
34276
34326
|
function buildProgram() {
|
|
34277
|
-
const program2 = new Command6().name("tolkbot").description("Localization workflow for your repo").version(version, "-v, --version", "Output the version number").option(
|
|
34327
|
+
const program2 = new Command6().name("tolkbot").description("Localization workflow for your repo").version(version, "-v, --version", "Output the version number").helpOption("-h, --help", "Show help").helpCommand("help [command]", "Show help for a command").option(
|
|
34278
34328
|
"--token <token>",
|
|
34279
34329
|
`Auth token to use for this invocation (overrides $${TOKEN_ENV_VAR} and the stored token)`
|
|
34280
34330
|
);
|
|
@@ -34283,7 +34333,7 @@ function buildProgram() {
|
|
|
34283
34333
|
setTokenOverride(token);
|
|
34284
34334
|
beginCommand(commandPath(actionCommand), version);
|
|
34285
34335
|
});
|
|
34286
|
-
program2.command("init").description("Initialize
|
|
34336
|
+
program2.command("init").description("Initialize TolkBot in the current repo").option("--force", "Overwrite existing config").option(
|
|
34287
34337
|
"-y, --yes",
|
|
34288
34338
|
"Skip all prompts, accepting detected settings. Required outside a terminal."
|
|
34289
34339
|
).option("--json", "Output the result as JSON (implies --yes)").option("--base <locale>", "Base locale (default: detected, else en)").option(
|
|
@@ -34296,7 +34346,6 @@ function buildProgram() {
|
|
|
34296
34346
|
"--install",
|
|
34297
34347
|
"Also install i18n dependencies and scaffold files. Off by default when non-interactive."
|
|
34298
34348
|
).action((opts) => runInit(opts));
|
|
34299
|
-
program2.command("help").description("Show help message").action(() => runHelp());
|
|
34300
34349
|
program2.command("validate").description("Validate translation files and configuration").option("--json", "Output the report as JSON").option(
|
|
34301
34350
|
"--strict",
|
|
34302
34351
|
"Treat warnings (incomplete locales) as errors. Off by default, since a locale is normally behind the base while a translation job is in flight."
|
|
@@ -34308,8 +34357,24 @@ function buildProgram() {
|
|
|
34308
34357
|
program2.addCommand(learningsCommand);
|
|
34309
34358
|
program2.addCommand(telemetryCommand);
|
|
34310
34359
|
program2.addCommand(translateCommand);
|
|
34360
|
+
program2.addHelpText("after", PROGRAM_HELP_FOOTER);
|
|
34311
34361
|
return program2;
|
|
34312
34362
|
}
|
|
34363
|
+
var PROGRAM_HELP_FOOTER = `
|
|
34364
|
+
Examples:
|
|
34365
|
+
$ tolkbot auth login
|
|
34366
|
+
$ tolkbot init --yes
|
|
34367
|
+
$ tolkbot translate plan --dst nb --json
|
|
34368
|
+
$ tolkbot translate run --all
|
|
34369
|
+
$ tolkbot translate apply --job-id <id>
|
|
34370
|
+
$ tolkbot validate --strict
|
|
34371
|
+
|
|
34372
|
+
Environment variables:
|
|
34373
|
+
${TOKEN_ENV_VAR} Auth token for CI and headless environments (--token overrides it)
|
|
34374
|
+
${TELEMETRY_ENV_VAR} Set to 0 to stop reporting usage
|
|
34375
|
+
${DO_NOT_TRACK_ENV_VAR} Set to 1 to stop reporting usage
|
|
34376
|
+
|
|
34377
|
+
Run 'tolkbot <command> --help' for a command's options.`;
|
|
34313
34378
|
function currentExitCode() {
|
|
34314
34379
|
return typeof process.exitCode === "number" ? process.exitCode : 0;
|
|
34315
34380
|
}
|