@agentsean/daemon 1.0.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.
Files changed (82) hide show
  1. package/LICENSE +661 -0
  2. package/dist/action-routes.d.ts +10 -0
  3. package/dist/action-routes.d.ts.map +1 -0
  4. package/dist/action-routes.js +303 -0
  5. package/dist/action-routes.js.map +1 -0
  6. package/dist/activity-page.d.ts +2 -0
  7. package/dist/activity-page.d.ts.map +1 -0
  8. package/dist/activity-page.js +115 -0
  9. package/dist/activity-page.js.map +1 -0
  10. package/dist/bind.d.ts +12 -0
  11. package/dist/bind.d.ts.map +1 -0
  12. package/dist/bind.js +62 -0
  13. package/dist/bind.js.map +1 -0
  14. package/dist/boot.d.ts +15 -0
  15. package/dist/boot.d.ts.map +1 -0
  16. package/dist/boot.js +113 -0
  17. package/dist/boot.js.map +1 -0
  18. package/dist/connect-page.d.ts +2 -0
  19. package/dist/connect-page.d.ts.map +1 -0
  20. package/dist/connect-page.js +170 -0
  21. package/dist/connect-page.js.map +1 -0
  22. package/dist/dashboard-routes.d.ts +16 -0
  23. package/dist/dashboard-routes.d.ts.map +1 -0
  24. package/dist/dashboard-routes.js +1059 -0
  25. package/dist/dashboard-routes.js.map +1 -0
  26. package/dist/events.d.ts +6 -0
  27. package/dist/events.d.ts.map +1 -0
  28. package/dist/events.js +16 -0
  29. package/dist/events.js.map +1 -0
  30. package/dist/google-routes.d.ts +13 -0
  31. package/dist/google-routes.d.ts.map +1 -0
  32. package/dist/google-routes.js +297 -0
  33. package/dist/google-routes.js.map +1 -0
  34. package/dist/hosted-routes.d.ts +7 -0
  35. package/dist/hosted-routes.d.ts.map +1 -0
  36. package/dist/hosted-routes.js +88 -0
  37. package/dist/hosted-routes.js.map +1 -0
  38. package/dist/index.d.ts +10 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +10 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/main.d.ts +3 -0
  43. package/dist/main.d.ts.map +1 -0
  44. package/dist/main.js +25 -0
  45. package/dist/main.js.map +1 -0
  46. package/dist/paths.d.ts +13 -0
  47. package/dist/paths.d.ts.map +1 -0
  48. package/dist/paths.js +49 -0
  49. package/dist/paths.js.map +1 -0
  50. package/dist/pdf.d.ts +3 -0
  51. package/dist/pdf.d.ts.map +1 -0
  52. package/dist/pdf.js +51 -0
  53. package/dist/pdf.js.map +1 -0
  54. package/dist/pid.d.ts +11 -0
  55. package/dist/pid.d.ts.map +1 -0
  56. package/dist/pid.js +38 -0
  57. package/dist/pid.js.map +1 -0
  58. package/dist/security.d.ts +14 -0
  59. package/dist/security.d.ts.map +1 -0
  60. package/dist/security.js +93 -0
  61. package/dist/security.js.map +1 -0
  62. package/dist/server.d.ts +25 -0
  63. package/dist/server.d.ts.map +1 -0
  64. package/dist/server.js +84 -0
  65. package/dist/server.js.map +1 -0
  66. package/dist/settings.d.ts +5 -0
  67. package/dist/settings.d.ts.map +1 -0
  68. package/dist/settings.js +25 -0
  69. package/dist/settings.js.map +1 -0
  70. package/dist/spa.d.ts +4 -0
  71. package/dist/spa.d.ts.map +1 -0
  72. package/dist/spa.js +95 -0
  73. package/dist/spa.js.map +1 -0
  74. package/dist/token.d.ts +6 -0
  75. package/dist/token.d.ts.map +1 -0
  76. package/dist/token.js +35 -0
  77. package/dist/token.js.map +1 -0
  78. package/dist/version.d.ts +2 -0
  79. package/dist/version.d.ts.map +1 -0
  80. package/dist/version.js +2 -0
  81. package/dist/version.js.map +1 -0
  82. package/package.json +81 -0
@@ -0,0 +1,303 @@
1
+ import { createHash } from "node:crypto";
2
+ import { desc, eq } from "drizzle-orm";
3
+ import { actions, changeSnapshots, changes, findings, pages, sites, } from "@agentsean/db";
4
+ import { claimForChange, DEFAULT_EVIDENCE_TIER, EVIDENCE_MEANING, } from "@agentsean/measure";
5
+ import { actionFromRow, executeAction, loadChange, loadGitConnection, markReverted, planTitleActions, revertChange, saveAction, listAdapterConnections, upsertAdapterConnection, upsertGitConnection, } from "@agentsean/actions";
6
+ import { adapterForSite } from "@agentsean/adapter-factory";
7
+ import { isCmsWriteKind, isHostedMode, refuseHostedCmsCredential, } from "@agentsean/hosted";
8
+ import { isHalted } from "./paths.js";
9
+ import { activityPageHtml } from "./activity-page.js";
10
+ function approvalKey(token) {
11
+ return createHash("sha256").update(token).digest();
12
+ }
13
+ function siteOf(db, origin) {
14
+ if (origin) {
15
+ return db.select().from(sites).where(eq(sites.origin, origin)).get();
16
+ }
17
+ return db.select().from(sites).all()[0];
18
+ }
19
+ function adapterFor(db, siteId, opts, repoOverride) {
20
+ if (repoOverride) {
21
+ upsertGitConnection(db, siteId, {
22
+ ...loadGitConnection(db, siteId),
23
+ repoPath: repoOverride,
24
+ });
25
+ }
26
+ const factoryOpts = opts.gitFetch ? { fetch: opts.gitFetch } : undefined;
27
+ return adapterForSite(db, siteId, factoryOpts);
28
+ }
29
+ export function registerActionRoutes(app, opts) {
30
+ const html = activityPageHtml();
31
+ app.get("/activity", async (_req, reply) => {
32
+ reply.type("text/html").send(html);
33
+ });
34
+ app.get("/api/actions", (req) => {
35
+ const q = req.query;
36
+ const rows = q.siteId
37
+ ? opts.db.select().from(actions).where(eq(actions.siteId, q.siteId)).all()
38
+ : opts.db.select().from(actions).all();
39
+ return {
40
+ actions: rows.map((r) => ({
41
+ id: r.id,
42
+ kind: r.actionType,
43
+ tier: r.tier,
44
+ state: r.state,
45
+ targetRef: r.targetRef,
46
+ error: r.error,
47
+ createdAt: r.createdAt,
48
+ appliedAt: r.appliedAt,
49
+ })),
50
+ };
51
+ });
52
+ app.get("/api/changes", () => {
53
+ const rows = opts.db.select().from(changes).orderBy(desc(changes.appliedAt)).all();
54
+ const out = rows.map((row) => {
55
+ const snaps = opts.db
56
+ .select()
57
+ .from(changeSnapshots)
58
+ .where(eq(changeSnapshots.changeId, row.id))
59
+ .all();
60
+ const before = snaps.find((s) => s.kind === "before")?.body ?? "";
61
+ const after = snaps.find((s) => s.kind === "after")?.body ?? "";
62
+ const metaRaw = snaps.find((s) => s.kind === "meta")?.body;
63
+ let prUrl = null;
64
+ if (metaRaw) {
65
+ try {
66
+ const meta = JSON.parse(metaRaw);
67
+ prUrl = meta.prUrl ?? null;
68
+ }
69
+ catch {
70
+ prUrl = null;
71
+ }
72
+ }
73
+ const claim = claimForChange(opts.db, row.id);
74
+ return {
75
+ id: row.id,
76
+ actionId: row.actionId,
77
+ summary: row.summary,
78
+ appliedAt: row.appliedAt,
79
+ revertedAt: row.revertedAt,
80
+ revertible: Boolean(row.revertible) && !row.revertedAt,
81
+ before,
82
+ after,
83
+ prUrl,
84
+ evidenceTier: claim?.evidenceTier ?? DEFAULT_EVIDENCE_TIER,
85
+ causationClaimed: claim?.causationClaimed ?? false,
86
+ evidenceStatement: claim?.statement ?? EVIDENCE_MEANING.E,
87
+ };
88
+ });
89
+ return { changes: out };
90
+ });
91
+ app.post("/api/adapters/git", async (req, reply) => {
92
+ const body = (req.body ?? {});
93
+ const site = siteOf(opts.db, body.origin);
94
+ if (!site)
95
+ return reply.code(400).send({ error: "unknown_site" });
96
+ if (!body.repoPath)
97
+ return reply.code(400).send({ error: "missing_repoPath" });
98
+ const config = { repoPath: body.repoPath };
99
+ if (body.token)
100
+ config["token"] = body.token;
101
+ upsertGitConnection(opts.db, site.id, config);
102
+ return { ok: true, siteId: site.id, kind: "git" };
103
+ });
104
+ app.get("/api/adapters", (req) => {
105
+ const q = req.query;
106
+ const site = q.siteId
107
+ ? opts.db.select().from(sites).where(eq(sites.id, q.siteId)).get()
108
+ : opts.db.select().from(sites).all()[0];
109
+ if (!site)
110
+ return { adapters: [] };
111
+ return {
112
+ adapters: listAdapterConnections(opts.db, site.id).map((r) => ({
113
+ kind: r.kind,
114
+ connected: true,
115
+ })),
116
+ };
117
+ });
118
+ app.post("/api/adapters", async (req, reply) => {
119
+ const body = (req.body ?? {});
120
+ const site = siteOf(opts.db, body.origin);
121
+ if (!site)
122
+ return reply.code(400).send({ error: "unknown_site" });
123
+ if (!body.kind || !body.config)
124
+ return reply.code(400).send({ error: "missing_kind_or_config" });
125
+ if (isHostedMode() && isCmsWriteKind(body.kind)) {
126
+ try {
127
+ refuseHostedCmsCredential(body.kind);
128
+ }
129
+ catch (err) {
130
+ return reply.code(403).send({
131
+ error: "hosted_connector",
132
+ message: err instanceof Error ? err.message : "refused",
133
+ });
134
+ }
135
+ }
136
+ upsertAdapterConnection(opts.db, site.id, body.kind, body.config);
137
+ return { ok: true, siteId: site.id, kind: body.kind };
138
+ });
139
+ app.post("/api/actions/plan", async (req, reply) => {
140
+ const body = (req.body ?? {});
141
+ const site = siteOf(opts.db, body.origin);
142
+ if (!site)
143
+ return reply.code(400).send({ error: "unknown_site" });
144
+ const pageRows = opts.db
145
+ .select()
146
+ .from(pages)
147
+ .where(eq(pages.siteId, site.id))
148
+ .all();
149
+ const findingRows = opts.db
150
+ .select()
151
+ .from(findings)
152
+ .where(eq(findings.siteId, site.id))
153
+ .all();
154
+ const planned = planTitleActions({
155
+ siteId: site.id,
156
+ origin: site.origin,
157
+ pages: pageRows.map((p) => ({
158
+ id: p.id,
159
+ url: p.url,
160
+ title: p.title,
161
+ metaDescription: p.metaDescription,
162
+ h1: p.h1,
163
+ })),
164
+ findings: findingRows.map((f) => ({
165
+ id: f.id,
166
+ siteId: f.siteId,
167
+ pageId: f.pageId,
168
+ ruleId: f.ruleId,
169
+ status: f.status,
170
+ })),
171
+ });
172
+ for (const a of planned)
173
+ saveAction(opts.db, a, "proposed");
174
+ return { ok: true, actions: planned };
175
+ });
176
+ app.post("/api/actions/:id/apply", async (req, reply) => {
177
+ const id = req.params.id;
178
+ const body = (req.body ?? {});
179
+ const row = opts.db.select().from(actions).where(eq(actions.id, id)).get();
180
+ if (!row)
181
+ return reply.code(404).send({ error: "unknown_action" });
182
+ const action = actionFromRow(row);
183
+ if (!action)
184
+ return reply.code(400).send({ error: "malformed_action" });
185
+ let adapter;
186
+ try {
187
+ adapter = adapterFor(opts.db, action.siteId, opts, body.repoPath);
188
+ }
189
+ catch (e) {
190
+ return reply.code(400).send({
191
+ error: "adapter",
192
+ message: e instanceof Error ? e.message : String(e),
193
+ });
194
+ }
195
+ const result = await executeAction({
196
+ db: opts.db,
197
+ action,
198
+ adapter,
199
+ approvalKey: approvalKey(opts.token),
200
+ halted: isHalted(opts.seanHome),
201
+ });
202
+ return result;
203
+ });
204
+ app.post("/api/changes/:id/revert", async (req, reply) => {
205
+ const id = req.params.id;
206
+ const change = loadChange(opts.db, id);
207
+ if (!change)
208
+ return reply.code(404).send({ error: "unknown_change" });
209
+ const existing = opts.db.select().from(changes).where(eq(changes.id, id)).get();
210
+ if (existing?.revertedAt)
211
+ return reply.code(409).send({ error: "already_reverted" });
212
+ let adapter;
213
+ try {
214
+ adapter = adapterFor(opts.db, change.siteId, opts);
215
+ }
216
+ catch (e) {
217
+ return reply.code(400).send({
218
+ error: "adapter",
219
+ message: e instanceof Error ? e.message : String(e),
220
+ });
221
+ }
222
+ const result = await revertChange({ db: opts.db, change, adapter });
223
+ if (!result.ok)
224
+ return reply.code(500).send({ error: result.error });
225
+ markReverted(opts.db, id);
226
+ const actionRow = opts.db
227
+ .select()
228
+ .from(actions)
229
+ .where(eq(actions.id, change.actionId))
230
+ .get();
231
+ if (actionRow) {
232
+ opts.db
233
+ .update(actions)
234
+ .set({ state: "reverted" })
235
+ .where(eq(actions.id, actionRow.id))
236
+ .run();
237
+ }
238
+ return { ok: true, changeId: id };
239
+ });
240
+ app.post("/api/apply", async (req, reply) => {
241
+ const body = (req.body ?? {});
242
+ const site = siteOf(opts.db, body.origin);
243
+ if (!site)
244
+ return reply.code(400).send({ error: "unknown_site" });
245
+ if (body.repoPath) {
246
+ upsertGitConnection(opts.db, site.id, {
247
+ ...loadGitConnection(opts.db, site.id),
248
+ repoPath: body.repoPath,
249
+ });
250
+ }
251
+ let adapter;
252
+ try {
253
+ adapter = adapterFor(opts.db, site.id, opts, body.repoPath);
254
+ }
255
+ catch (e) {
256
+ return reply.code(400).send({
257
+ error: "adapter",
258
+ message: e instanceof Error ? e.message : String(e),
259
+ });
260
+ }
261
+ const pageRows = opts.db
262
+ .select()
263
+ .from(pages)
264
+ .where(eq(pages.siteId, site.id))
265
+ .all();
266
+ const findingRows = opts.db
267
+ .select()
268
+ .from(findings)
269
+ .where(eq(findings.siteId, site.id))
270
+ .all();
271
+ const planned = planTitleActions({
272
+ siteId: site.id,
273
+ origin: site.origin,
274
+ pages: pageRows.map((p) => ({
275
+ id: p.id,
276
+ url: p.url,
277
+ title: p.title,
278
+ metaDescription: p.metaDescription,
279
+ h1: p.h1,
280
+ })),
281
+ findings: findingRows.map((f) => ({
282
+ id: f.id,
283
+ siteId: f.siteId,
284
+ pageId: f.pageId,
285
+ ruleId: f.ruleId,
286
+ status: f.status,
287
+ })),
288
+ });
289
+ const results = [];
290
+ for (const action of planned) {
291
+ results.push(await executeAction({
292
+ db: opts.db,
293
+ action,
294
+ adapter,
295
+ approvalKey: approvalKey(opts.token),
296
+ halted: isHalted(opts.seanHome),
297
+ dryRun: Boolean(body.dryRun),
298
+ }));
299
+ }
300
+ return { ok: true, results, activity: "/activity" };
301
+ });
302
+ }
303
+ //# sourceMappingURL=action-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-routes.js","sourceRoot":"","sources":["../src/action-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function activityPageHtml(): string;
2
+ //# sourceMappingURL=activity-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-page.d.ts","sourceRoot":"","sources":["../src/activity-page.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,IAAI,MAAM,CAiHzC"}
@@ -0,0 +1,115 @@
1
+ export function activityPageHtml() {
2
+ return `<!doctype html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="utf-8"/>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
7
+ <title>Activity — Agent Sean</title>
8
+ <style>
9
+ :root { color-scheme: light dark; --fg: #111; --muted: #555; --acc: #0b57d0; --bg: #f6f7f9; --card: #fff; --bd: #d0d7de; --del: #c00; --ins: #0a0; }
10
+ @media (prefers-color-scheme: dark) {
11
+ :root { --fg: #eef; --muted: #9aa; --acc: #8ab4f8; --bg: #0f1115; --card: #171a21; --bd: #2c313a; --del: #f88; --ins: #8d8; }
12
+ }
13
+ body { font: 16px/1.45 system-ui, sans-serif; margin: 0; background: var(--bg); color: var(--fg); }
14
+ main { max-width: 880px; margin: 2rem auto; padding: 0 1.25rem 3rem; }
15
+ h1 { font-size: 1.5rem; margin: 0 0 .25rem; }
16
+ p.lead { color: var(--muted); margin-top: 0; }
17
+ .card { background: var(--card); border: 1px solid var(--bd); border-radius: 12px; padding: 1.25rem; margin: 1rem 0; }
18
+ button { background: var(--acc); color: #fff; border: 0; border-radius: 8px; padding: .5rem 1rem; font: inherit; cursor: pointer; }
19
+ button.secondary { background: transparent; color: var(--acc); border: 1px solid var(--acc); }
20
+ pre { overflow: auto; background: var(--bg); padding: .75rem; border-radius: 8px; font-size: .8rem; }
21
+ .del { color: var(--del); }
22
+ .ins { color: var(--ins); }
23
+ .muted { color: var(--muted); font-size: .9rem; }
24
+ .row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
25
+ a { color: var(--acc); }
26
+ </style>
27
+ </head>
28
+ <body>
29
+ <main>
30
+ <h1>Activity</h1>
31
+ <p class="lead">Every write is a reversible diff. One click reverts it. The LLM never holds credentials.</p>
32
+ <p class="muted"><a href="/connect">Connect Google</a></p>
33
+ <div id="app"><p class="muted">Loading…</p></div>
34
+ </main>
35
+ <script>
36
+ const csrf = { "x-sean-csrf": "1" };
37
+ function tokenFromHash() {
38
+ const h = new URLSearchParams(location.hash.replace(/^#/, ""));
39
+ return h.get("token");
40
+ }
41
+ async function session() {
42
+ const t = tokenFromHash();
43
+ const headers = t ? { "x-sean-token": t } : {};
44
+ const r = await fetch("/api/session", { headers });
45
+ if (t && r.ok) history.replaceState(null, "", location.pathname + location.search);
46
+ return r.ok;
47
+ }
48
+ async function api(path, opts = {}) {
49
+ const r = await fetch(path, {
50
+ ...opts,
51
+ headers: { "content-type": "application/json", ...csrf, ...(opts.headers || {}) },
52
+ });
53
+ const text = await r.text();
54
+ let json = null;
55
+ try { json = text ? JSON.parse(text) : null; } catch { json = { raw: text }; }
56
+ if (!r.ok) throw new Error((json && (json.error || json.message)) || r.status + " " + path);
57
+ return json;
58
+ }
59
+ function el(html) { const d = document.createElement("div"); d.innerHTML = html; return d; }
60
+ function render(node) { document.getElementById("app").replaceChildren(node); }
61
+ function esc(s) {
62
+ return String(s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c]));
63
+ }
64
+ function diffHtml(before, after) {
65
+ const a = String(before || "").split("\\n");
66
+ const b = String(after || "").split("\\n");
67
+ const max = Math.max(a.length, b.length);
68
+ const lines = [];
69
+ for (let i = 0; i < max; i++) {
70
+ if (a[i] === b[i]) continue;
71
+ if (a[i] !== undefined) lines.push("<div class='del'>- " + esc(a[i]) + "</div>");
72
+ if (b[i] !== undefined) lines.push("<div class='ins'>+ " + esc(b[i]) + "</div>");
73
+ }
74
+ return lines.join("") || "<div class='muted'>No line-level diff.</div>";
75
+ }
76
+ async function revert(id) {
77
+ await api("/api/changes/" + id + "/revert", { method: "POST", body: "{}" });
78
+ await show();
79
+ }
80
+ async function show() {
81
+ const data = await api("/api/changes");
82
+ const actions = await api("/api/actions");
83
+ const wrap = document.createElement("div");
84
+ if (!data.changes.length && !actions.actions.length) {
85
+ wrap.appendChild(el("<div class='card'><p>No writes yet. Run <code>sean apply --repo ./site</code> after an audit. Sean fixes a title tag by opening a PR you can revert.</p></div>"));
86
+ render(wrap);
87
+ return;
88
+ }
89
+ for (const a of actions.actions) {
90
+ wrap.appendChild(el("<div class='card'><p><strong>" + esc(a.kind) + "</strong> · T" + esc(a.tier) + " · " + esc(a.state) + "</p><p class='muted'>" + esc(a.targetRef) + "</p></div>"));
91
+ }
92
+ for (const c of data.changes) {
93
+ const card = el("<div class='card' data-id='" + esc(c.id) + "'><p><strong>" + esc(c.summary) + "</strong></p><p class='muted'>" + esc(c.appliedAt) + (c.revertedAt ? " · reverted " + esc(c.revertedAt) : "") + (c.prUrl ? " · <a href='" + esc(c.prUrl) + "'>pull request</a>" : "") + "</p><pre>" + diffHtml(c.before, c.after) + "</pre></div>");
94
+ if (c.revertible && !c.revertedAt) {
95
+ const b = document.createElement("button");
96
+ b.textContent = "Revert";
97
+ b.onclick = () => revert(c.id);
98
+ card.querySelector(".card")?.appendChild(b) || card.firstElementChild.appendChild(b);
99
+ }
100
+ wrap.appendChild(card);
101
+ }
102
+ render(wrap);
103
+ }
104
+ session().then((ok) => {
105
+ if (!ok) {
106
+ render(el("<div class='card'><p>Open this page from <code>sean apply</code> or <code>sean start</code> so the local session cookie can be set.</p></div>"));
107
+ return;
108
+ }
109
+ return show();
110
+ }).catch((e) => render(el("<div class='card'><p class='err'>" + esc(e.message) + "</p></div>")));
111
+ </script>
112
+ </body>
113
+ </html>`;
114
+ }
115
+ //# sourceMappingURL=activity-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-page.js","sourceRoot":"","sources":["../src/activity-page.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+GD,CAAC;AACT,CAAC"}
package/dist/bind.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export declare class BindError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare function isLoopbackHost(host: string): boolean;
5
+ /**
6
+ * Refuse to start if the process would be exposed without auth.
7
+ * Auth is on by default; `--no-auth` is only legal on loopback.
8
+ */
9
+ export declare function assertBindAllowed(host: string, authEnabled: boolean): void;
10
+ export declare function allowedHosts(port: number, publicOrigin?: string | undefined): Set<string>;
11
+ export declare function allowedOrigins(port: number, publicOrigin?: string | undefined): Set<string>;
12
+ //# sourceMappingURL=bind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMpD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI,CAO1E;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAChC,GAAG,CAAC,MAAM,CAAC,CAgBb;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAChC,GAAG,CAAC,MAAM,CAAC,CAQb"}
package/dist/bind.js ADDED
@@ -0,0 +1,62 @@
1
+ export class BindError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "BindError";
5
+ }
6
+ }
7
+ const LOOPBACK_EXACT = new Set([
8
+ "127.0.0.1",
9
+ "::1",
10
+ "localhost",
11
+ "0:0:0:0:0:0:0:1",
12
+ "::ffff:127.0.0.1",
13
+ ]);
14
+ export function isLoopbackHost(host) {
15
+ const h = host.trim().toLowerCase();
16
+ if (LOOPBACK_EXACT.has(h))
17
+ return true;
18
+ // 127.0.0.0/8
19
+ if (/^127(?:\.\d{1,3}){3}$/.test(h))
20
+ return true;
21
+ return false;
22
+ }
23
+ /**
24
+ * Refuse to start if the process would be exposed without auth.
25
+ * Auth is on by default; `--no-auth` is only legal on loopback.
26
+ */
27
+ export function assertBindAllowed(host, authEnabled) {
28
+ if (isLoopbackHost(host))
29
+ return;
30
+ if (!authEnabled) {
31
+ throw new BindError(`Refusing to bind ${host}: off-loopback bind requires auth. Use Tailscale Serve or a Cloudflare Tunnel; never bind 0.0.0.0 without auth.`);
32
+ }
33
+ }
34
+ export function allowedHosts(port, publicOrigin) {
35
+ const hosts = new Set([
36
+ `127.0.0.1:${port}`,
37
+ `localhost:${port}`,
38
+ `[::1]:${port}`,
39
+ `::1:${port}`,
40
+ ]);
41
+ if (publicOrigin) {
42
+ try {
43
+ const u = new URL(publicOrigin);
44
+ hosts.add(u.host);
45
+ }
46
+ catch {
47
+ // ignore malformed
48
+ }
49
+ }
50
+ return hosts;
51
+ }
52
+ export function allowedOrigins(port, publicOrigin) {
53
+ const origins = new Set([
54
+ `http://127.0.0.1:${port}`,
55
+ `http://localhost:${port}`,
56
+ `http://[::1]:${port}`,
57
+ ]);
58
+ if (publicOrigin)
59
+ origins.add(publicOrigin.replace(/\/$/, ""));
60
+ return origins;
61
+ }
62
+ //# sourceMappingURL=bind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.js","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,WAAW;IACX,KAAK;IACL,WAAW;IACX,iBAAiB;IACjB,kBAAkB;CACnB,CAAC,CAAC;AAEH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,cAAc;IACd,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,WAAoB;IAClE,IAAI,cAAc,CAAC,IAAI,CAAC;QAAE,OAAO;IACjC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,SAAS,CACjB,oBAAoB,IAAI,iHAAiH,CAC1I,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,YAAiC;IAEjC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC;QACpB,aAAa,IAAI,EAAE;QACnB,aAAa,IAAI,EAAE;QACnB,SAAS,IAAI,EAAE;QACf,OAAO,IAAI,EAAE;KACd,CAAC,CAAC;IACH,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;YAChC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,YAAiC;IAEjC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;QACtB,oBAAoB,IAAI,EAAE;QAC1B,oBAAoB,IAAI,EAAE;QAC1B,gBAAgB,IAAI,EAAE;KACvB,CAAC,CAAC;IACH,IAAI,YAAY;QAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/D,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dist/boot.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export type BootOptions = {
2
+ host?: string | undefined;
3
+ port?: number | undefined;
4
+ seanHome?: string | undefined;
5
+ authEnabled?: boolean | undefined;
6
+ registerSignals?: boolean | undefined;
7
+ };
8
+ export type RunningDaemon = {
9
+ host: string;
10
+ port: number;
11
+ pid: number;
12
+ close: () => Promise<void>;
13
+ };
14
+ export declare function startDaemon(options?: BootOptions): Promise<RunningDaemon>;
15
+ //# sourceMappingURL=boot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,CAAC;AAEF,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CA+GnF"}