@snarkipus/opencode-beads 1.1.0-beta.3 → 1.1.0-beta.5

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
@@ -11,7 +11,7 @@
11
11
 
12
12
  This is an independent project maintained by Matt Jackson under the MIT license. It began as a fork of [Josh Thomas's `opencode-beads`](https://github.com/joshuadavidthomas/opencode-beads), and the original work remains credited to its author. 1.0 rebuilt the plugin for OpenCode 2, and development now continues here independently. It vendors nothing from upstream Beads; instead, every Beads release is checked against the `bd` behavior the plugin relies on (see [Tracking upstream Beads](#tracking-upstream-beads)).
13
13
 
14
- This release is **1.1.0-beta.3**, an opt-in beta targeting npm dist-tag `next`; its integration diagnostic command is `oc-beads:diagnostics`. Beta.1 used `oc-beads:status`; the rename is documented below. The beta's normal public entrypoint enables the eleven qualified operations in the native `beads` code-mode namespace on supported hosts: find, get, edges, memories, recall, claim, note, selected-field update, close, create and remember. No wrapper, internal dependency injection, manual skill copy or activation setting is needed. The opt-in is selecting the beta artifact. The published stable 1.0.2 package is unchanged.
14
+ This release is **1.1.0-beta.5**, an opt-in beta targeting npm dist-tag `next`; its integration diagnostic command is `oc-beads:diagnostics`. Beta.1 used `oc-beads:status`; the rename is documented below. The beta's normal public entrypoint enables the eleven qualified operations in the native `beads` code-mode namespace on supported hosts: find, get, edges, memories, recall, claim, note, selected-field update, close, create and remember. No wrapper, internal dependency injection, manual skill copy or activation setting is needed. The opt-in is selecting the beta artifact. The published stable 1.0.2 package is unchanged.
15
15
 
16
16
  The beta registers 29 `oc-beads:<stem>` workflows plus `oc-beads:diagnostics` through ordinary native command registration and owns its packaged `oc-beads` skill at the installed path, with all 15 corpus resources plus CODE_MODE and ADR (17 links). User configuration/file commands retain native precedence on load and rebuild; removing an override restores the package definition. Other plugin conflicts follow native ordering. Diagnostics reports observed registration and name/description mismatches; identical-description overrides and public owner identity remain unobservable.
17
17
 
@@ -45,7 +45,7 @@ The beta requires OpenCode `>=2.1.1 <2.2` and `bd` 1.3.1 or later. Exact OpenCod
45
45
 
46
46
  ```json
47
47
  {
48
- "plugins": ["@snarkipus/opencode-beads@1.1.0-beta.3"]
48
+ "plugins": ["@snarkipus/opencode-beads@1.1.0-beta.5"]
49
49
  }
50
50
  ```
51
51
 
@@ -63,7 +63,7 @@ Plugin options use the object form:
63
63
  {
64
64
  "plugins": [
65
65
  {
66
- "package": "@snarkipus/opencode-beads@1.1.0-beta.3",
66
+ "package": "@snarkipus/opencode-beads@1.1.0-beta.5",
67
67
  "options": { "luna": true, "autoMigrate": false }
68
68
  }
69
69
  ]
@@ -131,6 +131,22 @@ explicit modes and parent acceptance still apply. Guide/report commands produce
131
131
  their advertised artifact. This action-contract correction starts with beta.3;
132
132
  earlier beta artifacts do not contain this correction.
133
133
 
134
+ Beta.4 keeps all 29 `/oc-beads:<workflow>` invocations compact, with
135
+ single-line free text inline and multiline text below, preserving whitespace.
136
+ Full static instructions live in durable `ocBeadsWorkflow` message metadata,
137
+ expanded by existing primary and compaction hooks; retained `ocBeadsSync` v1
138
+ history remains readable. Attachments/skills, prompt hooks and native delivery
139
+ remain normal inputs. Starting with beta.5, diagnostics also uses compact history:
140
+ its dynamic observed report is captured once into the same metadata/hook path,
141
+ without adding store access. Its answer includes the loaded plugin name/version
142
+ from the installed package manifest alongside the observed OpenCode host version.
143
+ A version label alone is not a unique canary build fingerprint.
144
+ Plugin activation is required for expansion; summaries retain semantic context,
145
+ not guaranteed verbatim snapshots. Native storage/estimates can include copies or
146
+ miss hidden text; this is not a token-savings claim. See the
147
+ [workflow evaluation](docs/workflow-native-context-evaluation.md) and original
148
+ [sync design](docs/sync-native-context-plan.md) / [evaluation](docs/sync-native-context-evaluation.md).
149
+
134
150
  Starting with beta.2, the package-owned `oc-beads:status` is removed without an alias. Use `oc-beads:diagnostics` for integration health and `oc-beads:stats` for the issue-database overview via `bd status` (alias `bd stats`). User-defined old status overrides are untouched and are not migrated; the package does not edit configuration.
135
151
 
136
152
  `oc-beads:compact` guides semantic issue compaction with `bd admin compact`; `bd compact` squashes Dolt history and is a different operation. Neither is conversation compaction. A bare invocation explains the workflow; a sufficiently specified semantic apply request supplies its bounded authority under actual permissions and policy. See the packaged [compact guidance](assets/oc-beads/resources/TROUBLESHOOTING.md) for mode/actor boundaries and upstream help uncertainty. `oc-beads:restore` retrieves pre-compaction issue content, displaying it by default; `--apply` requires explicit authority to write it back and does not mean database backup recovery. Quickstart uses installed help and authorized context; sync guides Dolt-remote synchronization, distinct from `bd federation sync`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snarkipus/opencode-beads",
3
- "version": "1.1.0-beta.3",
3
+ "version": "1.1.0-beta.5",
4
4
  "type": "module",
5
5
  "description": "A maintained OpenCode V2 integration for the Beads issue tracker: bd prime context injection with a schema-migration guard, and a bounded task agent.",
6
6
  "author": "Matt Jackson",
package/src/guidance.ts CHANGED
@@ -73,6 +73,7 @@ Beads workflow context could not be loaded: \`bd prime\` ${reason}. Beads may st
73
73
  /** Added to compaction requests so the summary keeps the Beads work in flight. */
74
74
  export const BEADS_COMPACTION_GUIDANCE = `<beads-compaction>
75
75
  This session tracks work in Beads (bd). Carry acknowledged durable task/memory references, current scope, attempts, blockers, pending validation and known unsaved or uncertain gaps into the summary or native-provider context. A summary is not a Beads write. Do not persist, wait for permission or a queued write, or request a recursive same-session checkpoint during compaction. Earlier meaningful checkpoints support recovery; no final-write guarantee applies. Fresh guarded context is requested after compaction. Preserve host-owned native replay, metadata.keepID and legacy metadata.recent; do not inject result.native.messages or a replacement result to add references.
76
+ Preserve an active /oc-beads workflow invocation's requested outcome, unresolved inputs or explicit modes, and applicable authority limits in the summary.
76
77
  </beads-compaction>`;
77
78
 
78
79
  /** Observed after native request filtering; selective operation permission remains per call. */
package/src/host.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Plugin } from "@opencode/plugin";
2
- import { applyBeadsSkill, createBeadsCommands, loadBeadsSkill, type SkillLoadDependencies } from "./workflows";
2
+ import packageManifest from "../package.json";
3
+ import { applyBeadsSkill, createBeadsCommands, expandBeadsWorkflowContext, loadBeadsSkill, type SkillLoadDependencies } from "./workflows";
3
4
  import { applyBeadsAgents, beadsAgents, BEADS_TASK_AGENTS } from "./agents";
4
5
  import { BEADS_COMPACTION_GUIDANCE, UNKNOWN_CAPABILITIES, type RequestCapabilities } from "./guidance";
5
6
  import {
@@ -254,6 +255,7 @@ export async function setupBeads(
254
255
  try { effectiveSkills = ctx.skill ? (await ctx.skill.list()).data.map((entry) => String(entry.id)) : "unavailable"; }
255
256
  catch { effectiveSkills = "unavailable: registry lookup failed"; }
256
257
  return JSON.stringify({
258
+ plugin: { name: packageManifest.name, version: packageManifest.version },
257
259
  host: hostVersion, admission: SUPPORTED_OPENCODE_RANGE, liveQualification: "not measured by diagnostics; see release acceptance evidence",
258
260
  commands: {
259
261
  registration: commandRegistration,
@@ -334,6 +336,7 @@ export async function setupBeads(
334
336
 
335
337
  registrations.push(await ctx.session.hook("context", async (event) => {
336
338
  if (abort.signal.aborted) return;
339
+ expandBeadsWorkflowContext(event.messages);
337
340
  if (ctx.session.get) {
338
341
  try {
339
342
  const info = await ctx.session.get({ sessionID: event.sessionID });
@@ -373,7 +376,9 @@ export async function setupBeads(
373
376
  }));
374
377
 
375
378
  registrations.push(await ctx.session.hook("compaction", (event) => {
376
- if (!abort.signal.aborted && beadsSessions.get(event.sessionID)?.has(event.agent)) {
379
+ if (abort.signal.aborted) return;
380
+ expandBeadsWorkflowContext(event.messages);
381
+ if (beadsSessions.get(event.sessionID)?.has(event.agent)) {
377
382
  event.system.push({ type: "text", text: BEADS_COMPACTION_GUIDANCE });
378
383
  const known = references.get(event.sessionID);
379
384
  const gap = gapFor(event.sessionID);
package/src/workflows.ts CHANGED
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
2
2
  import { dirname, resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import type { Plugin } from "@opencode/plugin";
5
+ import type { SessionContext } from "@opencode/plugin/promise/session";
5
6
  import type { CommandDefinition } from "@opencode/plugin/promise/command";
6
7
 
7
8
  type SkillEditor = Parameters<Parameters<Plugin.Context["skill"]["transform"]>[0]>[0];
@@ -87,7 +88,29 @@ export function applyBeadsSkill(editor: SkillEditor, skill: BeadsSkill, diagnose
87
88
  editor.add(skill);
88
89
  }
89
90
 
90
- /** Build native prompt commands, never shell/template interpolation or synthetic continuation. */
91
+ /** Expand supported workflow/legacy snapshots only in transient user request copies. */
92
+ export function expandBeadsWorkflowContext(messages: SessionContext["messages"]): void {
93
+ for (const [index, message] of messages.entries()) {
94
+ if (message.role !== "user") continue;
95
+ const metadata = { ...message.metadata };
96
+ let instructions: string | undefined;
97
+ for (const key of ["ocBeadsSync", "ocBeadsWorkflow"]) {
98
+ const snapshot = metadata[key];
99
+ if (!snapshot || typeof snapshot !== "object" || !("version" in snapshot) || snapshot.version !== 1
100
+ || !("instructions" in snapshot) || typeof snapshot.instructions !== "string") continue;
101
+ instructions = snapshot.instructions;
102
+ delete metadata[key];
103
+ }
104
+ if (instructions === undefined) continue;
105
+ messages[index] = {
106
+ ...message,
107
+ metadata,
108
+ content: [{ type: "text", text: instructions }, ...message.content],
109
+ };
110
+ }
111
+ }
112
+
113
+ /** Build native prompt commands with compact text and durable static workflow instructions. */
91
114
  export function createBeadsCommands(
92
115
  session: Pick<Plugin.Context["session"], "prompt">,
93
116
  diagnostics: (sessionID: string) => Promise<string>,
@@ -109,11 +132,13 @@ export function createBeadsCommands(
109
132
  description: purpose,
110
133
  async execute(input) {
111
134
  if (signal?.aborted) throw new Error("Beads workflow unloaded");
135
+ const instructions = `Invoked command: /oc-beads:${stem}\nRequested outcome: ${purpose}\n${common}\nSupporting guidance: ${JSON.stringify(resolve(dirname(skillPath), "resources", `${resource}.md`))}`;
112
136
  await session.prompt({
113
137
  ...input.prompt,
114
138
  sessionID: input.sessionID,
115
139
  delivery: input.delivery,
116
- text: `Invoked command: /oc-beads:${stem}\nRequested outcome: ${purpose}\n${common}\nSupporting guidance: ${JSON.stringify(resolve(dirname(skillPath), "resources", `${resource}.md`))}${input.prompt.text ? `\n\nLiteral user details:\n${input.prompt.text}` : ""}`,
140
+ text: `/oc-beads:${stem}${input.prompt.text ? `${/[\r\n]/.test(input.prompt.text) ? "\n" : " "}${input.prompt.text}` : ""}`,
141
+ metadata: { ocBeadsWorkflow: { version: 1, instructions } },
117
142
  });
118
143
  },
119
144
  }));
@@ -126,7 +151,8 @@ export function createBeadsCommands(
126
151
  if (signal?.aborted) throw new Error("Beads workflow unloaded");
127
152
  await session.prompt({
128
153
  ...input.prompt, sessionID: input.sessionID, delivery: input.delivery,
129
- text: `Report these observed Beads diagnostics. This is read-only; do not run store-opening commands, change configuration or infer live qualification.\n${report}\n\nUser request:\n${input.prompt.text}`,
154
+ text: `/oc-beads:diagnostics${input.prompt.text ? `${/[\r\n]/.test(input.prompt.text) ? "\n" : " "}${input.prompt.text}` : ""}`,
155
+ metadata: { ocBeadsWorkflow: { version: 1, instructions: `Report these observed Beads diagnostics. This is read-only; do not run store-opening commands, change configuration or infer live qualification.\n${report}\nInclude the loaded plugin name/version and observed OpenCode host version near the start of your report. Preserve unavailable, withheld and uncertain observations; do not infer a unique build identity from a version label.` } },
130
156
  });
131
157
  },
132
158
  });