paperkite 0.1.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 (121) hide show
  1. package/README.md +81 -0
  2. package/data/flows.example.yml +65 -0
  3. package/data/settings.example.yml +13 -0
  4. package/dist/data/hooks/weekend-slot.d.ts +12 -0
  5. package/dist/data/hooks/weekend-slot.js +107 -0
  6. package/dist/data/hooks/weekend-slot.js.map +1 -0
  7. package/dist/packages/account-health/src/index.d.ts +8 -0
  8. package/dist/packages/account-health/src/index.js +37 -0
  9. package/dist/packages/account-health/src/index.js.map +1 -0
  10. package/dist/packages/archive/src/archiver.d.ts +98 -0
  11. package/dist/packages/archive/src/archiver.js +399 -0
  12. package/dist/packages/archive/src/archiver.js.map +1 -0
  13. package/dist/packages/archive/src/config.d.ts +22 -0
  14. package/dist/packages/archive/src/config.js +62 -0
  15. package/dist/packages/archive/src/config.js.map +1 -0
  16. package/dist/packages/archive/src/console/live.d.ts +24 -0
  17. package/dist/packages/archive/src/console/live.js +144 -0
  18. package/dist/packages/archive/src/console/live.js.map +1 -0
  19. package/dist/packages/archive/src/console/media.d.ts +66 -0
  20. package/dist/packages/archive/src/console/media.js +368 -0
  21. package/dist/packages/archive/src/console/media.js.map +1 -0
  22. package/dist/packages/archive/src/console/server.d.ts +12 -0
  23. package/dist/packages/archive/src/console/server.js +583 -0
  24. package/dist/packages/archive/src/console/server.js.map +1 -0
  25. package/dist/packages/archive/src/console/service.d.ts +13 -0
  26. package/dist/packages/archive/src/console/service.js +86 -0
  27. package/dist/packages/archive/src/console/service.js.map +1 -0
  28. package/dist/packages/archive/src/storage/index.d.ts +6 -0
  29. package/dist/packages/archive/src/storage/index.js +23 -0
  30. package/dist/packages/archive/src/storage/index.js.map +1 -0
  31. package/dist/packages/archive/src/storage/model.d.ts +296 -0
  32. package/dist/packages/archive/src/storage/model.js +151 -0
  33. package/dist/packages/archive/src/storage/model.js.map +1 -0
  34. package/dist/packages/archive/src/storage/postgres.d.ts +67 -0
  35. package/dist/packages/archive/src/storage/postgres.js +1021 -0
  36. package/dist/packages/archive/src/storage/postgres.js.map +1 -0
  37. package/dist/packages/archive/src/storage/sqlite.d.ts +59 -0
  38. package/dist/packages/archive/src/storage/sqlite.js +981 -0
  39. package/dist/packages/archive/src/storage/sqlite.js.map +1 -0
  40. package/dist/packages/notify-bark/src/index.d.ts +33 -0
  41. package/dist/packages/notify-bark/src/index.js +96 -0
  42. package/dist/packages/notify-bark/src/index.js.map +1 -0
  43. package/dist/packages/runtime-console/src/console/errors.d.ts +5 -0
  44. package/dist/packages/runtime-console/src/console/errors.js +11 -0
  45. package/dist/packages/runtime-console/src/console/errors.js.map +1 -0
  46. package/dist/packages/runtime-console/src/console/logs.d.ts +1 -0
  47. package/dist/packages/runtime-console/src/console/logs.js +27 -0
  48. package/dist/packages/runtime-console/src/console/logs.js.map +1 -0
  49. package/dist/packages/runtime-console/src/console/server.d.ts +6 -0
  50. package/dist/packages/runtime-console/src/console/server.js +182 -0
  51. package/dist/packages/runtime-console/src/console/server.js.map +1 -0
  52. package/dist/packages/runtime-console/src/index.d.ts +10 -0
  53. package/dist/packages/runtime-console/src/index.js +83 -0
  54. package/dist/packages/runtime-console/src/index.js.map +1 -0
  55. package/dist/src/app.d.ts +15 -0
  56. package/dist/src/app.js +34 -0
  57. package/dist/src/app.js.map +1 -0
  58. package/dist/src/cli.d.ts +2 -0
  59. package/dist/src/cli.js +250 -0
  60. package/dist/src/cli.js.map +1 -0
  61. package/dist/src/config/editor.d.ts +2 -0
  62. package/dist/src/config/editor.js +19 -0
  63. package/dist/src/config/editor.js.map +1 -0
  64. package/dist/src/config/loader.d.ts +6 -0
  65. package/dist/src/config/loader.js +188 -0
  66. package/dist/src/config/loader.js.map +1 -0
  67. package/dist/src/config/model.d.ts +71 -0
  68. package/dist/src/config/model.js +97 -0
  69. package/dist/src/config/model.js.map +1 -0
  70. package/dist/src/config/paths.d.ts +3 -0
  71. package/dist/src/config/paths.js +12 -0
  72. package/dist/src/config/paths.js.map +1 -0
  73. package/dist/src/config/settings.d.ts +19 -0
  74. package/dist/src/config/settings.js +44 -0
  75. package/dist/src/config/settings.js.map +1 -0
  76. package/dist/src/control/process-lock.d.ts +4 -0
  77. package/dist/src/control/process-lock.js +57 -0
  78. package/dist/src/control/process-lock.js.map +1 -0
  79. package/dist/src/control/socket.d.ts +14 -0
  80. package/dist/src/control/socket.js +131 -0
  81. package/dist/src/control/socket.js.map +1 -0
  82. package/dist/src/engine/hooks.d.ts +4 -0
  83. package/dist/src/engine/hooks.js +38 -0
  84. package/dist/src/engine/hooks.js.map +1 -0
  85. package/dist/src/engine/logger.d.ts +17 -0
  86. package/dist/src/engine/logger.js +78 -0
  87. package/dist/src/engine/logger.js.map +1 -0
  88. package/dist/src/engine/runtime.d.ts +78 -0
  89. package/dist/src/engine/runtime.js +799 -0
  90. package/dist/src/engine/runtime.js.map +1 -0
  91. package/dist/src/engine/scheduler.d.ts +9 -0
  92. package/dist/src/engine/scheduler.js +58 -0
  93. package/dist/src/engine/scheduler.js.map +1 -0
  94. package/dist/src/extensions/loader.d.ts +11 -0
  95. package/dist/src/extensions/loader.js +202 -0
  96. package/dist/src/extensions/loader.js.map +1 -0
  97. package/dist/src/extensions/manager.d.ts +1 -0
  98. package/dist/src/extensions/manager.js +121 -0
  99. package/dist/src/extensions/manager.js.map +1 -0
  100. package/dist/src/extensions/profile.d.ts +14 -0
  101. package/dist/src/extensions/profile.js +57 -0
  102. package/dist/src/extensions/profile.js.map +1 -0
  103. package/dist/src/extensions/registry.d.ts +19 -0
  104. package/dist/src/extensions/registry.js +62 -0
  105. package/dist/src/extensions/registry.js.map +1 -0
  106. package/dist/src/telegram/client.d.ts +20 -0
  107. package/dist/src/telegram/client.js +54 -0
  108. package/dist/src/telegram/client.js.map +1 -0
  109. package/dist/src/telegram/failure.d.ts +2 -0
  110. package/dist/src/telegram/failure.js +98 -0
  111. package/dist/src/telegram/failure.js.map +1 -0
  112. package/dist/src/telegram/login.d.ts +1 -0
  113. package/dist/src/telegram/login.js +31 -0
  114. package/dist/src/telegram/login.js.map +1 -0
  115. package/dist/src/telegram/pool.d.ts +47 -0
  116. package/dist/src/telegram/pool.js +300 -0
  117. package/dist/src/telegram/pool.js.map +1 -0
  118. package/dist/src/telegram/session-files.d.ts +4 -0
  119. package/dist/src/telegram/session-files.js +34 -0
  120. package/dist/src/telegram/session-files.js.map +1 -0
  121. package/package.json +62 -0
@@ -0,0 +1,97 @@
1
+ export const FLOW_SECTIONS = ["triggers", "commands", "schedules", "services"];
2
+ export class FlowCatalog {
3
+ definitionsByKind;
4
+ path;
5
+ constructor(definitionsByKind, path) {
6
+ this.definitionsByKind = definitionsByKind;
7
+ this.path = path;
8
+ }
9
+ definitions(kind) {
10
+ if (!kind)
11
+ return FLOW_SECTIONS.flatMap((section) => this.definitionsByKind[sectionToKind(section)]);
12
+ return [...this.definitionsByKind[normalizeKind(kind)]];
13
+ }
14
+ enabled(kind) {
15
+ return this.definitions(kind).filter((item) => item.kind === "command" || item.enabled);
16
+ }
17
+ capabilityRefs() {
18
+ const refs = new Set();
19
+ for (const item of this.enabled()) {
20
+ if ("capability" in item && item.capability)
21
+ refs.add(item.capability);
22
+ if (item.kind === "schedule" || item.kind === "command")
23
+ refs.add(item.action.capability);
24
+ if (item.kind === "trigger") {
25
+ for (const action of item.actions)
26
+ refs.add(action.capability);
27
+ }
28
+ }
29
+ return refs;
30
+ }
31
+ find(identifier, kind) {
32
+ const value = identifier.trim();
33
+ const separator = value.indexOf(":");
34
+ const requestedKind = separator >= 0 ? normalizeKind(value.slice(0, separator)) : kind;
35
+ const requestedId = separator >= 0 ? value.slice(separator + 1) : value;
36
+ const candidates = this.definitions(requestedKind);
37
+ const matches = candidates.filter((item) => item.id === requestedId);
38
+ if (matches.length > 1)
39
+ throw new Error(`flow id is ambiguous: ${identifier}`);
40
+ return matches[0];
41
+ }
42
+ }
43
+ export function normalizeKind(kind) {
44
+ if (kind === "triggers" || kind === "trigger")
45
+ return "trigger";
46
+ if (kind === "commands" || kind === "command")
47
+ return "command";
48
+ if (kind === "schedules" || kind === "schedule")
49
+ return "schedule";
50
+ if (kind === "services" || kind === "service")
51
+ return "service";
52
+ throw new Error(`unknown flow kind: ${kind}`);
53
+ }
54
+ function sectionToKind(section) {
55
+ return normalizeKind(section);
56
+ }
57
+ export function normalizeBool(value, fallback) {
58
+ if (value === undefined || value === null)
59
+ return fallback;
60
+ if (typeof value === "boolean")
61
+ return value;
62
+ if (typeof value === "string") {
63
+ const normalized = value.trim().toLowerCase();
64
+ if (["true", "yes", "on", "1"].includes(normalized))
65
+ return true;
66
+ if (["false", "no", "off", "0", ""].includes(normalized))
67
+ return false;
68
+ throw new Error(`invalid boolean: ${value}`);
69
+ }
70
+ return Boolean(value);
71
+ }
72
+ export function normalizeSession(value) {
73
+ if (value === undefined || value === null)
74
+ return undefined;
75
+ const result = String(value).trim();
76
+ return result || undefined;
77
+ }
78
+ export function normalizePositiveInt(value, field, fallback) {
79
+ if (value === undefined || value === null || value === "")
80
+ return fallback;
81
+ const number = Number(value);
82
+ if (!Number.isInteger(number) || number <= 0)
83
+ throw new Error(`${field} must be a positive integer`);
84
+ return number;
85
+ }
86
+ export function normalizeMaxRuns(value) {
87
+ if (value === undefined || value === null || value === "" || Number(value) === -1)
88
+ return undefined;
89
+ const number = Number(value);
90
+ if (!Number.isInteger(number) || number <= 0)
91
+ throw new Error("maxRuns must be a positive integer or -1");
92
+ return number;
93
+ }
94
+ export function isRecord(value) {
95
+ return typeof value === "object" && value !== null && !Array.isArray(value);
96
+ }
97
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/config/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function paperkiteHome(): string;
2
+ export declare function defaultSettingsFile(): string;
3
+ export declare function defaultFlowsFile(): string;
@@ -0,0 +1,12 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ export function paperkiteHome() {
4
+ return process.env.PAPERKITE_HOME?.trim() || join(homedir(), ".paperkite");
5
+ }
6
+ export function defaultSettingsFile() {
7
+ return join(paperkiteHome(), "settings.yml");
8
+ }
9
+ export function defaultFlowsFile() {
10
+ return join(paperkiteHome(), "flows.yml");
11
+ }
12
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/config/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,cAAc,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface SessionGuardSettings {
2
+ readonly windowMs: number;
3
+ readonly threshold: number;
4
+ readonly backoffMinMs: number;
5
+ readonly backoffMaxMs: number;
6
+ }
7
+ export interface AppSettings {
8
+ readonly telegram: {
9
+ readonly apiId: number;
10
+ readonly apiHash: string;
11
+ readonly sessionsDir: string;
12
+ readonly sessionGuard?: SessionGuardSettings;
13
+ };
14
+ readonly logging: {
15
+ readonly level: string;
16
+ readonly directory: string;
17
+ };
18
+ }
19
+ export declare function loadSettings(path?: string): Promise<AppSettings>;
@@ -0,0 +1,44 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { dirname, resolve } from "node:path";
3
+ import { parse } from "yaml";
4
+ import { isRecord, normalizeSession } from "./model.js";
5
+ import { defaultSettingsFile } from "./paths.js";
6
+ export async function loadSettings(path = defaultSettingsFile()) {
7
+ const base = dirname(resolve(path));
8
+ const data = parse(await readFile(resolve(path), "utf8"));
9
+ if (!isRecord(data) || !isRecord(data.telegram)) {
10
+ throw new Error("settings.yml needs a telegram section");
11
+ }
12
+ const apiId = Number(data.telegram.apiId);
13
+ const apiHash = normalizeSession(data.telegram.apiHash);
14
+ if (!Number.isInteger(apiId) || apiId <= 0 || !apiHash) {
15
+ throw new Error("settings.yml needs telegram.apiId and telegram.apiHash");
16
+ }
17
+ const sessionsDir = normalizeSession(data.telegram.sessionsDir) ?? "accounts";
18
+ const logging = isRecord(data.logging) ? data.logging : {};
19
+ const guard = isRecord(data.telegram.sessionGuard) ? data.telegram.sessionGuard : {};
20
+ return {
21
+ telegram: {
22
+ apiId,
23
+ apiHash,
24
+ sessionsDir: resolve(base, sessionsDir),
25
+ sessionGuard: {
26
+ windowMs: positiveNumber(guard.windowMs ?? 60_000, "sessionGuard.windowMs"),
27
+ threshold: positiveNumber(guard.threshold ?? 5, "sessionGuard.threshold"),
28
+ backoffMinMs: positiveNumber(guard.backoffMinMs ?? 30_000, "sessionGuard.backoffMinMs"),
29
+ backoffMaxMs: positiveNumber(guard.backoffMaxMs ?? 30 * 60_000, "sessionGuard.backoffMaxMs")
30
+ }
31
+ },
32
+ logging: {
33
+ level: String(logging.level ?? "info").toLowerCase(),
34
+ directory: resolve(base, String(logging.directory ?? "logs"))
35
+ }
36
+ };
37
+ }
38
+ function positiveNumber(value, field) {
39
+ const number = Number(value);
40
+ if (!Number.isFinite(number) || number <= 0)
41
+ throw new Error("settings.yml needs a positive " + field);
42
+ return Math.floor(number);
43
+ }
44
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/config/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export interface ProcessLock {
2
+ release(): Promise<void>;
3
+ }
4
+ export declare function acquireProcessLock(file: string): Promise<ProcessLock>;
@@ -0,0 +1,57 @@
1
+ import { mkdir, open, readFile, unlink } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ export async function acquireProcessLock(file) {
4
+ await mkdir(dirname(file), { recursive: true });
5
+ try {
6
+ const handle = await open(file, "wx");
7
+ await handle.writeFile(JSON.stringify({ pid: process.pid, startedAt: new Date().toISOString() }) + "\n");
8
+ let released = false;
9
+ return {
10
+ release: async () => {
11
+ if (released)
12
+ return;
13
+ released = true;
14
+ await handle.close();
15
+ await unlink(file).catch(() => undefined);
16
+ }
17
+ };
18
+ }
19
+ catch (error) {
20
+ if (!isNodeError(error) || error.code !== "EEXIST")
21
+ throw error;
22
+ const existing = await readLock(file);
23
+ if (existing?.pid && isRunning(existing.pid)) {
24
+ throw new Error("another paperkite process is using " + file);
25
+ }
26
+ await unlink(file).catch(() => undefined);
27
+ return acquireProcessLock(file);
28
+ }
29
+ }
30
+ async function readLock(file) {
31
+ try {
32
+ const value = JSON.parse(await readFile(file, "utf8"));
33
+ if (typeof value === "object" && value !== null && "pid" in value) {
34
+ const pid = Number(value.pid);
35
+ return Number.isInteger(pid) ? { pid } : undefined;
36
+ }
37
+ }
38
+ catch {
39
+ return undefined;
40
+ }
41
+ return undefined;
42
+ }
43
+ function isRunning(pid) {
44
+ if (pid === process.pid)
45
+ return true;
46
+ try {
47
+ process.kill(pid, 0);
48
+ return true;
49
+ }
50
+ catch (error) {
51
+ return isNodeError(error) && error.code === "EPERM";
52
+ }
53
+ }
54
+ function isNodeError(error) {
55
+ return error instanceof Error && "code" in error;
56
+ }
57
+ //# sourceMappingURL=process-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-lock.js","sourceRoot":"","sources":["../../../src/control/process-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ActionSpecInput, FlowPatch, RuntimeControl } from "@paperkite/sdk";
2
+ export type { RuntimeControl };
3
+ interface ControlRequest {
4
+ readonly action?: string;
5
+ readonly id?: string;
6
+ readonly spec?: ActionSpecInput;
7
+ readonly patch?: FlowPatch;
8
+ }
9
+ export interface ControlServer {
10
+ close(): Promise<void>;
11
+ }
12
+ export declare function controlPath(): string;
13
+ export declare function startControlServer(runtime: RuntimeControl, path?: string): Promise<ControlServer>;
14
+ export declare function requestControl<T = unknown>(request: ControlRequest, path?: string, timeoutMs?: number): Promise<T>;
@@ -0,0 +1,131 @@
1
+ import { chmod, mkdir, unlink } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { createConnection, createServer } from "node:net";
4
+ import { createInterface } from "node:readline";
5
+ import { paperkiteHome } from "../config/paths.js";
6
+ export function controlPath() {
7
+ if (process.platform === "win32")
8
+ return "\\\\.\\pipe\\paperkite-control";
9
+ return join(paperkiteHome(), "control.sock");
10
+ }
11
+ export async function startControlServer(runtime, path = controlPath()) {
12
+ if (process.platform !== "win32") {
13
+ await mkdir(dirname(path), { recursive: true });
14
+ await unlink(path).catch(() => undefined);
15
+ }
16
+ const server = createServer((socket) => handleConnection(socket, runtime));
17
+ await listen(server, path);
18
+ if (process.platform !== "win32")
19
+ await chmod(path, 0o600).catch(() => undefined);
20
+ return {
21
+ close: async () => {
22
+ server.close();
23
+ await unlink(path).catch(() => undefined);
24
+ }
25
+ };
26
+ }
27
+ export async function requestControl(request, path = controlPath(), timeoutMs = 3_000) {
28
+ return new Promise((resolve, reject) => {
29
+ const socket = createConnection(path);
30
+ const input = createInterface({ input: socket, crlfDelay: Infinity });
31
+ const timer = setTimeout(() => {
32
+ socket.destroy(new Error("control request timed out"));
33
+ }, timeoutMs);
34
+ let settled = false;
35
+ const finish = (error, value) => {
36
+ if (settled)
37
+ return;
38
+ settled = true;
39
+ clearTimeout(timer);
40
+ input.close();
41
+ socket.destroy();
42
+ if (error)
43
+ reject(error);
44
+ else
45
+ resolve(value);
46
+ };
47
+ socket.once("error", (error) => finish(error));
48
+ socket.once("connect", () => socket.write(JSON.stringify(request) + "\n"));
49
+ input.once("line", (line) => {
50
+ try {
51
+ const response = JSON.parse(line);
52
+ if (response.ok)
53
+ finish(undefined, response.result);
54
+ else
55
+ finish(new Error(response.error || "control request failed"));
56
+ }
57
+ catch (error) {
58
+ finish(error instanceof Error ? error : new Error(String(error)));
59
+ }
60
+ });
61
+ });
62
+ }
63
+ async function handleConnection(socket, runtime) {
64
+ const input = createInterface({ input: socket, crlfDelay: Infinity });
65
+ for await (const line of input) {
66
+ let response;
67
+ try {
68
+ response = { ok: true, result: await dispatch(runtime, JSON.parse(line)) };
69
+ }
70
+ catch (error) {
71
+ response = { ok: false, error: error instanceof Error ? error.message : String(error) };
72
+ }
73
+ socket.write(JSON.stringify(response) + "\n");
74
+ }
75
+ socket.end();
76
+ }
77
+ async function dispatch(runtime, request) {
78
+ const action = request.action;
79
+ if (action === "snapshot")
80
+ return runtime.snapshot;
81
+ if (action === "plugins")
82
+ return runtime.listPlugins();
83
+ if (action === "runtime.reload") {
84
+ await runtime.reload();
85
+ return true;
86
+ }
87
+ if (action === "action.run") {
88
+ if (!request.spec)
89
+ throw new Error("action.run needs spec");
90
+ await runtime.executeAction(request.spec);
91
+ return true;
92
+ }
93
+ if (!request.id)
94
+ throw new Error("control request needs id");
95
+ if (action === "flow.run") {
96
+ await runtime.runFlow(request.id);
97
+ return true;
98
+ }
99
+ if (action === "service.start") {
100
+ await runtime.startService(request.id);
101
+ return true;
102
+ }
103
+ if (action === "service.stop") {
104
+ await runtime.stopService(request.id);
105
+ return true;
106
+ }
107
+ if (action === "flow.update") {
108
+ if (!request.patch)
109
+ throw new Error("flow.update needs id and patch");
110
+ return runtime.updateFlow(request.id, request.patch);
111
+ }
112
+ if (action === "flow.reload") {
113
+ await runtime.reloadFlow(request.id);
114
+ return true;
115
+ }
116
+ if (action === "session.reconnect") {
117
+ await runtime.reconnectSession(request.id);
118
+ return true;
119
+ }
120
+ throw new Error("unknown control action: " + action);
121
+ }
122
+ function listen(server, path) {
123
+ return new Promise((resolve, reject) => {
124
+ server.once("error", reject);
125
+ server.listen(path, () => {
126
+ server.off("error", reject);
127
+ resolve();
128
+ });
129
+ });
130
+ }
131
+ //# sourceMappingURL=socket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.js","sourceRoot":"","sources":["../../../src/control/socket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ActionHook } from "@paperkite/sdk";
2
+ export declare function loadHook(reference: string | undefined, configFile: string | undefined): Promise<ActionHook | undefined>;
3
+ export declare function invalidateHook(reference: string | undefined, configFile: string | undefined): void;
4
+ export declare function invalidateAllHooks(): void;
@@ -0,0 +1,38 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { stripTypeScriptTypes } from "node:module";
3
+ import { resolve } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ const loaded = new Map();
6
+ export async function loadHook(reference, configFile) {
7
+ if (!reference)
8
+ return undefined;
9
+ const file = hookFile(reference, configFile);
10
+ const cached = loaded.get(file);
11
+ if (cached)
12
+ return cached;
13
+ const hook = await importHook(file);
14
+ loaded.set(file, hook);
15
+ return hook;
16
+ }
17
+ export function invalidateHook(reference, configFile) {
18
+ if (!reference)
19
+ return;
20
+ loaded.delete(hookFile(reference, configFile));
21
+ }
22
+ export function invalidateAllHooks() {
23
+ loaded.clear();
24
+ }
25
+ function hookFile(reference, configFile) {
26
+ const base = configFile ? resolve(configFile, "..") : process.cwd();
27
+ return resolve(base, reference);
28
+ }
29
+ async function importHook(file) {
30
+ const source = await readFile(file, "utf8");
31
+ const js = stripTypeScriptTypes(source, { sourceUrl: pathToFileURL(file).href });
32
+ const url = `data:text/javascript;base64,${Buffer.from(js, "utf8").toString("base64")}`;
33
+ const module = (await import(url));
34
+ if (typeof module.default !== "function")
35
+ throw new Error("hook must export a default function: " + file);
36
+ return module.default;
37
+ }
38
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../src/engine/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,SAA6B,EAAE,UAA8B;IAC1F,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAA6B,EAAE,UAA8B;IAC1F,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,SAAiB,EAAE,UAA8B;IACjE,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACpE,OAAO,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5C,MAAM,EAAE,GAAG,oBAAoB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,+BAA+B,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACxF,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAA0B,CAAC;IAC5D,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,GAAG,IAAI,CAAC,CAAC;IAC1G,OAAO,MAAM,CAAC,OAAqB,CAAC;AACtC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { RuntimeLogger } from "@paperkite/sdk";
2
+ export declare class AppLogger implements RuntimeLogger {
3
+ private readonly level;
4
+ private readonly directory?;
5
+ private readonly scope?;
6
+ private readonly threshold;
7
+ private readonly children;
8
+ constructor(level?: string, directory?: string | undefined, scope?: string | undefined);
9
+ child(scope: string): AppLogger;
10
+ registeredScopes(): readonly string[];
11
+ logDirectory(): string | undefined;
12
+ debug(message: string, ...values: unknown[]): void;
13
+ info(message: string, ...values: unknown[]): void;
14
+ warn(message: string, ...values: unknown[]): void;
15
+ error(message: string, ...values: unknown[]): void;
16
+ private write;
17
+ }
@@ -0,0 +1,78 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { basename, join } from "node:path";
3
+ const levels = ["debug", "info", "warn", "error"];
4
+ export class AppLogger {
5
+ level;
6
+ directory;
7
+ scope;
8
+ threshold;
9
+ children = new Map();
10
+ constructor(level = "info", directory, scope) {
11
+ this.level = level;
12
+ this.directory = directory;
13
+ this.scope = scope;
14
+ this.threshold = Math.max(0, levels.indexOf(normalizeLevel(level)));
15
+ }
16
+ child(scope) {
17
+ const existing = this.children.get(scope);
18
+ if (existing)
19
+ return existing;
20
+ const child = new AppLogger(this.level, this.directory, scope);
21
+ this.children.set(scope, child);
22
+ return child;
23
+ }
24
+ registeredScopes() {
25
+ return [...this.children.keys()];
26
+ }
27
+ logDirectory() {
28
+ return this.directory;
29
+ }
30
+ debug(message, ...values) {
31
+ this.write("debug", message, values);
32
+ }
33
+ info(message, ...values) {
34
+ this.write("info", message, values);
35
+ }
36
+ warn(message, ...values) {
37
+ this.write("warn", message, values);
38
+ }
39
+ error(message, ...values) {
40
+ this.write("error", message, values);
41
+ }
42
+ write(level, message, values) {
43
+ if (levels.indexOf(level) < this.threshold)
44
+ return;
45
+ const suffix = values.length ? " " + values.map(formatValue).join(" ") : "";
46
+ const line = new Date().toISOString() +
47
+ " " +
48
+ level.toUpperCase() +
49
+ (this.scope ? " [" + this.scope + "]" : "") +
50
+ " " +
51
+ message +
52
+ suffix +
53
+ "\n";
54
+ process.stderr.write(line);
55
+ if (this.directory) {
56
+ void mkdir(this.directory, { recursive: true })
57
+ .then(() => appendFile(join(this.directory, basename(this.scope || "paperkite") + ".log"), line, "utf8"))
58
+ .catch(() => undefined);
59
+ }
60
+ }
61
+ }
62
+ function normalizeLevel(value) {
63
+ const lowered = value.toLowerCase();
64
+ return levels.includes(lowered) ? lowered : "info";
65
+ }
66
+ function formatValue(value) {
67
+ if (value instanceof Error)
68
+ return value.stack || value.message;
69
+ if (typeof value === "string")
70
+ return value;
71
+ try {
72
+ return JSON.stringify(value);
73
+ }
74
+ catch {
75
+ return String(value);
76
+ }
77
+ }
78
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/engine/logger.ts"],"names":[],"mappings":"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"}