@repogo/plugins 0.1.34 → 0.1.37

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 (41) hide show
  1. package/README.md +380 -26
  2. package/dist/cache.d.ts +27 -0
  3. package/dist/collections.d.ts +11 -1
  4. package/dist/context.d.ts +117 -1
  5. package/dist/cron.d.ts +21 -0
  6. package/dist/define.d.ts +36 -11
  7. package/dist/generated.d.ts +16 -0
  8. package/dist/index.d.ts +10 -3
  9. package/dist/index.js +100 -5
  10. package/dist/logs.d.ts +55 -0
  11. package/dist/runtime.d.ts +173 -0
  12. package/dist/self.d.ts +1 -0
  13. package/dist/testing.d.ts +53 -0
  14. package/dist/testing.js +3492 -0
  15. package/dist/tracking.d.ts +5 -0
  16. package/dist/uploads.d.ts +24 -0
  17. package/dist/workflow/attempts.d.ts +25 -0
  18. package/dist/workflow/availability.d.ts +8 -0
  19. package/dist/workflow/catalog.d.ts +21 -0
  20. package/dist/workflow/clock.d.ts +6 -0
  21. package/dist/workflow/contracts.d.ts +121 -0
  22. package/dist/workflow/definition.d.ts +35 -0
  23. package/dist/workflow/errors.d.ts +19 -0
  24. package/dist/workflow/events.d.ts +132 -0
  25. package/dist/workflow/interrupted.d.ts +3 -0
  26. package/dist/workflow/journal.d.ts +28 -0
  27. package/dist/workflow/lease.d.ts +2 -0
  28. package/dist/workflow/lifetime.d.ts +27 -0
  29. package/dist/workflow/policy.d.ts +36 -0
  30. package/dist/workflow/register.d.ts +11 -0
  31. package/dist/workflow/retry.d.ts +14 -0
  32. package/dist/workflow/runner.d.ts +29 -0
  33. package/dist/workflow/scope.d.ts +4 -0
  34. package/dist/workflow/service.d.ts +48 -0
  35. package/dist/workflow/sleep.d.ts +6 -0
  36. package/dist/workflow/state.d.ts +41 -0
  37. package/dist/workflow/storage.d.ts +22 -0
  38. package/dist/workflow/summary.d.ts +80 -0
  39. package/dist/workflow/testing.d.ts +12 -0
  40. package/dist/workflow-executor.js +22917 -0
  41. package/package.json +7 -3
package/dist/context.d.ts CHANGED
@@ -2,16 +2,74 @@ import type { Bucket } from "./buckets";
2
2
  import type { Collection } from "./collections";
3
3
  import type { Kv } from "./kv";
4
4
  import type { Stream } from "./streams";
5
- import type { MethodKind } from "./define";
5
+ import type { HTTPAccess, MethodKind } from "./define";
6
+ import type { Duration } from "./duration";
6
7
  /** An alert for the user's phones: what it says, and the page a tap opens. */
7
8
  export type Notice = {
8
9
  title: string;
9
10
  body: string;
10
11
  /** A page target, `.repogo/tabs/vercel.md?project=a`; a tap opens it. */
11
12
  page?: string;
13
+ /** An `https` or `itms-services` link a tap opens instead of the page, such as a build's install. */
14
+ url?: string;
12
15
  /** Alerts sharing a collapse id replace one another; defaults to the plugin and title. */
13
16
  collapse?: string;
14
17
  };
18
+ /** A Live Activity's color: the cards' named colors, less `secondary`. */
19
+ export type ActivityTint = "primary" | "accent" | "success" | "warning" | "danger" | "blue" | "green" | "orange" | "red" | "purple" | "pink" | "teal" | "yellow" | "gray";
20
+ /** A segment per step, or one bar. */
21
+ export type ActivityProgress = {
22
+ kind: "steps";
23
+ /** 1 to 8 names of at most 24 characters. */
24
+ steps: string[];
25
+ /** The active step, 0 to `steps.length`; the ones before it are complete. */
26
+ current: number;
27
+ } | {
28
+ kind: "bar";
29
+ /** 0 to 1. */
30
+ value: number;
31
+ };
32
+ /** The card's clock, which the phone ticks with no pushes. */
33
+ export type ActivityTimer = {
34
+ kind: "elapsed";
35
+ /** Unix ms; the activity's first start unless said. */
36
+ startedAt?: number;
37
+ } | {
38
+ kind: "countdown";
39
+ /** Unix ms; reaching it ends nothing. */
40
+ endsAt: number;
41
+ } | {
42
+ kind: "none";
43
+ };
44
+ /**
45
+ * A Live Activity on the user's phones, sent whole each time: the same `id`
46
+ * updates it, a field left out takes its default, and status `done` or
47
+ * `failed` ends it with this state.
48
+ */
49
+ export type Activity = {
50
+ /** The activity's id within the plugin, at most 64 bytes. */
51
+ id: string;
52
+ /** At most 60 characters, as a notice's title. */
53
+ title: string;
54
+ /** At most 120 characters, as a notice's body. */
55
+ body?: string;
56
+ /** A page target of the calling project, `.repogo/tabs/deploys.ui?project=web`; a tap opens it. */
57
+ page?: string;
58
+ /** An SF Symbol name, `shippingbox`; `circle.dotted`, or a check or a cross once ended, unless said. */
59
+ symbol?: string;
60
+ /** Colors the symbol, the progress and the label; white, or green or red once ended, unless said. */
61
+ tint?: ActivityTint;
62
+ /** The card's value, at most 24 characters; "2 of 4", "40%" or the status unless said, and "" hides it. */
63
+ label?: string;
64
+ /** The Dynamic Island's value, at most 10 characters; the label, or "2/4", unless said. */
65
+ compactLabel?: string;
66
+ /** No progress unless said. */
67
+ progress?: ActivityProgress;
68
+ /** Elapsed since the first start unless said. */
69
+ timer?: ActivityTimer;
70
+ /** `running` unless said; `done` and `failed` end it. */
71
+ status?: "running" | "done" | "failed";
72
+ };
15
73
  /** One method as `ctx.plugins()` and the agent's `plugins` tool list it. */
16
74
  export type ManifestMethod = {
17
75
  /** `<plugin>.<method>`, the name `ctx.call` takes. */
@@ -20,6 +78,8 @@ export type ManifestMethod = {
20
78
  description: string | null;
21
79
  /** What a card asks before running it; null runs on tap. */
22
80
  confirm: string | null;
81
+ /** Who may call it at the environment's own address; null, no one. */
82
+ http: HTTPAccess | null;
23
83
  /** JSON Schema of the input, and of the output when the method declares one. */
24
84
  input: unknown;
25
85
  output: unknown;
@@ -32,6 +92,8 @@ export type ManifestCron = {
32
92
  nextRunAt: number | null;
33
93
  lastRunAt: number | null;
34
94
  lastError: string | null;
95
+ /** How long its last run took: a run far past its interval blocked or waited on something. */
96
+ lastDurationMs: number | null;
35
97
  running: boolean;
36
98
  runs: number;
37
99
  };
@@ -49,6 +111,21 @@ export type ManifestStorage = {
49
111
  path: string;
50
112
  }[];
51
113
  };
114
+ /**
115
+ * One schedule the host gives a Worker, from a line of `~/.repogo/crons.json`: call
116
+ * `<plugin>.<method>` with `{}` when `schedule` comes due in `timezone` (the environment's).
117
+ */
118
+ export type CronEntry = {
119
+ plugin: string;
120
+ method: string;
121
+ schedule: string;
122
+ timezone?: string;
123
+ };
124
+ /** A schedule and how it's going; `error` says why it couldn't be set, and then nothing runs. */
125
+ export type CronStatus = ManifestCron & {
126
+ plugin: string;
127
+ error: string | null;
128
+ };
52
129
  export type Manifest = {
53
130
  plugins: {
54
131
  name: string;
@@ -58,8 +135,27 @@ export type Manifest = {
58
135
  storage: ManifestStorage;
59
136
  }[];
60
137
  };
138
+ /** Who started a call: a tap or a card's query, an agent's `plugin_call`, a cron, or plugin code with none of those behind it. */
139
+ export type Caller = "card" | "agent" | "cron" | "code" | "http";
140
+ /** How `ctx.agent` runs a chat: which agent, in which project, and how long to wait for its answer. */
141
+ export type AgentOptions = {
142
+ /** `claude` or `codex`, as `agents.list` names them. */
143
+ agent: string;
144
+ /** The project the chat runs in; the calling project unless said. */
145
+ project?: string;
146
+ title?: string;
147
+ /** How long to wait for the answer; 10 minutes unless said. */
148
+ timeout?: Duration;
149
+ };
150
+ /** What the agent answered, and the chat it answered in, to open or message later. */
151
+ export type AgentReply = {
152
+ chatId: string;
153
+ text: string;
154
+ };
61
155
  export type Context = {
62
156
  plugin: string;
157
+ /** Who started the outermost call; `ctx.call` passes it on. */
158
+ caller: Caller;
63
159
  /** The project's checkout, for a plugin that reads the project's files. */
64
160
  root: string;
65
161
  collections: Record<string, Collection<any>>;
@@ -73,6 +169,13 @@ export type Context = {
73
169
  * `ctx.host("git.status", { path: ctx.root })`. Its answer doesn't re-run a query.
74
170
  */
75
171
  host: (method: string, params?: unknown) => Promise<unknown>;
172
+ /**
173
+ * Runs a tool of an MCP server the user switched on for the calling project:
174
+ * `ctx.mcp("stripe", "stripe_api_read", { … })`, answering the tool's result.
175
+ * A query may run only read-only tools; a destructive tool runs only from a
176
+ * method with a `confirm`. Its answer doesn't re-run a query.
177
+ */
178
+ mcp: (server: string, tool: string, input?: unknown) => Promise<unknown>;
76
179
  /**
77
180
  * The plugins beside this one, in the same folder (the project's, or the
78
181
  * environment's), with their methods: what `call` can reach.
@@ -82,5 +185,18 @@ export type Context = {
82
185
  signal: AbortSignal;
83
186
  /** Sends an alert to every phone paired with this environment. */
84
187
  notify: (notice: Notice) => void;
188
+ /**
189
+ * Shows or updates a Live Activity on every paired phone:
190
+ * `await ctx.activity({ id: "deploy", title: "Deploying", progress: { kind: "steps", steps: ["Build", "Ship"], current: 0 } })`.
191
+ * A plugin shows at most two at once.
192
+ */
193
+ activity: (activity: Activity) => Promise<void>;
194
+ /**
195
+ * Starts a chat with `prompt` and waits for the agent's whole answer:
196
+ * `await ctx.agent("Why is the build failing?", { agent: "claude" })`.
197
+ * Throws once `timeout` passes, naming the chat, which keeps running.
198
+ */
199
+ agent: (prompt: string, options: AgentOptions) => Promise<AgentReply>;
200
+ /** The same as `console.log`: every console line is kept with the plugin and the call that wrote it. */
85
201
  log: (...args: unknown[]) => void;
86
202
  };
package/dist/cron.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ export type Schedule = {
2
+ seconds: Set<number> | null;
3
+ minutes: Set<number>;
4
+ hours: Set<number>;
5
+ days: Set<number>;
6
+ months: Set<number>;
7
+ weekdays: Set<number>;
8
+ /** Day fields given as other than `*`, for cron's either-day rule. */
9
+ daysRestricted: boolean;
10
+ weekdaysRestricted: boolean;
11
+ };
12
+ /** Reads a schedule, or throws saying what's wrong with it. */
13
+ export declare function parseSchedule(source: string): Schedule;
14
+ /** Throws unless `zone` is a time zone this machine knows, such as "America/New_York". */
15
+ export declare function checkTimezone(zone: string): void;
16
+ /**
17
+ * The first due time strictly after `after` (ms), in `zone`, or null when there
18
+ * is none within four years (`0 0 31 2 *`). A wall time that a fall-back night
19
+ * shows twice is due only the first time.
20
+ */
21
+ export declare function nextDue(s: Schedule, after: number, zone: string): number | null;
package/dist/define.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import type { z } from "zod";
2
+ import type { CacheOptions } from "./cache";
2
3
  import type { Context } from "./context";
4
+ import { type Duration } from "./duration";
5
+ import type { Workflow } from "./workflow/definition";
3
6
  import type { Retain } from "./streams";
4
7
  export type Collections = Record<string, z.ZodObject>;
5
8
  /** A stream's lines' schema, or that and how long it keeps them (7 days or 50 MB a key unless it says). */
@@ -25,26 +28,25 @@ export type Method<I extends z.ZodType = z.ZodType, O extends z.ZodType = z.ZodT
25
28
  * runs, such as "Delete every item?". Methods without one run on tap.
26
29
  */
27
30
  confirm?: string;
31
+ /** Who may call it at the environment's own address; unset, no one. */
32
+ http?: HTTPAccess;
33
+ /** Set by `cached`: the query answers from what it saved, and checks again when that's old. */
34
+ cache?: CacheOptions;
28
35
  run: (input: z.infer<I>, ctx: Context) => unknown | Promise<unknown>;
29
36
  };
30
- export type Handler = (payload: any, ctx: Context) => unknown | Promise<unknown>;
31
37
  /**
32
- * Runs one of the plugin's methods on a schedule, called with `{}` as a tap
33
- * would: `{ method: "watch", schedule: "*\/5 * * * *" }`. `schedule` is a cron,
34
- * five fields or six with seconds first; `timezone` defaults to the environment's.
38
+ * `key`: the host checks a key the caller sends. `none`: anyone reaches the
39
+ * method, which checks the caller itself, such as a provider's signature.
35
40
  */
36
- export type Cron = {
37
- method: string;
38
- schedule: string;
39
- timezone?: string;
40
- };
41
+ export type HTTPAccess = "key" | "none";
42
+ export type Handler = (payload: any, ctx: Context) => unknown | Promise<unknown>;
41
43
  export type PluginDefinition = {
42
44
  /** One line, shown to the agent in the index of plugins. */
43
45
  description?: string;
44
46
  /**
45
47
  * Where the plugin's data lives: `<namespace>/` in the data dir, holding `data.db`
46
48
  * and its buckets' and streams' files. Plugins naming the same namespace share its
47
- * data. The plugin's folder name when left out; by convention a project's own is
49
+ * data. Required once the plugin keeps data; by convention a project's own is
48
50
  * `<project>.<name>` (`repogo.plans`) and data for every project a bare name (`todos`).
49
51
  */
50
52
  namespace?: string;
@@ -56,8 +58,13 @@ export type PluginDefinition = {
56
58
  /** Append-only JSONL per key, in `<namespace>/streams/<name>/`, kept as `retain` says. */
57
59
  streams?: Record<string, StreamDefinition>;
58
60
  methods?: Record<string, Method<any, any>>;
61
+ workflows?: Record<string, Workflow<any, any>>;
59
62
  on?: Record<string, Handler>;
60
- crons?: Cron[];
63
+ /**
64
+ * Data named here gets no generated methods (list, create, delete…), so cards
65
+ * and agents reach it only through the plugin's own: an audit log, say.
66
+ */
67
+ private?: string[];
61
68
  };
62
69
  export declare function definePlugin<T extends PluginDefinition>(plugin: T): T;
63
70
  export declare function method<I extends z.ZodType, O extends z.ZodType = z.ZodType>(input: I, run: (input: z.infer<I>, ctx: Context) => unknown | Promise<unknown>, options?: {
@@ -65,6 +72,24 @@ export declare function method<I extends z.ZodType, O extends z.ZodType = z.ZodT
65
72
  output?: O;
66
73
  description?: string;
67
74
  confirm?: string;
75
+ http?: true | {
76
+ auth: HTTPAccess;
77
+ };
78
+ }): Method<I, O>;
79
+ /**
80
+ * A query that answers at once from what it saved last time, for answers that
81
+ * are slow to get: a CLI's list, another service's API. When the saved answer
82
+ * is older than `fresh`, `run` goes again in the background, and cards showing
83
+ * it redraw only if the answer changed. With nothing saved, the first call
84
+ * waits for `run`. Each project keeps its own answers unless `shared`.
85
+ * `run` is read-only, like a query's; it has `timeout` (a minute unless it says).
86
+ */
87
+ export declare function cached<I extends z.ZodType, O extends z.ZodType = z.ZodType>(input: I, run: (input: z.infer<I>, ctx: Context) => unknown | Promise<unknown>, options: {
88
+ fresh: Duration;
89
+ shared?: boolean;
90
+ timeout?: Duration;
91
+ output?: O;
92
+ description?: string;
68
93
  }): Method<I, O>;
69
94
  /**
70
95
  * A method that sends items as they happen: a log tail, a build's output. Each
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ import type { Bucket } from "./buckets";
3
+ import type { MethodKind } from "./define";
4
+ import type { Kv } from "./kv";
5
+ import type { Stream } from "./streams";
6
+ export type Generated = {
7
+ kind: MethodKind;
8
+ description: string;
9
+ input: z.ZodType;
10
+ output?: z.ZodType;
11
+ confirm?: string;
12
+ run: (input: any, signal: AbortSignal) => unknown;
13
+ };
14
+ export declare function kvMethods(name: string, kv: Kv<any>, schema: z.ZodType): Record<string, Generated>;
15
+ export declare function streamMethods(name: string, stream: Stream<any>, schema: z.ZodType): Record<string, Generated>;
16
+ export declare function bucketMethods(name: string, bucket: Bucket<any>, schema: z.ZodObject): Record<string, Generated>;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,16 @@
1
- export { definePlugin, method, stream } from "./define";
2
- export type { PluginDefinition, Method, MethodKind, Cron, StreamDefinition } from "./define";
3
- export type { Context, Manifest, ManifestCron, ManifestMethod, ManifestStorage } from "./context";
1
+ export { cached, definePlugin, method, stream } from "./define";
2
+ export { upload, type UploadedFile } from "./uploads";
3
+ export type { PluginDefinition, Method, MethodKind, HTTPAccess, StreamDefinition } from "./define";
4
+ export type { Activity, ActivityProgress, ActivityTimer, ActivityTint, AgentOptions, AgentReply, Caller, Context, CronEntry, CronStatus, Manifest, ManifestCron, ManifestMethod, ManifestStorage } from "./context";
5
+ export type { LogLevel, LogRecord } from "./logs";
4
6
  export type { BucketFile, FileStatus, PutFile } from "./buckets";
5
7
  export type { KvEntry, SetOptions } from "./kv";
6
8
  export type { Retain, StreamEntry, StreamKey } from "./streams";
7
9
  export type { Duration } from "./duration";
8
10
  export { MethodError, toCallError, type CallError } from "./errors";
9
11
  export { z } from "zod";
12
+ export { workflow, type Workflow, type WorkflowContext, type WorkflowOptions } from "./workflow/definition";
13
+ export { NonRetryable } from "./workflow/errors";
14
+ export type { StepContext } from "./workflow/definition";
15
+ export type { StepOptions } from "./workflow/policy";
16
+ export type { RunSummary } from "./workflow/contracts";
package/dist/index.js CHANGED
@@ -1,4 +1,47 @@
1
1
  // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true,
8
+ configurable: true,
9
+ set: (newValue) => all[name] = () => newValue
10
+ });
11
+ };
12
+
13
+ // src/index.ts
14
+ var exports_src = {};
15
+ __export(exports_src, {
16
+ z: () => z3,
17
+ workflow: () => workflow,
18
+ upload: () => upload,
19
+ toCallError: () => toCallError,
20
+ stream: () => stream,
21
+ method: () => method,
22
+ definePlugin: () => definePlugin,
23
+ cached: () => cached,
24
+ NonRetryable: () => NonRetryable,
25
+ MethodError: () => MethodError
26
+ });
27
+
28
+ // src/duration.ts
29
+ var unitMs = { s: 1000, m: 60000, h: 3600000, d: 86400000 };
30
+ function parseDuration(duration) {
31
+ if (typeof duration === "number") {
32
+ if (!Number.isFinite(duration) || duration <= 0)
33
+ throw new Error(`a duration is a positive number of ms: ${duration}`);
34
+ return duration;
35
+ }
36
+ const match = /^(\d+(?:\.\d+)?)([smhd])$/.exec(duration);
37
+ if (!match)
38
+ throw new Error(`a duration is like "30s", "5m", "1h" or "7d": ${duration}`);
39
+ const ms = Number(match[1]) * unitMs[match[2]];
40
+ if (ms <= 0)
41
+ throw new Error(`a duration is longer than zero: ${duration}`);
42
+ return ms;
43
+ }
44
+
2
45
  // src/define.ts
3
46
  function definePlugin(plugin) {
4
47
  return plugin;
@@ -10,14 +53,34 @@ function method(input, run, options = {}) {
10
53
  kind: options.kind ?? "mutation",
11
54
  output: options.output,
12
55
  description: options.description,
13
- confirm: options.confirm
56
+ confirm: options.confirm,
57
+ http: options.http === true ? "key" : options.http?.auth
58
+ };
59
+ }
60
+ function cached(input, run, options) {
61
+ return {
62
+ input,
63
+ run,
64
+ kind: "query",
65
+ output: options.output,
66
+ description: options.description,
67
+ cache: { fresh: parseDuration(options.fresh), shared: options.shared ?? false, timeout: parseDuration(options.timeout ?? "1m") }
14
68
  };
15
69
  }
16
70
  function stream(input, run, options = {}) {
17
71
  return { input, run, kind: "stream", description: options.description };
18
72
  }
19
- // src/errors.ts
73
+ // src/uploads.ts
74
+ import { AsyncLocalStorage } from "async_hooks";
20
75
  import { z } from "zod";
76
+ var callFiles = new AsyncLocalStorage;
77
+ function upload() {
78
+ return z.object({ id: z.string(), name: z.string(), type: z.string(), size: z.number(), path: z.string() }).refine((file) => (callFiles.getStore() ?? []).some((held) => held.id === file.id && held.path === file.path), {
79
+ message: "Not a file uploaded for this call."
80
+ });
81
+ }
82
+ // src/errors.ts
83
+ import { z as z2 } from "zod";
21
84
 
22
85
  class MethodError extends Error {
23
86
  code;
@@ -32,7 +95,7 @@ function toCallError(error) {
32
95
  if (error instanceof MethodError) {
33
96
  return { code: error.code, message: error.message, ...error.fieldErrors ? { fieldErrors: error.fieldErrors } : {} };
34
97
  }
35
- if (error instanceof z.ZodError) {
98
+ if (error instanceof z2.ZodError) {
36
99
  const fieldErrors = {};
37
100
  for (const issue of error.issues)
38
101
  fieldErrors["/" + issue.path.join("/")] ??= issue.message;
@@ -44,12 +107,44 @@ function toCallError(error) {
44
107
  }
45
108
 
46
109
  // src/index.ts
47
- import { z as z2 } from "zod";
110
+ import { z as z3 } from "zod";
111
+
112
+ // src/workflow/scope.ts
113
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
114
+ var attemptScope = new AsyncLocalStorage2;
115
+ var workflowScope = new AsyncLocalStorage2;
116
+
117
+ // src/workflow/definition.ts
118
+ function workflowContext(base, run) {
119
+ return {
120
+ ...base,
121
+ ...run,
122
+ get signal() {
123
+ return attemptScope.getStore()?.signal ?? run.signal;
124
+ },
125
+ step: { run: (name, callback, options) => run.step.run(name, (context) => callback({ ...context, runId: run.runId, idempotencyKey: `${run.runId}:${name}` }), options) }
126
+ };
127
+ }
128
+ function workflow(input, run, options = {}) {
129
+ return { input, run, ...options };
130
+ }
131
+ // src/workflow/errors.ts
132
+ class NonRetryable extends Error {
133
+ constructor(message) {
134
+ super(message);
135
+ this.name = "NonRetryable";
136
+ }
137
+ }
48
138
  export {
49
- z2 as z,
139
+ z3 as z,
140
+ workflow,
141
+ upload,
50
142
  toCallError,
51
143
  stream,
52
144
  method,
53
145
  definePlugin,
146
+ cached,
147
+ NonRetryable,
54
148
  MethodError
55
149
  };
150
+ export { parseDuration, callFiles, MethodError, toCallError, attemptScope, workflowScope, workflowContext, exports_src };
package/dist/logs.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import type { Caller } from "./context";
3
+ export type LogLevel = "debug" | "info" | "warn" | "error";
4
+ export type LogRecord = {
5
+ /** ms since the epoch. */
6
+ at: number;
7
+ plugin: string;
8
+ level: LogLevel;
9
+ /** `<plugin>.<method>` of the run the line was written in; empty outside a run. */
10
+ method: string;
11
+ caller: Caller | "";
12
+ /** One id per outermost call, so a call's lines read together. */
13
+ callId: string;
14
+ /** The chat whose agent made the call, for `caller: "agent"`. */
15
+ chatId: string;
16
+ /** The arguments formatted as the console prints them, at most `textLimit` characters. */
17
+ text: string;
18
+ /** The arguments as given, as JSON can carry them. */
19
+ data: unknown[];
20
+ };
21
+ /** What a line is attributed to: the plugin, and the run when there is one. */
22
+ export type LogContext = {
23
+ plugin: string;
24
+ method?: string;
25
+ caller?: Caller;
26
+ callId?: string;
27
+ chatId?: string;
28
+ };
29
+ /** The run the code writing a line is in; the runtime sets it around every method, handler and cron. */
30
+ export declare const logContext: AsyncLocalStorage<LogContext>;
31
+ /**
32
+ * Runs `work` as an outermost run under `context`. An error nothing catches
33
+ * reaches its handler with no async context, so the newest run going is the
34
+ * best guess at whose it is.
35
+ */
36
+ export declare function runWith<T>(context: LogContext, work: () => Promise<T>): Promise<T>;
37
+ /** A line longer than this is cut: a dumped payload is read in the plugin's own data, not its log. */
38
+ export declare const textLimit: number;
39
+ type Sink = (record: LogRecord) => void;
40
+ /**
41
+ * Replaces `console.log`, `info`, `debug`, `warn` and `error` with ones that
42
+ * record each call. `passThrough` keeps printing them too, for tests.
43
+ */
44
+ export declare function captureConsole(to: Sink, options?: {
45
+ passThrough?: boolean;
46
+ }): void;
47
+ /** Puts the console back and stops recording. */
48
+ export declare function releaseConsole(): void;
49
+ /**
50
+ * Records one line under `context`, else the current run, else the newest run
51
+ * going, as an error nothing caught lands in. With no capture installed the
52
+ * line prints as the console would.
53
+ */
54
+ export declare function record(level: LogLevel, args: unknown[], context?: LogContext): void;
55
+ export {};