yams-blackboard 0.1.1 → 1.0.1

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 (3) hide show
  1. package/README.md +5 -4
  2. package/index.js +21 -26
  3. package/package.json +7 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # YAMS Blackboard Plugin for OpenCode
2
2
 
3
- A **blackboard architecture** plugin enabling agent-to-agent communication through [YAMS](https://github.com/yams-project/yams) as shared memory.
3
+ A **blackboard architecture** plugin enabling agent-to-agent communication through [YAMS](https://github.com/trvon/yams) as shared memory.
4
4
 
5
5
  ## Overview
6
6
 
@@ -24,7 +24,7 @@ This plugin implements the classic [blackboard pattern](https://en.wikipedia.org
24
24
 
25
25
  ## Prerequisites
26
26
 
27
- - **YAMS daemon** must be installed and running
27
+ - **[YAMS](https://github.com/trvon/yams)** - must be installed and daemon running
28
28
  - **bun** (for local development/building)
29
29
  - **OpenCode** v1.1.0+ (for plugin support)
30
30
 
@@ -36,7 +36,8 @@ Add to your `opencode.json`:
36
36
 
37
37
  ```json
38
38
  {
39
- "plugins": ["yams-blackboard"]
39
+ "$schema": "https://opencode.ai/config.json",
40
+ "plugin": ["yams-blackboard"]
40
41
  }
41
42
  ```
42
43
 
@@ -255,7 +256,7 @@ YAMS must be installed and in your PATH. Check your installation.
255
256
 
256
257
  ### Plugin not loading
257
258
 
258
- 1. Verify `opencode.json` has `"plugins": ["yams-blackboard"]`
259
+ 1. Verify `opencode.json` has `"plugin": ["yams-blackboard"]`
259
260
  2. Check OpenCode logs for plugin load errors
260
261
  3. Try clearing npm cache: `npm cache clean --force`
261
262
 
package/index.js CHANGED
@@ -34,19 +34,17 @@ class YamsBlackboard {
34
34
  if (typeof result === "string") {
35
35
  return result.trim();
36
36
  }
37
- if (this.isBufferLike(result)) {
38
- return result.toString("utf-8").trim();
39
- }
40
37
  if (result && typeof result === "object") {
41
- const output = result.stdout ?? result.output ?? result.text;
42
- if (typeof output === "string") {
43
- return output.trim();
38
+ let raw = result.stdout ?? result.output ?? result.text;
39
+ if (raw instanceof Uint8Array || Buffer.isBuffer(raw)) {
40
+ return new TextDecoder().decode(raw).trim();
44
41
  }
45
- if (this.isBufferLike(output)) {
46
- return output.toString("utf-8").trim();
42
+ if (typeof raw === "string") {
43
+ return raw.trim();
47
44
  }
48
- if (typeof output === "function") {
49
- return (await output()).trim();
45
+ if (typeof raw === "function") {
46
+ const text = await raw();
47
+ return typeof text === "string" ? text.trim() : String(text).trim();
50
48
  }
51
49
  }
52
50
  return String(result ?? "").trim();
@@ -337,7 +335,7 @@ ${finding.content}
337
335
  }
338
336
  }
339
337
  async getReadyTasks(agentCapabilities) {
340
- const pending = await this.queryTasks({ status: "pending", limit: 100 });
338
+ const pending = await this.queryTasks({ status: "pending", limit: 100, offset: 0 });
341
339
  const ready = [];
342
340
  for (const task of pending) {
343
341
  if (task.depends_on?.length) {
@@ -405,8 +403,8 @@ ${finding.content}
405
403
  }
406
404
  }
407
405
  async getContextSummary(contextId) {
408
- const findings = await this.queryFindings({ context_id: contextId, limit: 100 });
409
- const tasks = await this.queryTasks({ context_id: contextId, limit: 100 });
406
+ const findings = await this.queryFindings({ context_id: contextId, limit: 100, offset: 0 });
407
+ const tasks = await this.queryTasks({ context_id: contextId, limit: 100, offset: 0 });
410
408
  const agents = await this.listAgents();
411
409
  const activeAgents = agents.filter((a) => a.status === "active");
412
410
  const highSeverity = findings.filter((f) => f.severity === "high" || f.severity === "critical");
@@ -450,8 +448,8 @@ ${blockedTasks.length ? `- ${blockedTasks.length} tasks blocked` : ""}
450
448
  }
451
449
  async getStats() {
452
450
  const agents = await this.listAgents();
453
- const findings = await this.queryFindings({ limit: 1000 });
454
- const tasks = await this.queryTasks({ limit: 1000 });
451
+ const findings = await this.queryFindings({ limit: 1000, offset: 0 });
452
+ const tasks = await this.queryTasks({ limit: 1000, offset: 0 });
455
453
  const findingsByTopic = {};
456
454
  const findingsByStatus = {};
457
455
  const findingsBySeverity = {};
@@ -533,7 +531,7 @@ var FindingSchema = z.object({
533
531
  resolution: z.string().optional().describe("How it was resolved"),
534
532
  scope: FindingScope.default("persistent"),
535
533
  ttl: z.number().int().positive().optional().describe("TTL in seconds for session-scoped"),
536
- metadata: z.record(z.string()).optional()
534
+ metadata: z.record(z.string(), z.string()).optional()
537
535
  });
538
536
  var CreateFindingSchema = FindingSchema.omit({
539
537
  id: true,
@@ -587,7 +585,7 @@ var TaskSchema = z.object({
587
585
  error: z.string().optional().describe("Error message if failed"),
588
586
  retry_count: z.number().int().nonnegative().optional(),
589
587
  max_retries: z.number().int().nonnegative().optional(),
590
- metadata: z.record(z.string()).optional()
588
+ metadata: z.record(z.string(), z.string()).optional()
591
589
  });
592
590
  var CreateTaskSchema = TaskSchema.omit({
593
591
  id: true,
@@ -635,21 +633,18 @@ var TaskQuerySchema = z.object({
635
633
 
636
634
  // index.ts
637
635
  var YamsBlackboardPlugin = async ({ $, project, directory }) => {
638
- let blackboard = new YamsBlackboard($, { defaultScope: "persistent" });
636
+ const blackboard = new YamsBlackboard($, { defaultScope: "persistent" });
639
637
  let currentContextId;
640
638
  return {
641
639
  "session.created": async () => {
642
- const sessionName = await blackboard.startSession();
643
- console.log(`[yams-blackboard] Session started: ${sessionName}`);
640
+ await blackboard.startSession();
644
641
  },
645
642
  "session.compacted": async (input, output) => {
646
643
  try {
647
644
  const contextId = currentContextId || "default";
648
645
  const summary = await blackboard.getContextSummary(contextId);
649
646
  output.context.push(summary);
650
- } catch (e) {
651
- console.error("[yams-blackboard] Failed to generate compaction summary:", e);
652
- }
647
+ } catch {}
653
648
  },
654
649
  tool: {
655
650
  bb_register_agent: tool({
@@ -705,7 +700,7 @@ Registered at: ${agent.registered_at}`;
705
700
  context_id: z2.string().optional().describe("Group with related findings"),
706
701
  parent_id: z2.string().optional().describe("Reply to another finding"),
707
702
  scope: FindingScope.optional().describe("Persistence: 'persistent' (default) or 'session'"),
708
- metadata: z2.record(z2.string()).optional().describe("Additional key-value metadata")
703
+ metadata: z2.record(z2.string(), z2.string()).optional().describe("Additional key-value metadata")
709
704
  },
710
705
  async execute(args) {
711
706
  const finding = await blackboard.postFinding({
@@ -1016,8 +1011,8 @@ ${args.set_current !== false ? "(Set as current context)" : ""}`;
1016
1011
  },
1017
1012
  async execute(args) {
1018
1013
  const limit = args.limit || 10;
1019
- const findings = await blackboard.queryFindings({ limit });
1020
- const tasks = await blackboard.queryTasks({ limit });
1014
+ const findings = await blackboard.queryFindings({ limit, offset: 0 });
1015
+ const tasks = await blackboard.queryTasks({ limit, offset: 0 });
1021
1016
  const output = [`## Recent Activity
1022
1017
  `];
1023
1018
  if (findings.length > 0) {
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "yams-blackboard",
3
- "version": "0.1.1",
3
+ "version": "1.0.1",
4
4
  "description": "YAMS Blackboard plugin for OpenCode - agent-to-agent communication via shared memory",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
7
7
  "type": "module",
8
8
  "scripts": {
9
9
  "build": "bun build index.ts --outdir . --target node --external zod --external @opencode-ai/plugin",
10
- "typecheck": "tsc --noEmit"
10
+ "typecheck": "tsc --noEmit",
11
+ "test": "bun test __tests__/plugin.test.ts __tests__/blackboard.test.ts",
12
+ "test:integration": "YAMS_INTEGRATION=1 bun test __tests__/integration.test.ts",
13
+ "test:all": "bun test"
11
14
  },
12
15
  "files": [
13
16
  "index.js",
@@ -16,9 +19,10 @@
16
19
  ],
17
20
  "dependencies": {
18
21
  "@opencode-ai/plugin": "^1.1.0",
19
- "zod": "^3.23.0"
22
+ "zod": "^4.1.8"
20
23
  },
21
24
  "devDependencies": {
25
+ "bun-types": "^1.1.0",
22
26
  "typescript": "^5.0.0"
23
27
  },
24
28
  "keywords": [