@pattern-js/mod-buddy 0.4.0-main.c8eb671

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.
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @pattern-js/mod-buddy — thread persistence.
3
+ *
4
+ * One thread per (workflow slug, owner): the dock reloads it on mount, the
5
+ * turn pipeline replaces its messages with the agent's updated history after
6
+ * every turn (CAS-retried). mod-store is duck-typed via its well-known
7
+ * "storeService" key — when absent, Buddy degrades gracefully to stateless
8
+ * turns (the dock still works; memory just doesn't survive a reload).
9
+ */
10
+ export const THREADS = "buddy.threads";
11
+ const STORE_SERVICE = "storeService";
12
+ function docsOf(services) {
13
+ const svc = services[STORE_SERVICE];
14
+ return svc?.docs && typeof svc.docs.get === "function" ? svc.docs : null;
15
+ }
16
+ export function ownerOf(principal) {
17
+ return principal.kind === "user" ? principal.id : "anonymous";
18
+ }
19
+ const threadId = (slug, ownerId) => `${ownerId}::${slug}`;
20
+ // Per-store (not per-process): tests boot several engines, each with its own store.
21
+ const ensured = new WeakSet();
22
+ async function ensure(docs) {
23
+ if (ensured.has(docs))
24
+ return;
25
+ await docs.ensureCollection({ name: THREADS, indexes: ["slug", "ownerId"] });
26
+ ensured.add(docs);
27
+ }
28
+ /** The thread's messages (empty when no store / no thread yet). */
29
+ export async function loadThread(ctx, slug) {
30
+ const docs = docsOf(ctx.services);
31
+ if (!docs)
32
+ return [];
33
+ await ensure(docs);
34
+ const row = await docs.get(THREADS, threadId(slug, ownerOf(ctx.principal)));
35
+ const messages = row?.data?.messages;
36
+ return Array.isArray(messages) ? messages : [];
37
+ }
38
+ /** Replace the thread's messages with the turn's updated history (CAS-retried). */
39
+ export async function saveThread(ctx, slug, messages) {
40
+ const docs = docsOf(ctx.services);
41
+ if (!docs)
42
+ return false;
43
+ await ensure(docs);
44
+ const ownerId = ownerOf(ctx.principal);
45
+ const id = threadId(slug, ownerId);
46
+ const data = { slug, ownerId, messages, updatedAt: Date.now() };
47
+ for (let attempt = 0; attempt < 5; attempt++) {
48
+ const existing = await docs.get(THREADS, id);
49
+ const written = await docs.put(THREADS, id, data, existing?.version);
50
+ if (written)
51
+ return true;
52
+ }
53
+ console.warn(`[pattern/mod-buddy] thread "${id}": CAS save kept losing — dropping this turn's history`);
54
+ return false;
55
+ }
56
+ export async function clearThread(ctx, slug) {
57
+ const docs = docsOf(ctx.services);
58
+ if (!docs)
59
+ return false;
60
+ await ensure(docs);
61
+ return docs.delete(THREADS, threadId(slug, ownerOf(ctx.principal)));
62
+ }
63
+ /** Whether persistence is available (the dock's status probe reports it). */
64
+ export function hasThreadStore(services) {
65
+ return docsOf(services) !== null;
66
+ }
67
+ //# sourceMappingURL=threads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threads.js","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @pattern-js/mod-buddy — the pattern_* control-plane tools.
3
+ *
4
+ * Ten RESTRICTED `boundary.tool` workflows — the one capability layer both
5
+ * Buddy (in-admin) and external MCP clients consume. Bodies are ordinary
6
+ * graphs over the existing admin/docs ops, so every tool call is a
7
+ * traced, linked sub-run you can open on the canvas, and the admin ops
8
+ * re-check the caller's granular scope in-op (workflows:read/write,
9
+ * runs:read/write, deploy). `restricted: true` keeps them out of every
10
+ * `["*"]` toolset/MCP expansion — they are offered only by name.
11
+ */
12
+ import type { Workflow } from "@pattern-js/core";
13
+ /** The ten control-plane tools, in reading order of a typical Buddy session. */
14
+ export declare const CONTROL_PLANE_TOOLS: string[];
15
+ export declare function toolWorkflows(): Workflow[];
16
+ /**
17
+ * The Pattern MCP server route: POST /mcp/pattern, gated by requireAuth
18
+ * (workflows:read is the entry floor — each tool's admin ops then re-check
19
+ * their own granular scope against the SAME bearer principal, which flows
20
+ * through ctx.invoke into the tool sub-runs). Exposes exactly the ten
21
+ * control-plane tools by name — restricted tools never ride a wildcard.
22
+ */
23
+ export declare function patternMcpServerWorkflow(path?: string): Workflow;
24
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAmFjD,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAWvC,CAAC;AAEF,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAwI1C;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,SAAiB,GAAG,QAAQ,CA6BxE"}
package/dist/tools.js ADDED
@@ -0,0 +1,251 @@
1
+ /**
2
+ * @pattern-js/mod-buddy — the pattern_* control-plane tools.
3
+ *
4
+ * Ten RESTRICTED `boundary.tool` workflows — the one capability layer both
5
+ * Buddy (in-admin) and external MCP clients consume. Bodies are ordinary
6
+ * graphs over the existing admin/docs ops, so every tool call is a
7
+ * traced, linked sub-run you can open on the canvas, and the admin ops
8
+ * re-check the caller's granular scope in-op (workflows:read/write,
9
+ * runs:read/write, deploy). `restricted: true` keeps them out of every
10
+ * `["*"]` toolset/MCP expansion — they are offered only by name.
11
+ */
12
+ /** trigger → (extract) → op → (build) → return, laid out left to right. */
13
+ function toolWorkflow(spec) {
14
+ const nodes = [
15
+ {
16
+ id: "in",
17
+ op: "boundary.tool",
18
+ config: {
19
+ name: spec.name,
20
+ description: spec.description,
21
+ params: { type: "object", properties: spec.params, ...(spec.required?.length ? { required: spec.required } : {}) },
22
+ restricted: true,
23
+ ...(spec.needsApproval ? { needsApproval: true } : {}),
24
+ },
25
+ ui: { x: 60, y: 120, pair: "out" },
26
+ },
27
+ { id: "op", op: spec.op, ui: { x: 620, y: 120 } },
28
+ { id: "out", op: "boundary.tool.return", ui: { x: 1180, y: 120, pair: "in" } },
29
+ ];
30
+ const edges = [];
31
+ if (spec.extract.length) {
32
+ nodes.splice(1, 0, {
33
+ id: "args",
34
+ op: "core.object.extract",
35
+ config: { keys: spec.extract },
36
+ comment: "Fan the validated tool args out into the op's input ports.",
37
+ ui: { x: 340, y: 120 },
38
+ });
39
+ edges.push({ from: { node: "in", port: "args" }, to: { node: "args", port: "object" } });
40
+ for (const key of spec.extract) {
41
+ edges.push({ from: { node: "args", port: key }, to: { node: "op", port: key } });
42
+ }
43
+ }
44
+ else {
45
+ // No data flows from the trigger — a control edge threads reachability.
46
+ edges.push({ from: { node: "in", port: "out" }, to: { node: "op", port: "in" } });
47
+ }
48
+ if (typeof spec.out === "string") {
49
+ edges.push({ from: { node: "op", port: spec.out }, to: { node: "out", port: "result" } });
50
+ }
51
+ else {
52
+ nodes.splice(nodes.length - 1, 0, {
53
+ id: "combine",
54
+ op: "core.object.build",
55
+ config: { keys: spec.out },
56
+ ui: { x: 900, y: 120 },
57
+ });
58
+ for (const port of spec.out) {
59
+ edges.push({ from: { node: "op", port }, to: { node: "combine", port } });
60
+ }
61
+ edges.push({ from: { node: "combine", port: "out" }, to: { node: "out", port: "result" } });
62
+ }
63
+ return {
64
+ id: spec.id,
65
+ name: `Buddy · ${spec.name}`,
66
+ description: `${spec.description} (restricted control-plane tool — offered only by explicit name)`,
67
+ nodes,
68
+ edges,
69
+ };
70
+ }
71
+ const docSchema = { type: "object", description: "A full workflow document ({ id, nodes, edges })." };
72
+ /** The ten control-plane tools, in reading order of a typical Buddy session. */
73
+ export const CONTROL_PLANE_TOOLS = [
74
+ "pattern_list_ops",
75
+ "pattern_get_op",
76
+ "pattern_search_docs",
77
+ "pattern_get_workflow",
78
+ "pattern_validate_workflow",
79
+ "pattern_propose_workflow",
80
+ "pattern_save_workflow_draft",
81
+ "pattern_deploy_workflow",
82
+ "pattern_list_runs",
83
+ "pattern_get_run",
84
+ ];
85
+ export function toolWorkflows() {
86
+ return [
87
+ toolWorkflow({
88
+ id: "buddy.tool.list-ops",
89
+ name: "pattern_list_ops",
90
+ description: "List every op available in this app (type, ports, category, contributing mod — schemas trimmed). " +
91
+ "Call pattern_get_op for one op's full config schema and usage prose.",
92
+ params: {},
93
+ extract: [],
94
+ op: "docs.ops.list",
95
+ out: "ops",
96
+ }),
97
+ toolWorkflow({
98
+ id: "buddy.tool.get-op",
99
+ name: "pattern_get_op",
100
+ description: "One op's full definition: ports, config JSON Schema, and the handbook's usage prose.",
101
+ params: { type: { type: "string", description: 'The op type, e.g. "core.http.fetch".' } },
102
+ required: ["type"],
103
+ extract: ["type"],
104
+ op: "docs.ops.get",
105
+ out: "op",
106
+ }),
107
+ toolWorkflow({
108
+ id: "buddy.tool.search-docs",
109
+ name: "pattern_search_docs",
110
+ description: "Search the Pattern handbook and op catalog. Returns [{ title, path, snippet, score }] — " +
111
+ "use it before proposing a workflow to ground yourself in the house patterns.",
112
+ params: {
113
+ query: { type: "string", description: "What you want to know." },
114
+ k: { type: "number", description: "Max results (default 6)." },
115
+ },
116
+ required: ["query"],
117
+ extract: ["query", "k"],
118
+ op: "buddy.knowledge.search",
119
+ out: "results",
120
+ }),
121
+ toolWorkflow({
122
+ id: "buddy.tool.get-workflow",
123
+ name: "pattern_get_workflow",
124
+ description: "A workflow's meta (versions, live pointer, audit) + its live and latest-saved documents.",
125
+ params: { slug: { type: "string", description: "The workflow slug/id." } },
126
+ required: ["slug"],
127
+ extract: ["slug"],
128
+ op: "admin.workflow.get",
129
+ out: "workflow",
130
+ }),
131
+ toolWorkflow({
132
+ id: "buddy.tool.validate-workflow",
133
+ name: "pattern_validate_workflow",
134
+ description: "Validate a workflow document WITHOUT saving: { ok, issues } with located errors (nodeId + code). " +
135
+ "Iterate until ok before proposing or saving.",
136
+ params: { doc: docSchema },
137
+ required: ["doc"],
138
+ extract: ["doc"],
139
+ op: "admin.workflow.validate",
140
+ out: "result",
141
+ }),
142
+ toolWorkflow({
143
+ id: "buddy.tool.propose-workflow",
144
+ name: "pattern_propose_workflow",
145
+ description: "Propose a workflow doc to the human: it is validated here, and — when ok — surfaces as an Apply card " +
146
+ "in the editor dock (the human applies it to the canvas; nothing is saved or deployed). " +
147
+ "Include a one-sentence summary of what the workflow does and what changed.",
148
+ params: {
149
+ doc: docSchema,
150
+ summary: { type: "string", description: "One sentence: what this workflow does / what changed." },
151
+ slug: { type: "string", description: "Target workflow slug when editing an existing one." },
152
+ },
153
+ required: ["doc", "summary"],
154
+ extract: ["doc"],
155
+ op: "admin.workflow.validate",
156
+ out: "result",
157
+ }),
158
+ toolWorkflow({
159
+ id: "buddy.tool.save-workflow-draft",
160
+ name: "pattern_save_workflow_draft",
161
+ description: "Validate + save a doc as a new immutable DRAFT version (never deploys). Invalid docs are refused — " +
162
+ "you get { issues } back instead of a version.",
163
+ params: {
164
+ slug: { type: "string", description: "The workflow slug to save under." },
165
+ doc: docSchema,
166
+ note: { type: "string", description: "Short version note (what changed)." },
167
+ },
168
+ required: ["slug", "doc"],
169
+ extract: ["slug", "doc", "note"],
170
+ op: "admin.workflow.save",
171
+ out: ["version", "issues"],
172
+ }),
173
+ toolWorkflow({
174
+ id: "buddy.tool.deploy-workflow",
175
+ name: "pattern_deploy_workflow",
176
+ description: "Activate a saved version (route-conflict checked). Requires the deploy scope; agent calls pause for " +
177
+ "human approval. Pass swap=true to take over conflicting routes.",
178
+ params: {
179
+ slug: { type: "string" },
180
+ version: { type: "string", description: "The version id to activate." },
181
+ swap: { type: "boolean", description: "Take over route conflicts (default false)." },
182
+ },
183
+ required: ["slug", "version"],
184
+ extract: ["slug", "version", "swap"],
185
+ op: "admin.workflow.deploy",
186
+ out: "result",
187
+ needsApproval: true,
188
+ }),
189
+ toolWorkflow({
190
+ id: "buddy.tool.list-runs",
191
+ name: "pattern_list_runs",
192
+ description: "Recent runs from the trace store — filter by workflow slug and/or status (ok | error | canceled).",
193
+ params: {
194
+ workflow: { type: "string", description: "Only this workflow's runs." },
195
+ status: { type: "string", description: "ok | error | canceled" },
196
+ limit: { type: "number", description: "Max rows (default 50)." },
197
+ },
198
+ extract: ["workflow", "status", "limit"],
199
+ op: "admin.run.list",
200
+ out: "runs",
201
+ }),
202
+ toolWorkflow({
203
+ id: "buddy.tool.get-run",
204
+ name: "pattern_get_run",
205
+ description: "One run's full trace: per-node spans with status, timings, error messages/stacks, and masked I/O " +
206
+ "samples — everything needed to answer \"why did this run fail?\".",
207
+ params: { runId: { type: "string" } },
208
+ required: ["runId"],
209
+ extract: ["runId"],
210
+ op: "admin.run.get",
211
+ out: "run",
212
+ }),
213
+ ];
214
+ }
215
+ /**
216
+ * The Pattern MCP server route: POST /mcp/pattern, gated by requireAuth
217
+ * (workflows:read is the entry floor — each tool's admin ops then re-check
218
+ * their own granular scope against the SAME bearer principal, which flows
219
+ * through ctx.invoke into the tool sub-runs). Exposes exactly the ten
220
+ * control-plane tools by name — restricted tools never ride a wildcard.
221
+ */
222
+ export function patternMcpServerWorkflow(path = "/mcp/pattern") {
223
+ return {
224
+ id: "buddy.mcp.server",
225
+ name: `Buddy · Pattern MCP server (POST ${path})`,
226
+ description: "Exposes the pattern_* control-plane tools to external MCP clients (Claude Code, Cursor, …) over " +
227
+ "StreamableHTTP JSON-RPC. Gated by API tokens (mint them in admin → Access → API tokens); a token's " +
228
+ "scopes decide which calls succeed — authoring tokens can draft, only deploy-scoped tokens can ship.",
229
+ nodes: [
230
+ {
231
+ id: "in",
232
+ op: "boundary.http.request",
233
+ config: { method: "POST", path, requireAuth: { scopes: ["workflows:read"] } },
234
+ ui: { x: 60, y: 120, pair: "out" },
235
+ },
236
+ {
237
+ id: "serve",
238
+ op: "ai.mcp.serve",
239
+ config: { name: "pattern", tools: CONTROL_PLANE_TOOLS },
240
+ comment: "The ten pattern_* tools, by explicit name — wildcards never expose restricted tools.",
241
+ ui: { x: 340, y: 120 },
242
+ },
243
+ { id: "out", op: "boundary.http.response", ui: { x: 620, y: 120, pair: "in" } },
244
+ ],
245
+ edges: [
246
+ { from: { node: "in", port: "body" }, to: { node: "serve", port: "request" } },
247
+ { from: { node: "serve", port: "response" }, to: { node: "out", port: "body" } },
248
+ ],
249
+ };
250
+ }
251
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/turn.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @pattern-js/mod-buddy — the turn pipeline (Buddy's backend half).
3
+ *
4
+ * POST /buddy/api/turn → buddy.turn.begin (thread + instructions + model) →
5
+ * agents.agent + the ten pattern_* tools → agents.run → SSE out, while
6
+ * buddy.turn.save persists the updated history back to the thread. The
7
+ * pipeline is an ordinary editable workflow — Buddy is built from Pattern
8
+ * workflows, all the way down.
9
+ *
10
+ * The dock reads tool calls (incl. proposed docs) straight from the SSE
11
+ * turn events: `tool.activity` carries the tool's name and args.
12
+ */
13
+ import { type OpDefinition, type Workflow } from "@pattern-js/core";
14
+ import type { KnowledgeService } from "./knowledge.js";
15
+ /** The dock's boot probe: what Buddy can do in THIS app. */
16
+ export declare function statusOp(knowledge: () => KnowledgeService): OpDefinition;
17
+ export declare function turnOps(knowledge: () => KnowledgeService): OpDefinition[];
18
+ /** POST /buddy/api/turn → SSE turn events (the dock's one streaming call). */
19
+ export declare function turnPipelineWorkflow(): Workflow;
20
+ /** The dock's plumbing routes (thread load/clear, stop, status). */
21
+ export declare function buddyRoutes(): Workflow[];
22
+ //# sourceMappingURL=turn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn.d.ts","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAA2D,KAAK,YAAY,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAK7H,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA6HvD,4DAA4D;AAC5D,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,gBAAgB,GAAG,YAAY,CAoBxE;AAED,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,gBAAgB,GAAG,YAAY,EAAE,CAEzE;AAMD,8EAA8E;AAC9E,wBAAgB,oBAAoB,IAAI,QAAQ,CA+E/C;AAED,oEAAoE;AACpE,wBAAgB,WAAW,IAAI,QAAQ,EAAE,CAuCxC"}