@casey.gowrie/eve-ext-notes 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.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @casey.gowrie/eve-ext-notes
2
+
3
+ An [eve](https://github.com/vercel/eve) extension: a durable **notes toolkit**.
4
+ It contributes tools, a hook, and a skill that compose into any consuming agent
5
+ under a namespace.
6
+
7
+ ## Contents
8
+
9
+ - **Tools** — `add_note`, `list_notes`, `clear_notes`. Notes persist in
10
+ extension-scoped [`defineState`](https://eve.dev/docs), so they survive across
11
+ a session and never collide with the host agent's state.
12
+ - **Hook** — `audit`: observe-only logging of every successful note save.
13
+ - **Skill** — `daily-standup`: turns saved notes into a standup summary.
14
+
15
+ ## Config
16
+
17
+ Bound once when the consumer mounts the extension:
18
+
19
+ | key | type | default | meaning |
20
+ | ---------- | ------ | ------- | ---------------------------- |
21
+ | `maxNotes` | number | `50` | Cap on stored notes. |
22
+
23
+ ## Install & mount
24
+
25
+ ```bash
26
+ npm install @casey.gowrie/eve-ext-notes
27
+ ```
28
+
29
+ ```ts title="agent/extensions/notes.ts"
30
+ import notes from "@casey.gowrie/eve-ext-notes";
31
+
32
+ export default notes({ maxNotes: 25 });
33
+ ```
34
+
35
+ The mount file's basename is the namespace, so tools compose as `notes__add_note`,
36
+ `notes__list_notes`, and `notes__clear_notes`.
37
+
38
+ ## Requirements
39
+
40
+ `eve` is a **peer dependency** (`^0.22.3`): the consuming app supplies the single
41
+ eve install that resolves this extension's `eve/*` imports.
@@ -0,0 +1,4 @@
1
+ // Generated by eve. Do not edit by hand.
2
+
3
+ export { default } from "../ext/extension.js";
4
+ export { default as eve_ext_notes } from "../ext/extension.js";
package/dist/index.mjs ADDED
@@ -0,0 +1,18 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ __eveDirname(__eveFileURLToPath(import.meta.url));
5
+ __eveCreateRequire(import.meta.url);
6
+ import { defineExtension } from "eve/extension";
7
+ import { z } from "zod";
8
+ //#region \0eve-ext-scope:extension:casey.gowrie-eve-ext-notes
9
+ function defineExtension$1(options, namespace) {
10
+ return defineExtension(options, namespace === void 0 ? "casey.gowrie-eve-ext-notes" : namespace);
11
+ }
12
+ //#endregion
13
+ //#region ext/extension.ts
14
+ var extension_default = defineExtension$1({ config: z.object({ maxNotes: z.number().int().positive().default(50) }) });
15
+ //#endregion
16
+ export { extension_default as default, extension_default as eve_ext_notes };
17
+
18
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJkZWZpbmVFeHRlbnNpb24iXSwic291cmNlcyI6WyIuLi9leHQvZXh0ZW5zaW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlZmluZUV4dGVuc2lvbiB9IGZyb20gXCJldmUvZXh0ZW5zaW9uXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVFeHRlbnNpb24oe1xuICBjb25maWc6IHoub2JqZWN0KHtcbiAgICBtYXhOb3Rlczogei5udW1iZXIoKS5pbnQoKS5wb3NpdGl2ZSgpLmRlZmF1bHQoNTApLFxuICB9KSxcbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBR0EsSUFBQSxvQkFBQSxrQkFBQSxFQUFBLFFBQUEsRUFBQSxPQUFBLEVBQUEsVUFBQSxFQUFBLE9BQUEsQ0FBQSxDQUFBLElBQUEsQ0FBQSxDQUFBLFNBQUEsQ0FBQSxDQUFBLFFBQUEsRUFBQSxFQUFBLENBQUEsRUFBQSxDQUFBIn0=
@@ -0,0 +1,5 @@
1
+ // Generated by eve. Do not edit by hand.
2
+
3
+ export { default as add_note } from "../../ext/tools/add_note.js";
4
+ export { default as clear_notes } from "../../ext/tools/clear_notes.js";
5
+ export { default as list_notes } from "../../ext/tools/list_notes.js";
@@ -0,0 +1,73 @@
1
+ import { fileURLToPath as __eveFileURLToPath } from "node:url";
2
+ import { dirname as __eveDirname } from "node:path";
3
+ import { createRequire as __eveCreateRequire } from "node:module";
4
+ __eveDirname(__eveFileURLToPath(import.meta.url));
5
+ __eveCreateRequire(import.meta.url);
6
+ import { defineTool } from "eve/tools";
7
+ import { z } from "zod";
8
+ import { defineExtension } from "eve/extension";
9
+ import { defineState } from "eve/context";
10
+ //#region \0eve-ext-scope:extension:casey.gowrie-eve-ext-notes
11
+ function defineExtension$1(options, namespace) {
12
+ return defineExtension(options, namespace === void 0 ? "casey.gowrie-eve-ext-notes" : namespace);
13
+ }
14
+ //#endregion
15
+ //#region ext/extension.ts
16
+ var extension_default = defineExtension$1({ config: z.object({ maxNotes: z.number().int().positive().default(50) }) });
17
+ //#endregion
18
+ //#region \0eve-ext-scope:context:casey.gowrie-eve-ext-notes
19
+ function defineState$1(name, initial) {
20
+ return defineState("casey.gowrie-eve-ext-notes." + name, initial);
21
+ }
22
+ //#endregion
23
+ //#region ext/lib/store.ts
24
+ const notes = defineState$1("notes", () => []);
25
+ //#endregion
26
+ //#region ext/tools/add_note.ts
27
+ var add_note_default = defineTool({
28
+ description: "Save a short note to the durable notes list for later recall.",
29
+ inputSchema: z.object({ text: z.string().min(1).describe("The note to remember.") }),
30
+ async execute({ text }) {
31
+ const { maxNotes } = extension_default.config;
32
+ if (notes.get().length >= maxNotes) return {
33
+ ok: false,
34
+ reason: `note limit reached (${maxNotes})`
35
+ };
36
+ notes.update((list) => [...list, {
37
+ text,
38
+ createdAt: new Date().toISOString()
39
+ }]);
40
+ return {
41
+ ok: true,
42
+ count: notes.get().length
43
+ };
44
+ }
45
+ });
46
+ //#endregion
47
+ //#region ext/tools/clear_notes.ts
48
+ var clear_notes_default = defineTool({
49
+ description: "Delete all saved notes and report how many were removed.",
50
+ inputSchema: z.object({}),
51
+ async execute() {
52
+ const cleared = notes.get().length;
53
+ notes.update(() => []);
54
+ return { cleared };
55
+ }
56
+ });
57
+ //#endregion
58
+ //#region ext/tools/list_notes.ts
59
+ var list_notes_default = defineTool({
60
+ description: "List every saved note, oldest first.",
61
+ inputSchema: z.object({}),
62
+ async execute() {
63
+ const list = notes.get();
64
+ return {
65
+ count: list.length,
66
+ notes: list
67
+ };
68
+ }
69
+ });
70
+ //#endregion
71
+ export { add_note_default as add_note, clear_notes_default as clear_notes, list_notes_default as list_notes };
72
+
73
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJkZWZpbmVFeHRlbnNpb24iLCJkZWZpbmVTdGF0ZSIsImV4dGVuc2lvbiJdLCJzb3VyY2VzIjpbIi4uL2V4dC9leHRlbnNpb24udHMiLCIuLi9leHQvbGliL3N0b3JlLnRzIiwiLi4vZXh0L3Rvb2xzL2FkZF9ub3RlLnRzIiwiLi4vZXh0L3Rvb2xzL2NsZWFyX25vdGVzLnRzIiwiLi4vZXh0L3Rvb2xzL2xpc3Rfbm90ZXMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVmaW5lRXh0ZW5zaW9uIH0gZnJvbSBcImV2ZS9leHRlbnNpb25cIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZUV4dGVuc2lvbih7XG4gIGNvbmZpZzogei5vYmplY3Qoe1xuICAgIG1heE5vdGVzOiB6Lm51bWJlcigpLmludCgpLnBvc2l0aXZlKCkuZGVmYXVsdCg1MCksXG4gIH0pLFxufSk7XG4iLCJpbXBvcnQgeyBkZWZpbmVTdGF0ZSB9IGZyb20gXCJldmUvY29udGV4dFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5vdGUge1xuICB0ZXh0OiBzdHJpbmc7XG4gIGNyZWF0ZWRBdDogc3RyaW5nO1xufVxuXG4vLyBkZWZpbmVTdGF0ZSBpbiBhbiBleHRlbnNpb24gaXMgYXV0b21hdGljYWxseSBzY29wZWQgdG8gdGhpcyBwYWNrYWdlLCBzbyB0aGVcbi8vIFwibm90ZXNcIiBrZXkgbmV2ZXIgY29sbGlkZXMgd2l0aCB0aGUgY29uc3VtaW5nIGFnZW50IG9yIGFub3RoZXIgZXh0ZW5zaW9uLlxuZXhwb3J0IGNvbnN0IG5vdGVzID0gZGVmaW5lU3RhdGU8Tm90ZVtdPihcIm5vdGVzXCIsICgpID0+IFtdKTtcbiIsImltcG9ydCB7IGRlZmluZVRvb2wgfSBmcm9tIFwiZXZlL3Rvb2xzXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQgZXh0ZW5zaW9uIGZyb20gXCIuLi9leHRlbnNpb25cIjtcbmltcG9ydCB7IG5vdGVzIH0gZnJvbSBcIi4uL2xpYi9zdG9yZVwiO1xuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVUb29sKHtcbiAgZGVzY3JpcHRpb246IFwiU2F2ZSBhIHNob3J0IG5vdGUgdG8gdGhlIGR1cmFibGUgbm90ZXMgbGlzdCBmb3IgbGF0ZXIgcmVjYWxsLlwiLFxuICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgIHRleHQ6IHouc3RyaW5nKCkubWluKDEpLmRlc2NyaWJlKFwiVGhlIG5vdGUgdG8gcmVtZW1iZXIuXCIpLFxuICB9KSxcbiAgYXN5bmMgZXhlY3V0ZSh7IHRleHQgfSkge1xuICAgIGNvbnN0IHsgbWF4Tm90ZXMgfSA9IGV4dGVuc2lvbi5jb25maWc7XG4gICAgaWYgKG5vdGVzLmdldCgpLmxlbmd0aCA+PSBtYXhOb3Rlcykge1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlIGFzIGNvbnN0LCByZWFzb246IGBub3RlIGxpbWl0IHJlYWNoZWQgKCR7bWF4Tm90ZXN9KWAgfTtcbiAgICB9XG4gICAgbm90ZXMudXBkYXRlKChsaXN0KSA9PiBbLi4ubGlzdCwgeyB0ZXh0LCBjcmVhdGVkQXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSB9XSk7XG4gICAgcmV0dXJuIHsgb2s6IHRydWUgYXMgY29uc3QsIGNvdW50OiBub3Rlcy5nZXQoKS5sZW5ndGggfTtcbiAgfSxcbn0pO1xuIiwiaW1wb3J0IHsgZGVmaW5lVG9vbCB9IGZyb20gXCJldmUvdG9vbHNcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IG5vdGVzIH0gZnJvbSBcIi4uL2xpYi9zdG9yZVwiO1xuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVUb29sKHtcbiAgZGVzY3JpcHRpb246IFwiRGVsZXRlIGFsbCBzYXZlZCBub3RlcyBhbmQgcmVwb3J0IGhvdyBtYW55IHdlcmUgcmVtb3ZlZC5cIixcbiAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHt9KSxcbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICBjb25zdCBjbGVhcmVkID0gbm90ZXMuZ2V0KCkubGVuZ3RoO1xuICAgIG5vdGVzLnVwZGF0ZSgoKSA9PiBbXSk7XG4gICAgcmV0dXJuIHsgY2xlYXJlZCB9O1xuICB9LFxufSk7XG4iLCJpbXBvcnQgeyBkZWZpbmVUb29sIH0gZnJvbSBcImV2ZS90b29sc1wiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgbm90ZXMgfSBmcm9tIFwiLi4vbGliL3N0b3JlXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGRlZmluZVRvb2woe1xuICBkZXNjcmlwdGlvbjogXCJMaXN0IGV2ZXJ5IHNhdmVkIG5vdGUsIG9sZGVzdCBmaXJzdC5cIixcbiAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHt9KSxcbiAgYXN5bmMgZXhlY3V0ZSgpIHtcbiAgICBjb25zdCBsaXN0ID0gbm90ZXMuZ2V0KCk7XG4gICAgcmV0dXJuIHsgY291bnQ6IGxpc3QubGVuZ3RoLCBub3RlczogbGlzdCB9O1xuICB9LFxufSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUdBLElBQUEsb0JBQUEsa0JBQUEsRUFBQSxRQUFBLEVBQUEsT0FBQSxFQUFBLFVBQUEsRUFBQSxPQUFBLENBQUEsQ0FBQSxJQUFBLENBQUEsQ0FBQSxTQUFBLENBQUEsQ0FBQSxRQUFBLEVBQUEsRUFBQSxDQUFBLEVBQUEsQ0FBQTs7Ozs7Ozs7QUNNQSxNQUFBLFFBQUEsY0FBQSxlQUFBLENBQUEsQ0FBQTs7O0FDSEEsSUFBQSxtQkFBQSxXQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFhQSxDQUFBOzs7QUNkQSxJQUFBLHNCQUFBLFdBQUE7Ozs7Ozs7O0FBUUEsQ0FBQTs7O0FDUkEsSUFBQSxxQkFBQSxXQUFBOzs7Ozs7Ozs7O0FBT0EsQ0FBQSJ9
@@ -0,0 +1,8 @@
1
+ import { defineExtension } from "eve/extension";
2
+ import { z } from "zod";
3
+
4
+ export default defineExtension({
5
+ config: z.object({
6
+ maxNotes: z.number().int().positive().default(50),
7
+ }),
8
+ });
@@ -0,0 +1,18 @@
1
+ import { defineHook } from "eve/hooks";
2
+ import { toolResultFrom } from "eve/tools";
3
+
4
+ import addNote from "../tools/add_note";
5
+
6
+ // Observe-only: log every successful note save. `toolResultFrom` keys off the
7
+ // tool definition, so it matches the namespaced result (`<mount>__add_note`)
8
+ // regardless of how the consuming agent names the mount.
9
+ export default defineHook({
10
+ events: {
11
+ "action.result"(event) {
12
+ const saved = toolResultFrom(event.data.result, addNote);
13
+ if (saved?.output.ok) {
14
+ console.info("[notes] saved note", { count: saved.output.count });
15
+ }
16
+ },
17
+ },
18
+ });
@@ -0,0 +1,3 @@
1
+ When the user shares something worth remembering, save it with the notes tools.
2
+ Recall saved notes with `list_notes`, and load the `daily-standup` skill when
3
+ they ask for a summary of what they noted.
@@ -0,0 +1,10 @@
1
+ import { defineState } from "eve/context";
2
+
3
+ export interface Note {
4
+ text: string;
5
+ createdAt: string;
6
+ }
7
+
8
+ // defineState in an extension is automatically scoped to this package, so the
9
+ // "notes" key never collides with the consuming agent or another extension.
10
+ export const notes = defineState<Note[]>("notes", () => []);
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Turn the saved notes into a concise daily standup summary.
3
+ ---
4
+
5
+ # Daily standup
6
+
7
+ Use this when the user asks for a standup, daily summary, or "what did I note".
8
+
9
+ 1. Call `list_notes` to retrieve every saved note.
10
+ 2. If there are no notes, say so plainly and stop — do not invent activity.
11
+ 3. Otherwise, group the notes into three sections, inferring placement from each
12
+ note's wording:
13
+ - **Done** — completed work.
14
+ - **In progress** — ongoing work.
15
+ - **Blockers / next** — anything that reads as stuck, waiting, or a to-do.
16
+ 4. Render each section as a short bullet list. Keep the original wording; do not
17
+ embellish. Omit a section that has no matching notes.
18
+ 5. End with a one-line count, e.g. "5 notes since <earliest createdAt>".
@@ -0,0 +1,20 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+
4
+ import extension from "../extension";
5
+ import { notes } from "../lib/store";
6
+
7
+ export default defineTool({
8
+ description: "Save a short note to the durable notes list for later recall.",
9
+ inputSchema: z.object({
10
+ text: z.string().min(1).describe("The note to remember."),
11
+ }),
12
+ async execute({ text }) {
13
+ const { maxNotes } = extension.config;
14
+ if (notes.get().length >= maxNotes) {
15
+ return { ok: false as const, reason: `note limit reached (${maxNotes})` };
16
+ }
17
+ notes.update((list) => [...list, { text, createdAt: new Date().toISOString() }]);
18
+ return { ok: true as const, count: notes.get().length };
19
+ },
20
+ });
@@ -0,0 +1,14 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+
4
+ import { notes } from "../lib/store";
5
+
6
+ export default defineTool({
7
+ description: "Delete all saved notes and report how many were removed.",
8
+ inputSchema: z.object({}),
9
+ async execute() {
10
+ const cleared = notes.get().length;
11
+ notes.update(() => []);
12
+ return { cleared };
13
+ },
14
+ });
@@ -0,0 +1,13 @@
1
+ import { defineTool } from "eve/tools";
2
+ import { z } from "zod";
3
+
4
+ import { notes } from "../lib/store";
5
+
6
+ export default defineTool({
7
+ description: "List every saved note, oldest first.",
8
+ inputSchema: z.object({}),
9
+ async execute() {
10
+ const list = notes.get();
11
+ return { count: list.length, notes: list };
12
+ },
13
+ });
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@casey.gowrie/eve-ext-notes",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "eve extension: durable notes toolkit (tools + hook + skill).",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "eve",
9
+ "eve-extension",
10
+ "agent",
11
+ "notes"
12
+ ],
13
+ "eve": {
14
+ "extension": "./ext"
15
+ },
16
+ "files": [
17
+ "ext",
18
+ "dist"
19
+ ],
20
+ "peerDependencies": {
21
+ "eve": "^0.22.3"
22
+ },
23
+ "dependencies": {
24
+ "zod": "^4.4.3"
25
+ },
26
+ "devDependencies": {
27
+ "eve": "^0.22.3",
28
+ "typescript": "^5",
29
+ "@types/node": "^22"
30
+ },
31
+ "scripts": {
32
+ "build": "eve build",
33
+ "prepare": "eve build"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "exports": {
39
+ ".": {
40
+ "types": "./dist/index.d.ts",
41
+ "default": "./dist/index.mjs"
42
+ },
43
+ "./tools": {
44
+ "types": "./dist/tools/index.d.ts",
45
+ "default": "./dist/tools/index.mjs"
46
+ }
47
+ }
48
+ }