@repogo/plugins 0.1.30 → 0.1.32

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.
package/README.md CHANGED
@@ -22,6 +22,22 @@ export default definePlugin({
22
22
  });
23
23
  ```
24
24
 
25
+ A `stream` sends items as they happen, for as long as a card shows it. Each
26
+ `yield` is one item; `ctx.signal` aborts when the card goes, so hand it to what
27
+ you start:
28
+
29
+ ```ts
30
+ tail: stream(z.object({ file: z.string() }), async function* ({ file }, ctx) {
31
+ const tail = Bun.spawn(["tail", "-f", file], { signal: ctx.signal });
32
+ let partial = "";
33
+ for await (const chunk of tail.stdout.pipeThrough(new TextDecoderStream())) {
34
+ const lines = (partial + chunk).split("\n");
35
+ partial = lines.pop()!;
36
+ for (const line of lines) yield { id: crypto.randomUUID(), text: line };
37
+ }
38
+ }),
39
+ ```
40
+
25
41
  `db` names the SQLite file the collections live in, `~/.repogo/plugin-data/<db>.db`
26
42
  on the environment; left out, it is the plugin's folder name. Name a project's own
27
43
  data `<project>.<name>`. A bare name (`todos`) is shared by every plugin that
package/dist/context.d.ts CHANGED
@@ -15,6 +15,8 @@ export type Context = {
15
15
  db: Record<string, Collection<any>>;
16
16
  call: (method: string, input?: unknown) => Promise<unknown>;
17
17
  emit: (name: string, payload: unknown) => Promise<void>;
18
+ /** Aborts when a stream's last watcher leaves; a query or mutation's never does. */
19
+ signal: AbortSignal;
18
20
  /** Sends an alert to every phone paired with this environment. */
19
21
  notify: (notice: Notice) => void;
20
22
  log: (...args: unknown[]) => void;
package/dist/define.d.ts CHANGED
@@ -3,10 +3,11 @@ import type { Context } from "./context";
3
3
  export type Collections = Record<string, z.ZodObject>;
4
4
  /**
5
5
  * A query only reads, so cards may run it on their own and again when its data
6
- * changes. A mutation writes, and runs only when the user acts. Unmarked
7
- * methods are mutations: repeating one is never assumed safe.
6
+ * changes. A mutation writes, and runs only when the user acts. A stream only
7
+ * reads too, and sends items as they happen for as long as someone watches.
8
+ * Unmarked methods are mutations: repeating one is never assumed safe.
8
9
  */
9
- export type MethodKind = "query" | "mutation";
10
+ export type MethodKind = "query" | "mutation" | "stream";
10
11
  export type Method<I extends z.ZodType = z.ZodType, O extends z.ZodType = z.ZodType> = {
11
12
  input: I;
12
13
  /** What it returns; the agent and cards read field names from it. */
@@ -41,3 +42,12 @@ export declare function method<I extends z.ZodType, O extends z.ZodType = z.ZodT
41
42
  description?: string;
42
43
  confirm?: string;
43
44
  }): Method<I, O>;
45
+ /**
46
+ * A method that sends items as they happen: a log tail, a build's output. Each
47
+ * `yield` is one item; a card shows them as a list that grows. It runs while
48
+ * someone watches and `ctx.signal` aborts when the last one leaves, so pass it
49
+ * on (`Bun.spawn(cmd, { signal: ctx.signal })`). Like a query, it may not write.
50
+ */
51
+ export declare function stream<I extends z.ZodType>(input: I, run: (input: z.infer<I>, ctx: Context) => AsyncIterable<unknown>, options?: {
52
+ description?: string;
53
+ }): Method<I>;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { definePlugin, method } from "./define";
1
+ export { definePlugin, method, stream } from "./define";
2
2
  export type { PluginDefinition, Method, MethodKind } from "./define";
3
3
  export type { Context } from "./context";
4
4
  export { MethodError, toCallError, type CallError } from "./errors";
package/dist/index.js CHANGED
@@ -13,6 +13,9 @@ function method(input, run, options = {}) {
13
13
  confirm: options.confirm
14
14
  };
15
15
  }
16
+ function stream(input, run, options = {}) {
17
+ return { input, run, kind: "stream", description: options.description };
18
+ }
16
19
  // src/errors.ts
17
20
  import { z } from "zod";
18
21
 
@@ -45,6 +48,7 @@ import { z as z2 } from "zod";
45
48
  export {
46
49
  z2 as z,
47
50
  toCallError,
51
+ stream,
48
52
  method,
49
53
  definePlugin,
50
54
  MethodError
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repogo/plugins",
3
- "version": "0.1.30",
3
+ "version": "0.1.32",
4
4
  "description": "Write RepoGo plugins: collections and methods over SQLite that agents and cards call",
5
5
  "type": "module",
6
6
  "exports": {