agentsean 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 (114) hide show
  1. package/LICENSE +661 -0
  2. package/dist/args.d.ts +33 -0
  3. package/dist/args.d.ts.map +1 -0
  4. package/dist/args.js +314 -0
  5. package/dist/args.js.map +1 -0
  6. package/dist/bin.d.ts +3 -0
  7. package/dist/bin.d.ts.map +1 -0
  8. package/dist/bin.js +5 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/cli.d.ts +2 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +192 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/commands/apply.d.ts +8 -0
  15. package/dist/commands/apply.d.ts.map +1 -0
  16. package/dist/commands/apply.js +107 -0
  17. package/dist/commands/apply.js.map +1 -0
  18. package/dist/commands/audit.d.ts +9 -0
  19. package/dist/commands/audit.d.ts.map +1 -0
  20. package/dist/commands/audit.js +92 -0
  21. package/dist/commands/audit.js.map +1 -0
  22. package/dist/commands/connect.d.ts +10 -0
  23. package/dist/commands/connect.d.ts.map +1 -0
  24. package/dist/commands/connect.js +181 -0
  25. package/dist/commands/connect.js.map +1 -0
  26. package/dist/commands/content.d.ts +8 -0
  27. package/dist/commands/content.d.ts.map +1 -0
  28. package/dist/commands/content.js +50 -0
  29. package/dist/commands/content.js.map +1 -0
  30. package/dist/commands/doctor.d.ts +6 -0
  31. package/dist/commands/doctor.d.ts.map +1 -0
  32. package/dist/commands/doctor.js +61 -0
  33. package/dist/commands/doctor.js.map +1 -0
  34. package/dist/commands/freeze.d.ts +6 -0
  35. package/dist/commands/freeze.d.ts.map +1 -0
  36. package/dist/commands/freeze.js +12 -0
  37. package/dist/commands/freeze.js.map +1 -0
  38. package/dist/commands/keywords.d.ts +6 -0
  39. package/dist/commands/keywords.d.ts.map +1 -0
  40. package/dist/commands/keywords.js +68 -0
  41. package/dist/commands/keywords.js.map +1 -0
  42. package/dist/commands/local.d.ts +6 -0
  43. package/dist/commands/local.d.ts.map +1 -0
  44. package/dist/commands/local.js +43 -0
  45. package/dist/commands/local.js.map +1 -0
  46. package/dist/commands/mcp.d.ts +5 -0
  47. package/dist/commands/mcp.d.ts.map +1 -0
  48. package/dist/commands/mcp.js +26 -0
  49. package/dist/commands/mcp.js.map +1 -0
  50. package/dist/commands/measure.d.ts +6 -0
  51. package/dist/commands/measure.d.ts.map +1 -0
  52. package/dist/commands/measure.js +46 -0
  53. package/dist/commands/measure.js.map +1 -0
  54. package/dist/commands/mentions.d.ts +6 -0
  55. package/dist/commands/mentions.d.ts.map +1 -0
  56. package/dist/commands/mentions.js +34 -0
  57. package/dist/commands/mentions.js.map +1 -0
  58. package/dist/commands/onboard.d.ts +11 -0
  59. package/dist/commands/onboard.d.ts.map +1 -0
  60. package/dist/commands/onboard.js +89 -0
  61. package/dist/commands/onboard.js.map +1 -0
  62. package/dist/commands/recipes.d.ts +5 -0
  63. package/dist/commands/recipes.d.ts.map +1 -0
  64. package/dist/commands/recipes.js +20 -0
  65. package/dist/commands/recipes.js.map +1 -0
  66. package/dist/commands/revert.d.ts +6 -0
  67. package/dist/commands/revert.d.ts.map +1 -0
  68. package/dist/commands/revert.js +45 -0
  69. package/dist/commands/revert.js.map +1 -0
  70. package/dist/commands/service.d.ts +9 -0
  71. package/dist/commands/service.d.ts.map +1 -0
  72. package/dist/commands/service.js +66 -0
  73. package/dist/commands/service.js.map +1 -0
  74. package/dist/commands/signup.d.ts +6 -0
  75. package/dist/commands/signup.d.ts.map +1 -0
  76. package/dist/commands/signup.js +31 -0
  77. package/dist/commands/signup.js.map +1 -0
  78. package/dist/commands/start.d.ts +9 -0
  79. package/dist/commands/start.d.ts.map +1 -0
  80. package/dist/commands/start.js +86 -0
  81. package/dist/commands/start.js.map +1 -0
  82. package/dist/commands/status.d.ts +5 -0
  83. package/dist/commands/status.d.ts.map +1 -0
  84. package/dist/commands/status.js +35 -0
  85. package/dist/commands/status.js.map +1 -0
  86. package/dist/commands/stop.d.ts +5 -0
  87. package/dist/commands/stop.d.ts.map +1 -0
  88. package/dist/commands/stop.js +38 -0
  89. package/dist/commands/stop.js.map +1 -0
  90. package/dist/commands/telemetry.d.ts +6 -0
  91. package/dist/commands/telemetry.d.ts.map +1 -0
  92. package/dist/commands/telemetry.js +43 -0
  93. package/dist/commands/telemetry.js.map +1 -0
  94. package/dist/commands/tenant.d.ts +6 -0
  95. package/dist/commands/tenant.d.ts.map +1 -0
  96. package/dist/commands/tenant.js +25 -0
  97. package/dist/commands/tenant.js.map +1 -0
  98. package/dist/commands/uninstall.d.ts +6 -0
  99. package/dist/commands/uninstall.d.ts.map +1 -0
  100. package/dist/commands/uninstall.js +20 -0
  101. package/dist/commands/uninstall.js.map +1 -0
  102. package/dist/commands/update.d.ts +5 -0
  103. package/dist/commands/update.d.ts.map +1 -0
  104. package/dist/commands/update.js +19 -0
  105. package/dist/commands/update.js.map +1 -0
  106. package/dist/commands/visibility.d.ts +6 -0
  107. package/dist/commands/visibility.d.ts.map +1 -0
  108. package/dist/commands/visibility.js +40 -0
  109. package/dist/commands/visibility.js.map +1 -0
  110. package/dist/output.d.ts +3 -0
  111. package/dist/output.d.ts.map +1 -0
  112. package/dist/output.js +15 -0
  113. package/dist/output.js.map +1 -0
  114. package/package.json +68 -0
@@ -0,0 +1,31 @@
1
+ import { openSqlite } from "@agentsean/db";
2
+ import { isPlanId, signupTenant } from "@agentsean/hosted";
3
+ import { dbPath, defaultSeanHome, ensureSeanHome } from "@agentsean/daemon";
4
+ import { emit, emitError } from "../output.js";
5
+ export async function signupCommand(opts) {
6
+ const planRaw = (opts.target ?? "cloud_starter").toLowerCase();
7
+ if (!isPlanId(planRaw) || planRaw === "self_host") {
8
+ if (planRaw === "self_host") {
9
+ emit(opts.json, { command: "signup", plan: "self_host", priceUsd: 0 }, "Self-host is $0. Run `sean start`. Unlimited sites, BYOK, white-label included.");
10
+ return 0;
11
+ }
12
+ emitError(opts.json, { command: "signup", error: "unknown_plan" }, "Plan must be cloud_starter, cloud_pro, business, or agency.");
13
+ return 2;
14
+ }
15
+ const plan = planRaw;
16
+ const home = ensureSeanHome(opts.home ?? defaultSeanHome());
17
+ const { db, sqlite } = openSqlite(dbPath(home));
18
+ try {
19
+ const result = await signupTenant(db, {
20
+ name: "Sean tenant",
21
+ email: process.env["SEAN_SIGNUP_EMAIL"] ?? "owner@localhost",
22
+ plan,
23
+ });
24
+ emit(opts.json, { command: "signup", ok: true, ...result }, `Checkout: ${result.checkoutUrl}\nTenant ${result.tenantId}. BYOK is required. Complete the Stripe webhook, then sean tenant ${result.tenantId}.`);
25
+ return 0;
26
+ }
27
+ finally {
28
+ sqlite.close();
29
+ }
30
+ }
31
+ //# sourceMappingURL=signup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/commands/signup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAe,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAInC;IACC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,IAAI,CACF,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,EAAE,EACrD,iFAAiF,CAClF,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,SAAS,CACP,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,EAC5C,6DAA6D,CAC9D,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,OAAiB,CAAC;IAC/B,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC,CAAC;IAC5D,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE;YACpC,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,iBAAiB;YAC5D,IAAI;SACL,CAAC,CAAC;QACH,IAAI,CACF,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,EAC1C,aAAa,MAAM,CAAC,WAAW,YAAY,MAAM,CAAC,QAAQ,qEAAqE,MAAM,CAAC,QAAQ,GAAG,CAClJ,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function startCommand(opts: {
2
+ json: boolean;
3
+ foreground: boolean;
4
+ host?: string | undefined;
5
+ port?: number | undefined;
6
+ home?: string | undefined;
7
+ quiet?: boolean | undefined;
8
+ }): Promise<number>;
9
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AA2BA,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAkGlB"}
@@ -0,0 +1,86 @@
1
+ import { spawn } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { defaultSeanHome, DEFAULT_HOST, DEFAULT_PORT, ensureSeanHome, isPidAlive, loadOrCreateToken, logPath, openDaemonStore, pidPath, readPid, startDaemon, } from "@agentsean/daemon";
5
+ import { emit, emitError } from "../output.js";
6
+ async function daemonMainPath() {
7
+ const resolved = import.meta.resolve("@agentsean/daemon/main");
8
+ return fileURLToPath(resolved);
9
+ }
10
+ function sleep(ms) {
11
+ return new Promise((r) => setTimeout(r, ms));
12
+ }
13
+ export async function startCommand(opts) {
14
+ const host = opts.host ?? (process.env["SEAN_HOST"]?.trim() || DEFAULT_HOST);
15
+ const port = opts.port ?? DEFAULT_PORT;
16
+ const home = ensureSeanHome(opts.home ?? defaultSeanHome());
17
+ const existing = readPid(home);
18
+ const store = openDaemonStore(home);
19
+ const token = await loadOrCreateToken(store);
20
+ const dashFor = (h, p) => `http://${h}:${p}/#token=${token.unwrap()}`;
21
+ if (existing && isPidAlive(existing.pid)) {
22
+ if (!opts.quiet) {
23
+ emit(opts.json, {
24
+ ok: true,
25
+ command: "start",
26
+ alreadyRunning: true,
27
+ pid: existing.pid,
28
+ host: existing.host,
29
+ port: existing.port,
30
+ dashboard: dashFor(existing.host, existing.port),
31
+ }, `Sean is already running (pid ${existing.pid}) on http://${existing.host}:${existing.port}\nDashboard: ${dashFor(existing.host, existing.port)}`);
32
+ }
33
+ return 0;
34
+ }
35
+ if (opts.foreground) {
36
+ const running = await startDaemon({ host, port, seanHome: home });
37
+ emit(opts.json, {
38
+ ok: true,
39
+ command: "start",
40
+ pid: running.pid,
41
+ host: running.host,
42
+ port: running.port,
43
+ health: `http://${running.host}:${running.port}/api/health`,
44
+ dashboard: dashFor(running.host, running.port),
45
+ }, `Sean started on http://${running.host}:${running.port} (pid ${running.pid})\nDashboard: ${dashFor(running.host, running.port)}\nHealth: http://${running.host}:${running.port}/api/health`);
46
+ await new Promise(() => {
47
+ /* run until signal */
48
+ });
49
+ return 0;
50
+ }
51
+ const entry = await daemonMainPath();
52
+ const log = fs.openSync(logPath(home), "a", 0o600);
53
+ const child = spawn(process.execPath, [entry, "--host", host, "--port", String(port), "--home", home], {
54
+ detached: true,
55
+ stdio: ["ignore", log, log],
56
+ env: { ...process.env, SEAN_HOME: home },
57
+ windowsHide: true,
58
+ });
59
+ child.unref();
60
+ fs.closeSync(log);
61
+ for (let i = 0; i < 50; i++) {
62
+ await sleep(100);
63
+ const info = readPid(home);
64
+ if (info && isPidAlive(info.pid)) {
65
+ if (!opts.quiet) {
66
+ emit(opts.json, {
67
+ ok: true,
68
+ command: "start",
69
+ pid: info.pid,
70
+ host: info.host,
71
+ port: info.port,
72
+ health: `http://${info.host}:${info.port}/api/health`,
73
+ dashboard: dashFor(info.host, info.port),
74
+ }, `Sean started on http://${info.host}:${info.port} (pid ${info.pid})\nDashboard: ${dashFor(info.host, info.port)}`);
75
+ }
76
+ return 0;
77
+ }
78
+ // If the child already died, don't keep waiting.
79
+ if (child.pid && !isPidAlive(child.pid) && !fs.existsSync(pidPath(home))) {
80
+ break;
81
+ }
82
+ }
83
+ emitError(opts.json, { command: "start", error: "daemon_failed_to_start" }, "Sean failed to start. Check ~/.sean/daemon.log");
84
+ return 1;
85
+ }
86
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function statusCommand(opts: {
2
+ json: boolean;
3
+ home?: string | undefined;
4
+ }): Promise<number>;
5
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAUA,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,GAAG,OAAO,CAAC,MAAM,CAAC,CAmClB"}
@@ -0,0 +1,35 @@
1
+ import { defaultSeanHome, isPidAlive, isHalted, readPid, DEFAULT_HOST, DEFAULT_PORT, } from "@agentsean/daemon";
2
+ import { emit, emitError } from "../output.js";
3
+ export async function statusCommand(opts) {
4
+ const home = opts.home ?? defaultSeanHome();
5
+ const info = readPid(home);
6
+ if (!info || !isPidAlive(info.pid)) {
7
+ emitError(opts.json, { command: "status", running: false }, "Sean is not running.");
8
+ return 1;
9
+ }
10
+ const host = info.host || DEFAULT_HOST;
11
+ const port = info.port || DEFAULT_PORT;
12
+ let health = null;
13
+ try {
14
+ const res = await fetch(`http://${host}:${port}/api/health`, {
15
+ headers: { Host: `${host}:${port}` },
16
+ });
17
+ if (res.ok)
18
+ health = await res.json();
19
+ }
20
+ catch {
21
+ health = null;
22
+ }
23
+ emit(opts.json, {
24
+ ok: true,
25
+ command: "status",
26
+ running: true,
27
+ pid: info.pid,
28
+ host,
29
+ port,
30
+ halted: isHalted(home),
31
+ health,
32
+ }, `Sean is running (pid ${info.pid}) on http://${host}:${port}${isHalted(home) ? " (frozen)" : ""}`);
33
+ return 0;
34
+ }
35
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,UAAU,EACV,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,YAAY,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAGnC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,sBAAsB,CAAC,CAAC;QACpF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC;IACvC,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,aAAa,EAAE;YAC3D,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE;SACrC,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,EAAE;YAAE,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,CACF,IAAI,CAAC,IAAI,EACT;QACE,EAAE,EAAE,IAAI;QACR,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI;QACJ,IAAI;QACJ,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;QACtB,MAAM;KACP,EACD,wBAAwB,IAAI,CAAC,GAAG,eAAe,IAAI,IAAI,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAClG,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function stopCommand(opts: {
2
+ json: boolean;
3
+ home?: string | undefined;
4
+ }): Promise<number>;
5
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAOA,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,GAAG,OAAO,CAAC,MAAM,CAAC,CA2ClB"}
@@ -0,0 +1,38 @@
1
+ import { defaultSeanHome, isPidAlive, readPid, removePid } from "@agentsean/daemon";
2
+ import { emit, emitError } from "../output.js";
3
+ function sleep(ms) {
4
+ return new Promise((r) => setTimeout(r, ms));
5
+ }
6
+ export async function stopCommand(opts) {
7
+ const home = opts.home ?? defaultSeanHome();
8
+ const info = readPid(home);
9
+ if (!info || !isPidAlive(info.pid)) {
10
+ removePid(home);
11
+ emit(opts.json, { ok: true, command: "stop", running: false }, "Sean is not running.");
12
+ return 0;
13
+ }
14
+ try {
15
+ process.kill(info.pid, "SIGTERM");
16
+ }
17
+ catch (err) {
18
+ emitError(opts.json, { command: "stop", error: String(err) }, `Failed to stop pid ${info.pid}: ${String(err)}`);
19
+ return 1;
20
+ }
21
+ for (let i = 0; i < 50; i++) {
22
+ if (!isPidAlive(info.pid))
23
+ break;
24
+ await sleep(100);
25
+ }
26
+ if (isPidAlive(info.pid)) {
27
+ try {
28
+ process.kill(info.pid, "SIGKILL");
29
+ }
30
+ catch {
31
+ // ignore
32
+ }
33
+ }
34
+ removePid(home);
35
+ emit(opts.json, { ok: true, command: "stop", pid: info.pid }, `Stopped Sean (pid ${info.pid}).`);
36
+ return 0;
37
+ }
38
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAGjC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,IAAI,CACF,IAAI,CAAC,IAAI,EACT,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAC7C,sBAAsB,CACvB,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,SAAS,CACP,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EACvC,sBAAsB,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CACjD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM;QACjC,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,SAAS,CAAC,IAAI,CAAC,CAAC;IAChB,IAAI,CACF,IAAI,CAAC,IAAI,EACT,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAC5C,qBAAqB,IAAI,CAAC,GAAG,IAAI,CAClC,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function telemetryCommand(opts: {
2
+ json: boolean;
3
+ home?: string | undefined;
4
+ target?: string | undefined;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/commands/telemetry.ts"],"names":[],"mappings":"AAWA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CA0DlB"}
@@ -0,0 +1,43 @@
1
+ import { defaultSeanHome, ensureSeanHome } from "@agentsean/daemon";
2
+ import { consentTelemetry, isTelemetryEnabled, loadTelemetryConfig, previewPayload, readInstallMethod, readTelemetryLog, } from "@agentsean/launch";
3
+ import { emit, emitError } from "../output.js";
4
+ export async function telemetryCommand(opts) {
5
+ const home = ensureSeanHome(opts.home ?? defaultSeanHome());
6
+ const action = (opts.target ?? "status").toLowerCase();
7
+ const method = readInstallMethod(home);
8
+ if (action === "log") {
9
+ const events = readTelemetryLog(home);
10
+ emit(opts.json, { ok: true, command: "telemetry", action: "log", events }, events.length === 0
11
+ ? "No telemetry events recorded."
12
+ : events.map((e) => JSON.stringify(e)).join("\n"));
13
+ return 0;
14
+ }
15
+ if (action === "on" || action === "off") {
16
+ const cfg = consentTelemetry(home, action === "on", method);
17
+ emit(opts.json, {
18
+ ok: true,
19
+ command: "telemetry",
20
+ enabled: cfg.enabled,
21
+ preview: previewPayload({ installMethod: method }),
22
+ }, cfg.enabled
23
+ ? `Telemetry on. Payload preview:\n${JSON.stringify(previewPayload({ installMethod: method }), null, 2)}\nOpt out: sean telemetry off · DO_NOT_TRACK=1`
24
+ : "Telemetry off. Nothing is sent.");
25
+ return 0;
26
+ }
27
+ if (action === "status" || action === "preview") {
28
+ const cfg = loadTelemetryConfig(home);
29
+ const enabled = isTelemetryEnabled(home);
30
+ const preview = previewPayload({ installMethod: cfg.installMethod || method });
31
+ emit(opts.json, {
32
+ ok: true,
33
+ command: "telemetry",
34
+ enabled,
35
+ consentedAt: cfg.consentedAt,
36
+ preview,
37
+ }, `Telemetry ${enabled ? "on" : "off"}. Preview:\n${JSON.stringify(preview, null, 2)}`);
38
+ return 0;
39
+ }
40
+ emitError(opts.json, { command: "telemetry", error: "unknown_action" }, "Usage: sean telemetry [status|log|on|off]");
41
+ return 2;
42
+ }
43
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/commands/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare function tenantCommand(opts: {
2
+ json: boolean;
3
+ home?: string | undefined;
4
+ target?: string | undefined;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=tenant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/commands/tenant.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBlB"}
@@ -0,0 +1,25 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { openSqlite, tenants } from "@agentsean/db";
3
+ import { hostedStatus } from "@agentsean/hosted";
4
+ import { dbPath, defaultSeanHome, ensureSeanHome } from "@agentsean/daemon";
5
+ import { emit, emitError } from "../output.js";
6
+ export async function tenantCommand(opts) {
7
+ const home = ensureSeanHome(opts.home ?? defaultSeanHome());
8
+ const { db, sqlite } = openSqlite(dbPath(home));
9
+ try {
10
+ const row = opts.target
11
+ ? db.select().from(tenants).where(eq(tenants.id, opts.target)).get()
12
+ : db.select().from(tenants).all()[0];
13
+ if (!row) {
14
+ emitError(opts.json, { command: "tenant", error: "unknown_tenant" }, "No tenant. Run sean signup <plan>.");
15
+ return 2;
16
+ }
17
+ const status = hostedStatus(db, row.id);
18
+ emit(opts.json, { command: "tenant", ok: true, ...status }, `${row.email} · ${row.plan} · ${status?.cost.sites ?? 0}/${status?.plan.sites ?? 0} sites · ledger $${(status?.cost.ledgerUsd ?? 0).toFixed(2)} · BYOK ${row.byok ? "on" : "off"}`);
19
+ return 0;
20
+ }
21
+ finally {
22
+ sqlite.close();
23
+ }
24
+ }
25
+ //# sourceMappingURL=tenant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant.js","sourceRoot":"","sources":["../../src/commands/tenant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAInC;IACC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC,CAAC;IAC5D,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM;YACrB,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE;YACpE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,SAAS,CACP,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAC9C,oCAAoC,CACrC,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CACF,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,EAC1C,GAAG,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,IAAI,MAAM,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CACnL,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function uninstallCommand(opts: {
2
+ json: boolean;
3
+ home?: string | undefined;
4
+ purge?: boolean | undefined;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAMA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBlB"}
@@ -0,0 +1,20 @@
1
+ import fs from "node:fs";
2
+ import { defaultSeanHome } from "@agentsean/daemon";
3
+ import { emit } from "../output.js";
4
+ import { serviceCommand } from "./service.js";
5
+ import { stopCommand } from "./stop.js";
6
+ export async function uninstallCommand(opts) {
7
+ const home = opts.home ?? defaultSeanHome();
8
+ await stopCommand({ json: true, home });
9
+ await serviceCommand({ json: true, home, target: "uninstall", yes: true });
10
+ let purged = false;
11
+ if (opts.purge && fs.existsSync(home)) {
12
+ fs.rmSync(home, { recursive: true, force: true });
13
+ purged = true;
14
+ }
15
+ emit(opts.json, { ok: true, command: "uninstall", home, purged }, purged
16
+ ? `Stopped Sean, removed the user service, and deleted ${home}.`
17
+ : `Stopped Sean and removed the user service. Data remains in ${home}. Pass --purge to delete it.`);
18
+ return 0;
19
+ }
20
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAItC;IACC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;IAC5C,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CACF,IAAI,CAAC,IAAI,EACT,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,EAChD,MAAM;QACJ,CAAC,CAAC,uDAAuD,IAAI,GAAG;QAChE,CAAC,CAAC,8DAA8D,IAAI,8BAA8B,CACrG,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function updateCommand(opts: {
2
+ json: boolean;
3
+ channel?: string | undefined;
4
+ }): Promise<number>;
5
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlB"}
@@ -0,0 +1,19 @@
1
+ import { checkUpdate, isChannel, VERSION } from "@agentsean/launch";
2
+ import { emit, emitError } from "../output.js";
3
+ export async function updateCommand(opts) {
4
+ const raw = opts.channel ?? "stable";
5
+ if (!isChannel(raw)) {
6
+ emitError(opts.json, { command: "update", error: "unknown_channel", channel: raw }, "Channel must be stable, extended-stable, or dev.");
7
+ return 2;
8
+ }
9
+ const channel = raw;
10
+ const result = await checkUpdate({ channel });
11
+ const human = result.published
12
+ ? result.behind
13
+ ? `Update available: ${result.current} → ${result.latest} (${channel}). Auto-update never runs while an Action is mid-flight. npm install -g agentsean@${result.latest}`
14
+ : `Agent Sean ${VERSION} is current on ${channel}.`
15
+ : `Agent Sean ${VERSION}. Not on npm yet — install from source or wait for the first publish.`;
16
+ emit(opts.json, { ok: true, command: "update", ...result }, human);
17
+ return 0;
18
+ }
19
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAgB,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAGnC;IACC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC;IACrC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,SAAS,CACP,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,GAAG,EAAE,EAC7D,kDAAkD,CACnD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,OAAO,GAAY,GAAG,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS;QAC5B,CAAC,CAAC,MAAM,CAAC,MAAM;YACb,CAAC,CAAC,qBAAqB,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,MAAM,KAAK,OAAO,qFAAqF,MAAM,CAAC,MAAM,EAAE;YACxK,CAAC,CAAC,cAAc,OAAO,kBAAkB,OAAO,GAAG;QACrD,CAAC,CAAC,cAAc,OAAO,uEAAuE,CAAC;IACjG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function visibilityCommand(opts: {
2
+ json: boolean;
3
+ home?: string | undefined;
4
+ target?: string | undefined;
5
+ }): Promise<number>;
6
+ //# sourceMappingURL=visibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visibility.d.ts","sourceRoot":"","sources":["../../src/commands/visibility.ts"],"names":[],"mappings":"AAYA,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAuClB"}
@@ -0,0 +1,40 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { openSqlite, sites } from "@agentsean/db";
3
+ import { loadLlmConfig } from "@agentsean/llm";
4
+ import { runSurfacesJob } from "@agentsean/surfaces";
5
+ import { dbPath, defaultSeanHome, ensureSeanHome, openDaemonStore, } from "@agentsean/daemon";
6
+ import { emit, emitError } from "../output.js";
7
+ export async function visibilityCommand(opts) {
8
+ const home = ensureSeanHome(opts.home ?? defaultSeanHome());
9
+ const { db, sqlite } = openSqlite(dbPath(home));
10
+ try {
11
+ const site = opts.target
12
+ ? db.select().from(sites).where(eq(sites.origin, opts.target)).get()
13
+ : db.select().from(sites).all()[0];
14
+ if (!site) {
15
+ emitError(opts.json, { command: "visibility", error: "unknown_site" }, "No site. Run sean audit first.");
16
+ return 2;
17
+ }
18
+ const store = openDaemonStore(home);
19
+ const llm = await loadLlmConfig({ store });
20
+ const result = await runSurfacesJob(db, {
21
+ siteId: site.id,
22
+ origin: site.origin,
23
+ ...(llm?.generate ? { generate: llm.generate } : {}),
24
+ });
25
+ emit(opts.json, {
26
+ command: "visibility",
27
+ ok: true,
28
+ citationShare: result.citationShare,
29
+ shareOfVoice: result.shareOfVoice,
30
+ estimatedUsd: result.estimatedUsd,
31
+ bingShare: result.bingShare,
32
+ vertical: result.vertical,
33
+ }, `AI citation share ${Math.round(result.citationShare * 100)}% · ~$${result.estimatedUsd.toFixed(2)}/run · vertical ${result.vertical}. Schema/llms.txt are not sold as AEO levers.`);
34
+ return 0;
35
+ }
36
+ finally {
37
+ sqlite.close();
38
+ }
39
+ }
40
+ //# sourceMappingURL=visibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visibility.js","sourceRoot":"","sources":["../../src/commands/visibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,MAAM,EACN,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAIvC;IACC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC,CAAC;IAC5D,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM;YACtB,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE;YACpE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS,CACP,IAAI,CAAC,IAAI,EACT,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,EAChD,gCAAgC,CACjC,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE;YACtC,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrD,CAAC,CAAC;QACH,IAAI,CACF,IAAI,CAAC,IAAI,EACT;YACE,OAAO,EAAE,YAAY;YACrB,EAAE,EAAE,IAAI;YACR,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,EACD,qBAAqB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,GAAG,GAAG,CAAC,SAAS,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,QAAQ,+CAA+C,CACpL,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function emit(jsonMode: boolean, payload: Record<string, unknown>, human: string): void;
2
+ export declare function emitError(jsonMode: boolean, payload: Record<string, unknown>, human: string): void;
3
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,wBAAgB,IAAI,CAClB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,GACZ,IAAI,CAMN;AAED,wBAAgB,SAAS,CACvB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,GACZ,IAAI,CAMN"}
package/dist/output.js ADDED
@@ -0,0 +1,15 @@
1
+ export function emit(jsonMode, payload, human) {
2
+ if (jsonMode) {
3
+ process.stdout.write(JSON.stringify(payload) + "\n");
4
+ return;
5
+ }
6
+ process.stdout.write(human.endsWith("\n") ? human : human + "\n");
7
+ }
8
+ export function emitError(jsonMode, payload, human) {
9
+ if (jsonMode) {
10
+ process.stdout.write(JSON.stringify({ ok: false, ...payload }) + "\n");
11
+ return;
12
+ }
13
+ process.stderr.write(human.endsWith("\n") ? human : human + "\n");
14
+ }
15
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,IAAI,CAClB,QAAiB,EACjB,OAAgC,EAChC,KAAa;IAEb,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,QAAiB,EACjB,OAAgC,EAChC,KAAa;IAEb,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACvE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "agentsean",
3
+ "version": "1.0.0",
4
+ "license": "AGPL-3.0-only",
5
+ "description": "Agent Sean — the self-hosted autonomous SEO engineer",
6
+ "type": "module",
7
+ "bin": {
8
+ "agentsean": "./dist/bin.js",
9
+ "sean": "./dist/bin.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/seziro-team/agentsean.git",
17
+ "directory": "packages/cli"
18
+ },
19
+ "engines": {
20
+ "node": ">=22.19.0"
21
+ },
22
+ "dependencies": {
23
+ "drizzle-orm": "0.45.2",
24
+ "@agentsean/actions": "1.0.0",
25
+ "@agentsean/adapter-git": "1.0.0",
26
+ "@agentsean/adapter-factory": "1.0.0",
27
+ "@agentsean/analyzers": "1.0.0",
28
+ "@agentsean/content": "1.0.0",
29
+ "@agentsean/credentials": "1.0.0",
30
+ "@agentsean/crawler": "1.0.0",
31
+ "@agentsean/daemon": "1.0.0",
32
+ "@agentsean/llm": "1.0.0",
33
+ "@agentsean/db": "1.0.0",
34
+ "@agentsean/google": "1.0.0",
35
+ "@agentsean/keywords": "1.0.0",
36
+ "@agentsean/measure": "1.0.0",
37
+ "@agentsean/surfaces": "1.0.0",
38
+ "@agentsean/hosted": "1.0.0",
39
+ "@agentsean/launch": "1.0.0",
40
+ "@agentsean/mcp": "1.0.0",
41
+ "@agentsean/providers": "1.0.0",
42
+ "@agentsean/scheduler": "1.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "typescript": "~5.9.3",
46
+ "vitest": "^4.1.11"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "homepage": "https://github.com/seziro-team/agentsean#readme",
52
+ "bugs": {
53
+ "url": "https://github.com/seziro-team/agentsean/issues"
54
+ },
55
+ "author": "Seziro (https://seziro.com)",
56
+ "keywords": [
57
+ "seo",
58
+ "agent",
59
+ "agentsean",
60
+ "seo-automation"
61
+ ],
62
+ "scripts": {
63
+ "build": "tsc -p tsconfig.json",
64
+ "typecheck": "tsc -p tsconfig.json --noEmit",
65
+ "test": "vitest run --config ../../vitest.config.ts",
66
+ "start": "node dist/bin.js"
67
+ }
68
+ }