@dosu/cli 0.4.0 → 0.6.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/bin/dosu.js +171 -236
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -3751,6 +3751,18 @@ var init_client = __esm(() => {
|
|
|
3751
3751
|
};
|
|
3752
3752
|
});
|
|
3753
3753
|
|
|
3754
|
+
// src/setup/styles.ts
|
|
3755
|
+
function dim(msg) {
|
|
3756
|
+
return import_picocolors2.default.dim(msg);
|
|
3757
|
+
}
|
|
3758
|
+
function info(msg) {
|
|
3759
|
+
return import_picocolors2.default.cyan(msg);
|
|
3760
|
+
}
|
|
3761
|
+
var import_picocolors2;
|
|
3762
|
+
var init_styles = __esm(() => {
|
|
3763
|
+
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
3764
|
+
});
|
|
3765
|
+
|
|
3754
3766
|
// src/auth/server.ts
|
|
3755
3767
|
function buildSuccessHtml(email) {
|
|
3756
3768
|
const emailLine = email ? `<p class="email">Signed in as <strong>${email.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</strong></p>` : "";
|
|
@@ -4527,240 +4539,6 @@ var init_flow = __esm(() => {
|
|
|
4527
4539
|
init_server();
|
|
4528
4540
|
});
|
|
4529
4541
|
|
|
4530
|
-
// src/tui/tui.ts
|
|
4531
|
-
var exports_tui = {};
|
|
4532
|
-
__export(exports_tui, {
|
|
4533
|
-
runTUI: () => runTUI,
|
|
4534
|
-
handleLogout: () => handleLogout
|
|
4535
|
-
});
|
|
4536
|
-
async function runTUI() {
|
|
4537
|
-
console.log(import_picocolors2.default.magenta(LOGO));
|
|
4538
|
-
const cfg = loadConfig();
|
|
4539
|
-
if (!isAuthenticated(cfg)) {
|
|
4540
|
-
await handleAuthenticate(cfg);
|
|
4541
|
-
if (!isAuthenticated(cfg))
|
|
4542
|
-
return;
|
|
4543
|
-
}
|
|
4544
|
-
while (true) {
|
|
4545
|
-
const hasMcpTarget = cfg.mode === MODE_OSS || !!cfg.deployment_id;
|
|
4546
|
-
const action = await ve({
|
|
4547
|
-
message: "What would you like to do?",
|
|
4548
|
-
options: [
|
|
4549
|
-
{
|
|
4550
|
-
label: "Authenticate",
|
|
4551
|
-
value: "auth",
|
|
4552
|
-
hint: isAuthenticated(cfg) ? "Re-authenticate" : undefined
|
|
4553
|
-
},
|
|
4554
|
-
{
|
|
4555
|
-
label: "Choose MCP",
|
|
4556
|
-
value: "deployments",
|
|
4557
|
-
hint: !isAuthenticated(cfg) ? "Login first" : undefined
|
|
4558
|
-
},
|
|
4559
|
-
{
|
|
4560
|
-
label: "Add MCP",
|
|
4561
|
-
value: "mcp-add",
|
|
4562
|
-
hint: !hasMcpTarget ? "Select deployment first" : undefined
|
|
4563
|
-
},
|
|
4564
|
-
{
|
|
4565
|
-
label: "Remove MCP",
|
|
4566
|
-
value: "mcp-remove",
|
|
4567
|
-
hint: !hasMcpTarget ? "Select deployment first" : undefined
|
|
4568
|
-
},
|
|
4569
|
-
{ label: "Clear Credentials", value: "logout" },
|
|
4570
|
-
{ label: "Exit", value: "exit" }
|
|
4571
|
-
]
|
|
4572
|
-
});
|
|
4573
|
-
if (pD(action) || action === "exit") {
|
|
4574
|
-
break;
|
|
4575
|
-
}
|
|
4576
|
-
switch (action) {
|
|
4577
|
-
case "auth":
|
|
4578
|
-
await handleAuthenticate(cfg);
|
|
4579
|
-
break;
|
|
4580
|
-
case "deployments":
|
|
4581
|
-
await handleDeployments(cfg);
|
|
4582
|
-
break;
|
|
4583
|
-
case "mcp-add":
|
|
4584
|
-
if (!hasMcpTarget) {
|
|
4585
|
-
M2.warn("Please select a deployment first.");
|
|
4586
|
-
continue;
|
|
4587
|
-
}
|
|
4588
|
-
await handleMCPAdd(cfg);
|
|
4589
|
-
break;
|
|
4590
|
-
case "mcp-remove":
|
|
4591
|
-
if (!hasMcpTarget) {
|
|
4592
|
-
M2.warn("Please select a deployment first.");
|
|
4593
|
-
continue;
|
|
4594
|
-
}
|
|
4595
|
-
await handleMCPRemove(cfg);
|
|
4596
|
-
break;
|
|
4597
|
-
case "logout":
|
|
4598
|
-
handleLogout(cfg);
|
|
4599
|
-
break;
|
|
4600
|
-
}
|
|
4601
|
-
}
|
|
4602
|
-
Se("Goodbye!");
|
|
4603
|
-
}
|
|
4604
|
-
async function handleDeployments(cfg) {
|
|
4605
|
-
if (!isAuthenticated(cfg)) {
|
|
4606
|
-
M2.warn("Please authenticate first.");
|
|
4607
|
-
return;
|
|
4608
|
-
}
|
|
4609
|
-
const client = new Client(cfg);
|
|
4610
|
-
try {
|
|
4611
|
-
const deployments = await client.getDeployments();
|
|
4612
|
-
if (deployments.length === 0) {
|
|
4613
|
-
M2.warn("No deployments found.");
|
|
4614
|
-
return;
|
|
4615
|
-
}
|
|
4616
|
-
const selected = await ve({
|
|
4617
|
-
message: "Select an MCP",
|
|
4618
|
-
options: deployments.map((d3) => ({
|
|
4619
|
-
label: `${d3.name} ${import_picocolors2.default.dim(`(${d3.org_name})`)}`,
|
|
4620
|
-
value: d3.deployment_id
|
|
4621
|
-
}))
|
|
4622
|
-
});
|
|
4623
|
-
if (pD(selected))
|
|
4624
|
-
return;
|
|
4625
|
-
const deployment = deployments.find((d3) => d3.deployment_id === selected);
|
|
4626
|
-
if (deployment) {
|
|
4627
|
-
cfg.deployment_id = deployment.deployment_id;
|
|
4628
|
-
cfg.deployment_name = deployment.name;
|
|
4629
|
-
saveConfig(cfg);
|
|
4630
|
-
M2.success(`Selected: ${deployment.name}`);
|
|
4631
|
-
}
|
|
4632
|
-
} catch (err) {
|
|
4633
|
-
M2.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4634
|
-
}
|
|
4635
|
-
}
|
|
4636
|
-
async function handleMCPAdd(cfg) {
|
|
4637
|
-
const { allProviders: allProviders2 } = await Promise.resolve().then(() => (init_providers(), exports_providers));
|
|
4638
|
-
const providers = allProviders2();
|
|
4639
|
-
const selected = await ve({
|
|
4640
|
-
message: "Select tool to add MCP to",
|
|
4641
|
-
options: providers.map((p2) => ({
|
|
4642
|
-
label: p2.name(),
|
|
4643
|
-
value: p2.id(),
|
|
4644
|
-
hint: p2.supportsLocal() ? "local + global" : "global only"
|
|
4645
|
-
}))
|
|
4646
|
-
});
|
|
4647
|
-
if (pD(selected))
|
|
4648
|
-
return;
|
|
4649
|
-
const provider = providers.find((p2) => p2.id() === selected);
|
|
4650
|
-
if (!provider)
|
|
4651
|
-
return;
|
|
4652
|
-
try {
|
|
4653
|
-
provider.install(cfg, true);
|
|
4654
|
-
M2.success(`Added Dosu MCP to ${provider.name()}`);
|
|
4655
|
-
} catch (err) {
|
|
4656
|
-
M2.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4657
|
-
}
|
|
4658
|
-
}
|
|
4659
|
-
async function handleMCPRemove(_cfg) {
|
|
4660
|
-
const { allProviders: allProviders2 } = await Promise.resolve().then(() => (init_providers(), exports_providers));
|
|
4661
|
-
const providers = allProviders2();
|
|
4662
|
-
const selected = await ve({
|
|
4663
|
-
message: "Select tool to remove MCP from",
|
|
4664
|
-
options: providers.filter((p2) => p2.id() !== "manual").map((p2) => ({
|
|
4665
|
-
label: p2.name(),
|
|
4666
|
-
value: p2.id()
|
|
4667
|
-
}))
|
|
4668
|
-
});
|
|
4669
|
-
if (pD(selected))
|
|
4670
|
-
return;
|
|
4671
|
-
const provider = providers.find((p2) => p2.id() === selected);
|
|
4672
|
-
if (!provider)
|
|
4673
|
-
return;
|
|
4674
|
-
try {
|
|
4675
|
-
provider.remove(true);
|
|
4676
|
-
M2.success(`Removed Dosu MCP from ${provider.name()}`);
|
|
4677
|
-
} catch (err) {
|
|
4678
|
-
M2.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4679
|
-
}
|
|
4680
|
-
}
|
|
4681
|
-
async function handleAuthenticate(cfg) {
|
|
4682
|
-
if (cfg.access_token) {
|
|
4683
|
-
const s = Y2();
|
|
4684
|
-
s.start("Verifying session...");
|
|
4685
|
-
try {
|
|
4686
|
-
const apiClient = new Client(cfg);
|
|
4687
|
-
const resp = await apiClient.doRequestRaw("GET", "/v1/mcp/deployments");
|
|
4688
|
-
if (resp.status === 200) {
|
|
4689
|
-
s.stop("Already authenticated.");
|
|
4690
|
-
return;
|
|
4691
|
-
}
|
|
4692
|
-
try {
|
|
4693
|
-
await apiClient.refreshToken();
|
|
4694
|
-
s.stop("Session refreshed.");
|
|
4695
|
-
return;
|
|
4696
|
-
} catch {}
|
|
4697
|
-
s.stop("Session expired.");
|
|
4698
|
-
} catch {
|
|
4699
|
-
s.stop("Verification failed.");
|
|
4700
|
-
}
|
|
4701
|
-
}
|
|
4702
|
-
const shouldLogin = await ye({ message: "Open browser to log in?" });
|
|
4703
|
-
if (pD(shouldLogin) || !shouldLogin)
|
|
4704
|
-
return;
|
|
4705
|
-
try {
|
|
4706
|
-
const { startOAuthFlow: startOAuthFlow2 } = await Promise.resolve().then(() => (init_flow(), exports_flow));
|
|
4707
|
-
const s = Y2();
|
|
4708
|
-
s.start("Waiting for authentication...");
|
|
4709
|
-
const token = await startOAuthFlow2(undefined, "/cli/auth");
|
|
4710
|
-
s.stop("Authenticated");
|
|
4711
|
-
cfg.access_token = token.access_token;
|
|
4712
|
-
cfg.refresh_token = token.refresh_token;
|
|
4713
|
-
cfg.expires_at = Math.floor(Date.now() / 1000) + token.expires_in;
|
|
4714
|
-
cfg.mode = token.mode === MODE_OSS ? MODE_OSS : undefined;
|
|
4715
|
-
saveConfig(cfg);
|
|
4716
|
-
} catch (err) {
|
|
4717
|
-
M2.error(`Authentication failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4718
|
-
}
|
|
4719
|
-
}
|
|
4720
|
-
function handleLogout(cfg) {
|
|
4721
|
-
if (!isAuthenticated(cfg)) {
|
|
4722
|
-
M2.warn("You are not logged in.");
|
|
4723
|
-
return;
|
|
4724
|
-
}
|
|
4725
|
-
cfg.access_token = "";
|
|
4726
|
-
cfg.refresh_token = "";
|
|
4727
|
-
cfg.expires_at = 0;
|
|
4728
|
-
cfg.mode = undefined;
|
|
4729
|
-
cfg.deployment_id = undefined;
|
|
4730
|
-
cfg.deployment_name = undefined;
|
|
4731
|
-
cfg.api_key = undefined;
|
|
4732
|
-
saveConfig(cfg);
|
|
4733
|
-
M2.success("Credentials cleared.");
|
|
4734
|
-
}
|
|
4735
|
-
var import_picocolors2, LOGO = `
|
|
4736
|
-
/$$$$$$$
|
|
4737
|
-
| $$__ $$
|
|
4738
|
-
| $$ \\ $$ /$$$$$$ /$$$$$$$ /$$ /$$
|
|
4739
|
-
| $$ | $$ /$$__ $$ /$$_____/| $$ | $$
|
|
4740
|
-
| $$ | $$| $$ \\ $$| $$$$$$ | $$ | $$
|
|
4741
|
-
| $$ | $$| $$ | $$ \\____ $$| $$ | $$
|
|
4742
|
-
| $$$$$$$/| $$$$$$/ /$$$$$$$/| $$$$$$/
|
|
4743
|
-
|_______/ \\______/ |_______/ \\______/
|
|
4744
|
-
`;
|
|
4745
|
-
var init_tui = __esm(() => {
|
|
4746
|
-
init_dist2();
|
|
4747
|
-
init_client();
|
|
4748
|
-
init_config();
|
|
4749
|
-
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
4750
|
-
});
|
|
4751
|
-
|
|
4752
|
-
// src/setup/styles.ts
|
|
4753
|
-
function dim(msg) {
|
|
4754
|
-
return import_picocolors3.default.dim(msg);
|
|
4755
|
-
}
|
|
4756
|
-
function info(msg) {
|
|
4757
|
-
return import_picocolors3.default.cyan(msg);
|
|
4758
|
-
}
|
|
4759
|
-
var import_picocolors3;
|
|
4760
|
-
var init_styles = __esm(() => {
|
|
4761
|
-
import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
4762
|
-
});
|
|
4763
|
-
|
|
4764
4542
|
// src/setup/flow.ts
|
|
4765
4543
|
var exports_flow2 = {};
|
|
4766
4544
|
__export(exports_flow2, {
|
|
@@ -5076,7 +4854,7 @@ ${lines}`);
|
|
|
5076
4854
|
M2.success("All tools already configured. No changes needed.");
|
|
5077
4855
|
}
|
|
5078
4856
|
if (installed.length > 0 || skipped.length > 0) {
|
|
5079
|
-
const prompt = mode === MODE_OSS ? `What can Dosu
|
|
4857
|
+
const prompt = mode === MODE_OSS ? `What can Dosu help me with? Pick an open source library related to my project and explain how it works.` : `I'm new to this codebase. Give me a 5-minute mental model: main services, request flow, where to start.`;
|
|
5080
4858
|
M2.message(`Try it out! Paste this into your agent:
|
|
5081
4859
|
|
|
5082
4860
|
${info(prompt)}`);
|
|
@@ -5090,6 +4868,163 @@ var init_flow2 = __esm(() => {
|
|
|
5090
4868
|
init_styles();
|
|
5091
4869
|
});
|
|
5092
4870
|
|
|
4871
|
+
// src/tui/tui.ts
|
|
4872
|
+
var exports_tui = {};
|
|
4873
|
+
__export(exports_tui, {
|
|
4874
|
+
runTUI: () => runTUI,
|
|
4875
|
+
handleLogout: () => handleLogout
|
|
4876
|
+
});
|
|
4877
|
+
async function runTUI() {
|
|
4878
|
+
console.log(import_picocolors3.default.magenta(LOGO));
|
|
4879
|
+
const cfg = loadConfig();
|
|
4880
|
+
if (!isAuthenticated(cfg)) {
|
|
4881
|
+
await handleAuthenticate(cfg);
|
|
4882
|
+
if (!isAuthenticated(cfg))
|
|
4883
|
+
return;
|
|
4884
|
+
}
|
|
4885
|
+
while (true) {
|
|
4886
|
+
const hasMcpTarget = cfg.mode === MODE_OSS || !!cfg.deployment_id;
|
|
4887
|
+
const action = await ve({
|
|
4888
|
+
message: "What would you like to do?",
|
|
4889
|
+
options: [
|
|
4890
|
+
{
|
|
4891
|
+
label: "Setup",
|
|
4892
|
+
value: "setup",
|
|
4893
|
+
hint: "Configure MCP for your AI tools"
|
|
4894
|
+
},
|
|
4895
|
+
{
|
|
4896
|
+
label: "Authenticate",
|
|
4897
|
+
value: "auth",
|
|
4898
|
+
hint: isAuthenticated(cfg) ? "Re-authenticate" : undefined
|
|
4899
|
+
},
|
|
4900
|
+
{
|
|
4901
|
+
label: "Remove MCP",
|
|
4902
|
+
value: "mcp-remove",
|
|
4903
|
+
hint: !hasMcpTarget ? "Select deployment first" : undefined
|
|
4904
|
+
},
|
|
4905
|
+
{ label: "Clear Credentials", value: "logout" },
|
|
4906
|
+
{ label: "Exit", value: "exit" }
|
|
4907
|
+
]
|
|
4908
|
+
});
|
|
4909
|
+
if (pD(action) || action === "exit") {
|
|
4910
|
+
break;
|
|
4911
|
+
}
|
|
4912
|
+
switch (action) {
|
|
4913
|
+
case "auth":
|
|
4914
|
+
await handleAuthenticate(cfg);
|
|
4915
|
+
break;
|
|
4916
|
+
case "setup":
|
|
4917
|
+
await runSetup();
|
|
4918
|
+
Object.assign(cfg, loadConfig());
|
|
4919
|
+
break;
|
|
4920
|
+
case "mcp-remove":
|
|
4921
|
+
if (!hasMcpTarget) {
|
|
4922
|
+
M2.warn("Please select a deployment first.");
|
|
4923
|
+
continue;
|
|
4924
|
+
}
|
|
4925
|
+
await handleMCPRemove(cfg);
|
|
4926
|
+
break;
|
|
4927
|
+
case "logout":
|
|
4928
|
+
handleLogout(cfg);
|
|
4929
|
+
break;
|
|
4930
|
+
}
|
|
4931
|
+
}
|
|
4932
|
+
Se("Goodbye!");
|
|
4933
|
+
}
|
|
4934
|
+
async function handleMCPRemove(_cfg) {
|
|
4935
|
+
const { allProviders: allProviders2 } = await Promise.resolve().then(() => (init_providers(), exports_providers));
|
|
4936
|
+
const providers = allProviders2();
|
|
4937
|
+
const selected = await ve({
|
|
4938
|
+
message: "Select tool to remove MCP from",
|
|
4939
|
+
options: providers.filter((p2) => p2.id() !== "manual").map((p2) => ({
|
|
4940
|
+
label: p2.name(),
|
|
4941
|
+
value: p2.id()
|
|
4942
|
+
}))
|
|
4943
|
+
});
|
|
4944
|
+
if (pD(selected))
|
|
4945
|
+
return;
|
|
4946
|
+
const provider = providers.find((p2) => p2.id() === selected);
|
|
4947
|
+
if (!provider)
|
|
4948
|
+
return;
|
|
4949
|
+
try {
|
|
4950
|
+
provider.remove(true);
|
|
4951
|
+
M2.success(`Removed Dosu MCP from ${provider.name()}`);
|
|
4952
|
+
} catch (err) {
|
|
4953
|
+
M2.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4954
|
+
}
|
|
4955
|
+
}
|
|
4956
|
+
async function handleAuthenticate(cfg) {
|
|
4957
|
+
if (cfg.access_token) {
|
|
4958
|
+
const s = Y2();
|
|
4959
|
+
s.start("Verifying session...");
|
|
4960
|
+
try {
|
|
4961
|
+
const apiClient = new Client(cfg);
|
|
4962
|
+
const resp = await apiClient.doRequestRaw("GET", "/v1/mcp/deployments");
|
|
4963
|
+
if (resp.status === 200) {
|
|
4964
|
+
s.stop("Already authenticated.");
|
|
4965
|
+
return;
|
|
4966
|
+
}
|
|
4967
|
+
try {
|
|
4968
|
+
await apiClient.refreshToken();
|
|
4969
|
+
s.stop("Session refreshed.");
|
|
4970
|
+
return;
|
|
4971
|
+
} catch {}
|
|
4972
|
+
s.stop("Session expired.");
|
|
4973
|
+
} catch {
|
|
4974
|
+
s.stop("Verification failed.");
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
const shouldLogin = await ye({ message: "Open browser to log in?" });
|
|
4978
|
+
if (pD(shouldLogin) || !shouldLogin)
|
|
4979
|
+
return;
|
|
4980
|
+
try {
|
|
4981
|
+
const { startOAuthFlow: startOAuthFlow2 } = await Promise.resolve().then(() => (init_flow(), exports_flow));
|
|
4982
|
+
const s = Y2();
|
|
4983
|
+
s.start("Waiting for authentication...");
|
|
4984
|
+
const token = await startOAuthFlow2(undefined, "/cli/auth");
|
|
4985
|
+
s.stop("Authenticated");
|
|
4986
|
+
cfg.access_token = token.access_token;
|
|
4987
|
+
cfg.refresh_token = token.refresh_token;
|
|
4988
|
+
cfg.expires_at = Math.floor(Date.now() / 1000) + token.expires_in;
|
|
4989
|
+
cfg.mode = token.mode === MODE_OSS ? MODE_OSS : undefined;
|
|
4990
|
+
saveConfig(cfg);
|
|
4991
|
+
} catch (err) {
|
|
4992
|
+
M2.error(`Authentication failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
4993
|
+
}
|
|
4994
|
+
}
|
|
4995
|
+
function handleLogout(cfg) {
|
|
4996
|
+
if (!isAuthenticated(cfg)) {
|
|
4997
|
+
M2.warn("You are not logged in.");
|
|
4998
|
+
return;
|
|
4999
|
+
}
|
|
5000
|
+
cfg.access_token = "";
|
|
5001
|
+
cfg.refresh_token = "";
|
|
5002
|
+
cfg.expires_at = 0;
|
|
5003
|
+
cfg.mode = undefined;
|
|
5004
|
+
cfg.deployment_id = undefined;
|
|
5005
|
+
cfg.deployment_name = undefined;
|
|
5006
|
+
cfg.api_key = undefined;
|
|
5007
|
+
saveConfig(cfg);
|
|
5008
|
+
M2.success("Credentials cleared.");
|
|
5009
|
+
}
|
|
5010
|
+
var import_picocolors3, LOGO = `
|
|
5011
|
+
/$$$$$$$
|
|
5012
|
+
| $$__ $$
|
|
5013
|
+
| $$ \\ $$ /$$$$$$ /$$$$$$$ /$$ /$$
|
|
5014
|
+
| $$ | $$ /$$__ $$ /$$_____/| $$ | $$
|
|
5015
|
+
| $$ | $$| $$ \\ $$| $$$$$$ | $$ | $$
|
|
5016
|
+
| $$ | $$| $$ | $$ \\____ $$| $$ | $$
|
|
5017
|
+
| $$$$$$$/| $$$$$$/ /$$$$$$$/| $$$$$$/
|
|
5018
|
+
|_______/ \\______/ |_______/ \\______/
|
|
5019
|
+
`;
|
|
5020
|
+
var init_tui = __esm(() => {
|
|
5021
|
+
init_dist2();
|
|
5022
|
+
init_client();
|
|
5023
|
+
init_config();
|
|
5024
|
+
init_flow2();
|
|
5025
|
+
import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
5026
|
+
});
|
|
5027
|
+
|
|
5093
5028
|
// node_modules/commander/esm.mjs
|
|
5094
5029
|
var import__ = __toESM(require_commander(), 1);
|
|
5095
5030
|
var {
|
|
@@ -5111,7 +5046,7 @@ init_config();
|
|
|
5111
5046
|
init_providers();
|
|
5112
5047
|
|
|
5113
5048
|
// src/version/version.ts
|
|
5114
|
-
var VERSION = "0.
|
|
5049
|
+
var VERSION = "0.6.0";
|
|
5115
5050
|
function getVersionString() {
|
|
5116
5051
|
return `v${VERSION}`;
|
|
5117
5052
|
}
|