claudemesh-cli 0.9.4 → 0.9.6
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 +219 -116
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -40093,7 +40093,7 @@ var package_default;
|
|
|
40093
40093
|
var init_package = __esm(() => {
|
|
40094
40094
|
package_default = {
|
|
40095
40095
|
name: "claudemesh-cli",
|
|
40096
|
-
version: "0.9.
|
|
40096
|
+
version: "0.9.6",
|
|
40097
40097
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
40098
40098
|
keywords: [
|
|
40099
40099
|
"claude-code",
|
|
@@ -53943,14 +53943,24 @@ function center(s) {
|
|
|
53943
53943
|
function writeCentered(row, s) {
|
|
53944
53944
|
process.stdout.write(moveTo(row, 1) + center(s) + CLEAR_LINE);
|
|
53945
53945
|
}
|
|
53946
|
-
function drawTopBar() {
|
|
53946
|
+
function drawTopBar(extra) {
|
|
53947
53947
|
const { cols } = termSize();
|
|
53948
|
-
const
|
|
53949
|
-
const
|
|
53950
|
-
const
|
|
53951
|
-
const
|
|
53952
|
-
const
|
|
53953
|
-
|
|
53948
|
+
const bg = "\x1B[48;5;208m\x1B[30m";
|
|
53949
|
+
const reset = "\x1B[0m";
|
|
53950
|
+
const left = ` claudemesh v${VERSION}`;
|
|
53951
|
+
const right = `claudemesh.com `;
|
|
53952
|
+
const mid = extra ? ` ${extra}` : "";
|
|
53953
|
+
const gap = Math.max(1, cols - left.length - right.length - mid.length);
|
|
53954
|
+
process.stdout.write(moveTo(1, 1) + bg + left + mid + " ".repeat(gap) + right + reset);
|
|
53955
|
+
}
|
|
53956
|
+
function drawBottomBar(left, right) {
|
|
53957
|
+
const { cols, rows } = termSize();
|
|
53958
|
+
const bg = "\x1B[48;5;208m\x1B[30m";
|
|
53959
|
+
const reset = "\x1B[0m";
|
|
53960
|
+
const l = ` ${left}`;
|
|
53961
|
+
const r = right ? `${right} ` : "";
|
|
53962
|
+
const gap = Math.max(1, cols - l.length - r.length);
|
|
53963
|
+
process.stdout.write(moveTo(rows, 1) + bg + l + " ".repeat(gap) + r + reset);
|
|
53954
53964
|
}
|
|
53955
53965
|
function enterFullScreen() {
|
|
53956
53966
|
process.stdout.write(HIDE_CURSOR + CLEAR_SCREEN);
|
|
@@ -54000,6 +54010,87 @@ async function menuSelect(opts) {
|
|
|
54000
54010
|
stdin.on("data", onData);
|
|
54001
54011
|
});
|
|
54002
54012
|
}
|
|
54013
|
+
async function textInput(opts) {
|
|
54014
|
+
const { label, row, placeholder } = opts;
|
|
54015
|
+
let value = "";
|
|
54016
|
+
const render = () => {
|
|
54017
|
+
const display = value || dim(placeholder ?? "");
|
|
54018
|
+
const cursor = SHOW_CURSOR;
|
|
54019
|
+
writeCentered(row, `${bold2(label)} ${display}${CLEAR_LINE}`);
|
|
54020
|
+
const fullText = `${label.replace(/\x1b\[[^m]*m/g, "")} ${value}`;
|
|
54021
|
+
const { cols } = termSize();
|
|
54022
|
+
const leftPad = Math.max(0, Math.floor((cols - fullText.length) / 2));
|
|
54023
|
+
process.stdout.write(moveTo(row, leftPad + fullText.length + 1) + cursor);
|
|
54024
|
+
};
|
|
54025
|
+
process.stdout.write(SHOW_CURSOR);
|
|
54026
|
+
render();
|
|
54027
|
+
return new Promise((resolve2) => {
|
|
54028
|
+
const stdin = process.stdin;
|
|
54029
|
+
const wasRaw = stdin.isRaw;
|
|
54030
|
+
stdin.setRawMode(true);
|
|
54031
|
+
stdin.resume();
|
|
54032
|
+
stdin.setEncoding("utf8");
|
|
54033
|
+
const onData = (key) => {
|
|
54034
|
+
if (key === "\r" || key === `
|
|
54035
|
+
`) {
|
|
54036
|
+
stdin.removeListener("data", onData);
|
|
54037
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54038
|
+
stdin.pause();
|
|
54039
|
+
process.stdout.write(HIDE_CURSOR);
|
|
54040
|
+
const final = value || dim("skipped");
|
|
54041
|
+
writeCentered(row, `${label} ${green("✓")} ${final}${CLEAR_LINE}`);
|
|
54042
|
+
resolve2(value);
|
|
54043
|
+
} else if (key === "" || key === "\b") {
|
|
54044
|
+
value = value.slice(0, -1);
|
|
54045
|
+
render();
|
|
54046
|
+
} else if (key === "\x03") {
|
|
54047
|
+
stdin.removeListener("data", onData);
|
|
54048
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54049
|
+
exitFullScreen();
|
|
54050
|
+
process.exit(0);
|
|
54051
|
+
} else if (key === "\x1B") {
|
|
54052
|
+
stdin.removeListener("data", onData);
|
|
54053
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54054
|
+
stdin.pause();
|
|
54055
|
+
process.stdout.write(HIDE_CURSOR);
|
|
54056
|
+
writeCentered(row, `${label} ${dim("skipped")}${CLEAR_LINE}`);
|
|
54057
|
+
resolve2("");
|
|
54058
|
+
} else if (key >= " " && key <= "~") {
|
|
54059
|
+
value += key;
|
|
54060
|
+
render();
|
|
54061
|
+
}
|
|
54062
|
+
};
|
|
54063
|
+
stdin.on("data", onData);
|
|
54064
|
+
});
|
|
54065
|
+
}
|
|
54066
|
+
async function confirmPrompt(opts) {
|
|
54067
|
+
const { message, row } = opts;
|
|
54068
|
+
const defaultYes = opts.defaultYes ?? true;
|
|
54069
|
+
const hint = defaultYes ? `${bold2("Y")}/${dim("n")}` : `${dim("y")}/${bold2("N")}`;
|
|
54070
|
+
writeCentered(row, `${message} [${hint}]`);
|
|
54071
|
+
process.stdout.write(SHOW_CURSOR);
|
|
54072
|
+
return new Promise((resolve2) => {
|
|
54073
|
+
const stdin = process.stdin;
|
|
54074
|
+
const wasRaw = stdin.isRaw;
|
|
54075
|
+
stdin.setRawMode(true);
|
|
54076
|
+
stdin.resume();
|
|
54077
|
+
stdin.setEncoding("utf8");
|
|
54078
|
+
const onData = (key) => {
|
|
54079
|
+
stdin.removeListener("data", onData);
|
|
54080
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54081
|
+
stdin.pause();
|
|
54082
|
+
process.stdout.write(HIDE_CURSOR);
|
|
54083
|
+
if (key === "\x03") {
|
|
54084
|
+
exitFullScreen();
|
|
54085
|
+
process.exit(0);
|
|
54086
|
+
}
|
|
54087
|
+
const yes = key === "y" || key === "Y" || key === "\r" && defaultYes;
|
|
54088
|
+
writeCentered(row, `${message} ${yes ? green("✓ yes") : dim("✗ no")}${CLEAR_LINE}`);
|
|
54089
|
+
resolve2(yes);
|
|
54090
|
+
};
|
|
54091
|
+
stdin.on("data", onData);
|
|
54092
|
+
});
|
|
54093
|
+
}
|
|
54003
54094
|
|
|
54004
54095
|
// src/commands/launch.ts
|
|
54005
54096
|
init_spinner();
|
|
@@ -54034,45 +54125,115 @@ function parseGroupsString(raw) {
|
|
|
54034
54125
|
return { name: token.slice(0, idx), role: token.slice(idx + 1) };
|
|
54035
54126
|
});
|
|
54036
54127
|
}
|
|
54037
|
-
function
|
|
54038
|
-
|
|
54039
|
-
|
|
54040
|
-
|
|
54041
|
-
|
|
54042
|
-
|
|
54043
|
-
|
|
54044
|
-
|
|
54045
|
-
}
|
|
54046
|
-
|
|
54047
|
-
|
|
54048
|
-
|
|
54049
|
-
|
|
54050
|
-
const
|
|
54051
|
-
|
|
54052
|
-
|
|
54053
|
-
|
|
54054
|
-
|
|
54055
|
-
|
|
54056
|
-
|
|
54057
|
-
|
|
54058
|
-
|
|
54059
|
-
|
|
54060
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
54061
|
-
return new Promise((resolve2, reject) => {
|
|
54062
|
-
rl.question(` ${bold3("Continue?")} [Y/n] `, (answer) => {
|
|
54063
|
-
rl.close();
|
|
54064
|
-
const a = answer.trim().toLowerCase();
|
|
54065
|
-
if (a === "" || a === "y" || a === "yes") {
|
|
54066
|
-
resolve2();
|
|
54067
|
-
} else {
|
|
54068
|
-
console.log(`
|
|
54069
|
-
Aborted. Run without autonomous mode:`);
|
|
54070
|
-
console.log(` claude --dangerously-load-development-channels server:claudemesh
|
|
54071
|
-
`);
|
|
54072
|
-
process.exit(0);
|
|
54128
|
+
async function runLaunchWizard(opts) {
|
|
54129
|
+
if (!process.stdout.isTTY) {
|
|
54130
|
+
return {
|
|
54131
|
+
role: opts.existingRole,
|
|
54132
|
+
groups: opts.existingGroups,
|
|
54133
|
+
messageMode: opts.existingMessageMode ?? "push",
|
|
54134
|
+
skipPermissions: opts.skipPermConfirm
|
|
54135
|
+
};
|
|
54136
|
+
}
|
|
54137
|
+
const { rows } = termSize();
|
|
54138
|
+
enterFullScreen();
|
|
54139
|
+
drawTopBar();
|
|
54140
|
+
drawBottomBar("↑↓ navigate ⏎ select esc skip ctrl-c quit", `mesh: ${opts.meshSlug}`);
|
|
54141
|
+
const logoTop = Math.floor((rows - FRAME_HEIGHT - 16) / 2);
|
|
54142
|
+
const brandRow = logoTop + FRAME_HEIGHT + 1;
|
|
54143
|
+
const subtitleRow = brandRow + 1;
|
|
54144
|
+
const formRow = subtitleRow + 2;
|
|
54145
|
+
writeCentered(brandRow, boldOrange("claudemesh"));
|
|
54146
|
+
writeCentered(subtitleRow, dim("peer mesh for Claude Code"));
|
|
54147
|
+
const spinner = createSpinner({
|
|
54148
|
+
render(lines) {
|
|
54149
|
+
for (let i = 0;i < lines.length; i++) {
|
|
54150
|
+
writeCentered(logoTop + i, lines[i]);
|
|
54073
54151
|
}
|
|
54074
|
-
}
|
|
54152
|
+
},
|
|
54153
|
+
interval: 70
|
|
54075
54154
|
});
|
|
54155
|
+
spinner.start();
|
|
54156
|
+
let row = formRow;
|
|
54157
|
+
writeCentered(row, `Directory ${green("✓")} ${process.cwd()}`);
|
|
54158
|
+
row++;
|
|
54159
|
+
writeCentered(row, `Name ${green("✓")} ${opts.displayName}`);
|
|
54160
|
+
row++;
|
|
54161
|
+
writeCentered(row, `Mesh ${green("✓")} ${opts.meshSlug}`);
|
|
54162
|
+
row += 2;
|
|
54163
|
+
let role = opts.existingRole;
|
|
54164
|
+
let groups = opts.existingGroups;
|
|
54165
|
+
let messageMode = opts.existingMessageMode ?? "push";
|
|
54166
|
+
if (role === null) {
|
|
54167
|
+
spinner.stop();
|
|
54168
|
+
const answer = await textInput({ label: "Role", row, placeholder: "optional — press Enter to skip" });
|
|
54169
|
+
if (answer)
|
|
54170
|
+
role = answer;
|
|
54171
|
+
spinner.start();
|
|
54172
|
+
row++;
|
|
54173
|
+
} else {
|
|
54174
|
+
writeCentered(row, `Role ${green("✓")} ${role}`);
|
|
54175
|
+
row++;
|
|
54176
|
+
}
|
|
54177
|
+
if (groups.length === 0) {
|
|
54178
|
+
spinner.stop();
|
|
54179
|
+
const answer = await textInput({ label: "Groups", row, placeholder: "comma-separated, optional" });
|
|
54180
|
+
if (answer)
|
|
54181
|
+
groups = parseGroupsString(answer);
|
|
54182
|
+
spinner.start();
|
|
54183
|
+
row++;
|
|
54184
|
+
} else {
|
|
54185
|
+
const tags = groups.map((g) => `@${g.name}${g.role ? `:${g.role}` : ""}`).join(", ");
|
|
54186
|
+
writeCentered(row, `Groups ${green("✓")} ${tags}`);
|
|
54187
|
+
row++;
|
|
54188
|
+
}
|
|
54189
|
+
if (opts.existingMessageMode === null) {
|
|
54190
|
+
row++;
|
|
54191
|
+
spinner.stop();
|
|
54192
|
+
const choice = await menuSelect({
|
|
54193
|
+
title: "Message mode",
|
|
54194
|
+
items: [
|
|
54195
|
+
"Push (real-time, peers can interrupt)",
|
|
54196
|
+
"Inbox (held until you check)",
|
|
54197
|
+
"Off (tools only, no messages)"
|
|
54198
|
+
],
|
|
54199
|
+
row
|
|
54200
|
+
});
|
|
54201
|
+
messageMode = ["push", "inbox", "off"][choice];
|
|
54202
|
+
spinner.start();
|
|
54203
|
+
row += 5;
|
|
54204
|
+
} else {
|
|
54205
|
+
writeCentered(row, `Messages ${green("✓")} ${messageMode}`);
|
|
54206
|
+
row++;
|
|
54207
|
+
}
|
|
54208
|
+
let skipPermissions = opts.skipPermConfirm;
|
|
54209
|
+
if (!skipPermissions) {
|
|
54210
|
+
row++;
|
|
54211
|
+
spinner.stop();
|
|
54212
|
+
writeCentered(row, dim("Claude will run with --dangerously-skip-permissions,"));
|
|
54213
|
+
writeCentered(row + 1, dim("bypassing ALL permission prompts — not just claudemesh."));
|
|
54214
|
+
row += 3;
|
|
54215
|
+
const confirmed = await confirmPrompt({
|
|
54216
|
+
message: boldOrange("Autonomous mode?"),
|
|
54217
|
+
row,
|
|
54218
|
+
defaultYes: true
|
|
54219
|
+
});
|
|
54220
|
+
if (!confirmed) {
|
|
54221
|
+
exitFullScreen();
|
|
54222
|
+
console.log(" Run without autonomous mode:");
|
|
54223
|
+
console.log(` claude --dangerously-load-development-channels server:claudemesh
|
|
54224
|
+
`);
|
|
54225
|
+
process.exit(0);
|
|
54226
|
+
}
|
|
54227
|
+
skipPermissions = true;
|
|
54228
|
+
spinner.start();
|
|
54229
|
+
}
|
|
54230
|
+
row += 2;
|
|
54231
|
+
writeCentered(row, dim("Launching Claude Code..."));
|
|
54232
|
+
drawBottomBar(`${opts.displayName} on ${opts.meshSlug}`, `mode: ${messageMode}`);
|
|
54233
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
54234
|
+
spinner.stop();
|
|
54235
|
+
exitFullScreen();
|
|
54236
|
+
return { role, groups, messageMode, skipPermissions };
|
|
54076
54237
|
}
|
|
54077
54238
|
function printBanner(name, meshSlug, role, groups, messageMode) {
|
|
54078
54239
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
@@ -54095,44 +54256,6 @@ function printBanner(name, meshSlug, role, groups, messageMode) {
|
|
|
54095
54256
|
console.log(rule);
|
|
54096
54257
|
console.log("");
|
|
54097
54258
|
}
|
|
54098
|
-
async function showLaunchSplash(name, meshSlug, role, groups, messageMode) {
|
|
54099
|
-
if (!process.stdout.isTTY)
|
|
54100
|
-
return;
|
|
54101
|
-
const { rows } = termSize();
|
|
54102
|
-
enterFullScreen();
|
|
54103
|
-
drawTopBar();
|
|
54104
|
-
const logoTop = Math.floor((rows - FRAME_HEIGHT - 10) / 2);
|
|
54105
|
-
const brandRow = logoTop + FRAME_HEIGHT + 1;
|
|
54106
|
-
const subtitleRow = brandRow + 1;
|
|
54107
|
-
const infoRow = subtitleRow + 2;
|
|
54108
|
-
writeCentered(brandRow, boldOrange("claudemesh"));
|
|
54109
|
-
writeCentered(subtitleRow, dim("peer mesh for Claude Code"));
|
|
54110
|
-
const spinner = createSpinner({
|
|
54111
|
-
render(lines) {
|
|
54112
|
-
for (let i = 0;i < lines.length; i++) {
|
|
54113
|
-
writeCentered(logoTop + i, lines[i]);
|
|
54114
|
-
}
|
|
54115
|
-
},
|
|
54116
|
-
interval: 70
|
|
54117
|
-
});
|
|
54118
|
-
spinner.start();
|
|
54119
|
-
const roleSuffix = role ? ` (${role})` : "";
|
|
54120
|
-
const groupStr = groups.length ? " " + groups.map((g) => dim(`@${g.name}`)).join(", ") : "";
|
|
54121
|
-
const steps = [
|
|
54122
|
-
{ label: `Identity`, value: `${name}${roleSuffix}` },
|
|
54123
|
-
{ label: `Mesh`, value: meshSlug },
|
|
54124
|
-
{ label: `Messages`, value: messageMode }
|
|
54125
|
-
];
|
|
54126
|
-
for (let i = 0;i < steps.length; i++) {
|
|
54127
|
-
await new Promise((r) => setTimeout(r, 300));
|
|
54128
|
-
writeCentered(infoRow + i, `${steps[i].label} ${green("✓")} ${steps[i].value}${i === 0 ? groupStr : ""}`);
|
|
54129
|
-
}
|
|
54130
|
-
await new Promise((r) => setTimeout(r, 400));
|
|
54131
|
-
writeCentered(infoRow + steps.length + 1, dim("Launching Claude Code..."));
|
|
54132
|
-
await new Promise((r) => setTimeout(r, 600));
|
|
54133
|
-
spinner.stop();
|
|
54134
|
-
exitFullScreen();
|
|
54135
|
-
}
|
|
54136
54259
|
async function runLaunch(flags, rawArgs) {
|
|
54137
54260
|
const dashIdx = rawArgs.indexOf("--");
|
|
54138
54261
|
const claudePassthrough = dashIdx >= 0 ? rawArgs.slice(dashIdx + 1) : [];
|
|
@@ -54266,34 +54389,18 @@ async function runLaunch(flags, rawArgs) {
|
|
|
54266
54389
|
let parsedGroups = args.groups ? parseGroupsString(args.groups) : [];
|
|
54267
54390
|
let messageMode = args.messageMode ?? "push";
|
|
54268
54391
|
if (!args.quiet && !justSynced) {
|
|
54269
|
-
|
|
54270
|
-
|
|
54271
|
-
|
|
54272
|
-
|
|
54273
|
-
|
|
54274
|
-
|
|
54275
|
-
|
|
54276
|
-
|
|
54277
|
-
|
|
54278
|
-
|
|
54279
|
-
|
|
54280
|
-
|
|
54281
|
-
Message mode:`);
|
|
54282
|
-
console.log(" 1) Push (real-time, peers can interrupt your work)");
|
|
54283
|
-
console.log(" 2) Inbox (held until you check, notification only)");
|
|
54284
|
-
console.log(" 3) Off (tools only, no messages)");
|
|
54285
|
-
console.log("");
|
|
54286
|
-
const answer = await askLine(" Choice [1]: ");
|
|
54287
|
-
const choice = parseInt(answer || "1", 10);
|
|
54288
|
-
if (choice === 2)
|
|
54289
|
-
messageMode = "inbox";
|
|
54290
|
-
else if (choice === 3)
|
|
54291
|
-
messageMode = "off";
|
|
54292
|
-
else
|
|
54293
|
-
messageMode = "push";
|
|
54294
|
-
}
|
|
54295
|
-
if (role || parsedGroups.length)
|
|
54296
|
-
console.log("");
|
|
54392
|
+
const wizardResult = await runLaunchWizard({
|
|
54393
|
+
displayName,
|
|
54394
|
+
meshSlug: mesh.slug,
|
|
54395
|
+
existingRole: args.role,
|
|
54396
|
+
existingGroups: parsedGroups,
|
|
54397
|
+
existingMessageMode: args.messageMode ?? null,
|
|
54398
|
+
skipPermConfirm: args.skipPermConfirm
|
|
54399
|
+
});
|
|
54400
|
+
role = wizardResult.role;
|
|
54401
|
+
parsedGroups = wizardResult.groups;
|
|
54402
|
+
messageMode = wizardResult.messageMode;
|
|
54403
|
+
args.skipPermConfirm = wizardResult.skipPermissions;
|
|
54297
54404
|
}
|
|
54298
54405
|
const tmpBase = tmpdir();
|
|
54299
54406
|
try {
|
|
@@ -54356,12 +54463,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
54356
54463
|
writeFileSync4(join4(tmpDir, "config.json"), JSON.stringify(sessionConfig, null, 2) + `
|
|
54357
54464
|
`, "utf-8");
|
|
54358
54465
|
if (!args.quiet) {
|
|
54359
|
-
await showLaunchSplash(displayName, mesh.slug, role, parsedGroups, messageMode);
|
|
54360
54466
|
printBanner(displayName, mesh.slug, role, parsedGroups, messageMode);
|
|
54361
|
-
if (!args.skipPermConfirm) {
|
|
54362
|
-
await confirmPermissions();
|
|
54363
|
-
args.skipPermConfirm = true;
|
|
54364
|
-
}
|
|
54365
54467
|
}
|
|
54366
54468
|
const meshMcpEntries = [];
|
|
54367
54469
|
if (serviceCatalog.length > 0) {
|
|
@@ -54799,6 +54901,7 @@ async function runWelcome() {
|
|
|
54799
54901
|
const { rows } = termSize();
|
|
54800
54902
|
enterFullScreen();
|
|
54801
54903
|
drawTopBar();
|
|
54904
|
+
drawBottomBar("↑↓ navigate ⏎ select ctrl-c quit", "claudemesh.com");
|
|
54802
54905
|
const logoTop = Math.floor((rows - FRAME_HEIGHT - 10) / 2);
|
|
54803
54906
|
const brandRow = logoTop + FRAME_HEIGHT + 1;
|
|
54804
54907
|
const subtitleRow = brandRow + 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudemesh-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.6",
|
|
4
4
|
"description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"prettier": "3.6.2",
|
|
49
49
|
"typescript": "5.9.3",
|
|
50
50
|
"vitest": "4.0.14",
|
|
51
|
-
"@turbostarter/prettier-config": "0.1.0",
|
|
52
|
-
"@turbostarter/eslint-config": "0.1.0",
|
|
53
51
|
"@turbostarter/vitest-config": "0.1.0",
|
|
54
|
-
"@turbostarter/tsconfig": "0.1.0"
|
|
52
|
+
"@turbostarter/tsconfig": "0.1.0",
|
|
53
|
+
"@turbostarter/prettier-config": "0.1.0",
|
|
54
|
+
"@turbostarter/eslint-config": "0.1.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "bun build src/index.ts --target=node --outfile dist/index.js --banner \"#!/usr/bin/env node\" && chmod +x dist/index.js",
|