@agentsean/actions 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 (50) hide show
  1. package/LICENSE +661 -0
  2. package/dist/executor.d.ts +46 -0
  3. package/dist/executor.d.ts.map +1 -0
  4. package/dist/executor.js +150 -0
  5. package/dist/executor.js.map +1 -0
  6. package/dist/hmac.d.ts +4 -0
  7. package/dist/hmac.d.ts.map +1 -0
  8. package/dist/hmac.js +23 -0
  9. package/dist/hmac.js.map +1 -0
  10. package/dist/html.d.ts +15 -0
  11. package/dist/html.d.ts.map +1 -0
  12. package/dist/html.js +52 -0
  13. package/dist/html.js.map +1 -0
  14. package/dist/index.d.ts +12 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +12 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/kinds.d.ts +12 -0
  19. package/dist/kinds.d.ts.map +1 -0
  20. package/dist/kinds.js +135 -0
  21. package/dist/kinds.js.map +1 -0
  22. package/dist/payloads.d.ts +13 -0
  23. package/dist/payloads.d.ts.map +1 -0
  24. package/dist/payloads.js +368 -0
  25. package/dist/payloads.js.map +1 -0
  26. package/dist/persist.d.ts +65 -0
  27. package/dist/persist.d.ts.map +1 -0
  28. package/dist/persist.js +362 -0
  29. package/dist/persist.js.map +1 -0
  30. package/dist/planner.d.ts +20 -0
  31. package/dist/planner.d.ts.map +1 -0
  32. package/dist/planner.js +115 -0
  33. package/dist/planner.js.map +1 -0
  34. package/dist/scan.d.ts +19 -0
  35. package/dist/scan.d.ts.map +1 -0
  36. package/dist/scan.js +210 -0
  37. package/dist/scan.js.map +1 -0
  38. package/dist/types.d.ts +227 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +29 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/urls.d.ts +6 -0
  43. package/dist/urls.d.ts.map +1 -0
  44. package/dist/urls.js +74 -0
  45. package/dist/urls.js.map +1 -0
  46. package/dist/validator.d.ts +9 -0
  47. package/dist/validator.d.ts.map +1 -0
  48. package/dist/validator.js +398 -0
  49. package/dist/validator.js.map +1 -0
  50. package/package.json +51 -0
@@ -0,0 +1,46 @@
1
+ import type { SqliteDatabase } from "@agentsean/db";
2
+ import type { Action, AppliedChange, SiteAdapter, ValidationContext, ValidationResult } from "./types.js";
3
+ export type ExecuteResult = {
4
+ status: "applied";
5
+ action: Action;
6
+ change: AppliedChange;
7
+ changeId: string;
8
+ } | {
9
+ status: "queued" | "rejected" | "failed";
10
+ action: Action;
11
+ validation?: ValidationResult | undefined;
12
+ error?: string | undefined;
13
+ };
14
+ export type ExecuteOptions = {
15
+ db: SqliteDatabase;
16
+ action: Action;
17
+ adapter: SiteAdapter;
18
+ approvalKey: Buffer;
19
+ halted: boolean;
20
+ now?: Date | undefined;
21
+ runId?: string | undefined;
22
+ appliedThisRun?: number | undefined;
23
+ budgetUsdDaily?: number | undefined;
24
+ estimatedCostUsd?: number | undefined;
25
+ dryRun?: boolean | undefined;
26
+ };
27
+ export declare function buildValidationContext(opts: ExecuteOptions, before: string, after: string): ValidationContext | {
28
+ error: string;
29
+ };
30
+ /**
31
+ * snapshot → apply → verify → record.
32
+ * Verify is non-negotiable: never trust a 200. Re-read the target and confirm
33
+ * the change landed. On verify failure, roll back from the shadow ledger.
34
+ */
35
+ export declare function executeAction(opts: ExecuteOptions): Promise<ExecuteResult>;
36
+ export declare function revertChange(opts: {
37
+ db: SqliteDatabase;
38
+ change: AppliedChange;
39
+ adapter: SiteAdapter;
40
+ }): Promise<{
41
+ ok: true;
42
+ } | {
43
+ ok: false;
44
+ error: string;
45
+ }>;
46
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAepD,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,aAAa,GACrB;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAEN,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,cAAc,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAWF,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA0BvC;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAgGhF;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,EAAE,EAAE,cAAc,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAevD"}
@@ -0,0 +1,150 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { findings, pages } from "@agentsean/db";
3
+ import { eq } from "drizzle-orm";
4
+ import { validateParsed } from "./validator.js";
5
+ import { countsForLedger, loadAllowlist, loadEntities, loadPages, loadSitePolicy, loadTwoKey, recordChange, saveAction, } from "./persist.js";
6
+ function afterText(action, before) {
7
+ if ("title" in action.payload) {
8
+ return before;
9
+ }
10
+ if ("body" in action.payload)
11
+ return action.payload.body;
12
+ if ("metaDescription" in action.payload)
13
+ return action.payload.metaDescription;
14
+ return before;
15
+ }
16
+ export function buildValidationContext(opts, before, after) {
17
+ const site = loadSitePolicy(opts.db, opts.action.siteId);
18
+ if (!site)
19
+ return { error: `unknown site ${opts.action.siteId}` };
20
+ const now = opts.now ?? new Date();
21
+ const counts = countsForLedger(opts.db, opts.action.siteId, now);
22
+ return {
23
+ now,
24
+ site,
25
+ pages: loadPages(opts.db, opts.action.siteId),
26
+ allowlist: loadAllowlist(opts.db, opts.action.siteId),
27
+ entities: loadEntities(opts.db, opts.action.siteId),
28
+ appliedThisRun: opts.appliedThisRun ?? 0,
29
+ appliedThisHour: counts.appliedThisHour,
30
+ appliedThisDay: counts.appliedThisDay,
31
+ newPagesToday: counts.newPagesToday,
32
+ contentRefreshToday: counts.contentRefreshToday,
33
+ spentUsdToday: counts.spentUsdToday,
34
+ budgetUsdDaily: opts.budgetUsdDaily ?? 8,
35
+ estimatedCostUsd: opts.estimatedCostUsd ?? 0,
36
+ twoKeyApprovals: loadTwoKey(opts.db, opts.action.id),
37
+ halted: opts.halted,
38
+ beforeText: before,
39
+ afterText: after,
40
+ runId: opts.runId ?? randomUUID(),
41
+ approvalKey: opts.approvalKey,
42
+ };
43
+ }
44
+ /**
45
+ * snapshot → apply → verify → record.
46
+ * Verify is non-negotiable: never trust a 200. Re-read the target and confirm
47
+ * the change landed. On verify failure, roll back from the shadow ledger.
48
+ */
49
+ export async function executeAction(opts) {
50
+ const action = opts.action;
51
+ saveAction(opts.db, action, "proposed");
52
+ let before = "";
53
+ try {
54
+ const read = await opts.adapter.read(action.target);
55
+ before = read.body;
56
+ }
57
+ catch (e) {
58
+ const error = e instanceof Error ? e.message : String(e);
59
+ saveAction(opts.db, action, "failed", { error });
60
+ return { status: "failed", action, error };
61
+ }
62
+ const dry = await opts.adapter.dryRun(action);
63
+ const ctx = buildValidationContext(opts, before, dry.after || afterText(action, before));
64
+ if ("error" in ctx) {
65
+ saveAction(opts.db, action, "failed", { error: ctx.error });
66
+ return { status: "failed", action, error: ctx.error };
67
+ }
68
+ const validation = validateParsed(action, ctx);
69
+ if (!validation.ok) {
70
+ const queued = validation.vetoes.every((v) => v.code === "OBSERVE_PERIOD" || v.code === "TWO_KEY" || v.code === "POLICY_TIER");
71
+ const observeOnly = validation.vetoes.every((v) => v.code === "OBSERVE_PERIOD");
72
+ const state = observeOnly || queued ? "queued" : "rejected";
73
+ saveAction(opts.db, action, state, {
74
+ error: validation.vetoes.map((v) => v.code).join(","),
75
+ });
76
+ return { status: state === "queued" ? "queued" : "rejected", action, validation };
77
+ }
78
+ if (opts.dryRun) {
79
+ saveAction(opts.db, action, "proposed");
80
+ return { status: "queued", action, validation };
81
+ }
82
+ let applied;
83
+ try {
84
+ applied = await opts.adapter.apply(action);
85
+ }
86
+ catch (e) {
87
+ const error = e instanceof Error ? e.message : String(e);
88
+ saveAction(opts.db, action, "failed", { error });
89
+ return { status: "failed", action, error };
90
+ }
91
+ const change = {
92
+ id: randomUUID(),
93
+ actionId: action.id,
94
+ siteId: action.siteId,
95
+ targetRef: applied.targetRef,
96
+ before: applied.before,
97
+ after: applied.after,
98
+ summary: applied.summary,
99
+ ...(applied.branch ? { branch: applied.branch } : {}),
100
+ ...(applied.commitSha ? { commitSha: applied.commitSha } : {}),
101
+ ...(applied.prUrl ? { prUrl: applied.prUrl } : {}),
102
+ };
103
+ const verified = await opts.adapter.verify(change);
104
+ if (!verified.ok) {
105
+ try {
106
+ await opts.adapter.rollback(change);
107
+ }
108
+ catch {
109
+ /* shadow ledger still holds the before snapshot */
110
+ }
111
+ saveAction(opts.db, action, "failed", {
112
+ error: `verify failed: ${verified.detail}`,
113
+ });
114
+ return { status: "failed", action, error: `verify failed: ${verified.detail}` };
115
+ }
116
+ const { changeId } = recordChange(opts.db, action, change);
117
+ saveAction(opts.db, action, "applied");
118
+ for (const fid of action.findingIds) {
119
+ opts.db
120
+ .update(findings)
121
+ .set({ status: "applied", resolvedAt: new Date().toISOString() })
122
+ .where(eq(findings.id, fid))
123
+ .run();
124
+ }
125
+ if ("title" in action.payload) {
126
+ opts.db
127
+ .update(pages)
128
+ .set({ title: action.payload.title })
129
+ .where(eq(pages.id, action.target.pageId))
130
+ .run();
131
+ }
132
+ return { status: "applied", action, change: { ...change, id: changeId }, changeId };
133
+ }
134
+ export async function revertChange(opts) {
135
+ const verifiedBefore = await opts.adapter.rollback(opts.change);
136
+ const check = {
137
+ ...opts.change,
138
+ after: verifiedBefore.after,
139
+ before: verifiedBefore.before,
140
+ };
141
+ const verified = await opts.adapter.verify({
142
+ ...check,
143
+ after: opts.change.before,
144
+ });
145
+ if (!verified.ok) {
146
+ return { ok: false, error: `revert verify failed: ${verified.detail}` };
147
+ }
148
+ return { ok: true };
149
+ }
150
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
package/dist/hmac.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { Action } from "./types.js";
2
+ export declare function signApproval(key: Buffer, action: Action, actor: string): string;
3
+ export declare function verifyApproval(key: Buffer, action: Action, actor: string, hmac: string): boolean;
4
+ //# sourceMappingURL=hmac.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAWzC,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/E;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAMT"}
package/dist/hmac.js ADDED
@@ -0,0 +1,23 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ function canonicalPayload(action) {
3
+ return JSON.stringify({
4
+ id: action.id,
5
+ kind: action.kind,
6
+ target: action.target,
7
+ payload: action.payload,
8
+ });
9
+ }
10
+ export function signApproval(key, action, actor) {
11
+ return createHmac("sha256", key)
12
+ .update(`${actor}\n${canonicalPayload(action)}`)
13
+ .digest("hex");
14
+ }
15
+ export function verifyApproval(key, action, actor, hmac) {
16
+ const expected = signApproval(key, action, actor);
17
+ const a = Buffer.from(expected, "hex");
18
+ const b = Buffer.from(hmac, "hex");
19
+ if (a.length !== b.length)
20
+ return false;
21
+ return timingSafeEqual(a, b);
22
+ }
23
+ //# sourceMappingURL=hmac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmac.js","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG1D,SAAS,gBAAgB,CAAC,MAAc;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAc,EAAE,KAAa;IACrE,OAAO,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC;SAC7B,MAAM,CAAC,GAAG,KAAK,KAAK,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;SAC/C,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,MAAc,EACd,KAAa,EACb,IAAY;IAEZ,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC"}
package/dist/html.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /** Live HTML is the only verify surface. Never trust a 200 from a write API. */
2
+ export declare function htmlTitle(html: string): string | null;
3
+ export declare function patchHtmlTitle(html: string, title: string): string;
4
+ export declare function escapeHtml(value: string): string;
5
+ export declare function fetchHtml(url: string, fetchFn?: typeof fetch, headers?: Record<string, string>): Promise<string>;
6
+ export declare function verifyLiveTitle(url: string, expected: string, fetchFn?: typeof fetch): Promise<{
7
+ ok: boolean;
8
+ detail: string;
9
+ html: string;
10
+ }>;
11
+ export declare function titleFromPayload(payload: {
12
+ title?: string;
13
+ }): string | null;
14
+ export declare function requireTitle(payload: unknown): string;
15
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGrD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAclE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,OAAO,KAAa,EAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAWxD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAE3E;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAUrD"}
package/dist/html.js ADDED
@@ -0,0 +1,52 @@
1
+ /** Live HTML is the only verify surface. Never trust a 200 from a write API. */
2
+ export function htmlTitle(html) {
3
+ const m = /<title[^>]*>([\s\S]*?)<\/title>/i.exec(html);
4
+ return m?.[1] ? m[1].trim() : null;
5
+ }
6
+ export function patchHtmlTitle(html, title) {
7
+ if (/<title[^>]*>[\s\S]*?<\/title>/i.test(html)) {
8
+ return html.replace(/<title[^>]*>[\s\S]*?<\/title>/i, `<title>${escapeHtml(title)}</title>`);
9
+ }
10
+ if (/<head[^>]*>/i.test(html)) {
11
+ return html.replace(/<head[^>]*>/i, (h) => `${h}<title>${escapeHtml(title)}</title>`);
12
+ }
13
+ return `<!doctype html><html><head><title>${escapeHtml(title)}</title></head><body></body></html>`;
14
+ }
15
+ export function escapeHtml(value) {
16
+ return value
17
+ .replace(/&/g, "&amp;")
18
+ .replace(/</g, "&lt;")
19
+ .replace(/>/g, "&gt;")
20
+ .replace(/"/g, "&quot;");
21
+ }
22
+ export async function fetchHtml(url, fetchFn = fetch, headers) {
23
+ const res = await fetchFn(url, { headers: headers ?? {} });
24
+ if (!res.ok)
25
+ throw new Error(`GET ${url} → ${res.status}`);
26
+ return res.text();
27
+ }
28
+ export async function verifyLiveTitle(url, expected, fetchFn = fetch) {
29
+ const html = await fetchHtml(url, fetchFn);
30
+ const got = htmlTitle(html);
31
+ if (got === expected) {
32
+ return { ok: true, detail: `live <title> is ${expected}`, html };
33
+ }
34
+ return {
35
+ ok: false,
36
+ detail: `live <title> is ${got ?? "(missing)"}; expected ${expected}`,
37
+ html,
38
+ };
39
+ }
40
+ export function titleFromPayload(payload) {
41
+ return typeof payload.title === "string" ? payload.title : null;
42
+ }
43
+ export function requireTitle(payload) {
44
+ if (payload &&
45
+ typeof payload === "object" &&
46
+ "title" in payload &&
47
+ typeof payload.title === "string") {
48
+ return payload.title;
49
+ }
50
+ throw new Error("action payload has no title");
51
+ }
52
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,CAAC,GAAG,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa;IACxD,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,OAAO,CACjB,gCAAgC,EAChC,UAAU,UAAU,CAAC,KAAK,CAAC,UAAU,CACtC,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,OAAO,CACjB,cAAc,EACd,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,UAAU,CAAC,KAAK,CAAC,UAAU,CACjD,CAAC;IACJ,CAAC;IACD,OAAO,qCAAqC,UAAU,CAAC,KAAK,CAAC,qCAAqC,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,UAAwB,KAAK,EAC7B,OAAgC;IAEhC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,QAAgB,EAChB,UAAwB,KAAK;IAE7B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;IACnE,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,mBAAmB,GAAG,IAAI,WAAW,cAAc,QAAQ,EAAE;QACrE,IAAI;KACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IAC1D,OAAO,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,IACE,OAAO;QACP,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,IAAI,OAAO;QAClB,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EACjC,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC;IACvB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,12 @@
1
+ export { ACTION_KINDS, KIND_TIER, TWO_KEY_KINDS, NEW_PAGE_KINDS, CONTENT_GEN_KINDS, CONTENT_REFRESH_KINDS, isActionKind, type ActionKind, } from "./kinds.js";
2
+ export { parseAction } from "./payloads.js";
3
+ export { validateAction, validateParsed } from "./validator.js";
4
+ export { executeAction, revertChange, buildValidationContext } from "./executor.js";
5
+ export { planTitleActions, proposeTitle } from "./planner.js";
6
+ export { signApproval, verifyApproval } from "./hmac.js";
7
+ export { saveAction, recordChange, loadChange, markReverted, loadSitePolicy, loadPages, loadAllowlist, loadEntities, loadTwoKey, addTwoKey, recordEntity, upsertGitConnection, loadGitConnection, upsertAdapterConnection, loadAdapterConnection, listAdapterConnections, countsForLedger, actionFromRow, envelopeOf, } from "./persist.js";
8
+ export { bannedHits, encodedPayloadHits, invisibleHits, collectActionText, stripInvisible, } from "./scan.js";
9
+ export { extractUrls, extractDomains, sameSite } from "./urls.js";
10
+ export { BLAST, DIFF_CAPS, TITLE_MAX, META_MAX, OBSERVE_DEFAULT_MS, OBSERVE_MIN_MS, type Action, type ActionPayload, type ActionTarget, type Impact, type ValidationContext, type ValidationResult, type Veto, type SiteAdapter, type AppliedChange, type AdapterApplyResult, type AdapterCapabilities, type AdapterDryRun, type AdapterRead, type AdapterVerifyResult, type SitePolicy, type PageRow, } from "./types.js";
11
+ export { htmlTitle, patchHtmlTitle, fetchHtml, verifyLiveTitle, titleFromPayload, requireTitle, } from "./html.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,cAAc,EACd,SAAS,EACT,aAAa,EACb,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,MAAM,EACX,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export { ACTION_KINDS, KIND_TIER, TWO_KEY_KINDS, NEW_PAGE_KINDS, CONTENT_GEN_KINDS, CONTENT_REFRESH_KINDS, isActionKind, } from "./kinds.js";
2
+ export { parseAction } from "./payloads.js";
3
+ export { validateAction, validateParsed } from "./validator.js";
4
+ export { executeAction, revertChange, buildValidationContext } from "./executor.js";
5
+ export { planTitleActions, proposeTitle } from "./planner.js";
6
+ export { signApproval, verifyApproval } from "./hmac.js";
7
+ export { saveAction, recordChange, loadChange, markReverted, loadSitePolicy, loadPages, loadAllowlist, loadEntities, loadTwoKey, addTwoKey, recordEntity, upsertGitConnection, loadGitConnection, upsertAdapterConnection, loadAdapterConnection, listAdapterConnections, countsForLedger, actionFromRow, envelopeOf, } from "./persist.js";
8
+ export { bannedHits, encodedPayloadHits, invisibleHits, collectActionText, stripInvisible, } from "./scan.js";
9
+ export { extractUrls, extractDomains, sameSite } from "./urls.js";
10
+ export { BLAST, DIFF_CAPS, TITLE_MAX, META_MAX, OBSERVE_DEFAULT_MS, OBSERVE_MIN_MS, } from "./types.js";
11
+ export { htmlTitle, patchHtmlTitle, fetchHtml, verifyLiveTitle, titleFromPayload, requireTitle, } from "./html.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,GAEb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,cAAc,EACd,SAAS,EACT,aAAa,EACb,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,UAAU,GACX,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EACL,KAAK,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,kBAAkB,EAClB,cAAc,GAiBf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,YAAY,GACb,MAAM,WAAW,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** Closed ActionKind enum — ~40 members. The LLM cannot invent a new kind. */
2
+ export declare const ACTION_KINDS: readonly ["observe_snapshot", "record_finding", "inspect_indexation", "rewrite_title", "rewrite_meta_description", "rewrite_og_title", "rewrite_og_description", "rewrite_alt_text", "fix_heading", "add_h1", "repair_broken_internal_link", "regenerate_sitemap", "submit_sitemap", "add_lang", "add_viewport", "fix_title_length", "fix_meta_length", "add_image_dimensions", "insert_internal_link", "add_jsonld", "update_jsonld", "remove_invalid_jsonld", "refresh_content", "create_page", "add_breadcrumb", "add_faq_schema", "add_article_schema", "add_product_schema", "add_og_image", "edit_robots_txt", "edit_meta_robots", "add_redirect", "change_canonical", "change_hreflang", "delete_page", "send_outreach_email", "submit_disavow", "edit_llms_txt", "buy_link", "build_pbn", "exchange_links", "cloak", "sneaky_redirect", "hide_text", "write_third_party", "gate_reviews", "incentivize_reviews", "scrape_serp", "generate_ymyl", "generate_affiliate", "create_city_service_page"];
3
+ export type ActionKind = (typeof ACTION_KINDS)[number];
4
+ export declare const ACTION_KIND_SET: ReadonlySet<string>;
5
+ /** Policy matrix from PLAN §4. T3/T4 are not overridable. */
6
+ export declare const KIND_TIER: Record<ActionKind, 0 | 1 | 2 | 3 | 4>;
7
+ export declare const TWO_KEY_KINDS: ReadonlySet<ActionKind>;
8
+ export declare const NEW_PAGE_KINDS: ReadonlySet<ActionKind>;
9
+ export declare const CONTENT_REFRESH_KINDS: ReadonlySet<ActionKind>;
10
+ export declare const CONTENT_GEN_KINDS: ReadonlySet<ActionKind>;
11
+ export declare function isActionKind(value: string): value is ActionKind;
12
+ //# sourceMappingURL=kinds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kinds.d.ts","sourceRoot":"","sources":["../src/kinds.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,eAAO,MAAM,YAAY,48BAoDf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAAyB,CAAC;AAE1E,6DAA6D;AAC7D,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAoD3D,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,UAAU,CAUhD,CAAC;AAEH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,UAAU,CAA4B,CAAC;AAEhF,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,UAAU,CAExD,CAAC;AAEH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,UAAU,CAMpD,CAAC;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D"}
package/dist/kinds.js ADDED
@@ -0,0 +1,135 @@
1
+ /** Closed ActionKind enum — ~40 members. The LLM cannot invent a new kind. */
2
+ export const ACTION_KINDS = [
3
+ "observe_snapshot",
4
+ "record_finding",
5
+ "inspect_indexation",
6
+ "rewrite_title",
7
+ "rewrite_meta_description",
8
+ "rewrite_og_title",
9
+ "rewrite_og_description",
10
+ "rewrite_alt_text",
11
+ "fix_heading",
12
+ "add_h1",
13
+ "repair_broken_internal_link",
14
+ "regenerate_sitemap",
15
+ "submit_sitemap",
16
+ "add_lang",
17
+ "add_viewport",
18
+ "fix_title_length",
19
+ "fix_meta_length",
20
+ "add_image_dimensions",
21
+ "insert_internal_link",
22
+ "add_jsonld",
23
+ "update_jsonld",
24
+ "remove_invalid_jsonld",
25
+ "refresh_content",
26
+ "create_page",
27
+ "add_breadcrumb",
28
+ "add_faq_schema",
29
+ "add_article_schema",
30
+ "add_product_schema",
31
+ "add_og_image",
32
+ "edit_robots_txt",
33
+ "edit_meta_robots",
34
+ "add_redirect",
35
+ "change_canonical",
36
+ "change_hreflang",
37
+ "delete_page",
38
+ "send_outreach_email",
39
+ "submit_disavow",
40
+ "edit_llms_txt",
41
+ "buy_link",
42
+ "build_pbn",
43
+ "exchange_links",
44
+ "cloak",
45
+ "sneaky_redirect",
46
+ "hide_text",
47
+ "write_third_party",
48
+ "gate_reviews",
49
+ "incentivize_reviews",
50
+ "scrape_serp",
51
+ "generate_ymyl",
52
+ "generate_affiliate",
53
+ "create_city_service_page",
54
+ ];
55
+ export const ACTION_KIND_SET = new Set(ACTION_KINDS);
56
+ /** Policy matrix from PLAN §4. T3/T4 are not overridable. */
57
+ export const KIND_TIER = {
58
+ observe_snapshot: 0,
59
+ record_finding: 0,
60
+ inspect_indexation: 0,
61
+ rewrite_title: 1,
62
+ rewrite_meta_description: 1,
63
+ rewrite_og_title: 1,
64
+ rewrite_og_description: 1,
65
+ rewrite_alt_text: 1,
66
+ fix_heading: 1,
67
+ add_h1: 1,
68
+ repair_broken_internal_link: 1,
69
+ regenerate_sitemap: 1,
70
+ submit_sitemap: 1,
71
+ add_lang: 1,
72
+ add_viewport: 1,
73
+ fix_title_length: 1,
74
+ fix_meta_length: 1,
75
+ add_image_dimensions: 1,
76
+ insert_internal_link: 2,
77
+ add_jsonld: 2,
78
+ update_jsonld: 2,
79
+ remove_invalid_jsonld: 2,
80
+ refresh_content: 2,
81
+ create_page: 2,
82
+ add_breadcrumb: 2,
83
+ add_faq_schema: 2,
84
+ add_article_schema: 2,
85
+ add_product_schema: 2,
86
+ add_og_image: 2,
87
+ edit_robots_txt: 3,
88
+ edit_meta_robots: 3,
89
+ add_redirect: 3,
90
+ change_canonical: 3,
91
+ change_hreflang: 3,
92
+ delete_page: 3,
93
+ send_outreach_email: 3,
94
+ submit_disavow: 3,
95
+ edit_llms_txt: 3,
96
+ buy_link: 4,
97
+ build_pbn: 4,
98
+ exchange_links: 4,
99
+ cloak: 4,
100
+ sneaky_redirect: 4,
101
+ hide_text: 4,
102
+ write_third_party: 4,
103
+ gate_reviews: 4,
104
+ incentivize_reviews: 4,
105
+ scrape_serp: 4,
106
+ generate_ymyl: 4,
107
+ generate_affiliate: 4,
108
+ create_city_service_page: 4,
109
+ };
110
+ export const TWO_KEY_KINDS = new Set([
111
+ "edit_robots_txt",
112
+ "edit_meta_robots",
113
+ "add_redirect",
114
+ "change_canonical",
115
+ "change_hreflang",
116
+ "delete_page",
117
+ "submit_disavow",
118
+ "edit_llms_txt",
119
+ "send_outreach_email",
120
+ ]);
121
+ export const NEW_PAGE_KINDS = new Set(["create_page"]);
122
+ export const CONTENT_REFRESH_KINDS = new Set([
123
+ "refresh_content",
124
+ ]);
125
+ export const CONTENT_GEN_KINDS = new Set([
126
+ "refresh_content",
127
+ "create_page",
128
+ "generate_ymyl",
129
+ "generate_affiliate",
130
+ "create_city_service_page",
131
+ ]);
132
+ export function isActionKind(value) {
133
+ return ACTION_KIND_SET.has(value);
134
+ }
135
+ //# sourceMappingURL=kinds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kinds.js","sourceRoot":"","sources":["../src/kinds.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { ACTION_KIND_SET } from "./kinds.js";
2
+ import { type Action } from "./types.js";
3
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
4
+ /** Closed-schema parse. Unknown keys, open enums, and free-string URLs fail. */
5
+ export declare function parseAction(raw: unknown): {
6
+ ok: true;
7
+ action: Action;
8
+ } | {
9
+ ok: false;
10
+ error: string;
11
+ };
12
+ export { ACTION_KIND_SET };
13
+ //# sourceMappingURL=payloads.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payloads.d.ts","sourceRoot":"","sources":["../src/payloads.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA4C,MAAM,YAAY,CAAC;AACvF,OAAO,EAKL,KAAK,MAAM,EAIZ,MAAM,YAAY,CAAC;AAKpB,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE9E;AA0SD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,GACX;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA6C7D;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}