bertrand 0.15.0 → 0.17.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/bertrand.js +209 -87
- package/dist/dashboard/assets/bash-Yzrsuije.js +1 -0
- package/dist/dashboard/assets/css-DPfMkruS.js +1 -0
- package/dist/dashboard/assets/html-GMplVEZG.js +1 -0
- package/dist/dashboard/assets/index-e53khqNa.js +673 -0
- package/dist/dashboard/assets/index-qVHXGTGL.css +1 -0
- package/dist/dashboard/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/dashboard/assets/json-Cp-IABpG.js +1 -0
- package/dist/dashboard/assets/jsx-g9-lgVsj.js +1 -0
- package/dist/dashboard/assets/markdown-Cvjx9yec.js +1 -0
- package/dist/dashboard/assets/python-B6aJPvgy.js +1 -0
- package/dist/dashboard/assets/tsx-COt5Ahok.js +1 -0
- package/dist/dashboard/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/dashboard/assets/vitesse-black-Bkuqu6BP.js +1 -0
- package/dist/dashboard/assets/vitesse-light-CVO1_9PV.js +1 -0
- package/dist/dashboard/assets/workbox-window.prod.es5-BBnX5xw4.js +2 -0
- package/dist/dashboard/icon.svg +13 -0
- package/dist/dashboard/index.html +28 -0
- package/dist/dashboard/manifest.webmanifest +1 -0
- package/dist/dashboard/sw.js +1 -0
- package/dist/dashboard/workbox-e4022e15.js +1 -0
- package/dist/run-screen.js +507 -146
- package/package.json +1 -1
package/dist/bertrand.js
CHANGED
|
@@ -1193,6 +1193,15 @@ var init_session_archive = __esm(() => {
|
|
|
1193
1193
|
|
|
1194
1194
|
// src/server/index.ts
|
|
1195
1195
|
import { execFile } from "child_process";
|
|
1196
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1197
|
+
import { join as join3 } from "path";
|
|
1198
|
+
function liveStats(sessionId) {
|
|
1199
|
+
return {
|
|
1200
|
+
sessionId,
|
|
1201
|
+
...computeSessionStats(sessionId),
|
|
1202
|
+
updatedAt: new Date().toISOString()
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1196
1205
|
function archiveResponse(result) {
|
|
1197
1206
|
if (result.ok)
|
|
1198
1207
|
return Response.json(result.session);
|
|
@@ -1236,10 +1245,33 @@ function match(pathname, url) {
|
|
|
1236
1245
|
}
|
|
1237
1246
|
return Response.json({ error: "Not found" }, { status: 404 });
|
|
1238
1247
|
}
|
|
1248
|
+
function findDashboardDir() {
|
|
1249
|
+
const candidates = [
|
|
1250
|
+
join3(import.meta.dir, "dashboard"),
|
|
1251
|
+
join3(import.meta.dir, "..", "dashboard")
|
|
1252
|
+
];
|
|
1253
|
+
for (const dir of candidates) {
|
|
1254
|
+
if (existsSync3(join3(dir, "index.html")))
|
|
1255
|
+
return dir;
|
|
1256
|
+
}
|
|
1257
|
+
return null;
|
|
1258
|
+
}
|
|
1259
|
+
async function serveDashboard(pathname) {
|
|
1260
|
+
if (!DASHBOARD_DIR)
|
|
1261
|
+
return null;
|
|
1262
|
+
const requested = pathname === "/" ? "/index.html" : pathname;
|
|
1263
|
+
const filePath = join3(DASHBOARD_DIR, requested);
|
|
1264
|
+
if (!filePath.startsWith(DASHBOARD_DIR))
|
|
1265
|
+
return null;
|
|
1266
|
+
const file = Bun.file(filePath);
|
|
1267
|
+
if (await file.exists())
|
|
1268
|
+
return new Response(file);
|
|
1269
|
+
return new Response(Bun.file(join3(DASHBOARD_DIR, "index.html")));
|
|
1270
|
+
}
|
|
1239
1271
|
function startServer(port = PORT) {
|
|
1240
1272
|
const server = Bun.serve({
|
|
1241
1273
|
port,
|
|
1242
|
-
fetch(req) {
|
|
1274
|
+
async fetch(req) {
|
|
1243
1275
|
const url = new URL(req.url);
|
|
1244
1276
|
if (req.method === "OPTIONS") {
|
|
1245
1277
|
return new Response(null, {
|
|
@@ -1251,10 +1283,9 @@ function startServer(port = PORT) {
|
|
|
1251
1283
|
});
|
|
1252
1284
|
}
|
|
1253
1285
|
if (req.method === "POST" && url.pathname === "/api/open") {
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
});
|
|
1286
|
+
const r = await handleOpen(req);
|
|
1287
|
+
r.headers.set("Access-Control-Allow-Origin", "*");
|
|
1288
|
+
return r;
|
|
1258
1289
|
}
|
|
1259
1290
|
if (req.method === "POST") {
|
|
1260
1291
|
const archiveMatch = /^\/api\/sessions\/([^/]+)\/archive$/.exec(url.pathname);
|
|
@@ -1270,15 +1301,55 @@ function startServer(port = PORT) {
|
|
|
1270
1301
|
return response2;
|
|
1271
1302
|
}
|
|
1272
1303
|
}
|
|
1304
|
+
if (url.pathname.startsWith("/api/")) {
|
|
1305
|
+
const response2 = match(url.pathname, url);
|
|
1306
|
+
response2.headers.set("Access-Control-Allow-Origin", "*");
|
|
1307
|
+
return response2;
|
|
1308
|
+
}
|
|
1309
|
+
const dashboardResponse = await serveDashboard(url.pathname);
|
|
1310
|
+
if (dashboardResponse)
|
|
1311
|
+
return dashboardResponse;
|
|
1273
1312
|
const response = match(url.pathname, url);
|
|
1274
1313
|
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
1275
1314
|
return response;
|
|
1276
1315
|
}
|
|
1277
1316
|
});
|
|
1278
|
-
|
|
1317
|
+
const dashboardNote = DASHBOARD_DIR ? " (with bundled dashboard)" : "";
|
|
1318
|
+
console.log(`bertrand API server listening on http://localhost:${server.port}${dashboardNote}`);
|
|
1279
1319
|
return server;
|
|
1280
1320
|
}
|
|
1281
|
-
var PORT,
|
|
1321
|
+
var PORT, listSessions = (_params, url) => {
|
|
1322
|
+
const excludeArchived = url.searchParams.get("excludeArchived") !== "false";
|
|
1323
|
+
return getAllSessions({ excludeArchived });
|
|
1324
|
+
}, getSessionById = ({ id }) => getSession(id), listEvents = ({ sessionId }, url) => {
|
|
1325
|
+
const eventType = url.searchParams.get("type");
|
|
1326
|
+
if (eventType)
|
|
1327
|
+
return getEventsByType(sessionId, eventType);
|
|
1328
|
+
return getEventsBySession(sessionId);
|
|
1329
|
+
}, listAllStats = () => {
|
|
1330
|
+
const result = {};
|
|
1331
|
+
for (const { session } of getAllSessions()) {
|
|
1332
|
+
const isLive = session.status === "active" || session.status === "waiting";
|
|
1333
|
+
if (isLive) {
|
|
1334
|
+
result[session.id] = liveStats(session.id);
|
|
1335
|
+
continue;
|
|
1336
|
+
}
|
|
1337
|
+
result[session.id] = getSessionStats(session.id) ?? liveStats(session.id);
|
|
1338
|
+
}
|
|
1339
|
+
return result;
|
|
1340
|
+
}, getStatsBySession = ({
|
|
1341
|
+
sessionId
|
|
1342
|
+
}) => {
|
|
1343
|
+
const session = getSession(sessionId);
|
|
1344
|
+
if (!session)
|
|
1345
|
+
return null;
|
|
1346
|
+
const isLive = session.status === "active" || session.status === "waiting";
|
|
1347
|
+
if (isLive)
|
|
1348
|
+
return liveStats(sessionId);
|
|
1349
|
+
return getSessionStats(sessionId) ?? liveStats(sessionId);
|
|
1350
|
+
}, getEngagement = ({
|
|
1351
|
+
sessionId
|
|
1352
|
+
}) => computeEngagementStats(sessionId), listRecaps = () => getLatestRecaps(), routes, ARCHIVE_ERROR, DASHBOARD_DIR;
|
|
1282
1353
|
var init_server = __esm(() => {
|
|
1283
1354
|
init_sessions();
|
|
1284
1355
|
init_events();
|
|
@@ -1288,53 +1359,13 @@ var init_server = __esm(() => {
|
|
|
1288
1359
|
init_session_archive();
|
|
1289
1360
|
PORT = Number(process.env.BERTRAND_PORT ?? 5200);
|
|
1290
1361
|
routes = [
|
|
1291
|
-
[/^\/api\/sessions$/,
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
[/^\/api\/
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
[/^\/api\/events\/(?<sessionId>[^/]+)$/, ({ sessionId }, url) => {
|
|
1299
|
-
const eventType = url.searchParams.get("type");
|
|
1300
|
-
if (eventType)
|
|
1301
|
-
return getEventsByType(sessionId, eventType);
|
|
1302
|
-
return getEventsBySession(sessionId);
|
|
1303
|
-
}],
|
|
1304
|
-
[/^\/api\/stats$/, () => {
|
|
1305
|
-
const all = getAllSessions();
|
|
1306
|
-
const now = new Date().toISOString();
|
|
1307
|
-
const result = {};
|
|
1308
|
-
for (const { session } of all) {
|
|
1309
|
-
const isLive = session.status === "active" || session.status === "waiting";
|
|
1310
|
-
if (isLive) {
|
|
1311
|
-
result[session.id] = { sessionId: session.id, ...computeSessionStats(session.id), updatedAt: now };
|
|
1312
|
-
continue;
|
|
1313
|
-
}
|
|
1314
|
-
const stored = getSessionStats(session.id);
|
|
1315
|
-
result[session.id] = stored ?? { sessionId: session.id, ...computeSessionStats(session.id), updatedAt: now };
|
|
1316
|
-
}
|
|
1317
|
-
return result;
|
|
1318
|
-
}],
|
|
1319
|
-
[/^\/api\/stats\/(?<sessionId>[^/]+)$/, ({ sessionId }) => {
|
|
1320
|
-
const session = getSession(sessionId);
|
|
1321
|
-
if (!session)
|
|
1322
|
-
return null;
|
|
1323
|
-
const isLive = session.status === "active" || session.status === "waiting";
|
|
1324
|
-
if (isLive) {
|
|
1325
|
-
return { sessionId, ...computeSessionStats(sessionId), updatedAt: new Date().toISOString() };
|
|
1326
|
-
}
|
|
1327
|
-
const stored = getSessionStats(sessionId);
|
|
1328
|
-
if (stored)
|
|
1329
|
-
return stored;
|
|
1330
|
-
return { sessionId, ...computeSessionStats(sessionId), updatedAt: new Date().toISOString() };
|
|
1331
|
-
}],
|
|
1332
|
-
[/^\/api\/engagement\/(?<sessionId>[^/]+)$/, ({ sessionId }) => {
|
|
1333
|
-
return computeEngagementStats(sessionId);
|
|
1334
|
-
}],
|
|
1335
|
-
[/^\/api\/recaps$/, () => {
|
|
1336
|
-
return getLatestRecaps();
|
|
1337
|
-
}]
|
|
1362
|
+
[/^\/api\/sessions$/, listSessions],
|
|
1363
|
+
[/^\/api\/sessions\/(?<id>[^/]+)$/, getSessionById],
|
|
1364
|
+
[/^\/api\/events\/(?<sessionId>[^/]+)$/, listEvents],
|
|
1365
|
+
[/^\/api\/stats$/, listAllStats],
|
|
1366
|
+
[/^\/api\/stats\/(?<sessionId>[^/]+)$/, getStatsBySession],
|
|
1367
|
+
[/^\/api\/engagement\/(?<sessionId>[^/]+)$/, getEngagement],
|
|
1368
|
+
[/^\/api\/recaps$/, listRecaps]
|
|
1338
1369
|
];
|
|
1339
1370
|
ARCHIVE_ERROR = {
|
|
1340
1371
|
"not-found": { status: 404, message: "Session not found" },
|
|
@@ -1342,6 +1373,7 @@ var init_server = __esm(() => {
|
|
|
1342
1373
|
"already-archived": { status: 409, message: "Session is already archived" },
|
|
1343
1374
|
"not-archived": { status: 409, message: "Session is not archived" }
|
|
1344
1375
|
};
|
|
1376
|
+
DASHBOARD_DIR = findDashboardDir();
|
|
1345
1377
|
});
|
|
1346
1378
|
|
|
1347
1379
|
// src/cli/commands/serve.ts
|
|
@@ -1650,6 +1682,92 @@ var init_spawn_context = __esm(() => {
|
|
|
1650
1682
|
execFileAsync = promisify(execFile2);
|
|
1651
1683
|
});
|
|
1652
1684
|
|
|
1685
|
+
// src/lib/server-lifecycle.ts
|
|
1686
|
+
import { spawn as spawn2 } from "child_process";
|
|
1687
|
+
import { readFileSync as readFileSync3, writeFileSync, unlinkSync } from "fs";
|
|
1688
|
+
import { join as join4 } from "path";
|
|
1689
|
+
function readPidFile() {
|
|
1690
|
+
try {
|
|
1691
|
+
const pid = Number(readFileSync3(deps.pidFile, "utf-8").trim());
|
|
1692
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
1693
|
+
} catch {
|
|
1694
|
+
return null;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
function isProcessAlive(pid) {
|
|
1698
|
+
try {
|
|
1699
|
+
process.kill(pid, 0);
|
|
1700
|
+
return true;
|
|
1701
|
+
} catch {
|
|
1702
|
+
return false;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
async function isPortListening(port) {
|
|
1706
|
+
try {
|
|
1707
|
+
await fetch(`http://localhost:${port}/api/sessions`, {
|
|
1708
|
+
signal: AbortSignal.timeout(500)
|
|
1709
|
+
});
|
|
1710
|
+
return true;
|
|
1711
|
+
} catch {
|
|
1712
|
+
return false;
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
function removePidFile() {
|
|
1716
|
+
try {
|
|
1717
|
+
unlinkSync(deps.pidFile);
|
|
1718
|
+
} catch {}
|
|
1719
|
+
}
|
|
1720
|
+
async function ensureServerStarted() {
|
|
1721
|
+
const existingPid = readPidFile();
|
|
1722
|
+
if (existingPid && isProcessAlive(existingPid))
|
|
1723
|
+
return;
|
|
1724
|
+
if (existingPid)
|
|
1725
|
+
removePidFile();
|
|
1726
|
+
if (await isPortListening(deps.port))
|
|
1727
|
+
return;
|
|
1728
|
+
const bin = deps.resolveBin();
|
|
1729
|
+
if (!bin)
|
|
1730
|
+
return;
|
|
1731
|
+
const child = spawn2(bin, ["serve"], {
|
|
1732
|
+
detached: true,
|
|
1733
|
+
stdio: "ignore",
|
|
1734
|
+
env: { ...process.env, BERTRAND_PORT: String(deps.port) }
|
|
1735
|
+
});
|
|
1736
|
+
child.unref();
|
|
1737
|
+
if (child.pid)
|
|
1738
|
+
writeFileSync(deps.pidFile, String(child.pid));
|
|
1739
|
+
}
|
|
1740
|
+
function stopServerIfIdle() {
|
|
1741
|
+
if (deps.getActiveCount() > 0)
|
|
1742
|
+
return;
|
|
1743
|
+
const pid = readPidFile();
|
|
1744
|
+
if (!pid)
|
|
1745
|
+
return;
|
|
1746
|
+
try {
|
|
1747
|
+
process.kill(pid, "SIGTERM");
|
|
1748
|
+
} catch {}
|
|
1749
|
+
removePidFile();
|
|
1750
|
+
}
|
|
1751
|
+
var defaultDeps, deps;
|
|
1752
|
+
var init_server_lifecycle = __esm(() => {
|
|
1753
|
+
init_paths();
|
|
1754
|
+
init_sessions();
|
|
1755
|
+
defaultDeps = {
|
|
1756
|
+
pidFile: join4(paths.root, "server.pid"),
|
|
1757
|
+
port: Number(process.env.BERTRAND_PORT ?? 5200),
|
|
1758
|
+
resolveBin() {
|
|
1759
|
+
try {
|
|
1760
|
+
const config = JSON.parse(readFileSync3(join4(paths.root, "config.json"), "utf-8"));
|
|
1761
|
+
return typeof config?.bin === "string" ? config.bin : null;
|
|
1762
|
+
} catch {
|
|
1763
|
+
return null;
|
|
1764
|
+
}
|
|
1765
|
+
},
|
|
1766
|
+
getActiveCount: () => getActiveSessions().length
|
|
1767
|
+
};
|
|
1768
|
+
deps = defaultDeps;
|
|
1769
|
+
});
|
|
1770
|
+
|
|
1653
1771
|
// src/engine/session.ts
|
|
1654
1772
|
import { randomUUID } from "crypto";
|
|
1655
1773
|
async function launch(opts) {
|
|
@@ -1676,6 +1794,7 @@ async function launch(opts) {
|
|
|
1676
1794
|
sessionId: session.id
|
|
1677
1795
|
});
|
|
1678
1796
|
updateSession(session.id, { status: "active", pid: process.pid });
|
|
1797
|
+
await ensureServerStarted();
|
|
1679
1798
|
const spawnContext = await captureSpawnContext();
|
|
1680
1799
|
const sessionName = `${opts.groupPath}/${opts.slug}`;
|
|
1681
1800
|
insertEvent({
|
|
@@ -1721,6 +1840,7 @@ async function resume(opts) {
|
|
|
1721
1840
|
const group = getGroup(session.groupId);
|
|
1722
1841
|
const sessionName = group ? `${group.path}/${session.slug}` : session.name;
|
|
1723
1842
|
updateSession(session.id, { status: "active", pid: process.pid });
|
|
1843
|
+
await ensureServerStarted();
|
|
1724
1844
|
insertEvent({
|
|
1725
1845
|
sessionId: session.id,
|
|
1726
1846
|
conversationId: opts.conversationId,
|
|
@@ -1765,6 +1885,7 @@ function finalizeSession(sessionId, conversationId, exitCode) {
|
|
|
1765
1885
|
event: "session.end"
|
|
1766
1886
|
});
|
|
1767
1887
|
computeAndPersist(sessionId);
|
|
1888
|
+
stopServerIfIdle();
|
|
1768
1889
|
}
|
|
1769
1890
|
var init_session = __esm(() => {
|
|
1770
1891
|
init_sessions();
|
|
@@ -1777,16 +1898,17 @@ var init_session = __esm(() => {
|
|
|
1777
1898
|
init_process();
|
|
1778
1899
|
init_spawn_context();
|
|
1779
1900
|
init_timing();
|
|
1901
|
+
init_server_lifecycle();
|
|
1780
1902
|
});
|
|
1781
1903
|
|
|
1782
1904
|
// src/tui/app.tsx
|
|
1783
|
-
import { spawn as
|
|
1784
|
-
import { existsSync as
|
|
1785
|
-
import { join as
|
|
1905
|
+
import { spawn as spawn3 } from "child_process";
|
|
1906
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
1907
|
+
import { join as join5 } from "path";
|
|
1786
1908
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1787
1909
|
async function runScreen(screen, ...args) {
|
|
1788
1910
|
const tmpFile = `/tmp/bertrand-tui-${process.pid}-${Date.now()}.json`;
|
|
1789
|
-
const child =
|
|
1911
|
+
const child = spawn3("bun", ["run", SCREEN_ENTRY, screen, tmpFile, ...args], {
|
|
1790
1912
|
stdio: "inherit"
|
|
1791
1913
|
});
|
|
1792
1914
|
const exitCode = await new Promise((resolve) => {
|
|
@@ -1795,8 +1917,8 @@ async function runScreen(screen, ...args) {
|
|
|
1795
1917
|
if (exitCode !== 0) {
|
|
1796
1918
|
throw new Error(`TUI screen "${screen}" exited with code ${exitCode}`);
|
|
1797
1919
|
}
|
|
1798
|
-
const result = JSON.parse(
|
|
1799
|
-
|
|
1920
|
+
const result = JSON.parse(readFileSync4(tmpFile, "utf-8"));
|
|
1921
|
+
unlinkSync2(tmpFile);
|
|
1800
1922
|
return result;
|
|
1801
1923
|
}
|
|
1802
1924
|
async function startLaunchTui() {
|
|
@@ -1880,8 +2002,8 @@ var init_app = __esm(() => {
|
|
|
1880
2002
|
init_session_archive();
|
|
1881
2003
|
init_session();
|
|
1882
2004
|
SCREEN_ENTRY = (() => {
|
|
1883
|
-
const built =
|
|
1884
|
-
return
|
|
2005
|
+
const built = join5(import.meta.dir, "run-screen.js");
|
|
2006
|
+
return existsSync4(built) ? built : join5(import.meta.dir, "run-screen.tsx");
|
|
1885
2007
|
})();
|
|
1886
2008
|
});
|
|
1887
2009
|
|
|
@@ -1906,7 +2028,7 @@ function parseSessionName(input) {
|
|
|
1906
2028
|
}
|
|
1907
2029
|
|
|
1908
2030
|
// src/engine/recovery.ts
|
|
1909
|
-
function
|
|
2031
|
+
function isProcessAlive2(pid) {
|
|
1910
2032
|
try {
|
|
1911
2033
|
process.kill(pid, 0);
|
|
1912
2034
|
return true;
|
|
@@ -1918,7 +2040,7 @@ function recoverStaleSessions() {
|
|
|
1918
2040
|
const active = getActiveSessions();
|
|
1919
2041
|
let recovered = 0;
|
|
1920
2042
|
for (const { session } of active) {
|
|
1921
|
-
if (session.pid && !
|
|
2043
|
+
if (session.pid && !isProcessAlive2(session.pid)) {
|
|
1922
2044
|
updateSession(session.id, {
|
|
1923
2045
|
status: "paused",
|
|
1924
2046
|
pid: null
|
|
@@ -2254,13 +2376,13 @@ var init_scripts = __esm(() => {
|
|
|
2254
2376
|
});
|
|
2255
2377
|
|
|
2256
2378
|
// src/hooks/install.ts
|
|
2257
|
-
import { mkdirSync as mkdirSync3, writeFileSync, chmodSync } from "fs";
|
|
2258
|
-
import { join as
|
|
2379
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync2, chmodSync } from "fs";
|
|
2380
|
+
import { join as join6 } from "path";
|
|
2259
2381
|
function installHookScripts(bin) {
|
|
2260
2382
|
mkdirSync3(paths.hooks, { recursive: true });
|
|
2261
2383
|
for (const [filename, scriptFn] of Object.entries(HOOK_SCRIPTS)) {
|
|
2262
|
-
const filePath =
|
|
2263
|
-
|
|
2384
|
+
const filePath = join6(paths.hooks, filename);
|
|
2385
|
+
writeFileSync2(filePath, scriptFn(bin));
|
|
2264
2386
|
chmodSync(filePath, 493);
|
|
2265
2387
|
}
|
|
2266
2388
|
console.log(`Installed ${Object.keys(HOOK_SCRIPTS).length} hook scripts to ${paths.hooks}`);
|
|
@@ -2271,8 +2393,8 @@ var init_install = __esm(() => {
|
|
|
2271
2393
|
});
|
|
2272
2394
|
|
|
2273
2395
|
// src/hooks/settings.ts
|
|
2274
|
-
import { readFileSync as
|
|
2275
|
-
import { join as
|
|
2396
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "fs";
|
|
2397
|
+
import { join as join7, dirname as dirname3 } from "path";
|
|
2276
2398
|
import { homedir as homedir2 } from "os";
|
|
2277
2399
|
function isBertrandGroup(group) {
|
|
2278
2400
|
return group.hooks?.some((h) => h.command?.includes(".bertrand/hooks/")) ?? false;
|
|
@@ -2280,7 +2402,7 @@ function isBertrandGroup(group) {
|
|
|
2280
2402
|
function installHookSettings() {
|
|
2281
2403
|
let settings = {};
|
|
2282
2404
|
try {
|
|
2283
|
-
settings = JSON.parse(
|
|
2405
|
+
settings = JSON.parse(readFileSync5(SETTINGS_PATH, "utf-8"));
|
|
2284
2406
|
} catch {}
|
|
2285
2407
|
const existingHooks = settings.hooks && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? settings.hooks : {};
|
|
2286
2408
|
const merged = { ...existingHooks };
|
|
@@ -2290,14 +2412,14 @@ function installHookSettings() {
|
|
|
2290
2412
|
}
|
|
2291
2413
|
settings.hooks = merged;
|
|
2292
2414
|
mkdirSync4(dirname3(SETTINGS_PATH), { recursive: true });
|
|
2293
|
-
|
|
2415
|
+
writeFileSync3(SETTINGS_PATH, JSON.stringify(settings, null, 2) + `
|
|
2294
2416
|
`);
|
|
2295
2417
|
console.log(`Updated ${SETTINGS_PATH} with bertrand hooks`);
|
|
2296
2418
|
}
|
|
2297
2419
|
var SETTINGS_PATH, BERTRAND_HOOKS;
|
|
2298
2420
|
var init_settings = __esm(() => {
|
|
2299
2421
|
init_paths();
|
|
2300
|
-
SETTINGS_PATH =
|
|
2422
|
+
SETTINGS_PATH = join7(homedir2(), ".claude", "settings.json");
|
|
2301
2423
|
BERTRAND_HOOKS = {
|
|
2302
2424
|
PreToolUse: [
|
|
2303
2425
|
{
|
|
@@ -2341,8 +2463,8 @@ var init_settings = __esm(() => {
|
|
|
2341
2463
|
});
|
|
2342
2464
|
|
|
2343
2465
|
// src/lib/completions.ts
|
|
2344
|
-
import { writeFileSync as
|
|
2345
|
-
import { join as
|
|
2466
|
+
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "fs";
|
|
2467
|
+
import { join as join8 } from "path";
|
|
2346
2468
|
function bashCompletion() {
|
|
2347
2469
|
return `# bertrand bash completion
|
|
2348
2470
|
_bertrand() {
|
|
@@ -2372,11 +2494,11 @@ function fishCompletion() {
|
|
|
2372
2494
|
`;
|
|
2373
2495
|
}
|
|
2374
2496
|
function generateCompletions() {
|
|
2375
|
-
const dir =
|
|
2497
|
+
const dir = join8(paths.root, "completions");
|
|
2376
2498
|
mkdirSync5(dir, { recursive: true });
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2499
|
+
writeFileSync4(join8(dir, "bertrand.bash"), bashCompletion());
|
|
2500
|
+
writeFileSync4(join8(dir, "_bertrand"), zshCompletion());
|
|
2501
|
+
writeFileSync4(join8(dir, "bertrand.fish"), fishCompletion());
|
|
2380
2502
|
console.log(`Shell completions written to ${dir}`);
|
|
2381
2503
|
console.log(" Add to your shell config:");
|
|
2382
2504
|
console.log(` bash: source ${dir}/bertrand.bash`);
|
|
@@ -2403,9 +2525,9 @@ var init_completions = __esm(() => {
|
|
|
2403
2525
|
|
|
2404
2526
|
// src/cli/commands/init.ts
|
|
2405
2527
|
var exports_init = {};
|
|
2406
|
-
import { mkdirSync as mkdirSync6, readFileSync as
|
|
2528
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5, chmodSync as chmodSync2 } from "fs";
|
|
2407
2529
|
import { execSync as execSync2 } from "child_process";
|
|
2408
|
-
import { join as
|
|
2530
|
+
import { join as join9 } from "path";
|
|
2409
2531
|
function detectTerminal() {
|
|
2410
2532
|
try {
|
|
2411
2533
|
execSync2("which wsh", { stdio: "ignore" });
|
|
@@ -2415,12 +2537,12 @@ function detectTerminal() {
|
|
|
2415
2537
|
}
|
|
2416
2538
|
}
|
|
2417
2539
|
function writeConfig(config) {
|
|
2418
|
-
|
|
2540
|
+
writeFileSync5(CONFIG_PATH, JSON.stringify(config, null, 2) + `
|
|
2419
2541
|
`);
|
|
2420
2542
|
}
|
|
2421
2543
|
function readConfig() {
|
|
2422
2544
|
try {
|
|
2423
|
-
return JSON.parse(
|
|
2545
|
+
return JSON.parse(readFileSync6(CONFIG_PATH, "utf-8"));
|
|
2424
2546
|
} catch {
|
|
2425
2547
|
return null;
|
|
2426
2548
|
}
|
|
@@ -2431,10 +2553,10 @@ function resolveBin() {
|
|
|
2431
2553
|
return onPath;
|
|
2432
2554
|
const entry = process.argv[1];
|
|
2433
2555
|
if (entry && SOURCE_ENTRY.test(entry)) {
|
|
2434
|
-
const launcherDir =
|
|
2435
|
-
const launcher =
|
|
2556
|
+
const launcherDir = join9(paths.root, "bin");
|
|
2557
|
+
const launcher = join9(launcherDir, "bertrand-dev");
|
|
2436
2558
|
mkdirSync6(launcherDir, { recursive: true });
|
|
2437
|
-
|
|
2559
|
+
writeFileSync5(launcher, `#!/usr/bin/env bash
|
|
2438
2560
|
exec ${process.execPath} ${JSON.stringify(entry)} "$@"
|
|
2439
2561
|
`);
|
|
2440
2562
|
chmodSync2(launcher, 493);
|
|
@@ -2450,7 +2572,7 @@ var init_init = __esm(() => {
|
|
|
2450
2572
|
init_settings();
|
|
2451
2573
|
init_paths();
|
|
2452
2574
|
init_completions();
|
|
2453
|
-
CONFIG_PATH =
|
|
2575
|
+
CONFIG_PATH = join9(paths.root, "config.json");
|
|
2454
2576
|
SOURCE_ENTRY = /\/src\/index\.tsx?$/;
|
|
2455
2577
|
register("init", async () => {
|
|
2456
2578
|
console.log(`bertrand init
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=Object.freeze(JSON.parse(`{"displayName":"Shell","name":"shellscript","patterns":[{"include":"#initial_context"}],"repository":{"alias_statement":{"begin":"[\\\\t ]*+(alias)[\\\\t ]*+((?:((?<!\\\\w)-\\\\w+)\\\\b[\\\\t ]*+)*)[\\\\t ]*+((?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w))(?:(\\\\[)((?:(?:\\\\$?(?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w)|@)|\\\\*)|(-?\\\\d+))(]))?(?:(?:(=)|(\\\\+=))|(-=))","beginCaptures":{"1":{"name":"storage.type.alias.shell"},"2":{"patterns":[{"match":"(?<!\\\\w)-\\\\w+\\\\b","name":"string.unquoted.argument.shell constant.other.option.shell"}]},"3":{"name":"string.unquoted.argument.shell constant.other.option.shell"},"4":{"name":"variable.other.assignment.shell"},"5":{"name":"punctuation.definition.array.access.shell"},"6":{"name":"variable.other.assignment.shell"},"7":{"name":"constant.numeric.shell constant.numeric.integer.shell"},"8":{"name":"punctuation.definition.array.access.shell"},"9":{"name":"keyword.operator.assignment.shell"},"10":{"name":"keyword.operator.assignment.compound.shell"},"11":{"name":"keyword.operator.assignment.compound.shell"}},"end":"(?=[\\\\t ]|$)|(?:(?:(?:(;)|(&&))|(\\\\|\\\\|))|(&))","endCaptures":{"1":{"name":"punctuation.terminator.statement.semicolon.shell"},"2":{"name":"punctuation.separator.statement.and.shell"},"3":{"name":"punctuation.separator.statement.or.shell"},"4":{"name":"punctuation.separator.statement.background.shell"}},"name":"meta.expression.assignment.alias.shell","patterns":[{"include":"#normal_context"}]},"argument":{"begin":"[\\\\t ]++(?![\\\\n#\\\\&(\\\\[|]|$|;)","beginCaptures":{},"end":"(?=[\\\\t \\\\&;|]|$|[\\\\n)\`])","endCaptures":{},"name":"meta.argument.shell","patterns":[{"include":"#argument_context"},{"include":"#line_continuation"}]},"argument_context":{"patterns":[{"captures":{"1":{"name":"string.unquoted.argument.shell","patterns":[{"match":"\\\\*","name":"variable.language.special.wildcard.shell"},{"include":"#variable"},{"include":"#numeric_literal"},{"captures":{"1":{"name":"constant.language.$1.shell"}},"match":"(?<!\\\\w)\\\\b(true|false)\\\\b(?!\\\\w)"}]}},"match":"[\\\\t ]*+([^\\\\t\\\\n \\"$\\\\&-);<>\\\\\\\\\`|]+(?!>))"},{"include":"#normal_context"}]},"arithmetic_double":{"patterns":[{"begin":"\\\\(\\\\(","beginCaptures":{"0":{"name":"punctuation.section.arithmetic.double.shell"}},"end":"\\\\)\\\\s*\\\\)","endCaptures":{"0":{"name":"punctuation.section.arithmetic.double.shell"}},"name":"meta.arithmetic.shell","patterns":[{"include":"#math"},{"include":"#string"}]}]},"arithmetic_no_dollar":{"patterns":[{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.section.arithmetic.single.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.section.arithmetic.single.shell"}},"name":"meta.arithmetic.shell","patterns":[{"include":"#math"},{"include":"#string"}]}]},"array_access_inline":{"captures":{"1":{"name":"punctuation.section.array.shell"},"2":{"patterns":[{"include":"#special_expansion"},{"include":"#string"},{"include":"#variable"}]},"3":{"name":"punctuation.section.array.shell"}},"match":"(\\\\[)([^]\\\\[]+)(])"},"array_value":{"begin":"[\\\\t ]*+((?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w))(?:(\\\\[)((?:(?:\\\\$?(?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w)|@)|\\\\*)|(-?\\\\d+))(]))?(?:(?:(=)|(\\\\+=))|(-=))[\\\\t ]*+(\\\\()","beginCaptures":{"1":{"name":"variable.other.assignment.shell"},"2":{"name":"punctuation.definition.array.access.shell"},"3":{"name":"variable.other.assignment.shell"},"4":{"name":"constant.numeric.shell constant.numeric.integer.shell"},"5":{"name":"punctuation.definition.array.access.shell"},"6":{"name":"keyword.operator.assignment.shell"},"7":{"name":"keyword.operator.assignment.compound.shell"},"8":{"name":"keyword.operator.assignment.compound.shell"},"9":{"name":"punctuation.definition.array.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.array.shell"}},"patterns":[{"include":"#comment"},{"captures":{"1":{"name":"variable.other.assignment.array.shell entity.other.attribute-name.shell"},"2":{"name":"keyword.operator.assignment.shell punctuation.definition.assignment.shell"}},"match":"((?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w))(=)"},{"captures":{"1":{"name":"punctuation.definition.bracket.named-array.shell"},"2":{"name":"string.unquoted.shell entity.other.attribute-name.bracket.shell"},"3":{"name":"punctuation.definition.bracket.named-array.shell"},"4":{"name":"punctuation.definition.assignment.shell"}},"match":"(\\\\[)(.+?)(])(=)"},{"include":"#normal_context"},{"include":"#simple_unquoted"}]},"assignment_statement":{"patterns":[{"include":"#array_value"},{"include":"#modified_assignment_statement"},{"include":"#normal_assignment_statement"}]},"basic_command_name":{"captures":{"1":{"name":"storage.modifier.$1.shell"},"2":{"name":"entity.name.function.call.shell entity.name.command.shell","patterns":[{"match":"(?<!\\\\w)(?:continue|return|break)(?!\\\\w)","name":"keyword.control.$0.shell"},{"match":"(?<!\\\\w)(?:unfunction|continue|autoload|unsetopt|bindkey|builtin|getopts|command|declare|unalias|history|unlimit|typeset|suspend|source|printf|unhash|disown|ulimit|return|which|alias|break|false|print|shift|times|umask|unset|read|type|exec|eval|wait|echo|dirs|jobs|kill|hash|stat|exit|test|trap|true|let|set|pwd|cd|fg|bg|fc|[.:])(?!/)(?!\\\\w)(?!-)","name":"support.function.builtin.shell"},{"include":"#variable"}]}},"match":"(?![\\\\n!#\\\\&()<>\\\\[{|]|$|[\\\\t ;])(?!nocorrect |nocorrect\\\\t|nocorrect$|readonly |readonly\\\\t|readonly$|function |function\\\\t|function$|foreach |foreach\\\\t|foreach$|coproc |coproc\\\\t|coproc$|logout |logout\\\\t|logout$|export |export\\\\t|export$|select |select\\\\t|select$|repeat |repeat\\\\t|repeat$|pushd |pushd\\\\t|pushd$|until |until\\\\t|until$|while |while\\\\t|while$|local |local\\\\t|local$|case |case\\\\t|case$|done |done\\\\t|done$|elif |elif\\\\t|elif$|else |else\\\\t|else$|esac |esac\\\\t|esac$|popd |popd\\\\t|popd$|then |then\\\\t|then$|time |time\\\\t|time$|for |for\\\\t|for$|end |end\\\\t|end$|fi |fi\\\\t|fi$|do |do\\\\t|do$|in |in\\\\t|in$|if |if\\\\t|if$)(?:((?<=^|[\\\\t \\\\&;])(?:readonly|declare|typeset|export|local)(?=[\\\\t \\\\&;]|$))|((?![\\"']|\\\\\\\\\\\\n?$)[^\\\\t\\\\n\\\\r !\\"'<>]+?))(?:(?=[\\\\t ])|(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\))","name":"meta.statement.command.name.basic.shell"},"block_comment":{"begin":"\\\\s*+(/\\\\*)","beginCaptures":{"1":{"name":"punctuation.definition.comment.begin.shell"}},"end":"\\\\*/","endCaptures":{"0":{"name":"punctuation.definition.comment.end.shell"}},"name":"comment.block.shell"},"boolean":{"match":"\\\\b(?:true|false)\\\\b","name":"constant.language.$0.shell"},"case_statement":{"begin":"\\\\b(case)\\\\b[\\\\t ]*+(.+?)[\\\\t ]*+\\\\b(in)\\\\b","beginCaptures":{"1":{"name":"keyword.control.case.shell"},"2":{"patterns":[{"include":"#initial_context"}]},"3":{"name":"keyword.control.in.shell"}},"end":"\\\\besac\\\\b","endCaptures":{"0":{"name":"keyword.control.esac.shell"}},"name":"meta.case.shell","patterns":[{"include":"#comment"},{"captures":{"1":{"name":"keyword.operator.pattern.case.default.shell"}},"match":"[\\\\t ]*+(\\\\* *\\\\))"},{"begin":"(?<!\\\\))(?![\\\\t ]*+(?:esac\\\\b|$))","beginCaptures":{},"end":"(?=\\\\besac\\\\b)|(\\\\))","endCaptures":{"1":{"name":"keyword.operator.pattern.case.shell"}},"name":"meta.case.entry.pattern.shell","patterns":[{"include":"#case_statement_context"}]},{"begin":"(?<=\\\\))","beginCaptures":{},"end":"(;;)|(?=\\\\besac\\\\b)","endCaptures":{"1":{"name":"punctuation.terminator.statement.case.shell"}},"name":"meta.case.entry.body.shell","patterns":[{"include":"#typical_statements"},{"include":"#initial_context"}]}]},"case_statement_context":{"patterns":[{"match":"\\\\*","name":"variable.language.special.quantifier.star.shell keyword.operator.quantifier.star.shell punctuation.definition.arbitrary-repetition.shell punctuation.definition.regex.arbitrary-repetition.shell"},{"match":"\\\\+","name":"variable.language.special.quantifier.plus.shell keyword.operator.quantifier.plus.shell punctuation.definition.arbitrary-repetition.shell punctuation.definition.regex.arbitrary-repetition.shell"},{"match":"\\\\?","name":"variable.language.special.quantifier.question.shell keyword.operator.quantifier.question.shell punctuation.definition.arbitrary-repetition.shell punctuation.definition.regex.arbitrary-repetition.shell"},{"match":"@","name":"variable.language.special.at.shell keyword.operator.at.shell punctuation.definition.regex.at.shell"},{"match":"\\\\|","name":"keyword.operator.orvariable.language.special.or.shell keyword.operator.alternation.ruby.shell punctuation.definition.regex.alternation.shell punctuation.separator.regex.alternation.shell"},{"match":"\\\\\\\\.","name":"constant.character.escape.shell"},{"match":"(?<=\\\\tin| in|[\\\\t ]|;;)\\\\(","name":"keyword.operator.pattern.case.shell"},{"begin":"(?<=\\\\S)(\\\\()","beginCaptures":{"1":{"name":"punctuation.definition.group.shell punctuation.definition.regex.group.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.group.shell punctuation.definition.regex.group.shell"}},"name":"meta.parenthese.shell","patterns":[{"include":"#case_statement_context"}]},{"begin":"\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.character-class.shell"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.character-class.shell"}},"name":"string.regexp.character-class.shell","patterns":[{"match":"\\\\\\\\.","name":"constant.character.escape.shell"}]},{"include":"#string"},{"match":"[^\\\\t\\\\n )*?@\\\\[|]","name":"string.unquoted.pattern.shell string.regexp.unquoted.shell"}]},"command_name_range":{"begin":"\\\\G","beginCaptures":{},"end":"(?=[\\\\t \\\\&;|]|$|[\\\\n)\`])|(?=<)","endCaptures":{},"name":"meta.statement.command.name.shell","patterns":[{"match":"(?<!\\\\w)(?:continue|return|break)(?!\\\\w)","name":"entity.name.function.call.shell entity.name.command.shell keyword.control.$0.shell"},{"match":"(?<!\\\\w)(?:unfunction|continue|autoload|unsetopt|bindkey|builtin|getopts|command|declare|unalias|history|unlimit|typeset|suspend|source|printf|unhash|disown|ulimit|return|which|alias|break|false|print|shift|times|umask|unset|read|type|exec|eval|wait|echo|dirs|jobs|kill|hash|stat|exit|test|trap|true|let|set|pwd|cd|fg|bg|fc|[.:])(?!/)(?!\\\\w)(?!-)","name":"entity.name.function.call.shell entity.name.command.shell support.function.builtin.shell"},{"include":"#variable"},{"captures":{"1":{"name":"entity.name.function.call.shell entity.name.command.shell"}},"match":"(?<!\\\\w)(?<=\\\\G|[\\"')}])([^\\\\t\\\\n\\\\r \\"\\\\&');->\`{|]+)"},{"begin":"(?:\\\\G|(?<![\\\\t\\\\n #\\\\&;{|]))(\\\\$?)((\\")|('))","beginCaptures":{"1":{"name":"meta.statement.command.name.quoted.shell punctuation.definition.string.shell entity.name.function.call.shell entity.name.command.shell"},"2":{},"3":{"name":"meta.statement.command.name.quoted.shell string.quoted.double.shell punctuation.definition.string.begin.shell entity.name.function.call.shell entity.name.command.shell"},"4":{"name":"meta.statement.command.name.quoted.shell string.quoted.single.shell punctuation.definition.string.begin.shell entity.name.function.call.shell entity.name.command.shell"}},"end":"(?<!\\\\G)(?<=\\\\2)","endCaptures":{},"patterns":[{"include":"#continuation_of_single_quoted_command_name"},{"include":"#continuation_of_double_quoted_command_name"}]},{"include":"#line_continuation"},{"include":"#simple_unquoted"}]},"command_statement":{"begin":"[\\\\t ]*+(?![\\\\n!#\\\\&()<>\\\\[{|]|$|[\\\\t ;])(?!nocorrect |nocorrect\\\\t|nocorrect$|readonly |readonly\\\\t|readonly$|function |function\\\\t|function$|foreach |foreach\\\\t|foreach$|coproc |coproc\\\\t|coproc$|logout |logout\\\\t|logout$|export |export\\\\t|export$|select |select\\\\t|select$|repeat |repeat\\\\t|repeat$|pushd |pushd\\\\t|pushd$|until |until\\\\t|until$|while |while\\\\t|while$|local |local\\\\t|local$|case |case\\\\t|case$|done |done\\\\t|done$|elif |elif\\\\t|elif$|else |else\\\\t|else$|esac |esac\\\\t|esac$|popd |popd\\\\t|popd$|then |then\\\\t|then$|time |time\\\\t|time$|for |for\\\\t|for$|end |end\\\\t|end$|fi |fi\\\\t|fi$|do |do\\\\t|do$|in |in\\\\t|in$|if |if\\\\t|if$)(?!\\\\\\\\\\\\n?$)","beginCaptures":{},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.statement.command.shell","patterns":[{"include":"#command_name_range"},{"include":"#line_continuation"},{"include":"#option"},{"include":"#argument"},{"include":"#string"},{"include":"#heredoc"}]},"comment":{"captures":{"1":{"name":"comment.line.number-sign.shell meta.shebang.shell"},"2":{"name":"punctuation.definition.comment.shebang.shell"},"3":{"name":"comment.line.number-sign.shell"},"4":{"name":"punctuation.definition.comment.shell"}},"match":"(?:^|[\\\\t ]++)(?:((#!).*)|((#).*))"},"comments":{"patterns":[{"include":"#block_comment"},{"include":"#line_comment"}]},"compound-command":{"patterns":[{"begin":"\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.logical-expression.shell"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.logical-expression.shell"}},"name":"meta.scope.logical-expression.shell","patterns":[{"include":"#logical-expression"},{"include":"#initial_context"}]},{"begin":"(?<=\\\\s|^)\\\\{(?=\\\\s|$)","beginCaptures":{"0":{"name":"punctuation.definition.group.shell"}},"end":"(?<=^|;)\\\\s*(})","endCaptures":{"1":{"name":"punctuation.definition.group.shell"}},"name":"meta.scope.group.shell","patterns":[{"include":"#initial_context"}]}]},"continuation_of_double_quoted_command_name":{"begin":"\\\\G(?<=\\")","beginCaptures":{},"contentName":"meta.statement.command.name.continuation string.quoted.double entity.name.function.call entity.name.command","end":"\\"","endCaptures":{"0":{"name":"string.quoted.double.shell punctuation.definition.string.end.shell entity.name.function.call.shell entity.name.command.shell"}},"patterns":[{"match":"\\\\\\\\[\\\\n\\"$\\\\\\\\\`]","name":"constant.character.escape.shell"},{"include":"#variable"},{"include":"#interpolation"}]},"continuation_of_single_quoted_command_name":{"begin":"\\\\G(?<=')","beginCaptures":{},"contentName":"meta.statement.command.name.continuation string.quoted.single entity.name.function.call entity.name.command","end":"'","endCaptures":{"0":{"name":"string.quoted.single.shell punctuation.definition.string.end.shell entity.name.function.call.shell entity.name.command.shell"}}},"custom_command_names":{"patterns":[]},"custom_commands":{"patterns":[]},"double_quote_context":{"patterns":[{"match":"\\\\\\\\[\\\\n\\"$\\\\\\\\\`]","name":"constant.character.escape.shell"},{"include":"#variable"},{"include":"#interpolation"}]},"double_quote_escape_char":{"match":"\\\\\\\\[\\\\n\\"$\\\\\\\\\`]","name":"constant.character.escape.shell"},"floating_keyword":{"patterns":[{"match":"(?<=^|[\\\\t \\\\&;])(?:then|elif|else|done|end|do|if|fi)(?=[\\\\t \\\\&;]|$)","name":"keyword.control.$0.shell"}]},"for_statement":{"patterns":[{"begin":"\\\\b(for)\\\\b[\\\\t ]*+((?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w))[\\\\t ]*+\\\\b(in)\\\\b","beginCaptures":{"1":{"name":"keyword.control.for.shell"},"2":{"name":"variable.other.for.shell"},"3":{"name":"keyword.control.in.shell"}},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.for.in.shell","patterns":[{"include":"#string"},{"include":"#simple_unquoted"},{"include":"#normal_context"}]},{"begin":"\\\\b(for)\\\\b","beginCaptures":{"1":{"name":"keyword.control.for.shell"}},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.for.shell","patterns":[{"include":"#arithmetic_double"},{"include":"#normal_context"}]}]},"function_definition":{"applyEndPatternLast":1,"begin":"[\\\\t ]*+(?:\\\\b(function)\\\\b[\\\\t ]*+([^\\\\t\\\\n\\\\r \\"'()=]+)(?:(\\\\()[\\\\t ]*+(\\\\)))?|([^\\\\t\\\\n\\\\r \\"'()=]+)[\\\\t ]*+(\\\\()[\\\\t ]*+(\\\\)))","beginCaptures":{"1":{"name":"storage.type.function.shell"},"2":{"name":"entity.name.function.shell"},"3":{"name":"punctuation.definition.arguments.shell"},"4":{"name":"punctuation.definition.arguments.shell"},"5":{"name":"entity.name.function.shell"},"6":{"name":"punctuation.definition.arguments.shell"},"7":{"name":"punctuation.definition.arguments.shell"}},"end":"(?<=[)}])","endCaptures":{},"name":"meta.function.shell","patterns":[{"match":"\\\\G[\\\\t\\\\n ]"},{"begin":"\\\\{","beginCaptures":{"0":{"name":"punctuation.definition.group.shell punctuation.section.function.definition.shell"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.group.shell punctuation.section.function.definition.shell"}},"name":"meta.function.body.shell","patterns":[{"include":"#initial_context"}]},{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.group.shell punctuation.section.function.definition.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.group.shell punctuation.section.function.definition.shell"}},"name":"meta.function.body.shell","patterns":[{"include":"#initial_context"}]},{"include":"#initial_context"}]},"heredoc":{"patterns":[{"begin":"((?<!<)<<-)[\\\\t ]*+([\\"'])[\\\\t ]*+([^\\"']+?)(?=[\\"\\\\&';<\\\\s])(\\\\2)(.*)","beginCaptures":{"1":{"name":"keyword.operator.heredoc.shell"},"2":{"name":"punctuation.definition.string.heredoc.quote.shell"},"3":{"name":"punctuation.definition.string.heredoc.delimiter.shell"},"4":{"name":"punctuation.definition.string.heredoc.quote.shell"},"5":{"patterns":[{"include":"#redirect_fix"},{"include":"#typical_statements"}]}},"contentName":"string.quoted.heredoc.indent.$3","end":"^\\\\t*\\\\3(?=[\\\\&;\\\\s]|$)","endCaptures":{"0":{"name":"punctuation.definition.string.heredoc.$0.shell"}},"patterns":[]},{"begin":"((?<!<)<<(?!<))[\\\\t ]*+([\\"'])[\\\\t ]*+([^\\"']+?)(?=[\\"\\\\&';<\\\\s])(\\\\2)(.*)","beginCaptures":{"1":{"name":"keyword.operator.heredoc.shell"},"2":{"name":"punctuation.definition.string.heredoc.quote.shell"},"3":{"name":"punctuation.definition.string.heredoc.delimiter.shell"},"4":{"name":"punctuation.definition.string.heredoc.quote.shell"},"5":{"patterns":[{"include":"#redirect_fix"},{"include":"#typical_statements"}]}},"contentName":"string.quoted.heredoc.no-indent.$3","end":"^\\\\3(?=[\\\\&;\\\\s]|$)","endCaptures":{"0":{"name":"punctuation.definition.string.heredoc.delimiter.shell"}},"patterns":[]},{"begin":"((?<!<)<<-)[\\\\t ]*+([^\\\\t \\"']+)(?=[\\"\\\\&';<\\\\s])(.*)","beginCaptures":{"1":{"name":"keyword.operator.heredoc.shell"},"2":{"name":"punctuation.definition.string.heredoc.delimiter.shell"},"3":{"patterns":[{"include":"#redirect_fix"},{"include":"#typical_statements"}]}},"contentName":"string.unquoted.heredoc.indent.$2","end":"^\\\\t*\\\\2(?=[\\\\&;\\\\s]|$)","endCaptures":{"0":{"name":"punctuation.definition.string.heredoc.delimiter.shell"}},"patterns":[{"include":"#double_quote_escape_char"},{"include":"#variable"},{"include":"#interpolation"}]},{"begin":"((?<!<)<<(?!<))[\\\\t ]*+([^\\\\t \\"']+)(?=[\\"\\\\&';<\\\\s])(.*)","beginCaptures":{"1":{"name":"keyword.operator.heredoc.shell"},"2":{"name":"punctuation.definition.string.heredoc.delimiter.shell"},"3":{"patterns":[{"include":"#redirect_fix"},{"include":"#typical_statements"}]}},"contentName":"string.unquoted.heredoc.no-indent.$2","end":"^\\\\2(?=[\\\\&;\\\\s]|$)","endCaptures":{"0":{"name":"punctuation.definition.string.heredoc.delimiter.shell"}},"patterns":[{"include":"#double_quote_escape_char"},{"include":"#variable"},{"include":"#interpolation"}]}]},"herestring":{"patterns":[{"begin":"(<<<)\\\\s*(('))","beginCaptures":{"1":{"name":"keyword.operator.herestring.shell"},"2":{"name":"string.quoted.single.shell"},"3":{"name":"punctuation.definition.string.begin.shell"}},"contentName":"string.quoted.single.shell","end":"(')","endCaptures":{"0":{"name":"string.quoted.single.shell"},"1":{"name":"punctuation.definition.string.end.shell"}},"name":"meta.herestring.shell"},{"begin":"(<<<)\\\\s*((\\"))","beginCaptures":{"1":{"name":"keyword.operator.herestring.shell"},"2":{"name":"string.quoted.double.shell"},"3":{"name":"punctuation.definition.string.begin.shell"}},"contentName":"string.quoted.double.shell","end":"(\\")","endCaptures":{"0":{"name":"string.quoted.double.shell"},"1":{"name":"punctuation.definition.string.end.shell"}},"name":"meta.herestring.shell","patterns":[{"include":"#double_quote_context"}]},{"captures":{"1":{"name":"keyword.operator.herestring.shell"},"2":{"name":"string.unquoted.herestring.shell","patterns":[{"include":"#initial_context"}]}},"match":"(<<<)\\\\s*(([^)\\\\\\\\\\\\s]|\\\\\\\\.)+)","name":"meta.herestring.shell"}]},"initial_context":{"patterns":[{"include":"#comment"},{"include":"#pipeline"},{"include":"#normal_statement_seperator"},{"include":"#logical_expression_double"},{"include":"#logical_expression_single"},{"include":"#assignment_statement"},{"include":"#case_statement"},{"include":"#for_statement"},{"include":"#loop"},{"include":"#function_definition"},{"include":"#line_continuation"},{"include":"#arithmetic_double"},{"include":"#misc_ranges"},{"include":"#variable"},{"include":"#interpolation"},{"include":"#heredoc"},{"include":"#herestring"},{"include":"#redirection"},{"include":"#pathname"},{"include":"#floating_keyword"},{"include":"#alias_statement"},{"include":"#normal_statement"},{"include":"#string"},{"include":"#support"}]},"inline_comment":{"captures":{"1":{"name":"comment.block.shell punctuation.definition.comment.begin.shell"},"2":{"name":"comment.block.shell"},"3":{"patterns":[{"match":"\\\\*/","name":"comment.block.shell punctuation.definition.comment.end.shell"},{"match":"\\\\*","name":"comment.block.shell"}]}},"match":"(/\\\\*)((?:[^*]|\\\\*++[^/])*+(\\\\*++/))"},"interpolation":{"patterns":[{"include":"#arithmetic_dollar"},{"include":"#subshell_dollar"},{"begin":"\`","beginCaptures":{"0":{"name":"punctuation.definition.evaluation.backticks.shell"}},"end":"\`","endCaptures":{"0":{"name":"punctuation.definition.evaluation.backticks.shell"}},"name":"string.interpolated.backtick.shell","patterns":[{"match":"\\\\\\\\[$\\\\\\\\\`]","name":"constant.character.escape.shell"},{"begin":"(?<=\\\\W)(?=#)(?!#\\\\{)","beginCaptures":{"1":{"name":"punctuation.whitespace.comment.leading.shell"}},"end":"(?!\\\\G)","patterns":[{"begin":"#","beginCaptures":{"0":{"name":"punctuation.definition.comment.shell"}},"end":"(?=\`)","name":"comment.line.number-sign.shell"}]},{"include":"#initial_context"}]}]},"keyword":{"patterns":[{"match":"(?<=^|[\\\\&;\\\\s])(then|else|elif|fi|for|in|do|done|select|continue|esac|while|until|return)(?=[\\\\&;\\\\s]|$)","name":"keyword.control.shell"},{"match":"(?<=^|[\\\\&;\\\\s])(?:export|declare|typeset|local|readonly)(?=[\\\\&;\\\\s]|$)","name":"storage.modifier.shell"}]},"line_comment":{"begin":"\\\\s*+(//)","beginCaptures":{"1":{"name":"punctuation.definition.comment.shell"}},"end":"(?<=\\\\n)(?<!\\\\\\\\\\\\n)","endCaptures":{},"name":"comment.line.double-slash.shell","patterns":[{"include":"#line_continuation_character"}]},"line_continuation":{"match":"\\\\\\\\(?=\\\\n)","name":"constant.character.escape.line-continuation.shell"},"logical-expression":{"patterns":[{"include":"#arithmetic_no_dollar"},{"match":"=[=~]?|!=?|[<>]|&&|\\\\|\\\\|","name":"keyword.operator.logical.shell"},{"match":"(?<!\\\\S)-(nt|ot|ef|eq|ne|l[et]|g[et]|[GLNOSa-hknopr-uwxz])\\\\b","name":"keyword.operator.logical.shell"}]},"logical_expression_context":{"patterns":[{"include":"#regex_comparison"},{"include":"#arithmetic_no_dollar"},{"include":"#logical-expression"},{"include":"#logical_expression_single"},{"include":"#logical_expression_double"},{"include":"#comment"},{"include":"#boolean"},{"include":"#redirect_number"},{"include":"#numeric_literal"},{"include":"#pipeline"},{"include":"#normal_statement_seperator"},{"include":"#string"},{"include":"#variable"},{"include":"#interpolation"},{"include":"#heredoc"},{"include":"#herestring"},{"include":"#pathname"},{"include":"#floating_keyword"},{"include":"#support"}]},"logical_expression_double":{"begin":"\\\\[\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.logical-expression.shell"}},"end":"]]","endCaptures":{"0":{"name":"punctuation.definition.logical-expression.shell"}},"name":"meta.scope.logical-expression.shell","patterns":[{"include":"#logical_expression_context"}]},"logical_expression_single":{"begin":"\\\\[","beginCaptures":{"0":{"name":"punctuation.definition.logical-expression.shell"}},"end":"]","endCaptures":{"0":{"name":"punctuation.definition.logical-expression.shell"}},"name":"meta.scope.logical-expression.shell","patterns":[{"include":"#logical_expression_context"}]},"loop":{"patterns":[{"begin":"(?<=^|[\\\\&;\\\\s])(for)\\\\s+(.+?)\\\\s+(in)(?=[\\\\&;\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.control.shell"},"2":{"name":"variable.other.loop.shell","patterns":[{"include":"#string"}]},"3":{"name":"keyword.control.shell"}},"end":"(?<=^|[\\\\&;\\\\s])done(?=[\\\\&;\\\\s]|$|\\\\))","endCaptures":{"0":{"name":"keyword.control.shell"}},"name":"meta.scope.for-in-loop.shell","patterns":[{"include":"#initial_context"}]},{"begin":"(?<=^|[\\\\&;\\\\s])(while|until)(?=[\\\\&;\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.control.shell"}},"end":"(?<=^|[\\\\&;\\\\s])done(?=[\\\\&;\\\\s]|$|\\\\))","endCaptures":{"0":{"name":"keyword.control.shell"}},"name":"meta.scope.while-loop.shell","patterns":[{"include":"#initial_context"}]},{"begin":"(?<=^|[\\\\&;\\\\s])(select)\\\\s+((?:[^\\\\\\\\\\\\s]|\\\\\\\\.)+)(?=[\\\\&;\\\\s]|$)","beginCaptures":{"1":{"name":"keyword.control.shell"},"2":{"name":"variable.other.loop.shell"}},"end":"(?<=^|[\\\\&;\\\\s])(done)(?=[\\\\&;\\\\s]|$|\\\\))","endCaptures":{"1":{"name":"keyword.control.shell"}},"name":"meta.scope.select-block.shell","patterns":[{"include":"#initial_context"}]},{"begin":"(?<=^|[\\\\&;\\\\s])if(?=[\\\\&;\\\\s]|$)","beginCaptures":{"0":{"name":"keyword.control.if.shell"}},"end":"(?<=^|[\\\\&;\\\\s])fi(?=[\\\\&;\\\\s]|$)","endCaptures":{"0":{"name":"keyword.control.fi.shell"}},"name":"meta.scope.if-block.shell","patterns":[{"include":"#initial_context"}]}]},"math":{"patterns":[{"include":"#variable"},{"match":"\\\\+{1,2}|-{1,2}|[!~]|\\\\*{1,2}|[%/]|<[<=]?|>[=>]?|==|!=|^|\\\\|{1,2}|&{1,2}|[,:=?]|[-%\\\\&*+/^|]=|<<=|>>=","name":"keyword.operator.arithmetic.shell"},{"match":"0[Xx]\\\\h+","name":"constant.numeric.hex.shell"},{"match":";","name":"punctuation.separator.semicolon.range"},{"match":"0\\\\d+","name":"constant.numeric.octal.shell"},{"match":"\\\\d{1,2}#[0-9@-Z_a-z]+","name":"constant.numeric.other.shell"},{"match":"\\\\d+","name":"constant.numeric.integer.shell"},{"match":"(?<!\\\\w)[0-9A-Z_a-z]+(?!\\\\w)","name":"variable.other.normal.shell"}]},"math_operators":{"patterns":[{"match":"\\\\+{1,2}|-{1,2}|[!~]|\\\\*{1,2}|[%/]|<[<=]?|>[=>]?|==|!=|^|\\\\|{1,2}|&{1,2}|[,:=?]|[-%\\\\&*+/^|]=|<<=|>>=","name":"keyword.operator.arithmetic.shell"},{"match":"0[Xx]\\\\h+","name":"constant.numeric.hex.shell"},{"match":"0\\\\d+","name":"constant.numeric.octal.shell"},{"match":"\\\\d{1,2}#[0-9@-Z_a-z]+","name":"constant.numeric.other.shell"},{"match":"\\\\d+","name":"constant.numeric.integer.shell"}]},"misc_ranges":{"patterns":[{"include":"#logical_expression_single"},{"include":"#logical_expression_double"},{"include":"#subshell_dollar"},{"begin":"(?<![^\\\\t ])(\\\\{)(?![$\\\\w])","beginCaptures":{"1":{"name":"punctuation.definition.group.shell"}},"end":"}","endCaptures":{"0":{"name":"punctuation.definition.group.shell"}},"name":"meta.scope.group.shell","patterns":[{"include":"#initial_context"}]}]},"modified_assignment_statement":{"begin":"(?<=^|[\\\\t \\\\&;])(?:readonly|declare|typeset|export|local)(?=[\\\\t \\\\&;]|$)","beginCaptures":{"0":{"name":"storage.modifier.$0.shell"}},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.statement.shell meta.expression.assignment.modified.shell","patterns":[{"match":"(?<!\\\\w)-\\\\w+\\\\b","name":"string.unquoted.argument.shell constant.other.option.shell"},{"include":"#array_value"},{"captures":{"1":{"name":"variable.other.assignment.shell"},"2":{"name":"punctuation.definition.array.access.shell"},"3":{"name":"variable.other.assignment.shell"},"4":{"name":"constant.numeric.shell constant.numeric.integer.shell"},"5":{"name":"punctuation.definition.array.access.shell"},"6":{"name":"keyword.operator.assignment.shell"},"7":{"name":"keyword.operator.assignment.compound.shell"},"8":{"name":"keyword.operator.assignment.compound.shell"},"9":{"name":"constant.numeric.shell constant.numeric.hex.shell"},"10":{"name":"constant.numeric.shell constant.numeric.octal.shell"},"11":{"name":"constant.numeric.shell constant.numeric.other.shell"},"12":{"name":"constant.numeric.shell constant.numeric.decimal.shell"},"13":{"name":"constant.numeric.shell constant.numeric.version.shell"},"14":{"name":"constant.numeric.shell constant.numeric.integer.shell"}},"match":"((?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w))(?:(\\\\[)((?:(?:\\\\$?(?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w)|@)|\\\\*)|(-?\\\\d+))(]))?(?:(?:(=)|(\\\\+=))|(-=))?(?:(?<=[\\\\t =]|^|[(\\\\[{])(?:(?:(?:(?:(?:(0[Xx]\\\\h+)|(0\\\\d+))|(\\\\d{1,2}#[0-9@-Z_a-z]+))|(-?\\\\d+\\\\.\\\\d+))|(-?\\\\d+(?:\\\\.\\\\d+)+))|(-?\\\\d+))(?=[\\\\t ]|$|[);}]))?"},{"include":"#normal_context"}]},"modifiers":{"match":"(?<=^|[\\\\t \\\\&;])(?:readonly|declare|typeset|export|local)(?=[\\\\t \\\\&;]|$)","name":"storage.modifier.$0.shell"},"normal_assignment_statement":{"begin":"[\\\\t ]*+((?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w))(?:(\\\\[)((?:(?:\\\\$?(?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w)|@)|\\\\*)|(-?\\\\d+))(]))?(?:(?:(=)|(\\\\+=))|(-=))","beginCaptures":{"1":{"name":"variable.other.assignment.shell"},"2":{"name":"punctuation.definition.array.access.shell"},"3":{"name":"variable.other.assignment.shell"},"4":{"name":"constant.numeric.shell constant.numeric.integer.shell"},"5":{"name":"punctuation.definition.array.access.shell"},"6":{"name":"keyword.operator.assignment.shell"},"7":{"name":"keyword.operator.assignment.compound.shell"},"8":{"name":"keyword.operator.assignment.compound.shell"}},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.expression.assignment.shell","patterns":[{"include":"#comment"},{"include":"#string"},{"include":"#normal_assignment_statement"},{"begin":"(?<=[\\\\t ])(?![\\\\t ]|\\\\w+=)","beginCaptures":{},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.statement.command.env.shell","patterns":[{"include":"#command_name_range"},{"include":"#line_continuation"},{"include":"#option"},{"include":"#argument"},{"include":"#string"}]},{"include":"#simple_unquoted"},{"include":"#normal_context"}]},"normal_context":{"patterns":[{"include":"#comment"},{"include":"#pipeline"},{"include":"#normal_statement_seperator"},{"include":"#misc_ranges"},{"include":"#boolean"},{"include":"#redirect_number"},{"include":"#numeric_literal"},{"include":"#string"},{"include":"#variable"},{"include":"#interpolation"},{"include":"#heredoc"},{"include":"#herestring"},{"include":"#redirection"},{"include":"#pathname"},{"include":"#floating_keyword"},{"include":"#support"},{"include":"#parenthese"}]},"normal_statement":{"begin":"(?!^[\\\\t ]*+$)(?:(?<=(?:^until| until|\\\\tuntil|^while| while|\\\\twhile|^elif| elif|\\\\telif|^else| else|\\\\telse|^then| then|\\\\tthen|^do| do|\\\\tdo|^if| if|\\\\tif) )|(?<=^|[!\\\\&(;\`{|]))[\\\\t ]*+(?!nocorrect\\\\W|nocorrect\\\\$|function\\\\W|function\\\\$|foreach\\\\W|foreach\\\\$|repeat\\\\W|repeat\\\\$|logout\\\\W|logout\\\\$|coproc\\\\W|coproc\\\\$|select\\\\W|select\\\\$|while\\\\W|while\\\\$|pushd\\\\W|pushd\\\\$|until\\\\W|until\\\\$|case\\\\W|case\\\\$|done\\\\W|done\\\\$|elif\\\\W|elif\\\\$|else\\\\W|else\\\\$|esac\\\\W|esac\\\\$|popd\\\\W|popd\\\\$|then\\\\W|then\\\\$|time\\\\W|time\\\\$|for\\\\W|for\\\\$|end\\\\W|end\\\\$|fi\\\\W|fi\\\\$|do\\\\W|do\\\\$|in\\\\W|in\\\\$|if\\\\W|if\\\\$)","beginCaptures":{},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.statement.shell","patterns":[{"include":"#typical_statements"}]},"normal_statement_seperator":{"captures":{"1":{"name":"punctuation.terminator.statement.semicolon.shell"},"2":{"name":"punctuation.separator.statement.and.shell"},"3":{"name":"punctuation.separator.statement.or.shell"},"4":{"name":"punctuation.separator.statement.background.shell"}},"match":"(?:(?:(;)|(&&))|(\\\\|\\\\|))|(&)"},"numeric_literal":{"captures":{"1":{"name":"constant.numeric.shell constant.numeric.hex.shell"},"2":{"name":"constant.numeric.shell constant.numeric.octal.shell"},"3":{"name":"constant.numeric.shell constant.numeric.other.shell"},"4":{"name":"constant.numeric.shell constant.numeric.decimal.shell"},"5":{"name":"constant.numeric.shell constant.numeric.version.shell"},"6":{"name":"constant.numeric.shell constant.numeric.integer.shell"}},"match":"(?<=[\\\\t =]|^|[(\\\\[{])(?:(?:(?:(?:(?:(0[Xx]\\\\h+)|(0\\\\d+))|(\\\\d{1,2}#[0-9@-Z_a-z]+))|(-?\\\\d+\\\\.\\\\d+))|(-?\\\\d+(?:\\\\.\\\\d+)+))|(-?\\\\d+))(?=[\\\\t ]|$|[);}])"},"option":{"begin":"[\\\\t ]++(-)((?![\\\\n!#\\\\&()<>\\\\[{|]|$|[\\\\t ;]))","beginCaptures":{"1":{"name":"string.unquoted.argument.shell constant.other.option.dash.shell"},"2":{"name":"string.unquoted.argument.shell constant.other.option.shell"}},"contentName":"string.unquoted.argument constant.other.option","end":"(?=[\\\\t ])|(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"patterns":[{"include":"#option_context"}]},"option_context":{"patterns":[{"include":"#misc_ranges"},{"include":"#string"},{"include":"#variable"},{"include":"#interpolation"},{"include":"#heredoc"},{"include":"#herestring"},{"include":"#redirection"},{"include":"#pathname"},{"include":"#floating_keyword"},{"include":"#support"}]},"parenthese":{"patterns":[{"begin":"\\\\(","beginCaptures":{"0":{"name":"punctuation.section.parenthese.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.section.parenthese.shell"}},"name":"meta.parenthese.group.shell","patterns":[{"include":"#initial_context"}]}]},"pathname":{"patterns":[{"match":"(?<=[:=\\\\s]|^)~","name":"keyword.operator.tilde.shell"},{"match":"[*?]","name":"keyword.operator.glob.shell"},{"begin":"([!*+?@])(\\\\()","beginCaptures":{"1":{"name":"keyword.operator.extglob.shell"},"2":{"name":"punctuation.definition.extglob.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.extglob.shell"}},"name":"meta.structure.extglob.shell","patterns":[{"include":"#initial_context"}]}]},"pipeline":{"patterns":[{"match":"(?<=^|[\\\\&;\\\\s])(time)(?=[\\\\&;\\\\s]|$)","name":"keyword.other.shell"},{"match":"[!|]","name":"keyword.operator.pipe.shell"}]},"redirect_fix":{"captures":{"1":{"name":"keyword.operator.redirect.shell"},"2":{"name":"string.unquoted.argument.shell"}},"match":"(>>?)[\\\\t ]*+([^\\\\t\\\\n \\"$\\\\&-);<>\\\\\\\\\`|]+)"},"redirect_number":{"captures":{"1":{"name":"keyword.operator.redirect.stdout.shell"},"2":{"name":"keyword.operator.redirect.stderr.shell"},"3":{"name":"keyword.operator.redirect.$3.shell"}},"match":"(?<=[\\\\t ])(?:(1)|(2)|(\\\\d+))(?=>)"},"redirection":{"patterns":[{"begin":"[<>]\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.string.end.shell"}},"name":"string.interpolated.process-substitution.shell","patterns":[{"include":"#initial_context"}]},{"match":"(?<![<>])(&>|\\\\d*>&\\\\d*|\\\\d*(>>|[<>])|\\\\d*<&|\\\\d*<>)(?![<>])","name":"keyword.operator.redirect.shell"}]},"regex_comparison":{"match":"=~","name":"keyword.operator.logical.regex.shell"},"regexp":{"patterns":[{"match":".+"}]},"simple_options":{"captures":{"0":{"patterns":[{"captures":{"1":{"name":"string.unquoted.argument.shell constant.other.option.dash.shell"},"2":{"name":"string.unquoted.argument.shell constant.other.option.shell"}},"match":"[\\\\t ]++(-)(\\\\w+)"}]}},"match":"(?:[\\\\t ]++-\\\\w+)*"},"simple_unquoted":{"match":"[^\\\\t\\\\n \\"$\\\\&-);<>\\\\\\\\\`|]","name":"string.unquoted.shell"},"special_expansion":{"match":"!|:[-=?]?|[*@]|##?|%%|[%/]","name":"keyword.operator.expansion.shell"},"start_of_command":{"match":"[\\\\t ]*+(?![\\\\n!#\\\\&()<>\\\\[{|]|$|[\\\\t ;])(?!nocorrect |nocorrect\\\\t|nocorrect$|readonly |readonly\\\\t|readonly$|function |function\\\\t|function$|foreach |foreach\\\\t|foreach$|coproc |coproc\\\\t|coproc$|logout |logout\\\\t|logout$|export |export\\\\t|export$|select |select\\\\t|select$|repeat |repeat\\\\t|repeat$|pushd |pushd\\\\t|pushd$|until |until\\\\t|until$|while |while\\\\t|while$|local |local\\\\t|local$|case |case\\\\t|case$|done |done\\\\t|done$|elif |elif\\\\t|elif$|else |else\\\\t|else$|esac |esac\\\\t|esac$|popd |popd\\\\t|popd$|then |then\\\\t|then$|time |time\\\\t|time$|for |for\\\\t|for$|end |end\\\\t|end$|fi |fi\\\\t|fi$|do |do\\\\t|do$|in |in\\\\t|in$|if |if\\\\t|if$)(?!\\\\\\\\\\\\n?$)"},"string":{"patterns":[{"match":"\\\\\\\\.","name":"constant.character.escape.shell"},{"begin":"'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.shell"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.shell"}},"name":"string.quoted.single.shell"},{"begin":"\\\\$?\\"","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.shell"}},"end":"\\"","endCaptures":{"0":{"name":"punctuation.definition.string.end.shell"}},"name":"string.quoted.double.shell","patterns":[{"match":"\\\\\\\\[\\\\n\\"$\\\\\\\\\`]","name":"constant.character.escape.shell"},{"include":"#variable"},{"include":"#interpolation"}]},{"begin":"\\\\$'","beginCaptures":{"0":{"name":"punctuation.definition.string.begin.shell"}},"end":"'","endCaptures":{"0":{"name":"punctuation.definition.string.end.shell"}},"name":"string.quoted.single.dollar.shell","patterns":[{"match":"\\\\\\\\['\\\\\\\\abefnrtv]","name":"constant.character.escape.ansi-c.shell"},{"match":"\\\\\\\\[0-9]{3}\\"","name":"constant.character.escape.octal.shell"},{"match":"\\\\\\\\x\\\\h{2}\\"","name":"constant.character.escape.hex.shell"},{"match":"\\\\\\\\c.\\"","name":"constant.character.escape.control-char.shell"}]}]},"subshell_dollar":{"patterns":[{"begin":"\\\\$\\\\(","beginCaptures":{"0":{"name":"punctuation.definition.subshell.single.shell"}},"end":"\\\\)","endCaptures":{"0":{"name":"punctuation.definition.subshell.single.shell"}},"name":"meta.scope.subshell","patterns":[{"include":"#parenthese"},{"include":"#initial_context"}]}]},"support":{"patterns":[{"match":"(?<=^|[\\\\&;\\\\s])[.:](?=[\\\\&;\\\\s]|$)","name":"support.function.builtin.shell"}]},"typical_statements":{"patterns":[{"include":"#assignment_statement"},{"include":"#case_statement"},{"include":"#for_statement"},{"include":"#while_statement"},{"include":"#function_definition"},{"include":"#command_statement"},{"include":"#line_continuation"},{"include":"#arithmetic_double"},{"include":"#normal_context"}]},"variable":{"patterns":[{"captures":{"1":{"name":"punctuation.definition.variable.shell variable.parameter.positional.all.shell"},"2":{"name":"variable.parameter.positional.all.shell"}},"match":"(\\\\$)(@(?!\\\\w))"},{"captures":{"1":{"name":"punctuation.definition.variable.shell variable.parameter.positional.shell"},"2":{"name":"variable.parameter.positional.shell"}},"match":"(\\\\$)([0-9](?!\\\\w))"},{"captures":{"1":{"name":"punctuation.definition.variable.shell variable.language.special.shell"},"2":{"name":"variable.language.special.shell"}},"match":"(\\\\$)([-!#$*0?_](?!\\\\w))"},{"begin":"(\\\\$)(\\\\{)[\\\\t ]*+(?=\\\\d)","beginCaptures":{"1":{"name":"punctuation.definition.variable.shell variable.parameter.positional.shell"},"2":{"name":"punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell variable.parameter.positional.shell"}},"contentName":"meta.parameter-expansion","end":"}","endCaptures":{"0":{"name":"punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell variable.parameter.positional.shell"}},"patterns":[{"include":"#special_expansion"},{"include":"#array_access_inline"},{"match":"[0-9]+","name":"variable.parameter.positional.shell"},{"match":"(?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w)","name":"variable.other.normal.shell"},{"include":"#variable"},{"include":"#string"}]},{"begin":"(\\\\$)(\\\\{)","beginCaptures":{"1":{"name":"punctuation.definition.variable.shell"},"2":{"name":"punctuation.section.bracket.curly.variable.begin.shell punctuation.definition.variable.shell"}},"contentName":"meta.parameter-expansion","end":"}","endCaptures":{"0":{"name":"punctuation.section.bracket.curly.variable.end.shell punctuation.definition.variable.shell"}},"patterns":[{"include":"#special_expansion"},{"include":"#array_access_inline"},{"match":"(?<!\\\\w)[-0-9A-Z_a-z]+(?!\\\\w)","name":"variable.other.normal.shell"},{"include":"#variable"},{"include":"#string"}]},{"captures":{"1":{"name":"punctuation.definition.variable.shell variable.other.normal.shell"},"2":{"name":"variable.other.normal.shell"}},"match":"(\\\\$)(\\\\w+(?!\\\\w))"}]},"while_statement":{"patterns":[{"begin":"\\\\b(while)\\\\b","beginCaptures":{"1":{"name":"keyword.control.while.shell"}},"end":"(?=[\\\\n\\\\&);\`{|}]|[\\\\t ]*#|])(?<!\\\\\\\\)","endCaptures":{},"name":"meta.while.shell","patterns":[{"include":"#line_continuation"},{"include":"#math_operators"},{"include":"#option"},{"include":"#simple_unquoted"},{"include":"#normal_context"},{"include":"#string"}]}]}},"scopeName":"source.shell","aliases":["bash","sh","shell","zsh"]}`)),n=[e];export{n as default};
|