@lingo.dev/cli 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +108 -0
- package/dist/flush-telemetry.js +38 -0
- package/dist/index.js +3 -0
- package/dist/renderer-D2iDOMA6.js +1533 -0
- package/dist/server-DGIsMSAq.js +847 -0
- package/dist/update-RHUBOb93.js +816 -0
- package/package.json +2 -2
package/dist/bin.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { a as extractCommandInfo, b as ApiClientLive, d as subcommands, f as TelemetryService, g as cancel, i as collectOptions, l as helpConfig, m as trackCommand, n as renderRootHelp, o as unwrapCommand, p as TelemetryServiceLive, s as cliConfig, t as renderCommandHelp, u as run, w as AuthServiceLive, x as AuthContext, y as ConfigServiceLive } from "./renderer-D2iDOMA6.js";
|
|
2
|
+
import { n as UpdateService, r as UpdateServiceLive } from "./update-RHUBOb93.js";
|
|
3
|
+
import { AutoCorrect, CliConfig, ValidationError } from "@effect/cli";
|
|
4
|
+
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
|
5
|
+
import { Cause, Effect, Layer, pipe } from "effect";
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
//#region src/errors.ts
|
|
8
|
+
const GLOBAL_FLAGS = new Set(["--api-key"]);
|
|
9
|
+
/**
|
|
10
|
+
* Finds the closest known flag for a typo using Levenshtein distance.
|
|
11
|
+
* Returns the suggestion string (e.g. "--json") or undefined if no close match.
|
|
12
|
+
*/
|
|
13
|
+
function findFlagSuggestion(userArgs, subcommands, cliConfig) {
|
|
14
|
+
const commandName = userArgs[0];
|
|
15
|
+
if (!commandName) return void 0;
|
|
16
|
+
const match = subcommands.find((cmd) => extractCommandInfo(cmd.descriptor).name === commandName);
|
|
17
|
+
if (!match) return void 0;
|
|
18
|
+
const knownFlags = collectKnownFlags(match.descriptor);
|
|
19
|
+
const userFlags = userArgs.slice(1).filter((a) => a.startsWith("-")).map((a) => a.split("=")[0]);
|
|
20
|
+
for (const flag of userFlags) {
|
|
21
|
+
if (GLOBAL_FLAGS.has(flag) || knownFlags.has(flag)) continue;
|
|
22
|
+
const suggestion = closest(flag, knownFlags, cliConfig);
|
|
23
|
+
if (suggestion) return suggestion;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Finds the closest known subcommand for a typo using Levenshtein distance.
|
|
28
|
+
*/
|
|
29
|
+
function findSubcommandSuggestion(commandName, subcommands, cliConfig) {
|
|
30
|
+
return closest(commandName, new Set(subcommands.map((cmd) => extractCommandInfo(cmd.descriptor).name)), cliConfig);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Formats the hint lines shown after a validation error.
|
|
34
|
+
* When commandName is provided, hints at command-level help; otherwise root help.
|
|
35
|
+
*/
|
|
36
|
+
function formatValidationHint(cliName, commandName, suggestion) {
|
|
37
|
+
const lines = [];
|
|
38
|
+
if (suggestion) lines.push(` ${pc.yellow("Tip:")} Did you mean ${pc.bold(suggestion)}?`);
|
|
39
|
+
const helpCmd = commandName ? `${cliName} ${commandName} --help` : `${cliName} --help`;
|
|
40
|
+
const helpTarget = commandName ? "available options" : "available commands";
|
|
41
|
+
lines.push(` Run ${pc.bold(helpCmd)} for ${helpTarget}.`);
|
|
42
|
+
return lines.join("\n");
|
|
43
|
+
}
|
|
44
|
+
function collectKnownFlags(descriptor) {
|
|
45
|
+
const options = collectOptions(unwrapCommand(descriptor).options);
|
|
46
|
+
const flags = /* @__PURE__ */ new Set();
|
|
47
|
+
for (const opt of options) {
|
|
48
|
+
flags.add(`--${opt.long}`);
|
|
49
|
+
if (opt.short) flags.add(`-${opt.short}`);
|
|
50
|
+
}
|
|
51
|
+
return flags;
|
|
52
|
+
}
|
|
53
|
+
function closest(input, candidates, config) {
|
|
54
|
+
let best;
|
|
55
|
+
let bestDist = Infinity;
|
|
56
|
+
for (const candidate of candidates) {
|
|
57
|
+
const dist = AutoCorrect.levensteinDistance(input, candidate, config);
|
|
58
|
+
if (dist < bestDist) {
|
|
59
|
+
bestDist = dist;
|
|
60
|
+
best = candidate;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return bestDist <= 2 ? best : void 0;
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/bin.ts
|
|
67
|
+
process.on("SIGINT", () => process.exit(0));
|
|
68
|
+
process.on("SIGTERM", () => process.exit(0));
|
|
69
|
+
const args = process.argv;
|
|
70
|
+
const userArgs = args.slice(2).filter((a) => a !== "--");
|
|
71
|
+
if (userArgs[0] === "mcp") import("./server-DGIsMSAq.js").then((m) => m.startMcpServer()).catch((e) => {
|
|
72
|
+
process.stderr.write(`MCP server error: ${e}\n`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
});
|
|
75
|
+
else {
|
|
76
|
+
let globalApiKey;
|
|
77
|
+
const apiKeyIdx = userArgs.indexOf("--api-key");
|
|
78
|
+
if (apiKeyIdx !== -1 && userArgs[apiKeyIdx + 1]) globalApiKey = userArgs[apiKeyIdx + 1];
|
|
79
|
+
const isHelp = userArgs.includes("--help") || userArgs.includes("-h") || userArgs.length === 0;
|
|
80
|
+
if (process.env.npm_lifecycle_event === "npx" || process.env.npm_execpath?.includes("npx") || process.env.npm_execpath?.includes("dlx")) process.stderr.write(` ${pc.dim("Tip: install globally for faster startup:")} npm i -g @lingo.dev/cli\n\n`);
|
|
81
|
+
if (isHelp) {
|
|
82
|
+
const subcommandName = userArgs.filter((a) => a !== "--help" && a !== "-h")[0];
|
|
83
|
+
const match = subcommands.find((cmd) => extractCommandInfo(cmd.descriptor).name === subcommandName);
|
|
84
|
+
if (match) console.log(renderCommandHelp(helpConfig, match.descriptor));
|
|
85
|
+
else console.log(renderRootHelp(helpConfig, subcommands.map((cmd) => cmd.descriptor)));
|
|
86
|
+
} else {
|
|
87
|
+
const AuthContextLive = Layer.succeed(AuthContext, { apiKeyFlag: globalApiKey });
|
|
88
|
+
const authLayer = pipe(AuthServiceLive, Layer.provide(AuthContextLive));
|
|
89
|
+
const apiLayer = pipe(ApiClientLive, Layer.provide(authLayer));
|
|
90
|
+
const telemetryLayer = pipe(TelemetryServiceLive, Layer.provide(authLayer), Layer.provide(apiLayer), Layer.provide(ConfigServiceLive));
|
|
91
|
+
const appLayer = pipe(Layer.merge(NodeContext.layer, CliConfig.layer(cliConfig)), Layer.merge(ConfigServiceLive), Layer.merge(authLayer), Layer.merge(apiLayer), Layer.merge(telemetryLayer), Layer.merge(UpdateServiceLive));
|
|
92
|
+
const commandName = userArgs[0] ?? "unknown";
|
|
93
|
+
const flagNames = userArgs.filter((a) => a.startsWith("--")).map((a) => a.split("=")[0]);
|
|
94
|
+
const showUpdateNotification = commandName === "update" ? Effect.void : pipe(UpdateService, Effect.flatMap((u) => u.check), Effect.tap((info) => info ? Effect.sync(() => {
|
|
95
|
+
process.stderr.write(`\n Update available: ${pc.dim(info.current)} → ${pc.green(info.latest)}\n Run ${pc.bold("lingo update")} to upgrade\n`);
|
|
96
|
+
}) : Effect.void), Effect.catchAll(() => Effect.void));
|
|
97
|
+
pipe(run(args), trackCommand(commandName, flagNames), Effect.tap(() => showUpdateNotification), Effect.catchTag("PromptCancelledError", () => cancel("Cancelled.")), Effect.catchIf(ValidationError.isValidationError, (e) => {
|
|
98
|
+
const isSubcommandError = ValidationError.isCommandMismatch(e);
|
|
99
|
+
const suggestion = ValidationError.isInvalidValue(e) ? findFlagSuggestion(userArgs, subcommands, cliConfig) : isSubcommandError ? findSubcommandSuggestion(commandName, subcommands, cliConfig) : void 0;
|
|
100
|
+
return Effect.sync(() => process.stderr.write(formatValidationHint(helpConfig.name, isSubcommandError ? void 0 : commandName, suggestion) + "\n"));
|
|
101
|
+
}), Effect.tapErrorCause((cause) => Cause.isInterruptedOnly(cause) ? Effect.void : pipe(Effect.all([Effect.sync(() => process.stderr.write(`\n ${pc.red("Error:")} Something went wrong. Please try again.\n`)), pipe(TelemetryService, Effect.flatMap((t) => pipe(t.capture("cli_error", {
|
|
102
|
+
command: commandName,
|
|
103
|
+
error: Cause.pretty(cause)
|
|
104
|
+
}), Effect.andThen(t.shutdown))))]), Effect.catchAll(() => Effect.void))), Effect.tap(() => pipe(TelemetryService, Effect.flatMap((t) => t.shutdown), Effect.catchAll(() => Effect.void))), Effect.provide(appLayer), NodeRuntime.runMain({ disableErrorReporting: true }));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { PostHog } from "posthog-node";
|
|
3
|
+
//#region src/flush-telemetry.ts
|
|
4
|
+
/**
|
|
5
|
+
* Detached subprocess that sends buffered telemetry events to PostHog.
|
|
6
|
+
* Spawned by TelemetryService.shutdown -- runs after the main CLI process exits.
|
|
7
|
+
*/
|
|
8
|
+
const file = process.argv[2];
|
|
9
|
+
if (!file) process.exit(0);
|
|
10
|
+
let payload;
|
|
11
|
+
try {
|
|
12
|
+
payload = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
13
|
+
} catch {
|
|
14
|
+
process.exit(0);
|
|
15
|
+
}
|
|
16
|
+
const client = new PostHog(payload.apiKey, {
|
|
17
|
+
host: payload.host,
|
|
18
|
+
flushAt: payload.events.length || 1,
|
|
19
|
+
flushInterval: 0,
|
|
20
|
+
requestTimeout: 5e3,
|
|
21
|
+
fetchRetryCount: 1
|
|
22
|
+
});
|
|
23
|
+
if (payload.identifyTraits) client.identify({
|
|
24
|
+
distinctId: payload.distinctId,
|
|
25
|
+
properties: payload.identifyTraits
|
|
26
|
+
});
|
|
27
|
+
for (const event of payload.events) client.capture({
|
|
28
|
+
distinctId: payload.distinctId,
|
|
29
|
+
event: event.event,
|
|
30
|
+
properties: event.properties,
|
|
31
|
+
timestamp: new Date(event.timestamp)
|
|
32
|
+
});
|
|
33
|
+
await client.shutdown(1e4);
|
|
34
|
+
try {
|
|
35
|
+
fs.unlinkSync(file);
|
|
36
|
+
} catch {}
|
|
37
|
+
//#endregion
|
|
38
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as AuthService, S as AuthError, _ as ConfigError, a as extractCommandInfo, c as command, d as subcommands, h as PromptCancelledError, i as collectOptions, l as helpConfig, n as renderRootHelp, r as collectArgs, s as cliConfig, t as renderCommandHelp, u as run, v as ConfigService, w as AuthServiceLive, x as AuthContext, y as ConfigServiceLive } from "./renderer-D2iDOMA6.js";
|
|
2
|
+
import { n as UpdateService, r as UpdateServiceLive, s as VERSION, t as UpdateError } from "./update-RHUBOb93.js";
|
|
3
|
+
export { AuthContext, AuthError, AuthService, AuthServiceLive, ConfigError, ConfigService, ConfigServiceLive, PromptCancelledError, UpdateError, UpdateService, UpdateServiceLive, VERSION, cliConfig, collectArgs, collectOptions, command, extractCommandInfo, helpConfig, renderCommandHelp, renderRootHelp, run, subcommands };
|