@sleds/cli 0.1.49 → 0.1.51
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/sleds.mjs +492 -185
- package/package.json +1 -1
package/dist/sleds.mjs
CHANGED
|
@@ -769,6 +769,14 @@ var init_verbs = __esm(() => {
|
|
|
769
769
|
app: "Work › Moving (the runs on each sled) · Record › Receipts once they land",
|
|
770
770
|
how: "Newest first: id, status, route, cost. Hand-offs meant for you are listed first."
|
|
771
771
|
},
|
|
772
|
+
{
|
|
773
|
+
id: "metrics",
|
|
774
|
+
group: "meter",
|
|
775
|
+
want: "See how a workspace or the whole org ships — DORA and batch size for a period",
|
|
776
|
+
mcp: "metrics {workspace?, range?, from?, to?} — range 2w · 1m · 3m · 6m · 1y, or from/to days",
|
|
777
|
+
app: "Metrics",
|
|
778
|
+
how: "Deploy frequency, lead time, change failure rate, time to recover and production deploys by batch size, each against the same length just before. A workspace gives one line; no workspace gives the org, one line per workspace you see."
|
|
779
|
+
},
|
|
772
780
|
{
|
|
773
781
|
id: "status",
|
|
774
782
|
group: "meter",
|
|
@@ -1616,6 +1624,128 @@ var init_format = __esm(() => {
|
|
|
1616
1624
|
OFFLINE_LINE = `${PREFIX}offline`;
|
|
1617
1625
|
});
|
|
1618
1626
|
|
|
1627
|
+
// ../../packages/shared/src/item/outcome.ts
|
|
1628
|
+
var OUTCOME_WINDOW_DAYS = 14, OUTCOME_WINDOW_MS;
|
|
1629
|
+
var init_outcome = __esm(() => {
|
|
1630
|
+
OUTCOME_WINDOW_MS = OUTCOME_WINDOW_DAYS * 86400000;
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1633
|
+
// ../../packages/shared/src/deploys/metrics.ts
|
|
1634
|
+
var WEEK_MS;
|
|
1635
|
+
var init_metrics = __esm(() => {
|
|
1636
|
+
WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
1637
|
+
});
|
|
1638
|
+
|
|
1639
|
+
// ../../packages/shared/src/deploys/batchSize.ts
|
|
1640
|
+
var TIERS;
|
|
1641
|
+
var init_batchSize = __esm(() => {
|
|
1642
|
+
init_outcome();
|
|
1643
|
+
init_metrics();
|
|
1644
|
+
TIERS = ["S", "M", "L", "G"];
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
// ../../packages/shared/src/deploys/period.ts
|
|
1648
|
+
function periodChange(cur, prev, better) {
|
|
1649
|
+
if (cur == null || prev == null)
|
|
1650
|
+
return { pct: null, dir: "flat", tone: "neutral" };
|
|
1651
|
+
if (prev === 0)
|
|
1652
|
+
return { pct: null, dir: cur > 0 ? "up" : cur < 0 ? "down" : "flat", tone: "neutral" };
|
|
1653
|
+
const pct = (cur - prev) / Math.abs(prev) * 100;
|
|
1654
|
+
if (Math.abs(pct) < FLAT_PCT)
|
|
1655
|
+
return { pct, dir: "flat", tone: "neutral" };
|
|
1656
|
+
const dir = pct > 0 ? "up" : "down";
|
|
1657
|
+
return { pct, dir, tone: dir === better ? "success" : "error" };
|
|
1658
|
+
}
|
|
1659
|
+
var DAY_MS2, FLAT_PCT = 0.5;
|
|
1660
|
+
var init_period = __esm(() => {
|
|
1661
|
+
DAY_MS2 = 24 * 60 * 60 * 1000;
|
|
1662
|
+
});
|
|
1663
|
+
|
|
1664
|
+
// ../../packages/shared/src/deploys/report.ts
|
|
1665
|
+
function duration(ms) {
|
|
1666
|
+
const min = ms / 60000;
|
|
1667
|
+
if (min < 60)
|
|
1668
|
+
return `${Math.round(min)}m`;
|
|
1669
|
+
const hours = min / 60;
|
|
1670
|
+
if (hours < 48)
|
|
1671
|
+
return `${hours.toFixed(1)}h`;
|
|
1672
|
+
return `${(hours / 24).toFixed(1)}d`;
|
|
1673
|
+
}
|
|
1674
|
+
function change(pair, better) {
|
|
1675
|
+
const { current, previous } = pair;
|
|
1676
|
+
if (current == null)
|
|
1677
|
+
return "";
|
|
1678
|
+
if (previous == null)
|
|
1679
|
+
return " (none before)";
|
|
1680
|
+
const c = periodChange(current, previous, better);
|
|
1681
|
+
if (c.dir === "flat")
|
|
1682
|
+
return " (flat)";
|
|
1683
|
+
if (c.pct == null)
|
|
1684
|
+
return " (none before)";
|
|
1685
|
+
return ` (${c.pct > 0 ? "+" : "−"}${Math.round(Math.abs(c.pct))}%)`;
|
|
1686
|
+
}
|
|
1687
|
+
function timeFigure(label, pair) {
|
|
1688
|
+
if (pair.current == null)
|
|
1689
|
+
return `${label} none`;
|
|
1690
|
+
return `${label} ${duration(pair.current)}${change(pair, "down")}`;
|
|
1691
|
+
}
|
|
1692
|
+
function rateFigure(pair) {
|
|
1693
|
+
const { current, previous } = pair;
|
|
1694
|
+
if (current == null)
|
|
1695
|
+
return "failure rate none";
|
|
1696
|
+
const pct = Math.round(current * 100);
|
|
1697
|
+
if (previous == null)
|
|
1698
|
+
return `failure rate ${pct}% (none before)`;
|
|
1699
|
+
const pts = pct - Math.round(previous * 100);
|
|
1700
|
+
return `failure rate ${pct}% (${pts === 0 ? "flat" : `${pts > 0 ? "+" : "−"}${Math.abs(pts)} pts`})`;
|
|
1701
|
+
}
|
|
1702
|
+
function batchFigure(pair) {
|
|
1703
|
+
if (total(pair.current) === 0)
|
|
1704
|
+
return "batch none";
|
|
1705
|
+
const before = total(pair.previous) === 0 ? "none before" : `was ${tiers(pair.previous)}`;
|
|
1706
|
+
return `batch ${tiers(pair.current)} (${before})`;
|
|
1707
|
+
}
|
|
1708
|
+
function lineText(l) {
|
|
1709
|
+
const head = `${l.name} (${l.slug})`;
|
|
1710
|
+
if (l.production == null)
|
|
1711
|
+
return `${head} · no production environment set, so no deploy metrics`;
|
|
1712
|
+
const deploys = `${l.deploys.current} deploy${l.deploys.current === 1 ? "" : "s"}${change(l.deploys, "up")}`;
|
|
1713
|
+
return [
|
|
1714
|
+
`${head} · ${l.production}: ${deploys}`,
|
|
1715
|
+
timeFigure("lead time", l.leadTime),
|
|
1716
|
+
rateFigure(l.failRate),
|
|
1717
|
+
timeFigure("time to recover", l.recover),
|
|
1718
|
+
batchFigure(l.batch)
|
|
1719
|
+
].join(" · ");
|
|
1720
|
+
}
|
|
1721
|
+
function metricsText(r) {
|
|
1722
|
+
const sameYear = r.from.slice(0, 4) === r.to.slice(0, 4);
|
|
1723
|
+
const span = `${dayLabel(r.from, !sameYear)} – ${dayLabel(r.to, true)}`;
|
|
1724
|
+
const days = `${r.days} day${r.days === 1 ? "" : "s"}`;
|
|
1725
|
+
const header = `${r.scope === "org" ? "Org" : "Workspace"} · ${span} (${days}), against the ${days} before`;
|
|
1726
|
+
const lines = r.lines.length ? r.lines.map(lineText) : [r.scope === "org" ? "No workspaces in this org." : "No workspace."];
|
|
1727
|
+
return [header, ...lines].join(`
|
|
1728
|
+
`);
|
|
1729
|
+
}
|
|
1730
|
+
var DAY_MS3, METRICS_RANGES, tiers = (c) => TIERS.map((t) => `${t}${c[t]}`).join(" "), total = (c) => TIERS.reduce((n, t) => n + c[t], 0), dayLabel = (day, year) => new Date(`${day}T00:00:00Z`).toLocaleDateString("en-US", {
|
|
1731
|
+
month: "short",
|
|
1732
|
+
day: "numeric",
|
|
1733
|
+
...year ? { year: "numeric" } : {},
|
|
1734
|
+
timeZone: "UTC"
|
|
1735
|
+
});
|
|
1736
|
+
var init_report = __esm(() => {
|
|
1737
|
+
init_batchSize();
|
|
1738
|
+
init_period();
|
|
1739
|
+
DAY_MS3 = 24 * 60 * 60 * 1000;
|
|
1740
|
+
METRICS_RANGES = [
|
|
1741
|
+
{ key: "2w", days: 14 },
|
|
1742
|
+
{ key: "1m", days: 30 },
|
|
1743
|
+
{ key: "3m", days: 91 },
|
|
1744
|
+
{ key: "6m", days: 182 },
|
|
1745
|
+
{ key: "1y", days: 365 }
|
|
1746
|
+
];
|
|
1747
|
+
});
|
|
1748
|
+
|
|
1619
1749
|
// ../../packages/shared/src/guidance/model.ts
|
|
1620
1750
|
var CARD_FIELDS;
|
|
1621
1751
|
var init_model = __esm(() => {
|
|
@@ -2120,7 +2250,7 @@ var read = (title) => ({
|
|
|
2120
2250
|
destructiveHint: false,
|
|
2121
2251
|
idempotentHint: idempotent,
|
|
2122
2252
|
openWorldHint: false
|
|
2123
|
-
}),
|
|
2253
|
+
}), change2 = (title, idempotent = false) => ({
|
|
2124
2254
|
title,
|
|
2125
2255
|
readOnlyHint: false,
|
|
2126
2256
|
destructiveHint: true,
|
|
@@ -2130,6 +2260,7 @@ var read = (title) => ({
|
|
|
2130
2260
|
var init_annotations = __esm(() => {
|
|
2131
2261
|
TOOL_ANNOTATIONS = {
|
|
2132
2262
|
usage: read("Seat usage"),
|
|
2263
|
+
metrics: read("Delivery metrics"),
|
|
2133
2264
|
jobs: read("Overnight jobs"),
|
|
2134
2265
|
status: read("Where is it"),
|
|
2135
2266
|
touches: read("What it touches"),
|
|
@@ -2158,9 +2289,9 @@ var init_annotations = __esm(() => {
|
|
|
2158
2289
|
buddy: add("Pair with a buddy"),
|
|
2159
2290
|
pickup: add("Pick up a hand-off"),
|
|
2160
2291
|
reopen: add("Reopen an item", true),
|
|
2161
|
-
update:
|
|
2162
|
-
archive:
|
|
2163
|
-
withdraw:
|
|
2292
|
+
update: change2("Change an item", true),
|
|
2293
|
+
archive: change2("Archive an item", true),
|
|
2294
|
+
withdraw: change2("Withdraw a hand-off", true)
|
|
2164
2295
|
};
|
|
2165
2296
|
});
|
|
2166
2297
|
|
|
@@ -2421,19 +2552,23 @@ var init_plan2 = __esm(() => {
|
|
|
2421
2552
|
});
|
|
2422
2553
|
|
|
2423
2554
|
// ../../packages/shared/src/mcp/sled.ts
|
|
2424
|
-
function section(label, rows, now) {
|
|
2555
|
+
function section(label, rows, now, count = rows.length) {
|
|
2425
2556
|
if (rows.length === 0)
|
|
2426
2557
|
return null;
|
|
2427
|
-
|
|
2558
|
+
const total = Math.max(count, rows.length);
|
|
2559
|
+
const more = total > rows.length ? `
|
|
2560
|
+
|
|
2561
|
+
…and ${total - rows.length} more` : "";
|
|
2562
|
+
return `${label} (${total}):
|
|
2428
2563
|
|
|
2429
2564
|
${rows.map((r) => statusLine(r, now)).join(`
|
|
2430
2565
|
|
|
2431
|
-
`)}`;
|
|
2566
|
+
`)}${more}`;
|
|
2432
2567
|
}
|
|
2433
2568
|
function sledText(s, now) {
|
|
2434
2569
|
const parts = [
|
|
2435
2570
|
section("On your sled", s.mine, now),
|
|
2436
|
-
section("Proposed to you", s.proposed, now),
|
|
2571
|
+
section("Proposed to you", s.proposed, now, s.proposedCount),
|
|
2437
2572
|
section("Sent to you", s.sent, now)
|
|
2438
2573
|
].filter((p) => p !== null);
|
|
2439
2574
|
if (parts.length === 0)
|
|
@@ -2706,6 +2841,60 @@ async function usageTool(ctx) {
|
|
|
2706
2841
|
return { text: formatMeter(m, (ctx.now ?? Date.now)()).join(`
|
|
2707
2842
|
`) };
|
|
2708
2843
|
}
|
|
2844
|
+
function asMetricsReport(j) {
|
|
2845
|
+
if (!j || j.scope !== "workspace" && j.scope !== "org")
|
|
2846
|
+
return null;
|
|
2847
|
+
if (typeof j.from !== "string" || typeof j.to !== "string" || num3(j.days) === undefined)
|
|
2848
|
+
return null;
|
|
2849
|
+
if (!Array.isArray(j.lines) || !j.lines.every(isObject4))
|
|
2850
|
+
return null;
|
|
2851
|
+
return j;
|
|
2852
|
+
}
|
|
2853
|
+
async function metricsTool(ctx, args) {
|
|
2854
|
+
if (!ctx.client)
|
|
2855
|
+
return NOT_SET_UP;
|
|
2856
|
+
const qs = new URLSearchParams;
|
|
2857
|
+
for (const k of ["workspace", "range", "from", "to"]) {
|
|
2858
|
+
const v = str5(args[k])?.trim();
|
|
2859
|
+
if (v)
|
|
2860
|
+
qs.set(k, v);
|
|
2861
|
+
}
|
|
2862
|
+
const query = qs.toString();
|
|
2863
|
+
const path = query ? `/proxy/metrics?${query}` : "/proxy/metrics";
|
|
2864
|
+
const noReport = { text: "SLEDS answered without a metrics report.", isError: true };
|
|
2865
|
+
if (!ctx.client.getFull) {
|
|
2866
|
+
const j = await ctx.client.get(path);
|
|
2867
|
+
if (!j)
|
|
2868
|
+
return UNREACHABLE;
|
|
2869
|
+
const report = asMetricsReport(j);
|
|
2870
|
+
return report ? { text: metricsText(report) } : noReport;
|
|
2871
|
+
}
|
|
2872
|
+
const r = await ctx.client.getFull(path);
|
|
2873
|
+
if ("error" in r)
|
|
2874
|
+
return {
|
|
2875
|
+
text: `Control plane unreachable: ${r.error} → try again in a moment.`,
|
|
2876
|
+
isError: true
|
|
2877
|
+
};
|
|
2878
|
+
const why = errorMessage(r.json);
|
|
2879
|
+
if (r.status === 200) {
|
|
2880
|
+
const report = asMetricsReport(r.json);
|
|
2881
|
+
return report ? { text: metricsText(report) } : noReport;
|
|
2882
|
+
}
|
|
2883
|
+
const workspace = qs.get("workspace");
|
|
2884
|
+
if (r.status === 404)
|
|
2885
|
+
return {
|
|
2886
|
+
text: workspace ? `No workspace "${workspace}" that this seat sees. Leave workspace out for the whole org, one line per workspace.` : `${why ?? "Not found"} (HTTP 404).`,
|
|
2887
|
+
isError: true
|
|
2888
|
+
};
|
|
2889
|
+
if (r.status === 400)
|
|
2890
|
+
return { text: why ?? "Bad request (HTTP 400).", isError: true };
|
|
2891
|
+
if (r.status >= 500)
|
|
2892
|
+
return {
|
|
2893
|
+
text: `${why ?? "Control plane unreachable"} (HTTP ${r.status}) → try once more in a moment, then move on and say so.`,
|
|
2894
|
+
isError: true
|
|
2895
|
+
};
|
|
2896
|
+
return { text: `${why ?? "SLEDS refused it"} (HTTP ${r.status}).`, isError: true };
|
|
2897
|
+
}
|
|
2709
2898
|
function bandLine(band) {
|
|
2710
2899
|
if (!isObject4(band))
|
|
2711
2900
|
return null;
|
|
@@ -3328,7 +3517,12 @@ async function sledTool(ctx, args) {
|
|
|
3328
3517
|
return UNREACHABLE;
|
|
3329
3518
|
const rows = (k) => Array.isArray(r[k]) ? r[k].filter(isObject4) : [];
|
|
3330
3519
|
return {
|
|
3331
|
-
text: sledText({
|
|
3520
|
+
text: sledText({
|
|
3521
|
+
mine: rows("mine"),
|
|
3522
|
+
proposed: rows("proposed"),
|
|
3523
|
+
...typeof r.proposedCount === "number" ? { proposedCount: r.proposedCount } : {},
|
|
3524
|
+
sent: rows("sent")
|
|
3525
|
+
}, (ctx.now ?? Date.now)())
|
|
3332
3526
|
};
|
|
3333
3527
|
}
|
|
3334
3528
|
function checkWarningsOf(ctx, drafts) {
|
|
@@ -4300,6 +4494,8 @@ async function callTool(name, args, ctx) {
|
|
|
4300
4494
|
switch (name) {
|
|
4301
4495
|
case "usage":
|
|
4302
4496
|
return usageTool(ctx);
|
|
4497
|
+
case "metrics":
|
|
4498
|
+
return metricsTool(ctx, args);
|
|
4303
4499
|
case "estimate":
|
|
4304
4500
|
return estimateTool(ctx, args);
|
|
4305
4501
|
case "intake":
|
|
@@ -4439,6 +4635,7 @@ async function handleLine(line, ctx) {
|
|
|
4439
4635
|
}
|
|
4440
4636
|
var PROTOCOL_VERSION = "2025-06-18", SERVER_INFO, SERVER_INSTRUCTIONS, MCP_TIMEOUT_MS = 5000, sourceSchema, specSchema, TOOLS, VIEW_TOOLS, NOT_SET_UP, UNREACHABLE, isObject4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), num3 = (v) => typeof v === "number" && Number.isFinite(v) ? v : undefined, str5 = (v) => typeof v === "string" ? v : undefined, errorMessage = (j) => isObject4(j?.error) ? str5(j.error.message) : str5(j?.error), proposalText = (t) => (t ?? "").replace(/\n*Nothing runs until a person says yes:[^\n]*$/, ""), PROPOSED_NEXT = (key) => `Nothing runs until a person approves it: Approve in the SLEDS app or on the item page, or \`sleds route approve ${key}\`. If you are a planning session, stop here.`, strList = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : undefined, RELATION_HOWS, UI_RESOURCES, response = (id, result) => JSON.stringify({ jsonrpc: "2.0", id, result }), errorResponse = (id, code, message) => JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } });
|
|
4441
4637
|
var init_server = __esm(() => {
|
|
4638
|
+
init_report();
|
|
4442
4639
|
init_worth();
|
|
4443
4640
|
init_intake();
|
|
4444
4641
|
init_model();
|
|
@@ -4506,6 +4703,32 @@ var init_server = __esm(() => {
|
|
|
4506
4703
|
description: "The SLEDS meter for this seat: built today, month against the ceiling, window and reset, allowance, queued/running/delivered jobs, the last wall, and the seat's own Pro/Max limit bars.",
|
|
4507
4704
|
inputSchema: { type: "object", properties: {} }
|
|
4508
4705
|
},
|
|
4706
|
+
{
|
|
4707
|
+
name: "metrics",
|
|
4708
|
+
description: "DORA and batch-size metrics for a period, against the same length just before it: deploy frequency, lead time, change failure rate, time to recover and production deploys by batch size. For one workspace, or — with no `workspace` — the whole org, one line per workspace. Only the workspaces this seat sees. The same days the Metrics page counts.",
|
|
4709
|
+
inputSchema: {
|
|
4710
|
+
type: "object",
|
|
4711
|
+
properties: {
|
|
4712
|
+
workspace: {
|
|
4713
|
+
type: "string",
|
|
4714
|
+
description: "The workspace's slug. Leave it out for the whole org."
|
|
4715
|
+
},
|
|
4716
|
+
range: {
|
|
4717
|
+
type: "string",
|
|
4718
|
+
enum: METRICS_RANGES.map((r) => r.key),
|
|
4719
|
+
description: "A preset period ending today; default 2w. Leave it out when giving from."
|
|
4720
|
+
},
|
|
4721
|
+
from: {
|
|
4722
|
+
type: "string",
|
|
4723
|
+
description: "First day of a custom period, YYYY-MM-DD (UTC). At most 366 days."
|
|
4724
|
+
},
|
|
4725
|
+
to: {
|
|
4726
|
+
type: "string",
|
|
4727
|
+
description: "Last day of a custom period, YYYY-MM-DD, included; default today."
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
},
|
|
4509
4732
|
{
|
|
4510
4733
|
name: "estimate",
|
|
4511
4734
|
description: "Call this BEFORE starting any build that will take more than a few minutes — before the first line of work, not after. Sizes the task: the org estimator's cost and time band with confidence and a spend cap, never a point figure. Pass a stable `source` (kind · project · doc · item) so the item has a home on the sled and the later `actual` finds it. Recorded, so actuals calibrate the next estimate.",
|
|
@@ -5443,12 +5666,6 @@ var init_recommend = __esm(() => {
|
|
|
5443
5666
|
var init_profile2 = __esm(() => {
|
|
5444
5667
|
init_profile();
|
|
5445
5668
|
});
|
|
5446
|
-
// ../../packages/shared/src/item/outcome.ts
|
|
5447
|
-
var OUTCOME_WINDOW_DAYS = 14, OUTCOME_WINDOW_MS;
|
|
5448
|
-
var init_outcome = __esm(() => {
|
|
5449
|
-
OUTCOME_WINDOW_MS = OUTCOME_WINDOW_DAYS * 86400000;
|
|
5450
|
-
});
|
|
5451
|
-
|
|
5452
5669
|
// ../../packages/shared/src/slack/mention.ts
|
|
5453
5670
|
var MENTION_HELP;
|
|
5454
5671
|
var init_mention = __esm(() => {
|
|
@@ -5479,6 +5696,9 @@ var init_agent = __esm(() => {
|
|
|
5479
5696
|
init_mention();
|
|
5480
5697
|
});
|
|
5481
5698
|
|
|
5699
|
+
// ../../packages/shared/src/slack/channel.ts
|
|
5700
|
+
var init_channel = () => {};
|
|
5701
|
+
|
|
5482
5702
|
// ../../packages/shared/src/item/productHits.ts
|
|
5483
5703
|
var PATH_STOP, COMMON;
|
|
5484
5704
|
var init_productHits = __esm(() => {
|
|
@@ -6531,6 +6751,12 @@ var init_deploys = __esm(() => {
|
|
|
6531
6751
|
SERVICE_RE = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,39}$/;
|
|
6532
6752
|
});
|
|
6533
6753
|
|
|
6754
|
+
// ../../packages/shared/src/deploys/stability.ts
|
|
6755
|
+
var init_stability = __esm(() => {
|
|
6756
|
+
init_outcome();
|
|
6757
|
+
init_metrics();
|
|
6758
|
+
});
|
|
6759
|
+
|
|
6534
6760
|
// ../../packages/shared/src/newrelic/newrelic.ts
|
|
6535
6761
|
var init_newrelic = () => {};
|
|
6536
6762
|
|
|
@@ -7921,6 +8147,7 @@ var init_src = __esm(() => {
|
|
|
7921
8147
|
init_mention();
|
|
7922
8148
|
init_agent();
|
|
7923
8149
|
init_copy();
|
|
8150
|
+
init_channel();
|
|
7924
8151
|
init_productHits();
|
|
7925
8152
|
init_model();
|
|
7926
8153
|
init_parse();
|
|
@@ -7936,6 +8163,11 @@ var init_src = __esm(() => {
|
|
|
7936
8163
|
init_pack2();
|
|
7937
8164
|
init_flags();
|
|
7938
8165
|
init_deploys();
|
|
8166
|
+
init_metrics();
|
|
8167
|
+
init_period();
|
|
8168
|
+
init_stability();
|
|
8169
|
+
init_batchSize();
|
|
8170
|
+
init_report();
|
|
7939
8171
|
init_sentry();
|
|
7940
8172
|
init_newrelic();
|
|
7941
8173
|
init_musher();
|
|
@@ -8611,7 +8843,7 @@ var init_seat = __esm(() => {
|
|
|
8611
8843
|
|
|
8612
8844
|
// src/index.ts
|
|
8613
8845
|
import { existsSync as existsSync36, realpathSync as realpathSync3 } from "fs";
|
|
8614
|
-
import { homedir as
|
|
8846
|
+
import { homedir as homedir10, platform as platform3 } from "os";
|
|
8615
8847
|
import { fileURLToPath } from "url";
|
|
8616
8848
|
|
|
8617
8849
|
// ../../packages/shared/src/index.ts
|
|
@@ -8640,6 +8872,7 @@ init_outcome();
|
|
|
8640
8872
|
init_mention();
|
|
8641
8873
|
init_agent();
|
|
8642
8874
|
init_copy();
|
|
8875
|
+
init_channel();
|
|
8643
8876
|
init_productHits();
|
|
8644
8877
|
init_model();
|
|
8645
8878
|
init_parse();
|
|
@@ -8655,6 +8888,11 @@ init_cheatSheet();
|
|
|
8655
8888
|
init_pack2();
|
|
8656
8889
|
init_flags();
|
|
8657
8890
|
init_deploys();
|
|
8891
|
+
init_metrics();
|
|
8892
|
+
init_period();
|
|
8893
|
+
init_stability();
|
|
8894
|
+
init_batchSize();
|
|
8895
|
+
init_report();
|
|
8658
8896
|
init_sentry();
|
|
8659
8897
|
init_newrelic();
|
|
8660
8898
|
init_musher();
|
|
@@ -9824,6 +10062,7 @@ var defer = async (o) => {
|
|
|
9824
10062
|
init_src();
|
|
9825
10063
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
9826
10064
|
var DEPLOYS_URL = "https://hooks.sleds.ai/deploys";
|
|
10065
|
+
var DEPLOY_WAIT_MS = 120000;
|
|
9827
10066
|
var USAGE = "usage: sleds deploy --env <slug> [--service <name>] [--sha <sha>] [--repo <owner/name>]";
|
|
9828
10067
|
var FLAGS = ["env", "service", "sha", "repo"];
|
|
9829
10068
|
var set = (x) => x?.trim() ? x.trim() : undefined;
|
|
@@ -9880,7 +10119,7 @@ var defaultPost = async (url, token, body) => {
|
|
|
9880
10119
|
method: "POST",
|
|
9881
10120
|
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
9882
10121
|
body: JSON.stringify(body),
|
|
9883
|
-
signal: AbortSignal.timeout(
|
|
10122
|
+
signal: AbortSignal.timeout(DEPLOY_WAIT_MS)
|
|
9884
10123
|
});
|
|
9885
10124
|
let json = null;
|
|
9886
10125
|
try {
|
|
@@ -9888,7 +10127,8 @@ var defaultPost = async (url, token, body) => {
|
|
|
9888
10127
|
} catch {}
|
|
9889
10128
|
return { status: res.status, json };
|
|
9890
10129
|
} catch (e) {
|
|
9891
|
-
|
|
10130
|
+
const timedOut = e instanceof Error && e.name === "TimeoutError";
|
|
10131
|
+
return { error: e instanceof Error ? e.message : String(e), ...timedOut ? { timedOut } : {} };
|
|
9892
10132
|
}
|
|
9893
10133
|
};
|
|
9894
10134
|
function deployLine(body, json) {
|
|
@@ -9921,6 +10161,10 @@ var deployCmd = async (o) => {
|
|
|
9921
10161
|
const body = resolved.body;
|
|
9922
10162
|
const url = set(env.SLEDS_DEPLOYS_URL) ?? DEPLOYS_URL;
|
|
9923
10163
|
const r = await (o.post ?? defaultPost)(url, token, body);
|
|
10164
|
+
if ("error" in r && r.timedOut) {
|
|
10165
|
+
error(`notice: the report was sent but SLEDS did not answer within ${DEPLOY_WAIT_MS / 1000}s; it is usually still recorded — see Settings › Deploys › Recent deploys`);
|
|
10166
|
+
return 0;
|
|
10167
|
+
}
|
|
9924
10168
|
if ("error" in r) {
|
|
9925
10169
|
error(`warning: SLEDS unreachable, deploy not recorded — ${r.error}`);
|
|
9926
10170
|
return 0;
|
|
@@ -9952,7 +10196,7 @@ import {
|
|
|
9952
10196
|
writeFileSync as writeFileSync19
|
|
9953
10197
|
} from "node:fs";
|
|
9954
10198
|
import { tmpdir, userInfo as userInfo2 } from "node:os";
|
|
9955
|
-
import { delimiter as delimiter3, dirname as dirname17, join as
|
|
10199
|
+
import { delimiter as delimiter3, dirname as dirname17, join as join26, resolve as resolve9 } from "node:path";
|
|
9956
10200
|
|
|
9957
10201
|
// src/agentMcp.ts
|
|
9958
10202
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
@@ -10328,8 +10572,36 @@ var runCockpit = async (cockpit, argv, opts = {}) => {
|
|
|
10328
10572
|
// src/commands/doctor.ts
|
|
10329
10573
|
init_config();
|
|
10330
10574
|
|
|
10575
|
+
// src/engine/credential.ts
|
|
10576
|
+
import { homedir } from "node:os";
|
|
10577
|
+
import { join as join11 } from "node:path";
|
|
10578
|
+
var API_KEY_VAR = "ANTHROPIC_API_KEY";
|
|
10579
|
+
var SEAT_TOKEN_VAR = "CLAUDE_CODE_OAUTH_TOKEN";
|
|
10580
|
+
function namesVar(text, name) {
|
|
10581
|
+
return new RegExp(`^\\s*(?:export\\s+)?${name}\\s*=\\s*\\S`, "m").test(text);
|
|
10582
|
+
}
|
|
10583
|
+
function loginPath(env, home = homedir()) {
|
|
10584
|
+
return join11(env.CLAUDE_CONFIG_DIR?.trim() || join11(home, ".claude"), ".credentials.json");
|
|
10585
|
+
}
|
|
10586
|
+
function detectCredential(env, o) {
|
|
10587
|
+
const file = o.boxEnvText ?? "";
|
|
10588
|
+
const fileWhere = o.boxEnvPath ?? "box.env";
|
|
10589
|
+
const vars = [
|
|
10590
|
+
[API_KEY_VAR, "key", "api_key"],
|
|
10591
|
+
[SEAT_TOKEN_VAR, "seat", "seat_token"]
|
|
10592
|
+
];
|
|
10593
|
+
for (const [name, kind, source] of vars) {
|
|
10594
|
+
if (env[name]?.trim())
|
|
10595
|
+
return { kind, source, where: "this shell" };
|
|
10596
|
+
if (namesVar(file, name))
|
|
10597
|
+
return { kind, source, where: fileWhere };
|
|
10598
|
+
}
|
|
10599
|
+
const login = loginPath(env, o.home);
|
|
10600
|
+
return o.exists(login) ? { kind: "seat", source: "login", where: login } : null;
|
|
10601
|
+
}
|
|
10602
|
+
|
|
10331
10603
|
// src/engine/repos.ts
|
|
10332
|
-
import { basename as basename2, dirname as dirname9, join as
|
|
10604
|
+
import { basename as basename2, dirname as dirname9, join as join12 } from "node:path";
|
|
10333
10605
|
function splitReposDirs(raw) {
|
|
10334
10606
|
return (raw ?? "").split(/[:\n]/).map((d) => d.trim()).filter(Boolean);
|
|
10335
10607
|
}
|
|
@@ -10356,13 +10628,13 @@ function resolveRepoPath(o) {
|
|
|
10356
10628
|
if (name.startsWith("."))
|
|
10357
10629
|
continue;
|
|
10358
10630
|
for (const dir of dirs) {
|
|
10359
|
-
const p =
|
|
10360
|
-
if (o.exists(
|
|
10631
|
+
const p = join12(dir, name);
|
|
10632
|
+
if (o.exists(join12(p, ".git")))
|
|
10361
10633
|
return p;
|
|
10362
10634
|
}
|
|
10363
10635
|
}
|
|
10364
10636
|
const want = o.repos.join(", ");
|
|
10365
|
-
const where = names.flatMap((n) => dirs.map((d) =>
|
|
10637
|
+
const where = names.flatMap((n) => dirs.map((d) => join12(d, n))).join(" or ");
|
|
10366
10638
|
return {
|
|
10367
10639
|
error: `No checkout of ${want} on this engine's machine: expected ${where}. Clone it there (or pass --repo).`
|
|
10368
10640
|
};
|
|
@@ -10370,7 +10642,7 @@ function resolveRepoPath(o) {
|
|
|
10370
10642
|
var isRoot = (p) => dirname9(p) === p;
|
|
10371
10643
|
function insideCheckout(dir, exists) {
|
|
10372
10644
|
for (let d = dir;!isRoot(d); d = dirname9(d)) {
|
|
10373
|
-
if (exists(
|
|
10645
|
+
if (exists(join12(d, ".git")))
|
|
10374
10646
|
return true;
|
|
10375
10647
|
}
|
|
10376
10648
|
return false;
|
|
@@ -10400,12 +10672,12 @@ init_meter();
|
|
|
10400
10672
|
|
|
10401
10673
|
// src/runners/cmux.ts
|
|
10402
10674
|
import { existsSync as existsSync11, rmSync as rmSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
10403
|
-
import { delimiter, join as
|
|
10675
|
+
import { delimiter, join as join14 } from "node:path";
|
|
10404
10676
|
|
|
10405
10677
|
// src/runners/exec.ts
|
|
10406
10678
|
import { spawn, spawnSync as spawnSync3 } from "node:child_process";
|
|
10407
10679
|
import { closeSync as closeSync2, fstatSync, openSync as openSync2, readSync as readSync2 } from "node:fs";
|
|
10408
|
-
import { basename as basename3, dirname as dirname10, join as
|
|
10680
|
+
import { basename as basename3, dirname as dirname10, join as join13 } from "node:path";
|
|
10409
10681
|
|
|
10410
10682
|
// src/runners/sandbox.ts
|
|
10411
10683
|
var absRule = (dir) => `/${dir.replace(/\/+$/, "")}/**`;
|
|
@@ -10549,7 +10821,7 @@ var readLogTail = (path) => {
|
|
|
10549
10821
|
};
|
|
10550
10822
|
var logPathFor = (promptFile, ext, dir) => {
|
|
10551
10823
|
const base = basename3(promptFile).replace(/\.md$/i, "");
|
|
10552
|
-
return
|
|
10824
|
+
return join13(dir ?? dirname10(promptFile), `${base}.${ext}`);
|
|
10553
10825
|
};
|
|
10554
10826
|
var tailText = (s, bytes = 4096) => {
|
|
10555
10827
|
if (s.length <= bytes)
|
|
@@ -10573,7 +10845,7 @@ var isRunnerKey = (key) => /^(?:[1-9]|esc)$/.test(key);
|
|
|
10573
10845
|
var CMUX_APP_BIN = "/Applications/cmux.app/Contents/Resources/bin/cmux";
|
|
10574
10846
|
var resolveCmuxBin = (exists = existsSync11, path = process.env.PATH ?? "") => {
|
|
10575
10847
|
for (const dir of path.split(delimiter)) {
|
|
10576
|
-
if (dir && exists(
|
|
10848
|
+
if (dir && exists(join14(dir, "cmux")))
|
|
10577
10849
|
return "cmux";
|
|
10578
10850
|
}
|
|
10579
10851
|
return exists(CMUX_APP_BIN) ? CMUX_APP_BIN : "cmux";
|
|
@@ -10934,7 +11206,7 @@ function cmuxRunner(exec, deps = {}) {
|
|
|
10934
11206
|
|
|
10935
11207
|
// src/runners/orca.ts
|
|
10936
11208
|
import { existsSync as existsSync12, lstatSync, readlinkSync, writeFileSync as writeFileSync11 } from "node:fs";
|
|
10937
|
-
import { join as
|
|
11209
|
+
import { join as join15, resolve as resolve7 } from "node:path";
|
|
10938
11210
|
var obj = (v) => v !== null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
10939
11211
|
var str8 = (v) => typeof v === "string" && v.length > 0 ? v : null;
|
|
10940
11212
|
var parseOrcaJson = (stdout) => {
|
|
@@ -10995,7 +11267,7 @@ var realFs = { lstat: lstatSync, readlink: readlinkSync, exists: existsSync12 };
|
|
|
10995
11267
|
var ORCA_LINK_FIX = "reinstall Orca's shell command from Orca (it links `orca` onto your PATH)";
|
|
10996
11268
|
function danglingOrca(path, fs) {
|
|
10997
11269
|
for (const dir of path.split(":").filter(Boolean)) {
|
|
10998
|
-
const link =
|
|
11270
|
+
const link = join15(dir, "orca");
|
|
10999
11271
|
try {
|
|
11000
11272
|
if (!fs.lstat(link).isSymbolicLink())
|
|
11001
11273
|
return null;
|
|
@@ -11142,10 +11414,10 @@ function orcaRunner(exec, deps = {}) {
|
|
|
11142
11414
|
}
|
|
11143
11415
|
|
|
11144
11416
|
// src/runtime.ts
|
|
11145
|
-
import { homedir } from "node:os";
|
|
11146
|
-
import { join as
|
|
11417
|
+
import { homedir as homedir2 } from "node:os";
|
|
11418
|
+
import { join as join16, win32 } from "node:path";
|
|
11147
11419
|
var isCompiled = (argv1 = process.argv[1]) => Boolean(argv1 && (argv1.startsWith("/$bunfs/") || argv1.startsWith("B:\\~BUN\\")));
|
|
11148
|
-
var sledsLink = (home =
|
|
11420
|
+
var sledsLink = (home = homedir2(), platform = process.platform) => platform === "win32" ? win32.join(process.env.LOCALAPPDATA ?? win32.join(home, "AppData", "Local"), "sleds", "bin", "sleds.exe") : join16(home, ".sleds", "bin", "sleds");
|
|
11149
11421
|
|
|
11150
11422
|
// src/commands/doctor.ts
|
|
11151
11423
|
init_settings();
|
|
@@ -11165,7 +11437,7 @@ import {
|
|
|
11165
11437
|
writeFileSync as writeFileSync16
|
|
11166
11438
|
} from "node:fs";
|
|
11167
11439
|
import { hostname as hostname2, userInfo } from "node:os";
|
|
11168
|
-
import { dirname as dirname15, isAbsolute as isAbsolute3, join as
|
|
11440
|
+
import { dirname as dirname15, isAbsolute as isAbsolute3, join as join24, resolve as resolve8 } from "node:path";
|
|
11169
11441
|
|
|
11170
11442
|
// src/engine/beat.ts
|
|
11171
11443
|
var BEAT_EVERY_MS = 60000;
|
|
@@ -11177,10 +11449,11 @@ function beatBody(state, flags, host = {}, cap = {}) {
|
|
|
11177
11449
|
name: flags.name,
|
|
11178
11450
|
os: host.os ?? process.platform,
|
|
11179
11451
|
runner: flags.runner,
|
|
11180
|
-
version: host.version ?? "0.1.
|
|
11452
|
+
version: host.version ?? "0.1.51" ?? "dev",
|
|
11181
11453
|
running: live.length,
|
|
11182
11454
|
items: live.slice(0, BEAT_ITEMS).map((r) => `${r.item}/${r.node}`),
|
|
11183
11455
|
...cap.atOnce !== undefined ? { atOnce: cap.atOnce } : {},
|
|
11456
|
+
...host.credential ? { credential: host.credential } : {},
|
|
11184
11457
|
...m ? {
|
|
11185
11458
|
machine: {
|
|
11186
11459
|
cpuPct: m.cpuPct,
|
|
@@ -13067,9 +13340,9 @@ function providerFailure(screen) {
|
|
|
13067
13340
|
// src/engine/worktree.ts
|
|
13068
13341
|
init_src();
|
|
13069
13342
|
import { appendFileSync, existsSync as existsSync13, mkdirSync as mkdirSync11 } from "node:fs";
|
|
13070
|
-
import { dirname as dirname11, isAbsolute, join as
|
|
13343
|
+
import { dirname as dirname11, isAbsolute, join as join17 } from "node:path";
|
|
13071
13344
|
function worktreePath(repoPath, name) {
|
|
13072
|
-
return
|
|
13345
|
+
return join17(repoPath, ".worktrees", name);
|
|
13073
13346
|
}
|
|
13074
13347
|
var fail = (what, r) => new Error(`${what} failed: ${(r.stderr || r.stdout).trim() || `exit ${r.status}`}`);
|
|
13075
13348
|
function defaultBranch(exec, repoPath) {
|
|
@@ -13104,7 +13377,7 @@ function ensureIgnored(exec, repoPath, fs = realWorktreeFs) {
|
|
|
13104
13377
|
if (common.status !== 0)
|
|
13105
13378
|
return;
|
|
13106
13379
|
const dir = common.stdout.trim();
|
|
13107
|
-
const exclude =
|
|
13380
|
+
const exclude = join17(isAbsolute(dir) ? dir : join17(repoPath, dir), "info", "exclude");
|
|
13108
13381
|
fs.append(exclude, `
|
|
13109
13382
|
# sleds engine: one worktree per route node
|
|
13110
13383
|
.worktrees/
|
|
@@ -13116,7 +13389,7 @@ function ensureWorktree(exec, repoPath, branch, path, base = "main", fs = realWo
|
|
|
13116
13389
|
return path;
|
|
13117
13390
|
}
|
|
13118
13391
|
function makeWorktree(exec, repoPath, branch, path, base, fs, log) {
|
|
13119
|
-
if (fs.exists(
|
|
13392
|
+
if (fs.exists(join17(path, ".git"))) {
|
|
13120
13393
|
fastForwardUntouched(exec, path, base, log);
|
|
13121
13394
|
return path;
|
|
13122
13395
|
}
|
|
@@ -13192,13 +13465,13 @@ function installArgv(command) {
|
|
|
13192
13465
|
return rest.every((a) => a.startsWith("-")) ? argv : null;
|
|
13193
13466
|
}
|
|
13194
13467
|
function lockfileInstall(path, exists) {
|
|
13195
|
-
if (exists(
|
|
13468
|
+
if (exists(join17(path, "pnpm-lock.yaml")))
|
|
13196
13469
|
return ["pnpm", "install", "--frozen-lockfile"];
|
|
13197
|
-
if (exists(
|
|
13470
|
+
if (exists(join17(path, "bun.lock")) || exists(join17(path, "bun.lockb")))
|
|
13198
13471
|
return ["bun", "install", "--frozen-lockfile"];
|
|
13199
|
-
if (exists(
|
|
13472
|
+
if (exists(join17(path, "yarn.lock")))
|
|
13200
13473
|
return ["yarn", "install", "--frozen-lockfile"];
|
|
13201
|
-
if (exists(
|
|
13474
|
+
if (exists(join17(path, "package-lock.json")))
|
|
13202
13475
|
return ["npm", "ci"];
|
|
13203
13476
|
return null;
|
|
13204
13477
|
}
|
|
@@ -13256,7 +13529,7 @@ function claimRunOf(run, repo) {
|
|
|
13256
13529
|
};
|
|
13257
13530
|
}
|
|
13258
13531
|
function ensureInstalled(exec, path, fs, o = {}) {
|
|
13259
|
-
if (!fs.exists(
|
|
13532
|
+
if (!fs.exists(join17(path, "package.json")) || fs.exists(join17(path, "node_modules")))
|
|
13260
13533
|
return null;
|
|
13261
13534
|
const argv = installArgv(o.command) ?? lockfileInstall(path, fs.exists);
|
|
13262
13535
|
if (!argv)
|
|
@@ -13271,7 +13544,7 @@ function ensureInstalled(exec, path, fs, o = {}) {
|
|
|
13271
13544
|
return { argv, ok };
|
|
13272
13545
|
}
|
|
13273
13546
|
function ensureDetachedWorktree(exec, repoPath, path, base = "main", fs = realWorktreeFs) {
|
|
13274
|
-
if (fs.exists(
|
|
13547
|
+
if (fs.exists(join17(path, ".git")))
|
|
13275
13548
|
return path;
|
|
13276
13549
|
ensureIgnored(exec, repoPath, fs);
|
|
13277
13550
|
const f = exec("git", ["-C", repoPath, "fetch", "origin", base]);
|
|
@@ -16560,8 +16833,8 @@ init_settings();
|
|
|
16560
16833
|
|
|
16561
16834
|
// src/update/drain.ts
|
|
16562
16835
|
import { closeSync as closeSync4, existsSync as existsSync18, mkdirSync as mkdirSync17, openSync as openSync4, rmSync as rmSync9, statSync as statSync4, writeSync as writeSync2 } from "node:fs";
|
|
16563
|
-
import { homedir as
|
|
16564
|
-
import { join as
|
|
16836
|
+
import { homedir as homedir7 } from "node:os";
|
|
16837
|
+
import { join as join23 } from "node:path";
|
|
16565
16838
|
|
|
16566
16839
|
// ../../packages/shared/src/updates/manifest.ts
|
|
16567
16840
|
var CLI_PLATFORMS = [
|
|
@@ -16703,13 +16976,13 @@ import {
|
|
|
16703
16976
|
statSync as statSync2,
|
|
16704
16977
|
writeFileSync as writeFileSync13
|
|
16705
16978
|
} from "node:fs";
|
|
16706
|
-
import { homedir as
|
|
16707
|
-
import { dirname as dirname12, join as
|
|
16979
|
+
import { homedir as homedir3 } from "node:os";
|
|
16980
|
+
import { dirname as dirname12, join as join18, win32 as win322 } from "node:path";
|
|
16708
16981
|
var UPDATE_LOCK_STALE_MS = 10 * 60000;
|
|
16709
|
-
function sledsRoot(home =
|
|
16710
|
-
return platform === "win32" ? win322.join(process.env.LOCALAPPDATA ?? win322.join(home, "AppData", "Local"), "sleds") :
|
|
16982
|
+
function sledsRoot(home = homedir3(), platform = process.platform) {
|
|
16983
|
+
return platform === "win32" ? win322.join(process.env.LOCALAPPDATA ?? win322.join(home, "AppData", "Local"), "sleds") : join18(home, ".sleds");
|
|
16711
16984
|
}
|
|
16712
|
-
var pathFor = (platform) => platform === "win32" ? win322 : { join:
|
|
16985
|
+
var pathFor = (platform) => platform === "win32" ? win322 : { join: join18 };
|
|
16713
16986
|
function versionDir(home, v, platform = process.platform) {
|
|
16714
16987
|
return pathFor(platform).join(sledsRoot(home, platform), "versions", v);
|
|
16715
16988
|
}
|
|
@@ -16901,7 +17174,7 @@ async function fetchVersion(o) {
|
|
|
16901
17174
|
const platform = o.platform ?? process.platform;
|
|
16902
17175
|
const arch = o.arch ?? process.arch;
|
|
16903
17176
|
const publicKey = o.publicKey ?? RELEASE_PUBLIC_KEY;
|
|
16904
|
-
const running = o.running ?? "0.1.
|
|
17177
|
+
const running = o.running ?? "0.1.51";
|
|
16905
17178
|
if (!publicKey)
|
|
16906
17179
|
return { ok: false, why: "no release key yet" };
|
|
16907
17180
|
if (!VERSION_RE2.test(o.version))
|
|
@@ -16978,7 +17251,7 @@ async function fetchVersion(o) {
|
|
|
16978
17251
|
|
|
16979
17252
|
// src/update/guard.ts
|
|
16980
17253
|
import { existsSync as existsSync17 } from "node:fs";
|
|
16981
|
-
import { homedir as
|
|
17254
|
+
import { homedir as homedir6 } from "node:os";
|
|
16982
17255
|
|
|
16983
17256
|
// src/update/migrate.ts
|
|
16984
17257
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -16994,20 +17267,20 @@ import {
|
|
|
16994
17267
|
symlinkSync,
|
|
16995
17268
|
writeFileSync as writeFileSync15
|
|
16996
17269
|
} from "node:fs";
|
|
16997
|
-
import { homedir as
|
|
16998
|
-
import { basename as basename5, delimiter as delimiter2, dirname as dirname13, isAbsolute as isAbsolute2, join as
|
|
17270
|
+
import { homedir as homedir4 } from "node:os";
|
|
17271
|
+
import { basename as basename5, delimiter as delimiter2, dirname as dirname13, isAbsolute as isAbsolute2, join as join21, relative } from "node:path";
|
|
16999
17272
|
|
|
17000
17273
|
// src/commands/engineSystemd.ts
|
|
17001
|
-
import { join as
|
|
17274
|
+
import { join as join19 } from "node:path";
|
|
17002
17275
|
var BOX_ENV_UNIT_PATH = "%h/.config/sleds/box.env";
|
|
17003
17276
|
function boxEnvPath(home) {
|
|
17004
|
-
return
|
|
17277
|
+
return join19(home, ".config", "sleds", "box.env");
|
|
17005
17278
|
}
|
|
17006
17279
|
function engineUnitDir(home) {
|
|
17007
|
-
return
|
|
17280
|
+
return join19(home, ".config", "systemd", "user");
|
|
17008
17281
|
}
|
|
17009
17282
|
function engineUnitPath(home, label) {
|
|
17010
|
-
return
|
|
17283
|
+
return join19(engineUnitDir(home), `${label}.service`);
|
|
17011
17284
|
}
|
|
17012
17285
|
function systemdQuote(s) {
|
|
17013
17286
|
const body = s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\n").replace(/%/g, "%%").replace(/\$/g, "$$$$");
|
|
@@ -17049,7 +17322,7 @@ function parseEngineUnit(text) {
|
|
|
17049
17322
|
// src/schedule.ts
|
|
17050
17323
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
17051
17324
|
import { existsSync as existsSync15, mkdirSync as mkdirSync14, rmSync as rmSync6, writeFileSync as writeFileSync14 } from "node:fs";
|
|
17052
|
-
import { join as
|
|
17325
|
+
import { join as join20 } from "node:path";
|
|
17053
17326
|
var REVERT_LABEL = "ai.sleds.revert";
|
|
17054
17327
|
var defaultExec2 = (cmd, args) => {
|
|
17055
17328
|
const r = spawnSync4(cmd, [...args], { stdio: ["ignore", "ignore", "pipe"], encoding: "utf8" });
|
|
@@ -17057,7 +17330,7 @@ var defaultExec2 = (cmd, args) => {
|
|
|
17057
17330
|
return { ok: false, stderr: r.error.message };
|
|
17058
17331
|
return { ok: r.status === 0, stderr: r.stderr ?? "" };
|
|
17059
17332
|
};
|
|
17060
|
-
var plistPath = (home) =>
|
|
17333
|
+
var plistPath = (home) => join20(home, "Library", "LaunchAgents", `${REVERT_LABEL}.plist`);
|
|
17061
17334
|
var xmlEscape2 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
17062
17335
|
var buildLaunchdPlist = (sledsArgv, deadline) => {
|
|
17063
17336
|
const args = [...sledsArgv, "off"].map((a) => ` <string>${xmlEscape2(a)}</string>`).join(`
|
|
@@ -17096,7 +17369,7 @@ var scheduleRevert = (d, deadlineMs) => {
|
|
|
17096
17369
|
if (d.platform === "darwin") {
|
|
17097
17370
|
const p = plistPath(d.home);
|
|
17098
17371
|
try {
|
|
17099
|
-
mkdirSync14(
|
|
17372
|
+
mkdirSync14(join20(d.home, "Library", "LaunchAgents"), { recursive: true });
|
|
17100
17373
|
d.exec("launchctl", ["unload", p]);
|
|
17101
17374
|
writeFileSync14(p, buildLaunchdPlist(d.sledsArgv, deadline));
|
|
17102
17375
|
const r = d.exec("launchctl", ["load", p]);
|
|
@@ -17148,8 +17421,8 @@ var HOOK_SUBS = [
|
|
|
17148
17421
|
"stop-event",
|
|
17149
17422
|
"permission-event"
|
|
17150
17423
|
];
|
|
17151
|
-
var migrateBakDir = (home) =>
|
|
17152
|
-
var manifestPath = (home) =>
|
|
17424
|
+
var migrateBakDir = (home) => join21(sledsRoot(home), "migrate.bak");
|
|
17425
|
+
var manifestPath = (home) => join21(migrateBakDir(home), "manifest.json");
|
|
17153
17426
|
var xmlEscape3 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
17154
17427
|
var xmlUnescape = (s) => s.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
|
17155
17428
|
var shQuote = (s) => /^[\w./~-]+$/.test(s) ? s : `'${s.replace(/'/g, "'\\''")}'`;
|
|
@@ -17249,13 +17522,13 @@ function rewriteSettings(text, link) {
|
|
|
17249
17522
|
}
|
|
17250
17523
|
var listDir = (dir, keep) => {
|
|
17251
17524
|
try {
|
|
17252
|
-
return readdirSync2(dir).filter(keep).sort().map((n) =>
|
|
17525
|
+
return readdirSync2(dir).filter(keep).sort().map((n) => join21(dir, n));
|
|
17253
17526
|
} catch {
|
|
17254
17527
|
return [];
|
|
17255
17528
|
}
|
|
17256
17529
|
};
|
|
17257
17530
|
function unitFiles(home) {
|
|
17258
|
-
const agents = listDir(
|
|
17531
|
+
const agents = listDir(join21(home, "Library", "LaunchAgents"), (n) => n.startsWith("ai.sleds.") && n.endsWith(".plist")).map((path) => ({
|
|
17259
17532
|
path,
|
|
17260
17533
|
...basename5(path).startsWith("ai.sleds.revert") ? {} : { reload: "launchd" }
|
|
17261
17534
|
}));
|
|
@@ -17267,7 +17540,7 @@ function unitClaudeDir(text) {
|
|
|
17267
17540
|
return plist ? xmlUnescape(plist) : undefined;
|
|
17268
17541
|
}
|
|
17269
17542
|
function claudeDirs(home, env) {
|
|
17270
|
-
const dirs = [
|
|
17543
|
+
const dirs = [join21(home, ".claude"), claudeDir(home, env)];
|
|
17271
17544
|
for (const u of unitFiles(home)) {
|
|
17272
17545
|
try {
|
|
17273
17546
|
const d = unitClaudeDir(readFileSync14(u.path, "utf8"));
|
|
@@ -17291,7 +17564,7 @@ function migrationPlan(home, link, env = process.env) {
|
|
|
17291
17564
|
out.push({ ...u, text: next });
|
|
17292
17565
|
}
|
|
17293
17566
|
for (const dir of claudeDirs(home, env)) {
|
|
17294
|
-
const path =
|
|
17567
|
+
const path = join21(dir, "settings.json");
|
|
17295
17568
|
let text;
|
|
17296
17569
|
try {
|
|
17297
17570
|
text = readFileSync14(path, "utf8");
|
|
@@ -17306,7 +17579,7 @@ function migrationPlan(home, link, env = process.env) {
|
|
|
17306
17579
|
}
|
|
17307
17580
|
var backupFor = (home, path) => {
|
|
17308
17581
|
const rel = relative(home, path);
|
|
17309
|
-
return rel.startsWith("..") || isAbsolute2(rel) ?
|
|
17582
|
+
return rel.startsWith("..") || isAbsolute2(rel) ? join21(migrateBakDir(home), "abs", path) : join21(migrateBakDir(home), rel);
|
|
17310
17583
|
};
|
|
17311
17584
|
function writeKeepingMode(path, text) {
|
|
17312
17585
|
let mode = 420;
|
|
@@ -17391,7 +17664,7 @@ function putBack(home, m) {
|
|
|
17391
17664
|
return failed;
|
|
17392
17665
|
}
|
|
17393
17666
|
function restoreMigration(s, o) {
|
|
17394
|
-
const home = o.home ??
|
|
17667
|
+
const home = o.home ?? homedir4();
|
|
17395
17668
|
const m = readManifest(home);
|
|
17396
17669
|
const to = m?.to ?? s.pending?.to ?? "?";
|
|
17397
17670
|
const failed = m ? putBack(home, m) : [];
|
|
@@ -17403,7 +17676,7 @@ function restoreMigration(s, o) {
|
|
|
17403
17676
|
return failed.length ? `moved back to the npm install, but could not restore ${failed.join(", ")} — the copies are in ${migrateBakDir(home)}` : "moved back to the npm install";
|
|
17404
17677
|
}
|
|
17405
17678
|
async function migrateToBinary(o) {
|
|
17406
|
-
const home = o.home ??
|
|
17679
|
+
const home = o.home ?? homedir4();
|
|
17407
17680
|
const log = o.log ?? console.error;
|
|
17408
17681
|
const env = o.env ?? process.env;
|
|
17409
17682
|
const platform = o.platform ?? process.platform;
|
|
@@ -17497,11 +17770,11 @@ import {
|
|
|
17497
17770
|
rmSync as rmSync8,
|
|
17498
17771
|
symlinkSync as symlinkSync2
|
|
17499
17772
|
} from "node:fs";
|
|
17500
|
-
import { homedir as
|
|
17501
|
-
import { dirname as dirname14, join as
|
|
17773
|
+
import { homedir as homedir5 } from "node:os";
|
|
17774
|
+
import { dirname as dirname14, join as join22 } from "node:path";
|
|
17502
17775
|
var NO_PREVIOUS = "no previous version on this machine";
|
|
17503
|
-
function allStateFiles(home =
|
|
17504
|
-
const roots = [...new Set([configDir(home, env),
|
|
17776
|
+
function allStateFiles(home = homedir5(), env = process.env) {
|
|
17777
|
+
const roots = [...new Set([configDir(home, env), join22(home, ".config", "sleds")])];
|
|
17505
17778
|
const out = [];
|
|
17506
17779
|
const walk = (dir) => {
|
|
17507
17780
|
let names;
|
|
@@ -17512,20 +17785,20 @@ function allStateFiles(home = homedir4(), env = process.env) {
|
|
|
17512
17785
|
}
|
|
17513
17786
|
for (const n of names.sort())
|
|
17514
17787
|
if (n.endsWith(".json") && n !== "removed-engines.json")
|
|
17515
|
-
out.push(
|
|
17788
|
+
out.push(join22(dir, n));
|
|
17516
17789
|
for (const sub of ["orgs", "seats"]) {
|
|
17517
17790
|
let kids;
|
|
17518
17791
|
try {
|
|
17519
|
-
kids = readdirSync3(
|
|
17792
|
+
kids = readdirSync3(join22(dir, sub));
|
|
17520
17793
|
} catch {
|
|
17521
17794
|
continue;
|
|
17522
17795
|
}
|
|
17523
17796
|
for (const k of kids.sort())
|
|
17524
|
-
walk(
|
|
17797
|
+
walk(join22(dir, sub, k));
|
|
17525
17798
|
}
|
|
17526
17799
|
};
|
|
17527
17800
|
for (const r of roots)
|
|
17528
|
-
walk(
|
|
17801
|
+
walk(join22(r, "engine"));
|
|
17529
17802
|
return out;
|
|
17530
17803
|
}
|
|
17531
17804
|
var backupPath2 = (file, v) => `${file}.${v}.bak`;
|
|
@@ -17621,7 +17894,7 @@ function applyConfirm(s, home, o = {}) {
|
|
|
17621
17894
|
}
|
|
17622
17895
|
for (const n of names)
|
|
17623
17896
|
if (n.startsWith(prefix) && n.endsWith(".bak"))
|
|
17624
|
-
rmSync8(
|
|
17897
|
+
rmSync8(join22(dir, n), { force: true });
|
|
17625
17898
|
}
|
|
17626
17899
|
const keep = new Set([s.current, s.previous, s.drain?.to].filter(Boolean));
|
|
17627
17900
|
const versions = dirname14(versionDir(home, s.current, platform));
|
|
@@ -17711,7 +17984,7 @@ function movedAway(s, home, version, platform) {
|
|
|
17711
17984
|
return at && at !== version ? at : null;
|
|
17712
17985
|
}
|
|
17713
17986
|
async function startGuard(o) {
|
|
17714
|
-
const home = o.home ??
|
|
17987
|
+
const home = o.home ?? homedir6();
|
|
17715
17988
|
const platform = o.platform ?? process.platform;
|
|
17716
17989
|
const version = o.version;
|
|
17717
17990
|
if (!version || !guarded(home, version, platform))
|
|
@@ -17743,7 +18016,7 @@ async function startGuard(o) {
|
|
|
17743
18016
|
}
|
|
17744
18017
|
}
|
|
17745
18018
|
function firstBeatWatchdog(o) {
|
|
17746
|
-
const home = o.home ??
|
|
18019
|
+
const home = o.home ?? homedir6();
|
|
17747
18020
|
const platform = o.platform ?? process.platform;
|
|
17748
18021
|
const version = o.version;
|
|
17749
18022
|
const idle = { beat: async () => {}, stop: () => {} };
|
|
@@ -17884,7 +18157,7 @@ async function machineAnswer(client, tokens) {
|
|
|
17884
18157
|
}
|
|
17885
18158
|
async function fetchOnce(o) {
|
|
17886
18159
|
const dir = versionDir(o.home, o.version, o.platform);
|
|
17887
|
-
const lock =
|
|
18160
|
+
const lock = join23(dir, "fetch.lock");
|
|
17888
18161
|
mkdirSync17(dir, { recursive: true, mode: 493 });
|
|
17889
18162
|
let fd;
|
|
17890
18163
|
try {
|
|
@@ -17928,7 +18201,7 @@ var realPidAlive = (pid) => {
|
|
|
17928
18201
|
}
|
|
17929
18202
|
};
|
|
17930
18203
|
function engineUpdater(o) {
|
|
17931
|
-
const home = o.home ??
|
|
18204
|
+
const home = o.home ?? homedir7();
|
|
17932
18205
|
const platform = o.platform ?? process.platform;
|
|
17933
18206
|
const version = o.version;
|
|
17934
18207
|
if (!version || !VERSION_RE3.test(version))
|
|
@@ -18391,7 +18664,7 @@ function flagsFromProfile(flags, given, profile, home) {
|
|
|
18391
18664
|
}
|
|
18392
18665
|
}
|
|
18393
18666
|
if (profile.reposDir && !has("repos-dir") && !has("repo")) {
|
|
18394
|
-
out.reposDir = splitReposDirs(profile.reposDir).map((d) => home && /^~(\/|$)/.test(d) ?
|
|
18667
|
+
out.reposDir = splitReposDirs(profile.reposDir).map((d) => home && /^~(\/|$)/.test(d) ? join24(home, d.slice(1)) : d).join(":");
|
|
18395
18668
|
used.push(`repos ${profile.reposDir}`);
|
|
18396
18669
|
}
|
|
18397
18670
|
if (profile.mcpStrict !== undefined && !has("strict-mcp") && !has("no-strict-mcp")) {
|
|
@@ -18485,7 +18758,7 @@ function engineClient(o, org) {
|
|
|
18485
18758
|
return fetchClient({
|
|
18486
18759
|
...src,
|
|
18487
18760
|
timeoutMs: ENGINE_TIMEOUT_MS,
|
|
18488
|
-
version: "0.1.
|
|
18761
|
+
version: "0.1.51"
|
|
18489
18762
|
});
|
|
18490
18763
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
18491
18764
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -18525,12 +18798,12 @@ function memberMcpConfigs(o, cwd) {
|
|
|
18525
18798
|
});
|
|
18526
18799
|
const claudeDir = (o.env ?? process.env).CLAUDE_CONFIG_DIR;
|
|
18527
18800
|
return [
|
|
18528
|
-
read(claudeDir ?
|
|
18529
|
-
...cwd ? [read(
|
|
18801
|
+
read(claudeDir ? join24(claudeDir, ".claude.json") : join24(o.home, ".claude.json")),
|
|
18802
|
+
...cwd ? [read(join24(cwd, ".mcp.json"))] : []
|
|
18530
18803
|
];
|
|
18531
18804
|
}
|
|
18532
18805
|
function engineStateDir(o, org, seat) {
|
|
18533
|
-
return seatStateDir(orgStateDir(o.stateDir ??
|
|
18806
|
+
return seatStateDir(orgStateDir(o.stateDir ?? join24(configDir(o.home, o.env ?? process.env), "engine"), org), seat);
|
|
18534
18807
|
}
|
|
18535
18808
|
function engineSeat(o, org) {
|
|
18536
18809
|
try {
|
|
@@ -18560,8 +18833,8 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
18560
18833
|
const repo = flags.repo ? resolve8(cwd, flags.repo) : undefined;
|
|
18561
18834
|
const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve8(cwd, d));
|
|
18562
18835
|
const { branch, prTitle } = flags;
|
|
18563
|
-
const hooksDir =
|
|
18564
|
-
const permissionMark = (name) =>
|
|
18836
|
+
const hooksDir = join24(stateDir, "hooks");
|
|
18837
|
+
const permissionMark = (name) => join24(hooksDir, `${name}.permission.json`);
|
|
18565
18838
|
const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
|
|
18566
18839
|
return {
|
|
18567
18840
|
source,
|
|
@@ -18586,9 +18859,9 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
18586
18859
|
sandbox: true,
|
|
18587
18860
|
writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd, allow) => {
|
|
18588
18861
|
const gitCommonDir = gitCommonDirOf(exec, cwd);
|
|
18589
|
-
const dir =
|
|
18862
|
+
const dir = join24(stateDir, "sandbox");
|
|
18590
18863
|
mkdirSync18(dir, { recursive: true, mode: 448 });
|
|
18591
|
-
const p =
|
|
18864
|
+
const p = join24(dir, `${name}.json`);
|
|
18592
18865
|
const walls = engineSandboxSettings(o.home, o.env ?? process.env, gitCommonDir, [
|
|
18593
18866
|
...SANDBOX_DEFAULT_ALLOW,
|
|
18594
18867
|
...flags.sandboxAllow ?? []
|
|
@@ -18605,7 +18878,7 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
18605
18878
|
} : {},
|
|
18606
18879
|
writeHookSettings: (name, allow) => {
|
|
18607
18880
|
mkdirSync18(hooksDir, { recursive: true, mode: 448 });
|
|
18608
|
-
const p =
|
|
18881
|
+
const p = join24(hooksDir, `${name}.json`);
|
|
18609
18882
|
const base = allow?.length ? { permissions: { allow: [...allow] } } : {};
|
|
18610
18883
|
writeFileSync16(p, `${JSON.stringify(withHook(name, base), null, 2)}
|
|
18611
18884
|
`, { mode: 384 });
|
|
@@ -18633,9 +18906,9 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
18633
18906
|
exists
|
|
18634
18907
|
}),
|
|
18635
18908
|
writeMcpConfig: o.writeMcpConfig ?? ((name, runToken, worktree) => {
|
|
18636
|
-
const dir =
|
|
18909
|
+
const dir = join24(stateDir, "mcp");
|
|
18637
18910
|
mkdirSync18(dir, { recursive: true, mode: 448 });
|
|
18638
|
-
const p =
|
|
18911
|
+
const p = join24(dir, `${name}.json`);
|
|
18639
18912
|
let others = {};
|
|
18640
18913
|
if (flags.strictMcp && flags.mcpAllow?.length) {
|
|
18641
18914
|
const r = mcpPassThrough(flags.mcpAllow, memberMcpConfigs(o, worktree));
|
|
@@ -18651,9 +18924,9 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
18651
18924
|
}),
|
|
18652
18925
|
removeMcpConfig: o.removeMcpConfig ?? ((p) => rmSync10(p, { force: true })),
|
|
18653
18926
|
writePrompt: o.writePrompt ?? ((name, text) => {
|
|
18654
|
-
const dir =
|
|
18927
|
+
const dir = join24(stateDir, "prompts");
|
|
18655
18928
|
mkdirSync18(dir, { recursive: true, mode: 448 });
|
|
18656
|
-
const p =
|
|
18929
|
+
const p = join24(dir, `${name}.md`);
|
|
18657
18930
|
writeFileSync16(p, text, { mode: 384 });
|
|
18658
18931
|
return p;
|
|
18659
18932
|
}),
|
|
@@ -18680,14 +18953,14 @@ function engineDeps(o, flags, source, runner, stateName) {
|
|
|
18680
18953
|
}
|
|
18681
18954
|
function sandboxDenyRead(home, env) {
|
|
18682
18955
|
return {
|
|
18683
|
-
dirs: [...new Set([configDir(home, env),
|
|
18956
|
+
dirs: [...new Set([configDir(home, env), join24(home, ".config", "sleds")])],
|
|
18684
18957
|
files: [
|
|
18685
18958
|
...new Set([
|
|
18686
18959
|
tokenPath(home, env),
|
|
18687
|
-
|
|
18960
|
+
join24(home, ".sleds-token"),
|
|
18688
18961
|
settingsPath(home, env),
|
|
18689
18962
|
backupPath(home, env),
|
|
18690
|
-
|
|
18963
|
+
join24(claudeDir(home, env), "settings.local.json")
|
|
18691
18964
|
])
|
|
18692
18965
|
]
|
|
18693
18966
|
};
|
|
@@ -18708,7 +18981,7 @@ function gitCommonDirOf(exec, cwd) {
|
|
|
18708
18981
|
}
|
|
18709
18982
|
var LENT_NEEDS_SANDBOX = "a lent engine runs every session sandboxed (spec 48 rule 10) — add --sandbox to --lent-by";
|
|
18710
18983
|
function lenderHome(accountHome, lentBy) {
|
|
18711
|
-
return isAbsolute3(lentBy) ? resolve8(lentBy) :
|
|
18984
|
+
return isAbsolute3(lentBy) ? resolve8(lentBy) : join24(dirname15(accountHome), lentBy);
|
|
18712
18985
|
}
|
|
18713
18986
|
function lentHomeProblems(accountHome, lentBy, modeOf) {
|
|
18714
18987
|
const lender = lenderHome(accountHome, lentBy);
|
|
@@ -18776,7 +19049,7 @@ async function driveEngine(o, flags, deps, until = {}) {
|
|
|
18776
19049
|
runner: deps.runner.name,
|
|
18777
19050
|
atOnce: flags.atOnce,
|
|
18778
19051
|
interval: flags.interval,
|
|
18779
|
-
cliVersion: "0.1.
|
|
19052
|
+
cliVersion: "0.1.51"
|
|
18780
19053
|
};
|
|
18781
19054
|
const beat = (checkedAt) => {
|
|
18782
19055
|
const m = deps.machine;
|
|
@@ -19122,7 +19395,7 @@ import {
|
|
|
19122
19395
|
writeFileSync as writeFileSync17
|
|
19123
19396
|
} from "node:fs";
|
|
19124
19397
|
import { hostname as hostname3 } from "node:os";
|
|
19125
|
-
import { basename as basename6, dirname as dirname16, isAbsolute as isAbsolute4, join as
|
|
19398
|
+
import { basename as basename6, dirname as dirname16, isAbsolute as isAbsolute4, join as join25 } from "node:path";
|
|
19126
19399
|
init_state();
|
|
19127
19400
|
var ENGINE_LABEL = "ai.sleds.engine";
|
|
19128
19401
|
var ENGINE_INSTALL_USAGE = `usage: sleds engine install [engine flags] | sleds engine uninstall [--name <n>] [--org <slug>]
|
|
@@ -19143,13 +19416,13 @@ function engineLabel(name, org, seat) {
|
|
|
19143
19416
|
return [ENGINE_LABEL, org, seat?.trim(), name].filter((p) => Boolean(p)).map((p, i) => i === 0 ? p : engineSlug(p)).join(".");
|
|
19144
19417
|
}
|
|
19145
19418
|
function enginePlistPath(home, name, org, seat) {
|
|
19146
|
-
return
|
|
19419
|
+
return join25(home, "Library", "LaunchAgents", `${engineLabel(name, org, seat)}.plist`);
|
|
19147
19420
|
}
|
|
19148
19421
|
function engineLogPath(stateDir, name) {
|
|
19149
|
-
return
|
|
19422
|
+
return join25(stateDir, `${engineSlug(name)}.log`);
|
|
19150
19423
|
}
|
|
19151
19424
|
function engineEventsPath(stateDir, name) {
|
|
19152
|
-
return
|
|
19425
|
+
return join25(stateDir, `${engineSlug(name)}.events.jsonl`);
|
|
19153
19426
|
}
|
|
19154
19427
|
var xmlEscape4 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
19155
19428
|
function buildEnginePlist(o) {
|
|
@@ -19246,7 +19519,7 @@ function readEngines(dir, suffix, manager, parse) {
|
|
|
19246
19519
|
}
|
|
19247
19520
|
const out = [];
|
|
19248
19521
|
for (const name of names.filter((n) => n.startsWith(`${ENGINE_LABEL}.`) && n.endsWith(suffix))) {
|
|
19249
|
-
const path =
|
|
19522
|
+
const path = join25(dir, name);
|
|
19250
19523
|
let parsed;
|
|
19251
19524
|
try {
|
|
19252
19525
|
parsed = parse(readFileSync16(path, "utf8"), name);
|
|
@@ -19266,7 +19539,7 @@ function readEngines(dir, suffix, manager, parse) {
|
|
|
19266
19539
|
}
|
|
19267
19540
|
function installedEngines(home) {
|
|
19268
19541
|
return [
|
|
19269
|
-
...readEngines(
|
|
19542
|
+
...readEngines(join25(home, "Library", "LaunchAgents"), ".plist", "launchd", parseEnginePlist),
|
|
19270
19543
|
...readEngines(engineUnitDir(home), ".service", "systemd", (text, file) => {
|
|
19271
19544
|
const parsed = parseEngineUnit(text);
|
|
19272
19545
|
return parsed && { label: basename6(file, ".service"), ...parsed };
|
|
@@ -19923,12 +20196,12 @@ function sandboxChecks(o, env) {
|
|
|
19923
20196
|
}
|
|
19924
20197
|
];
|
|
19925
20198
|
const nonce = o.nonce ?? `sleds-probe-${randomBytes(16).toString("hex")}`;
|
|
19926
|
-
const probe =
|
|
19927
|
-
const work = mkdtempSync(
|
|
20199
|
+
const probe = join26(dir, SANDBOX_PROBE);
|
|
20200
|
+
const work = mkdtempSync(join26(tmpdir(), "sleds-sandbox-"));
|
|
19928
20201
|
try {
|
|
19929
20202
|
writeFileSync19(probe, `${nonce}
|
|
19930
20203
|
`, { mode: 384 });
|
|
19931
|
-
const settingsFile =
|
|
20204
|
+
const settingsFile = join26(work, "settings.json");
|
|
19932
20205
|
const settings = engineSandboxSettings(o.home, env, work, SANDBOX_DEFAULT_ALLOW);
|
|
19933
20206
|
const claudeSettings = settingsPath(o.home, env);
|
|
19934
20207
|
writeFileSync19(settingsFile, JSON.stringify(settings, null, 2), { mode: 384 });
|
|
@@ -20100,12 +20373,18 @@ function lentChecks(o, lentBy, engine) {
|
|
|
20100
20373
|
function boxChecks(o, env, which, need) {
|
|
20101
20374
|
const claude = which("claude");
|
|
20102
20375
|
const file = boxEnvPath(o.home);
|
|
20103
|
-
let
|
|
20376
|
+
let boxEnvText = null;
|
|
20104
20377
|
try {
|
|
20105
|
-
|
|
20378
|
+
boxEnvText = readFileSync19(file, "utf8");
|
|
20106
20379
|
} catch {
|
|
20107
|
-
|
|
20380
|
+
boxEnvText = null;
|
|
20108
20381
|
}
|
|
20382
|
+
const cred = detectCredential(env, {
|
|
20383
|
+
home: o.home,
|
|
20384
|
+
boxEnvText,
|
|
20385
|
+
boxEnvPath: file,
|
|
20386
|
+
exists: o.exists ?? existsSync21
|
|
20387
|
+
});
|
|
20109
20388
|
return [
|
|
20110
20389
|
claude ? { level: "ok", name: "claude cli", detail: `${claude} · the headless runner's agent` } : {
|
|
20111
20390
|
level: need,
|
|
@@ -20113,14 +20392,20 @@ function boxChecks(o, env, which, need) {
|
|
|
20113
20392
|
detail: "`claude` not on PATH — the headless runner starts Claude Code for each node",
|
|
20114
20393
|
fix: "npm install -g @anthropic-ai/claude-code"
|
|
20115
20394
|
},
|
|
20116
|
-
|
|
20395
|
+
cred ? { level: "ok", name: "credential", detail: credentialDetail(cred) } : {
|
|
20117
20396
|
level: need,
|
|
20118
|
-
name: "
|
|
20119
|
-
detail: `
|
|
20120
|
-
fix: `add
|
|
20397
|
+
name: "credential",
|
|
20398
|
+
detail: `no ${API_KEY_VAR}, ${SEAT_TOKEN_VAR} or claude login here or in ${file} — a headless session cannot sign in`,
|
|
20399
|
+
fix: `add ${API_KEY_VAR}=… (a key) or ${SEAT_TOKEN_VAR}=… (a seat, from \`claude setup-token\`) to ${file}, or sign in once with \`claude\` and /login`
|
|
20121
20400
|
}
|
|
20122
20401
|
];
|
|
20123
20402
|
}
|
|
20403
|
+
function credentialDetail(c) {
|
|
20404
|
+
if (c.source === "login")
|
|
20405
|
+
return `seat · claude login at ${c.where}`;
|
|
20406
|
+
const name = c.source === "api_key" ? API_KEY_VAR : SEAT_TOKEN_VAR;
|
|
20407
|
+
return `${c.kind} · ${name} ${c.where === "this shell" ? "set in this shell" : `named in ${c.where}`}`;
|
|
20408
|
+
}
|
|
20124
20409
|
function cmuxCheck(o, env) {
|
|
20125
20410
|
const exec = o.exec ?? defaultExec3;
|
|
20126
20411
|
const bin = resolveCmuxBin(o.exists ?? existsSync21, env.PATH ?? "");
|
|
@@ -20215,7 +20500,7 @@ import {
|
|
|
20215
20500
|
writeFileSync as writeFileSync20
|
|
20216
20501
|
} from "node:fs";
|
|
20217
20502
|
import { hostname as hostname4, userInfo as userInfo3 } from "node:os";
|
|
20218
|
-
import { dirname as dirname18, isAbsolute as isAbsolute5, join as
|
|
20503
|
+
import { dirname as dirname18, isAbsolute as isAbsolute5, join as join27, resolve as resolve10 } from "node:path";
|
|
20219
20504
|
init_machine();
|
|
20220
20505
|
init_state();
|
|
20221
20506
|
init_meter();
|
|
@@ -20475,7 +20760,7 @@ function flagsFromProfile2(flags, given, profile, home) {
|
|
|
20475
20760
|
}
|
|
20476
20761
|
}
|
|
20477
20762
|
if (profile.reposDir && !has("repos-dir") && !has("repo")) {
|
|
20478
|
-
out.reposDir = splitReposDirs(profile.reposDir).map((d) => home && /^~(\/|$)/.test(d) ?
|
|
20763
|
+
out.reposDir = splitReposDirs(profile.reposDir).map((d) => home && /^~(\/|$)/.test(d) ? join27(home, d.slice(1)) : d).join(":");
|
|
20479
20764
|
used.push(`repos ${profile.reposDir}`);
|
|
20480
20765
|
}
|
|
20481
20766
|
if (profile.mcpStrict !== undefined && !has("strict-mcp") && !has("no-strict-mcp")) {
|
|
@@ -20621,7 +20906,7 @@ function engineClient2(o, org) {
|
|
|
20621
20906
|
return fetchClient({
|
|
20622
20907
|
...src,
|
|
20623
20908
|
timeoutMs: ENGINE_TIMEOUT_MS2,
|
|
20624
|
-
version: "0.1.
|
|
20909
|
+
version: "0.1.51"
|
|
20625
20910
|
});
|
|
20626
20911
|
const asked = org?.trim() || env.SLEDS_ORG?.trim();
|
|
20627
20912
|
if (asked && !selectOrg(readConfig(o.home), org, env).seat)
|
|
@@ -20670,12 +20955,12 @@ function memberMcpConfigs2(o, cwd) {
|
|
|
20670
20955
|
});
|
|
20671
20956
|
const claudeDir = (o.env ?? process.env).CLAUDE_CONFIG_DIR;
|
|
20672
20957
|
return [
|
|
20673
|
-
read(claudeDir ?
|
|
20674
|
-
...cwd ? [read(
|
|
20958
|
+
read(claudeDir ? join27(claudeDir, ".claude.json") : join27(o.home, ".claude.json")),
|
|
20959
|
+
...cwd ? [read(join27(cwd, ".mcp.json"))] : []
|
|
20675
20960
|
];
|
|
20676
20961
|
}
|
|
20677
20962
|
function engineStateDir2(o, org, seat) {
|
|
20678
|
-
return seatStateDir(orgStateDir(o.stateDir ??
|
|
20963
|
+
return seatStateDir(orgStateDir(o.stateDir ?? join27(configDir(o.home, o.env ?? process.env), "engine"), org), seat);
|
|
20679
20964
|
}
|
|
20680
20965
|
function engineSeat2(o, org) {
|
|
20681
20966
|
try {
|
|
@@ -20694,6 +20979,19 @@ function engineToken2(o, org) {
|
|
|
20694
20979
|
}
|
|
20695
20980
|
}
|
|
20696
20981
|
var withToken2 = (token, now) => token ? { token, tokenNow: now } : {};
|
|
20982
|
+
function engineCredential(o) {
|
|
20983
|
+
const file = boxEnvPath(o.home);
|
|
20984
|
+
let boxEnvText = null;
|
|
20985
|
+
try {
|
|
20986
|
+
boxEnvText = readFileSync20(file, "utf8");
|
|
20987
|
+
} catch {}
|
|
20988
|
+
return detectCredential(o.env ?? process.env, {
|
|
20989
|
+
home: o.home,
|
|
20990
|
+
boxEnvText,
|
|
20991
|
+
boxEnvPath: file,
|
|
20992
|
+
exists: o.exists ?? realExists2
|
|
20993
|
+
})?.kind;
|
|
20994
|
+
}
|
|
20697
20995
|
function engineDeps2(o, flags, source, runner, stateName) {
|
|
20698
20996
|
const exec = guardGit(o.exec ?? defaultExec);
|
|
20699
20997
|
const cwd = o.cwd ?? process.cwd();
|
|
@@ -20705,8 +21003,8 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
20705
21003
|
const repo = flags.repo ? resolve10(cwd, flags.repo) : undefined;
|
|
20706
21004
|
const reposDirs = splitReposDirs(flags.reposDir).map((d) => resolve10(cwd, d));
|
|
20707
21005
|
const { branch, prTitle } = flags;
|
|
20708
|
-
const hooksDir =
|
|
20709
|
-
const permissionMark = (name) =>
|
|
21006
|
+
const hooksDir = join27(stateDir, "hooks");
|
|
21007
|
+
const permissionMark = (name) => join27(hooksDir, `${name}.permission.json`);
|
|
20710
21008
|
const withHook = (name, settings) => applyPermissionHook(settings, [...o.sledsArgv ?? ["sleds"], "permission-event", "--mark", permissionMark(name)].map(shq2).join(" "));
|
|
20711
21009
|
return {
|
|
20712
21010
|
source,
|
|
@@ -20731,9 +21029,9 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
20731
21029
|
sandbox: true,
|
|
20732
21030
|
writeSandboxSettings: o.writeSandboxSettings ?? ((name, cwd, allow) => {
|
|
20733
21031
|
const gitCommonDir = gitCommonDirOf2(exec, cwd);
|
|
20734
|
-
const dir =
|
|
21032
|
+
const dir = join27(stateDir, "sandbox");
|
|
20735
21033
|
mkdirSync21(dir, { recursive: true, mode: 448 });
|
|
20736
|
-
const p =
|
|
21034
|
+
const p = join27(dir, `${name}.json`);
|
|
20737
21035
|
const walls = engineSandboxSettings2(o.home, o.env ?? process.env, gitCommonDir, [
|
|
20738
21036
|
...SANDBOX_DEFAULT_ALLOW,
|
|
20739
21037
|
...flags.sandboxAllow ?? []
|
|
@@ -20750,7 +21048,7 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
20750
21048
|
} : {},
|
|
20751
21049
|
writeHookSettings: (name, allow) => {
|
|
20752
21050
|
mkdirSync21(hooksDir, { recursive: true, mode: 448 });
|
|
20753
|
-
const p =
|
|
21051
|
+
const p = join27(hooksDir, `${name}.json`);
|
|
20754
21052
|
const base = allow?.length ? { permissions: { allow: [...allow] } } : {};
|
|
20755
21053
|
writeFileSync20(p, `${JSON.stringify(withHook(name, base), null, 2)}
|
|
20756
21054
|
`, { mode: 384 });
|
|
@@ -20778,9 +21076,9 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
20778
21076
|
exists
|
|
20779
21077
|
}),
|
|
20780
21078
|
writeMcpConfig: o.writeMcpConfig ?? ((name, runToken, worktree) => {
|
|
20781
|
-
const dir =
|
|
21079
|
+
const dir = join27(stateDir, "mcp");
|
|
20782
21080
|
mkdirSync21(dir, { recursive: true, mode: 448 });
|
|
20783
|
-
const p =
|
|
21081
|
+
const p = join27(dir, `${name}.json`);
|
|
20784
21082
|
let others = {};
|
|
20785
21083
|
if (flags.strictMcp && flags.mcpAllow?.length) {
|
|
20786
21084
|
const r = mcpPassThrough(flags.mcpAllow, memberMcpConfigs2(o, worktree));
|
|
@@ -20796,9 +21094,9 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
20796
21094
|
}),
|
|
20797
21095
|
removeMcpConfig: o.removeMcpConfig ?? ((p) => rmSync14(p, { force: true })),
|
|
20798
21096
|
writePrompt: o.writePrompt ?? ((name, text) => {
|
|
20799
|
-
const dir =
|
|
21097
|
+
const dir = join27(stateDir, "prompts");
|
|
20800
21098
|
mkdirSync21(dir, { recursive: true, mode: 448 });
|
|
20801
|
-
const p =
|
|
21099
|
+
const p = join27(dir, `${name}.md`);
|
|
20802
21100
|
writeFileSync20(p, text, { mode: 384 });
|
|
20803
21101
|
return p;
|
|
20804
21102
|
}),
|
|
@@ -20825,14 +21123,14 @@ function engineDeps2(o, flags, source, runner, stateName) {
|
|
|
20825
21123
|
}
|
|
20826
21124
|
function sandboxDenyRead2(home, env) {
|
|
20827
21125
|
return {
|
|
20828
|
-
dirs: [...new Set([configDir(home, env),
|
|
21126
|
+
dirs: [...new Set([configDir(home, env), join27(home, ".config", "sleds")])],
|
|
20829
21127
|
files: [
|
|
20830
21128
|
...new Set([
|
|
20831
21129
|
tokenPath(home, env),
|
|
20832
|
-
|
|
21130
|
+
join27(home, ".sleds-token"),
|
|
20833
21131
|
settingsPath(home, env),
|
|
20834
21132
|
backupPath(home, env),
|
|
20835
|
-
|
|
21133
|
+
join27(claudeDir(home, env), "settings.local.json")
|
|
20836
21134
|
])
|
|
20837
21135
|
]
|
|
20838
21136
|
};
|
|
@@ -20866,7 +21164,7 @@ function sandboxRefusal(flags) {
|
|
|
20866
21164
|
}
|
|
20867
21165
|
var LENT_NEEDS_SANDBOX2 = "a lent engine runs every session sandboxed (spec 48 rule 10) — add --sandbox to --lent-by";
|
|
20868
21166
|
function lenderHome2(accountHome, lentBy) {
|
|
20869
|
-
return isAbsolute5(lentBy) ? resolve10(lentBy) :
|
|
21167
|
+
return isAbsolute5(lentBy) ? resolve10(lentBy) : join27(dirname18(accountHome), lentBy);
|
|
20870
21168
|
}
|
|
20871
21169
|
function lentHomeProblems2(accountHome, lentBy, modeOf) {
|
|
20872
21170
|
const lender = lenderHome2(accountHome, lentBy);
|
|
@@ -20934,7 +21232,7 @@ async function driveEngine2(o, flags, deps, until = {}) {
|
|
|
20934
21232
|
runner: deps.runner.name,
|
|
20935
21233
|
atOnce: flags.atOnce,
|
|
20936
21234
|
interval: flags.interval,
|
|
20937
|
-
cliVersion: "0.1.
|
|
21235
|
+
cliVersion: "0.1.51"
|
|
20938
21236
|
};
|
|
20939
21237
|
const beat = (checkedAt) => {
|
|
20940
21238
|
const m = deps.machine;
|
|
@@ -21312,9 +21610,10 @@ var engineCmd = async (o) => {
|
|
|
21312
21610
|
refused = r.refused;
|
|
21313
21611
|
error(r.below ? `${r.refused}. This engine is not shown as up until it beats on a version SLEDS serves.` : `${r.refused}. This engine is not shown as up until it beats under a name of its own.`);
|
|
21314
21612
|
};
|
|
21613
|
+
const credential = engineCredential(o);
|
|
21315
21614
|
const body = () => {
|
|
21316
21615
|
const m = deps.machine;
|
|
21317
|
-
return beatBody(deps.readState(), { name: flags.name, runner: deps.runner.name }, {}, {
|
|
21616
|
+
return beatBody(deps.readState(), { name: flags.name, runner: deps.runner.name }, credential ? { credential } : {}, {
|
|
21318
21617
|
atOnce: deps.atOnce,
|
|
21319
21618
|
...m?.last ? { machine: m.last } : {},
|
|
21320
21619
|
...m?.hold && !m.off ? { hold: m.hold } : {}
|
|
@@ -21556,7 +21855,7 @@ import {
|
|
|
21556
21855
|
writeFileSync as writeFileSync21
|
|
21557
21856
|
} from "node:fs";
|
|
21558
21857
|
import { hostname as hostname5 } from "node:os";
|
|
21559
|
-
import { basename as basename7, dirname as dirname19, isAbsolute as isAbsolute6, join as
|
|
21858
|
+
import { basename as basename7, dirname as dirname19, isAbsolute as isAbsolute6, join as join28 } from "node:path";
|
|
21560
21859
|
init_state();
|
|
21561
21860
|
var ENGINE_LABEL2 = "ai.sleds.engine";
|
|
21562
21861
|
var ENGINE_INSTALL_USAGE2 = `usage: sleds engine install [engine flags] | sleds engine uninstall [--name <n>] [--org <slug>]
|
|
@@ -21577,13 +21876,13 @@ function engineLabel2(name, org, seat) {
|
|
|
21577
21876
|
return [ENGINE_LABEL2, org, seat?.trim(), name].filter((p) => Boolean(p)).map((p, i) => i === 0 ? p : engineSlug(p)).join(".");
|
|
21578
21877
|
}
|
|
21579
21878
|
function enginePlistPath2(home, name, org, seat) {
|
|
21580
|
-
return
|
|
21879
|
+
return join28(home, "Library", "LaunchAgents", `${engineLabel2(name, org, seat)}.plist`);
|
|
21581
21880
|
}
|
|
21582
21881
|
function engineLogPath2(stateDir, name) {
|
|
21583
|
-
return
|
|
21882
|
+
return join28(stateDir, `${engineSlug(name)}.log`);
|
|
21584
21883
|
}
|
|
21585
21884
|
function engineEventsPath2(stateDir, name) {
|
|
21586
|
-
return
|
|
21885
|
+
return join28(stateDir, `${engineSlug(name)}.events.jsonl`);
|
|
21587
21886
|
}
|
|
21588
21887
|
var xmlEscape5 = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
21589
21888
|
function buildEnginePlist2(o) {
|
|
@@ -21680,7 +21979,7 @@ function readEngines2(dir, suffix, manager, parse) {
|
|
|
21680
21979
|
}
|
|
21681
21980
|
const out = [];
|
|
21682
21981
|
for (const name of names.filter((n) => n.startsWith(`${ENGINE_LABEL2}.`) && n.endsWith(suffix))) {
|
|
21683
|
-
const path =
|
|
21982
|
+
const path = join28(dir, name);
|
|
21684
21983
|
let parsed;
|
|
21685
21984
|
try {
|
|
21686
21985
|
parsed = parse(readFileSync21(path, "utf8"), name);
|
|
@@ -21700,7 +21999,7 @@ function readEngines2(dir, suffix, manager, parse) {
|
|
|
21700
21999
|
}
|
|
21701
22000
|
function installedEngines2(home) {
|
|
21702
22001
|
return [
|
|
21703
|
-
...readEngines2(
|
|
22002
|
+
...readEngines2(join28(home, "Library", "LaunchAgents"), ".plist", "launchd", parseEnginePlist2),
|
|
21704
22003
|
...readEngines2(engineUnitDir(home), ".service", "systemd", (text, file) => {
|
|
21705
22004
|
const parsed = parseEngineUnit(text);
|
|
21706
22005
|
return parsed && { label: basename7(file, ".service"), ...parsed };
|
|
@@ -21738,7 +22037,7 @@ async function ensureReposDir(o) {
|
|
|
21738
22037
|
return false;
|
|
21739
22038
|
}
|
|
21740
22039
|
const exists = o.exists ?? existsSync22;
|
|
21741
|
-
const missing = dirs.filter((d) => !exists(/^~(\/|$)/.test(d) ?
|
|
22040
|
+
const missing = dirs.filter((d) => !exists(/^~(\/|$)/.test(d) ? join28(o.home, d.slice(1)) : d));
|
|
21742
22041
|
if (missing.length) {
|
|
21743
22042
|
error(`Not a folder on this machine: ${missing.join(", ")}. ${REPOS_DIR_NEEDED}`);
|
|
21744
22043
|
return false;
|
|
@@ -22861,9 +23160,9 @@ init_meter();
|
|
|
22861
23160
|
// src/owed.ts
|
|
22862
23161
|
init_config();
|
|
22863
23162
|
import { existsSync as existsSync26, mkdirSync as mkdirSync23, readFileSync as readFileSync25, renameSync as renameSync11, writeFileSync as writeFileSync22 } from "node:fs";
|
|
22864
|
-
import { dirname as dirname20, join as
|
|
22865
|
-
var owedPath = (home) =>
|
|
22866
|
-
var sessionPath = (home) =>
|
|
23163
|
+
import { dirname as dirname20, join as join29 } from "node:path";
|
|
23164
|
+
var owedPath = (home) => join29(configDir(home), "owed.json");
|
|
23165
|
+
var sessionPath = (home) => join29(configDir(home), "session.json");
|
|
22867
23166
|
var OWED_TTL_MS = 3 * 24 * 60 * 60000;
|
|
22868
23167
|
var str14 = (v) => typeof v === "string" ? v : undefined;
|
|
22869
23168
|
function sourceKey(s) {
|
|
@@ -23021,7 +23320,7 @@ function contextFor(deps) {
|
|
|
23021
23320
|
...src,
|
|
23022
23321
|
fetchFn: deps.fetchFn,
|
|
23023
23322
|
timeoutMs: deps.timeoutMs,
|
|
23024
|
-
version: "0.1.
|
|
23323
|
+
version: "0.1.51"
|
|
23025
23324
|
}), deps.home, now) : null;
|
|
23026
23325
|
return {
|
|
23027
23326
|
channel: "code",
|
|
@@ -24588,7 +24887,7 @@ var orgCmd = (o) => {
|
|
|
24588
24887
|
init_src();
|
|
24589
24888
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
24590
24889
|
import { writeFileSync as writeFileSync25 } from "node:fs";
|
|
24591
|
-
import { join as
|
|
24890
|
+
import { join as join30 } from "node:path";
|
|
24592
24891
|
function packFileName(key) {
|
|
24593
24892
|
return `pack-${slugify(key, 80) || "item"}.md`;
|
|
24594
24893
|
}
|
|
@@ -24616,7 +24915,7 @@ var packCmd = async (o) => {
|
|
|
24616
24915
|
log(r.text);
|
|
24617
24916
|
return 0;
|
|
24618
24917
|
}
|
|
24619
|
-
const path =
|
|
24918
|
+
const path = join30(o.cwd ?? process.cwd(), packFileName(key));
|
|
24620
24919
|
(o.write ?? ((p, t) => writeFileSync25(p, t.endsWith(`
|
|
24621
24920
|
`) ? t : `${t}
|
|
24622
24921
|
`)))(path, r.text);
|
|
@@ -25764,12 +26063,12 @@ async function seatRevokeCmd(o) {
|
|
|
25764
26063
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
25765
26064
|
import { existsSync as existsSync30, mkdirSync as mkdirSync27, readFileSync as readFileSync30, readdirSync as readdirSync7, rmSync as rmSync21, writeFileSync as writeFileSync27 } from "node:fs";
|
|
25766
26065
|
import { platform as platform2 } from "node:os";
|
|
25767
|
-
import { dirname as dirname23, join as
|
|
26066
|
+
import { dirname as dirname23, join as join32 } from "node:path";
|
|
25768
26067
|
|
|
25769
26068
|
// src/cookieDb.ts
|
|
25770
26069
|
import { copyFileSync as copyFileSync3, rmSync as rmSync20 } from "node:fs";
|
|
25771
26070
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
25772
|
-
import { join as
|
|
26071
|
+
import { join as join31 } from "node:path";
|
|
25773
26072
|
var QUERY = "SELECT name, hex(encrypted_value) AS ev FROM cookies WHERE host_key LIKE '%claude.ai%'";
|
|
25774
26073
|
var isBun = () => typeof globalThis.Bun !== "undefined";
|
|
25775
26074
|
async function queryRows(dbPath) {
|
|
@@ -25798,7 +26097,7 @@ function nodeSqlite() {
|
|
|
25798
26097
|
return mod;
|
|
25799
26098
|
}
|
|
25800
26099
|
async function readCookieRows(dbPath) {
|
|
25801
|
-
const copy =
|
|
26100
|
+
const copy = join31(tmpdir2(), `sleds-cookies-${process.pid}-${Date.now()}.sqlite`);
|
|
25802
26101
|
copyFileSync3(dbPath, copy);
|
|
25803
26102
|
try {
|
|
25804
26103
|
const rows = await queryRows(copy);
|
|
@@ -26091,7 +26390,7 @@ function findFile(root, name) {
|
|
|
26091
26390
|
continue;
|
|
26092
26391
|
}
|
|
26093
26392
|
for (const e of entries) {
|
|
26094
|
-
const p =
|
|
26393
|
+
const p = join32(dir, e.name);
|
|
26095
26394
|
if (e.isDirectory())
|
|
26096
26395
|
stack.push(p);
|
|
26097
26396
|
else if (e.name === name)
|
|
@@ -26102,7 +26401,7 @@ function findFile(root, name) {
|
|
|
26102
26401
|
}
|
|
26103
26402
|
function findCookieDb(home, source) {
|
|
26104
26403
|
const b = BROWSERS[source.browser];
|
|
26105
|
-
const root =
|
|
26404
|
+
const root = join32(home, APP_SUPPORT, b.appDir);
|
|
26106
26405
|
if (!existsSync30(root))
|
|
26107
26406
|
throw new Error(`no ${source.browser} data at ${root} (is it installed?)`);
|
|
26108
26407
|
if (!b.profiled) {
|
|
@@ -26111,7 +26410,7 @@ function findCookieDb(home, source) {
|
|
|
26111
26410
|
throw new Error(`no cookie store under ${root}`);
|
|
26112
26411
|
return db;
|
|
26113
26412
|
}
|
|
26114
|
-
const localStatePath =
|
|
26413
|
+
const localStatePath = join32(root, "Local State");
|
|
26115
26414
|
const localState = existsSync30(localStatePath) ? readFileSync30(localStatePath, "utf8") : null;
|
|
26116
26415
|
const wanted = source.profile ?? "Default";
|
|
26117
26416
|
const { dir, ambiguous } = resolveProfileDir(localState, wanted);
|
|
@@ -26119,7 +26418,7 @@ function findCookieDb(home, source) {
|
|
|
26119
26418
|
throw new Error(`"${wanted}" names ${ambiguous.length} ${source.browser} profiles (${ambiguous.join(", ")}) — pass the directory or the account email instead`);
|
|
26120
26419
|
if (!dir)
|
|
26121
26420
|
throw new Error(`no ${source.browser} profile named "${wanted}" (check chrome://version)`);
|
|
26122
|
-
const db = cookieDbCandidates(
|
|
26421
|
+
const db = cookieDbCandidates(join32(root, dir)).find((p) => existsSync30(p));
|
|
26123
26422
|
if (!db)
|
|
26124
26423
|
throw new Error(`profile "${dir}" has no cookie store yet (open claude.ai in it once)`);
|
|
26125
26424
|
return db;
|
|
@@ -26163,7 +26462,7 @@ function fetchSeatUsage(jar, org, now, run) {
|
|
|
26163
26462
|
}
|
|
26164
26463
|
function launchAgentPlist(argv, home, source) {
|
|
26165
26464
|
const label = launchLabel(source);
|
|
26166
|
-
const log =
|
|
26465
|
+
const log = join32(home, ".config", "sleds", `${label.slice("ai.sleds.".length)}.log`);
|
|
26167
26466
|
const esc = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
26168
26467
|
const args = [...argv, "seat-sync", ...sourceArgs(source)].map((a) => ` <string>${esc(a)}</string>`).join(`
|
|
26169
26468
|
`);
|
|
@@ -26185,14 +26484,14 @@ ${args}
|
|
|
26185
26484
|
`;
|
|
26186
26485
|
}
|
|
26187
26486
|
function plistPath2(home, source) {
|
|
26188
|
-
return
|
|
26487
|
+
return join32(home, "Library", "LaunchAgents", `${launchLabel(source)}.plist`);
|
|
26189
26488
|
}
|
|
26190
26489
|
function install(home, argv, source, log, launchctl) {
|
|
26191
26490
|
if (!argv[0]) {
|
|
26192
26491
|
log("cannot resolve the sleds command to install the timer");
|
|
26193
26492
|
return 1;
|
|
26194
26493
|
}
|
|
26195
|
-
const dir =
|
|
26494
|
+
const dir = join32(home, "Library", "LaunchAgents");
|
|
26196
26495
|
mkdirSync27(dir, { recursive: true });
|
|
26197
26496
|
const path = plistPath2(home, source);
|
|
26198
26497
|
const tokenPath = seatTokenPath(home, source);
|
|
@@ -27041,7 +27340,7 @@ var hasEitherKey = (settings) => {
|
|
|
27041
27340
|
// src/commands/update.ts
|
|
27042
27341
|
init_server();
|
|
27043
27342
|
import { existsSync as existsSync34 } from "node:fs";
|
|
27044
|
-
import { homedir as
|
|
27343
|
+
import { homedir as homedir8, userInfo as userInfo4 } from "node:os";
|
|
27045
27344
|
import { basename as basename9 } from "node:path";
|
|
27046
27345
|
init_config();
|
|
27047
27346
|
init_state();
|
|
@@ -27107,7 +27406,7 @@ var realPidAlive4 = (pid) => {
|
|
|
27107
27406
|
};
|
|
27108
27407
|
function machineClient(home, env) {
|
|
27109
27408
|
const src = meterSource(home, undefined, { env });
|
|
27110
|
-
return src ? fetchClient({ ...src, version: "0.1.
|
|
27409
|
+
return src ? fetchClient({ ...src, version: "0.1.51" }) : null;
|
|
27111
27410
|
}
|
|
27112
27411
|
async function noteAnswer2(home, a, now) {
|
|
27113
27412
|
try {
|
|
@@ -27129,7 +27428,7 @@ function busyLine(busy) {
|
|
|
27129
27428
|
return `${n} session${n === 1 ? " is" : "s are"} running on ${on} — sleds update --now releases ${n === 1 ? "it" : "them"}`;
|
|
27130
27429
|
}
|
|
27131
27430
|
async function updateCmd(o) {
|
|
27132
|
-
const home = o.home ??
|
|
27431
|
+
const home = o.home ?? homedir8();
|
|
27133
27432
|
const env = o.env ?? process.env;
|
|
27134
27433
|
const log = o.log ?? console.log;
|
|
27135
27434
|
const error = o.error ?? console.error;
|
|
@@ -27433,12 +27732,12 @@ var webhooksCmd = async (o) => {
|
|
|
27433
27732
|
// src/config.ts
|
|
27434
27733
|
init_settings();
|
|
27435
27734
|
import { chmodSync as chmodSync8, existsSync as existsSync35, mkdirSync as mkdirSync28, readFileSync as readFileSync33, renameSync as renameSync13, writeFileSync as writeFileSync28 } from "node:fs";
|
|
27436
|
-
import { join as
|
|
27735
|
+
import { join as join33, resolve as resolve11 } from "node:path";
|
|
27437
27736
|
var configDir2 = (home, env = process.env) => {
|
|
27438
27737
|
const o = env.SLEDS_HOME?.trim();
|
|
27439
|
-
return o ? resolve11(home, o) :
|
|
27738
|
+
return o ? resolve11(home, o) : join33(home, ".config", "sleds");
|
|
27440
27739
|
};
|
|
27441
|
-
var configPath2 = (home) =>
|
|
27740
|
+
var configPath2 = (home) => join33(configDir2(home), "config.json");
|
|
27442
27741
|
var isObject17 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
27443
27742
|
var optString2 = (v) => typeof v === "string" ? v : undefined;
|
|
27444
27743
|
var parsePriorEnv2 = (v) => {
|
|
@@ -27615,10 +27914,10 @@ function runnerFor3(name, exec = defaultExec, o = {}) {
|
|
|
27615
27914
|
}
|
|
27616
27915
|
|
|
27617
27916
|
// src/runtime.ts
|
|
27618
|
-
import { homedir as
|
|
27619
|
-
import { join as
|
|
27917
|
+
import { homedir as homedir9 } from "node:os";
|
|
27918
|
+
import { join as join34, win32 as win323 } from "node:path";
|
|
27620
27919
|
var isCompiled2 = (argv1 = process.argv[1]) => Boolean(argv1 && (argv1.startsWith("/$bunfs/") || argv1.startsWith("B:\\~BUN\\")));
|
|
27621
|
-
var sledsLink2 = (home =
|
|
27920
|
+
var sledsLink2 = (home = homedir9(), platform = process.platform) => platform === "win32" ? win323.join(process.env.LOCALAPPDATA ?? win323.join(home, "AppData", "Local"), "sleds", "bin", "sleds.exe") : join34(home, ".sleds", "bin", "sleds");
|
|
27622
27921
|
|
|
27623
27922
|
// src/schedule.ts
|
|
27624
27923
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
@@ -27630,7 +27929,7 @@ var defaultExec5 = (cmd, args) => {
|
|
|
27630
27929
|
};
|
|
27631
27930
|
|
|
27632
27931
|
// src/settings.ts
|
|
27633
|
-
import { dirname as dirname24, join as
|
|
27932
|
+
import { dirname as dirname24, join as join35, resolve as resolve12 } from "node:path";
|
|
27634
27933
|
var withSeatEnv2 = (command, home, env = process.env, org) => {
|
|
27635
27934
|
const parts = [];
|
|
27636
27935
|
const sh = env.SLEDS_HOME?.trim();
|
|
@@ -27927,12 +28226,12 @@ var sledsArgv = (execPath = process.execPath, script = process.argv[1], realpath
|
|
|
27927
28226
|
return stableArgv2(script ? [execPath, script] : [execPath], realpath, o.home);
|
|
27928
28227
|
};
|
|
27929
28228
|
var shellQuote = (s) => /^[\w./-]+$/.test(s) ? s : `'${s.replace(/'/g, "'\\''")}'`;
|
|
27930
|
-
var statusLineCommand = (argv, home =
|
|
27931
|
-
var seatEventCommand = (argv, home =
|
|
27932
|
-
var promptEventCommand = (argv, home =
|
|
27933
|
-
var sessionEventCommand = (argv, home =
|
|
27934
|
-
var stopEventCommand = (argv, home =
|
|
27935
|
-
var specEventCommand = (argv, home =
|
|
28229
|
+
var statusLineCommand = (argv, home = homedir10()) => withSeatEnv2([...argv, "statusline"].map(shellQuote).join(" "), home);
|
|
28230
|
+
var seatEventCommand = (argv, home = homedir10()) => withSeatEnv2([...argv, "seat-event"].map(shellQuote).join(" "), home);
|
|
28231
|
+
var promptEventCommand = (argv, home = homedir10()) => withSeatEnv2([...argv, "prompt-event"].map(shellQuote).join(" "), home);
|
|
28232
|
+
var sessionEventCommand = (argv, home = homedir10()) => withSeatEnv2([...argv, "session-event"].map(shellQuote).join(" "), home);
|
|
28233
|
+
var stopEventCommand = (argv, home = homedir10()) => withSeatEnv2([...argv, "stop-event"].map(shellQuote).join(" "), home);
|
|
28234
|
+
var specEventCommand = (argv, home = homedir10()) => withSeatEnv2([...argv, "spec-event"].map(shellQuote).join(" "), home);
|
|
27936
28235
|
var mcpFlag = (flags) => flags["no-mcp"] === true ? false : flags.mcp === true ? true : undefined;
|
|
27937
28236
|
var main = async (argv) => {
|
|
27938
28237
|
const { cmd, flags } = parseArgs(argv);
|
|
@@ -27940,7 +28239,7 @@ var main = async (argv) => {
|
|
|
27940
28239
|
console.log(commandUsage(cmd));
|
|
27941
28240
|
return 0;
|
|
27942
28241
|
}
|
|
27943
|
-
const home =
|
|
28242
|
+
const home = homedir10();
|
|
27944
28243
|
const scheduler = {
|
|
27945
28244
|
platform: platform3(),
|
|
27946
28245
|
home,
|
|
@@ -27952,7 +28251,7 @@ var main = async (argv) => {
|
|
|
27952
28251
|
now: Date.now(),
|
|
27953
28252
|
stderr: (line) => console.error(line),
|
|
27954
28253
|
isTTY: !!process.stderr.isTTY,
|
|
27955
|
-
version: "0.1.
|
|
28254
|
+
version: "0.1.51"
|
|
27956
28255
|
});
|
|
27957
28256
|
switch (cmd) {
|
|
27958
28257
|
case "update":
|
|
@@ -28185,7 +28484,7 @@ ${renderHelpText(argv[1])}`);
|
|
|
28185
28484
|
case "version":
|
|
28186
28485
|
case "--version":
|
|
28187
28486
|
case "-v":
|
|
28188
|
-
console.log("sleds 0.1.
|
|
28487
|
+
console.log("sleds 0.1.51");
|
|
28189
28488
|
return 0;
|
|
28190
28489
|
default:
|
|
28191
28490
|
console.error(`unknown command: ${cmd}
|
|
@@ -28206,10 +28505,18 @@ var isMain = () => {
|
|
|
28206
28505
|
return false;
|
|
28207
28506
|
}
|
|
28208
28507
|
};
|
|
28508
|
+
var drained = (stream) => new Promise((resolve) => {
|
|
28509
|
+
stream.once("error", () => resolve());
|
|
28510
|
+
stream.write("", () => resolve());
|
|
28511
|
+
});
|
|
28512
|
+
var exitDrained = async (code) => {
|
|
28513
|
+
await Promise.all([drained(process.stdout), drained(process.stderr)]);
|
|
28514
|
+
process.exit(code);
|
|
28515
|
+
};
|
|
28209
28516
|
if (isMain()) {
|
|
28210
|
-
main(process.argv.slice(2)).then((code) =>
|
|
28517
|
+
main(process.argv.slice(2)).then((code) => exitDrained(code), (err) => {
|
|
28211
28518
|
console.error(err instanceof Error ? err.message : String(err));
|
|
28212
|
-
|
|
28519
|
+
return exitDrained(1);
|
|
28213
28520
|
});
|
|
28214
28521
|
}
|
|
28215
28522
|
export {
|