@brainervirus/workit-opencode 0.9.2 → 0.11.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.
@@ -19,7 +19,7 @@ Never ask for or accept tokens in chat. For missing YouTrack configuration, prev
19
19
 
20
20
  When the user wants to personalize the toolkit (locale, timezone, branch policy), ask native questions one at a time:
21
21
 
22
- 1. **Locale** — present a combobox of `localeOptions` (en, es-CL, es-MX, es-AR, pt-BR) + custom answer; validate the answer against BCP-47 (`^[a-z]{2,3}(-[A-Z]{2})?$`) before passing it.
22
+ 1. **Locale** — present a combobox of `localeOptions` (en, es-CL, es-MX, es-AR, pt-BR) + custom answer; validate the answer against BCP-47 (`^[a-z]{2,3}(-(?:[A-Z]{2}|[0-9]{3}))?$`, so `es-419` is valid) before passing it.
23
23
  2. **Timezone** — e.g. `America/Santiago`, custom allowed.
24
24
  3. **Branch policy preset** — gitflow / github-flow / trunk-based / custom.
25
25
  4. **Custom branch lists** (only when preset = custom): allowed patterns (`feature/*`, `codex/*`, …) and protected names (`main`, …).
@@ -24,10 +24,10 @@ This session is a handoff destination for a continued plan. The originating sess
24
24
  - Working state, briefs, ledgers, and review diffs live only under gitignored `<SDD_DIR>` in `docs/<slug>/sdd/` and use `workit_sdd_*` tools.
25
25
  - Use native `todowrite` for visible task state as well as the gitignored ledger.
26
26
  - Use native `question` for branch/stash choices and guarded external mutations; call mutation tools only after approval with `confirmed: true` (grounded in the recorded NativeChoiceEvidence).
27
- - Flow-tool confirmations are never agent-typed booleans and never caller-supplied evidence objects: on OpenCode the plugin records the user's native-`question` answer as a host-observed one-use receipt (`attested: true`, `callID`, `selectedLabel`, `recordedAt`) consumed by `workit_spec_approve` / `workit_plan_approve` / `workit_plan_menu` — no evidence argument exists, and delegated worker status comes from host session parentage (`parentID`), never a caller `role` field. On Cursor, confirmations are policy-only (`attested: false`) and subagent-driven execution is rejected as unsupported.
27
+ - Flow-tool confirmations are never agent-typed booleans and never caller-supplied evidence objects: on OpenCode the plugin records the user's native-`question` answer as a host-observed one-use receipt (`attested: true`, `callID`, `selectedLabel`, `recordedAt`) consumed by `workit_spec_approve` / `workit_plan_approve` / `workit_plan_menu` — no evidence argument exists, and delegated worker status comes from host session parentage (`parentID`), never a caller `role` field. On Cursor, confirmations are policy-only (`attested: false`), Subagent-driven execution is supported through the one-time `coordinator_lease` and per-task `delegation_token` minted by `workit_delegate` (fail-closed validation; no `parentID` identity exists on Cursor), and Inline runs single-agent in the current session.
28
28
  - Delegated authority is direct-child-only: a worker is the session whose host `parentID` exactly equals the activating coordinator's recorded `coordinator_session_id`; missing, mismatched, or multi-owner lineage fails closed with `delegation_lineage_denied`, and nested `opencode` launches are denied during active delegated work. An authorized child receives only the compact worker contract (execute the supplied brief, follow TDD, land one contiguous non-empty commit range, report results) — never coordinator guidance, `wk-implement`, or ledger management; coordinator bookkeeping via `workit_sdd_*` stays with the coordinator session.
29
29
  - On Cursor, for every repository-scoped `workit_*` call, pass the active Cursor workspace as `workspace_root`; never rely on the MCP process default.
30
- - Use native `task` with only the built-in `explore` and `general` agents.
30
+ - Use native `task` with only the built-in `explore` and `general` agents (OpenCode); on Cursor, Subagent-driven dispatches Cursor-native subagents with a task `delegation_token`, Inline runs single-agent in the current session.
31
31
 
32
32
  ## Flow gates (HARD)
33
33
 
@@ -51,7 +51,7 @@ For each top-level task absent from `completed_task_ids`:
51
51
 
52
52
  1. Mark it `in_progress` with `todowrite`.
53
53
  2. Create a working-state brief with `workit_sdd_task_brief` and `confirmed: true`.
54
- 3. Delegate read-only discovery, when needed, to an `explore` agent. Delegate implementation to a fresh `general` agent. Product changes follow TDD.
54
+ 3. Route by the approved execution mode: **Subagent-driven** delegates read-only discovery to an `explore` (OpenCode) agent, delegates implementation to a fresh `general` (OpenCode) agent (on Cursor, the coordinator mints a `delegation_token` with `workit_delegate` and the subagent prompt carries the raw token — the worker passes it as `delegation_token` on its mutation calls, and appending progress revokes it), and the coordinator never edits product code; **Inline** executes every task in the current agent with no dispatch and no token minting. Product changes follow TDD.
55
55
  4. Create a working-state diff with `workit_sdd_review_package` and `confirmed: true`.
56
56
  5. Delegate spec-compliance review and code-quality review to separate `general` agents.
57
57
  6. **Blocking** findings (Critical, Important, or spec-compliance) may trigger at most **two** fix+re-review rounds per task. **Advisory** findings (Minor, style, YAGNI, taste) never pause the loop — append them with `workit_sdd_append_advisory` (`--task <id> --text <text>`, `confirmed: true`) instead of an unrestricted file edit.
@@ -1,6 +1,6 @@
1
1
  # <Feature> Implementation Plan
2
2
 
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. On Cursor the two paths are: **Subagent-driven** — Cursor-native subagents dispatched by the coordinator, each carrying a task-scoped `delegation_token` minted with `workit_delegate` from the one-time `coordinator_lease`; **Inline** — `executing-plans` in the current session, single-agent, no dispatch, no token minting. Steps use checkbox (`- [ ]`) syntax for tracking.
4
4
 
5
5
  **Spec:** `docs/<slug>/spec.md`
6
6
  **Branch:** `feature/<slug>`
@@ -1,6 +1,6 @@
1
1
  # Superpowers document contract
2
2
 
3
- Use OpenCode's native `question` for every bounded user choice. Give concise choices and allow a custom answer; if the tool is unavailable, ask one concise plain-text question. Use `skill` to load workflow and Superpowers skills, `todowrite` for task state, and `task` for delegated work.
3
+ Use OpenCode's native `question` for every bounded user choice. Give concise choices and allow a custom answer; if the tool is unavailable, ask one concise plain-text question. Use `skill` to load workflow and Superpowers skills, `todowrite` for task state, and `task` for delegated work (OpenCode) or the host-native equivalent — on Cursor, Subagent-driven dispatches Cursor-native subagents with a task `delegation_token`, Inline runs single-agent in the current session.
4
4
 
5
5
  ## Tracked document layout
6
6
 
@@ -35,7 +35,7 @@ Before writing **Branch:** into a new spec or plan, call `workit_docs_branch` an
35
35
  - Commits use `wk-commit` after its native `question` confirmation.
36
36
  - Continuation uses `wk-handoff`, whose `workit_handoff_session` creates and seeds the OpenCode session automatically.
37
37
  - Never use worktrees. Resolve the declared branch with `workit_resolve_branch`, preview dirty-tree stash choices with `question`, and apply an approved in-place checkout through `workit_branch_setup` with `confirmed: true` (grounded in the recorded NativeChoiceEvidence).
38
- - Flow-tool confirmations are never agent-typed booleans and never caller-supplied evidence objects: on OpenCode the plugin records the user's native-`question` answer as a host-observed one-use receipt (`attested: true`, `callID`, `selectedLabel`, `recordedAt`) consumed by `workit_spec_approve` / `workit_plan_approve` / `workit_plan_menu` — no evidence argument exists, and delegated worker status comes from host session parentage (`parentID`), never a caller `role` field. On Cursor, confirmations are policy-only (`attested: false`) and subagent-driven execution is rejected as unsupported.
38
+ - Flow-tool confirmations are never agent-typed booleans and never caller-supplied evidence objects: on OpenCode the plugin records the user's native-`question` answer as a host-observed one-use receipt (`attested: true`, `callID`, `selectedLabel`, `recordedAt`) consumed by `workit_spec_approve` / `workit_plan_approve` / `workit_plan_menu` — no evidence argument exists, and delegated worker status comes from host session parentage (`parentID`), never a caller `role` field. On Cursor, confirmations are policy-only (`attested: false`), Subagent-driven execution is supported through the one-time `coordinator_lease` and per-task `delegation_token` minted by `workit_delegate` (fail-closed validation; no `parentID` identity exists on Cursor), and Inline runs single-agent in the current session.
39
39
  - Keep all SDD state under the gitignored `docs/<slug>/sdd/`; use `workit_sdd_context` and the registered `workit_sdd_*` tools.
40
40
  - After implementation, use `question` before an approved stash reapply through `workit_branch_setup` with `confirmed: true`.
41
41
 
@@ -7,11 +7,11 @@ description: Use when you have a written implementation plan to execute in a sep
7
7
 
8
8
  ## Overview
9
9
 
10
- Load plan, review critically, execute all tasks, report when complete.
10
+ Load plan, review critically, execute all tasks in the current session, report when complete. This is the single-agent Inline execution path.
11
11
 
12
12
  **Announce at start:** "I'm using the executing-plans skill to implement this plan."
13
13
 
14
- **Note:** Tell your human partner that Superpowers works much better with access to subagents. The quality of its work will be significantly higher if run on a platform with subagent support (Claude Code, Codex CLI, Codex App, and Copilot CLI all qualify; see the per-platform tool refs in `../using-superpowers/references/`). If subagents are available, use superpowers:subagent-driven-development instead of this skill.
14
+ **Note:** This skill is the single-agent Inline execution path: every task runs in the current session — no token minting, no subagent dispatching. Tell your human partner that Superpowers works much better with access to subagents. The quality of its work will be significantly higher if run on a platform with subagent support (Claude Code, Codex CLI, Codex App, and Copilot CLI all qualify; see the per-platform tool refs in `../using-superpowers/references/`). If subagents are available and the plan's approved execution mode is Subagent-driven, use superpowers:subagent-driven-development instead of this skill.
15
15
 
16
16
  ## The Process
17
17
 
@@ -11,6 +11,8 @@ Execute plan by dispatching a fresh implementer subagent per task, a task review
11
11
 
12
12
  **Core principle:** Fresh subagent per task + task review (spec + quality) + broad final review = high quality, fast iteration
13
13
 
14
+ On Cursor, the coordinator mints a task-scoped delegation token via `workit_delegate` (from the `workit_plan_menu` coordinator lease) and the subagent prompt must carry it as `delegation_token` for mutation calls.
15
+
14
16
  **Narration:** between tool calls, narrate at most one short line — the
15
17
  ledger and the tool results carry the record.
16
18
 
package/dist/plugin.js CHANGED
@@ -125,7 +125,7 @@ var ensureConfigDir = (dir = resolveConfigDir()) => {
125
125
  return dir;
126
126
  };
127
127
  var configDir = () => ensureConfigDir();
128
- var LOCALE_RE = /^[a-z]{2,3}(-[A-Z]{2})?$/;
128
+ var LOCALE_RE = /^[a-z]{2,3}(-(?:[A-Z]{2}|[0-9]{3}))?$/;
129
129
  var DEFAULTS = {
130
130
  locale: "en",
131
131
  localeOptions: ["en", "es-CL", "es-MX", "es-AR", "pt-BR"],
@@ -4117,7 +4117,7 @@ import {
4117
4117
  unlinkSync as unlinkSync2,
4118
4118
  writeFileSync as writeFileSync11
4119
4119
  } from "node:fs";
4120
- import { createHash as createHash2 } from "node:crypto";
4120
+ import { createHash as createHash2, randomBytes } from "node:crypto";
4121
4121
  import path22 from "node:path";
4122
4122
 
4123
4123
  // packages/workit-core/src/core/docs-validate.ts
@@ -5488,7 +5488,6 @@ root: ${cwd}
5488
5488
 
5489
5489
  // packages/workit-core/src/core/flow-state.ts
5490
5490
  var COORDINATOR_RECOVERY_TEXT = "A subagent-driven plan is active: coordinator product edits are blocked. " + "Delegate product mutations to an authenticated delegated worker via `task` / `wk-implement` instead of " + "editing in the coordinator session.";
5491
- var CURSOR_SUBAGENT_UNSUPPORTED_TEXT = "Cursor cannot execute subagent-driven plans: the MCP has no child-session " + "support. Choose Inline, Handoff, or a review option in this session, or " + "run the plan in OpenCode with `wk-implement`.";
5492
5491
  var MENU_CHOICES = [
5493
5492
  "subagent-driven",
5494
5493
  "inline",
@@ -5548,19 +5547,42 @@ var normalizeState = (parsed, slug) => {
5548
5547
  status: execution.status ?? "pending",
5549
5548
  mode: execution.mode ?? null,
5550
5549
  evidence: execution.evidence ?? null,
5551
- coordinator_session_id: execution.coordinator_session_id ?? null
5550
+ coordinator_session_id: execution.coordinator_session_id ?? null,
5551
+ ...execution.delegation !== undefined ? { delegation: normalizeDelegation(execution.delegation) } : {}
5552
5552
  },
5553
5553
  handoff_destination: p.handoff_destination ?? false,
5554
5554
  updated_at: p.updated_at ?? Date.now()
5555
5555
  };
5556
5556
  };
5557
+ var normalizeDelegation = (v) => {
5558
+ if (v === null || v === undefined)
5559
+ return null;
5560
+ if (!isRecord(v))
5561
+ return null;
5562
+ const hash = (x) => typeof x === "string" && HEX64_RE.test(x) ? x : null;
5563
+ return {
5564
+ coordinator_lease_hash: hash(v.coordinator_lease_hash),
5565
+ active_task_id: typeof v.active_task_id === "number" && Number.isSafeInteger(v.active_task_id) ? v.active_task_id : null,
5566
+ token_hash: hash(v.token_hash),
5567
+ token_workspace: typeof v.token_workspace === "string" ? v.token_workspace : null,
5568
+ token_slug: typeof v.token_slug === "string" ? v.token_slug : null,
5569
+ status: v.status === "active" ? "active" : "revoked"
5570
+ };
5571
+ };
5572
+ var delegationHash = (raw) => createHash2("sha256").update(raw).digest("hex");
5557
5573
  var emptyState = (slug) => ({
5558
5574
  slug,
5559
5575
  activated: false,
5560
5576
  spec: { path: "", status: "draft", evidence: null, approved_digest: null },
5561
5577
  plan: { path: "", status: "draft", evidence: null, approved_digest: null },
5562
5578
  menu: { presented: false, chosen: "", evidence: null },
5563
- execution: { status: "pending", mode: null, evidence: null, coordinator_session_id: null },
5579
+ execution: {
5580
+ status: "pending",
5581
+ mode: null,
5582
+ evidence: null,
5583
+ coordinator_session_id: null,
5584
+ delegation: null
5585
+ },
5564
5586
  handoff_destination: false,
5565
5587
  updated_at: Date.now()
5566
5588
  });
@@ -5698,7 +5720,8 @@ var validateState = (parsed, slug) => {
5698
5720
  status: execRaw?.status ?? "pending",
5699
5721
  mode: execRaw?.mode ?? null,
5700
5722
  evidence: execRaw?.evidence ?? null,
5701
- coordinator_session_id: execRaw?.coordinator_session_id ?? null
5723
+ coordinator_session_id: execRaw?.coordinator_session_id ?? null,
5724
+ ...execRaw?.delegation !== undefined ? { delegation: normalizeDelegation(execRaw.delegation) } : {}
5702
5725
  },
5703
5726
  handoff_destination: parsed.handoff_destination ?? false,
5704
5727
  updated_at: parsed.updated_at ?? Date.now()
@@ -5835,7 +5858,13 @@ var resetForSpecDrift = (state) => ({
5835
5858
  spec: { ...state.spec, status: "draft", evidence: null, approved_digest: null },
5836
5859
  plan: { ...state.plan, status: "draft", evidence: null, approved_digest: null },
5837
5860
  menu: { presented: false, chosen: "", evidence: null },
5838
- execution: { status: "pending", mode: null, evidence: null, coordinator_session_id: null },
5861
+ execution: {
5862
+ status: "pending",
5863
+ mode: null,
5864
+ evidence: null,
5865
+ coordinator_session_id: null,
5866
+ ...state.execution.delegation !== undefined ? { delegation: null } : {}
5867
+ },
5839
5868
  handoff_destination: false,
5840
5869
  updated_at: Date.now()
5841
5870
  });
@@ -5885,7 +5914,12 @@ var deriveLegacyExecution = (root2, slug, state) => {
5885
5914
  coordinator_session_id: null
5886
5915
  };
5887
5916
  }
5888
- return { status: "pending", mode: null, evidence: null, coordinator_session_id: null };
5917
+ return {
5918
+ status: "pending",
5919
+ mode: null,
5920
+ evidence: null,
5921
+ coordinator_session_id: null
5922
+ };
5889
5923
  };
5890
5924
  var normalizeCompatibility = (root2, slug, parsed, state) => {
5891
5925
  if (!isRecord(parsed) || !("execution" in parsed)) {
@@ -6287,7 +6321,12 @@ var prepareFlowState = (root2, slug, opts = {}, ctx) => {
6287
6321
  spec: { path: specPath, status: "draft", evidence: null, approved_digest: null },
6288
6322
  plan: { path: planPath, status: "draft", evidence: null, approved_digest: null },
6289
6323
  menu: { presented: false, chosen: "", evidence: null },
6290
- execution: { status: "pending", mode: null, evidence: null, coordinator_session_id: null },
6324
+ execution: {
6325
+ status: "pending",
6326
+ mode: null,
6327
+ evidence: null,
6328
+ coordinator_session_id: null
6329
+ },
6291
6330
  handoff_destination: false,
6292
6331
  updated_at: Date.now()
6293
6332
  });
@@ -6415,16 +6454,16 @@ var recordMenuChoice = (root2, slug, planPath, choice, evidence, ctx) => {
6415
6454
  if (typeof choice !== "string" || !MENU_CHOICES.includes(choice)) {
6416
6455
  return err2("menu_choice_invalid", `invalid menu choice: ${JSON.stringify(choice)}`);
6417
6456
  }
6418
- if (recorded.evidence.host === "cursor" && choice === "subagent-driven") {
6419
- return err2("unsupported_mode", CURSOR_SUBAGENT_UNSUPPORTED_TEXT);
6420
- }
6421
6457
  if (recorded.evidence.host === "opencode" && !sameChoiceLabel(recorded.evidence.selectedLabel, choice)) {
6422
6458
  return err2("evidence_mismatch", `evidence selectedLabel ${JSON.stringify(recorded.evidence.selectedLabel)} does not match choice ${JSON.stringify(choice)}`);
6423
6459
  }
6424
6460
  const doc = resolveDoc(root2, slug, planPath, "plan");
6425
6461
  if (!doc.ok)
6426
6462
  return err2("path_invalid", doc.error);
6427
- return readModifyWrite(root2, slug, (state) => {
6463
+ const cursorSubagent = recorded.evidence.host === "cursor" && choice === "subagent-driven";
6464
+ const lease = cursorSubagent ? randomBytes(32).toString("hex") : null;
6465
+ const leaseHash = lease === null ? null : delegationHash(lease);
6466
+ const result = readModifyWrite(root2, slug, (state) => {
6428
6467
  if (state.spec.status !== "approved")
6429
6468
  return err2("spec_not_approved", "spec must be approved before the execution menu");
6430
6469
  if (state.plan.status !== "approved")
@@ -6434,6 +6473,14 @@ var recordMenuChoice = (root2, slug, planPath, choice, evidence, ctx) => {
6434
6473
  }
6435
6474
  const executing = choice === "subagent-driven" || choice === "inline";
6436
6475
  const coordinatorSessionId = choice === "subagent-driven" && recorded.evidence.host === "opencode" ? ctx?.sessionId ?? null : null;
6476
+ const delegation = cursorSubagent ? {
6477
+ coordinator_lease_hash: leaseHash,
6478
+ active_task_id: null,
6479
+ token_hash: null,
6480
+ token_workspace: null,
6481
+ token_slug: null,
6482
+ status: "active"
6483
+ } : state.execution.delegation;
6437
6484
  return {
6438
6485
  ok: true,
6439
6486
  next: {
@@ -6444,17 +6491,22 @@ var recordMenuChoice = (root2, slug, planPath, choice, evidence, ctx) => {
6444
6491
  status: "active",
6445
6492
  mode: choice,
6446
6493
  evidence: recorded.evidence,
6447
- coordinator_session_id: coordinatorSessionId
6494
+ coordinator_session_id: coordinatorSessionId,
6495
+ delegation
6448
6496
  } : {
6449
6497
  status: "pending",
6450
6498
  mode: null,
6451
6499
  evidence: recorded.evidence,
6452
- coordinator_session_id: null
6500
+ coordinator_session_id: null,
6501
+ delegation
6453
6502
  },
6454
6503
  updated_at: Date.now()
6455
6504
  }
6456
6505
  };
6457
6506
  });
6507
+ if (!result.ok)
6508
+ return result;
6509
+ return cursorSubagent && lease !== null ? { ok: true, coordinator_lease: lease } : { ok: true };
6458
6510
  };
6459
6511
  var markHandoffDestination = (root2, slug, planPath) => {
6460
6512
  const doc = resolveDoc(root2, slug, planPath, "plan");
@@ -20294,7 +20346,7 @@ function createRepoTools(runtime = defaultRuntime) {
20294
20346
  return output(result.ok ? ok(result) : fail(result.error));
20295
20347
  }
20296
20348
  if (action === "config") {
20297
- const LOCALE_RE2 = /^[a-z]{2,3}(-[A-Z]{2})?$/;
20349
+ const LOCALE_RE2 = /^[a-z]{2,3}(-(?:[A-Z]{2}|[0-9]{3}))?$/;
20298
20350
  if (locale !== undefined && !LOCALE_RE2.test(locale)) {
20299
20351
  return output(fail(`invalid locale: ${JSON.stringify(locale)} — expected BCP-47 like en or es-CL`));
20300
20352
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-opencode",
3
- "version": "0.9.2",
3
+ "version": "0.11.0",
4
4
  "private": false,
5
5
  "description": "Workit OpenCode plugin (thin wrapper over @brainervirus/workit-core)",
6
6
  "keywords": [
@@ -34,7 +34,7 @@
34
34
  "typecheck": "tsc --noEmit"
35
35
  },
36
36
  "dependencies": {
37
- "@brainervirus/workit-core": "^0.9.2"
37
+ "@brainervirus/workit-core": "^0.11.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@opencode-ai/plugin": "1.17.7"