@brainervirus/workit-cli 4.0.0 → 5.0.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.
@@ -1,27 +1,26 @@
1
- # <Feature> Implementation Plan
1
+ # <Feature> plan
2
2
 
3
- > **For agentic workers:** Load `workit-implement` when policy selects implementation. Use bounded `workit_worker` delegation when the host supports it; otherwise execute inline within writer scope. Steps use checkbox (`- [ ]`) syntax for tracking.
3
+ Spec: `docs/<slug>/spec.md` · Goal: <one sentence>
4
4
 
5
- **Spec:** `docs/<slug>/spec.md`
6
- **Branch:** `feature/<slug>`
5
+ A plan records decisions, not code: per slice the branch, what it touches, its
6
+ acceptance, how it is verified, and what it depends on (workit-shape
7
+ `references/slicing.md`). Independent slices fan out (workit-fanout);
8
+ dependent ones stack (`workit stack plan <bottom> … <top>`).
7
9
 
8
- **Goal:** <one sentence>
10
+ ## Global constraints
9
11
 
10
- ## Global Constraints
11
-
12
- - Each task lands exactly one contiguous non-empty commit range (`base..head`): fix rounds append commits to that range and never rewrite/amend an active review range; record the real base..head shas in task progress.
13
- - The final task closes the lead Workit task with `workit_task` `action: "close"` (CLI: `workit task close --payload … [--confirm]`) once requirements are satisfied and repository verification passes — never finish while the task is still `active` or `paused`.
14
- - <project-wide requirements, one line each>
12
+ - <project-wide requirement, one line each>
15
13
 
16
14
  ---
17
15
 
18
- ### Task N: <Component>
19
-
20
- - [ ] **Step 1: <action>**
16
+ ### S1 <type>/<slug> (base: main)
21
17
 
22
- <!-- per-task criteria: how this task is verified -->
23
- **Criteria:** <verifiable check>
18
+ Touches: <areas, not line numbers>
19
+ Acceptance:
20
+ - Given <state>, When <action>, Then <observable result>
21
+ Verify: `workit check test`; verify-<app> "<feature>"
22
+ Decisions: <ledger refs or one-line rulings>
24
23
 
25
- | Status | Task |
26
- | --- | --- |
27
- | pending | N: <Component> |
24
+ | Slice | Branch | Depends on | Status |
25
+ | --- | --- | --- | --- |
26
+ | S1 | <type>/<slug> | — | pending |
@@ -19,14 +19,15 @@ no durable agreement: `Spec: none (<reason>)`, no file.)
19
19
 
20
20
  ## Architecture
21
21
 
22
- <!-- May be `N/A (<reason>)` when the change has no flows or architecture. -->
23
- <!-- Otherwise REQUIRED: render a mermaid diagram (workit-diagram skill). -->
22
+ <!-- Optional: only when a diagram argues a decision (workit-shape
23
+ references/diagrams.md); otherwise delete this section. -->
24
24
  ```mermaid
25
25
  flowchart TD
26
26
  A[Start] --> B[Step]
27
27
  ```
28
28
 
29
- <!-- REQUIRED if this spec touches UI: render an ASCII wireframe (workit-mockup skill). -->
29
+ <!-- Optional: a UI choice still open gets an ASCII sketch (workit-shape
30
+ references/mockups.md). -->
30
31
  ```text
31
32
  ┌──────────────┐
32
33
  │ Header │
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "@brainervirus/workit-cli",
68
- version: "3.0.0",
68
+ version: "4.0.0",
69
69
  private: false,
70
70
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
71
71
  keywords: [
@@ -15598,13 +15598,13 @@ var METHODS, methodMatches = (definition, requirement) => definition.dimensions?
15598
15598
  };
15599
15599
  var init_methods = __esm(() => {
15600
15600
  METHODS = {
15601
- "workit-challenge": { dimensions: ["challenge", "decisions"] },
15602
- "workit-behavioral-tdd": { dimensions: ["testing"], ruleIds: ["mechanical-existing-checks"] },
15601
+ "workit-shape": { dimensions: ["challenge", "decisions", "artifacts", "continuity"] },
15602
+ "workit-bdd": { dimensions: ["testing"] },
15603
15603
  "workit-review": { dimensions: ["review"], ruleIds: ["fresh-context-review", "self-review"] },
15604
- "workit-plan": { dimensions: ["artifacts", "continuity"] },
15605
- "workit-implement": { dimensions: ["delegation"] },
15604
+ "workit-implement": { ruleIds: ["mechanical-existing-checks"] },
15605
+ "workit-fanout": { dimensions: ["delegation"] },
15606
15606
  "workit-debug": {},
15607
- "workit-handoff": {},
15607
+ "workit-continue": {},
15608
15608
  "workit-deslop": { ruleIds: ["pre-pr-cleanup"] }
15609
15609
  };
15610
15610
  });
@@ -21627,10 +21627,15 @@ function recordVerdict(context, input) {
21627
21627
  if (key.dirty === true)
21628
21628
  return err("blocked", `dirty_worktree: ${branch} has uncommitted changes, so its head is not what was judged`, "commit or stash the changes, re-check, then record the verdict");
21629
21629
  const session = context.actor.session;
21630
- const selfReason = input.self === true ? "flag" : session ? null : "no_session";
21630
+ const selfReason = input.self === true ? "flag" : session && input.derivedFrom !== null ? null : "no_session";
21631
21631
  const self2 = selfReason !== null;
21632
- if (!self2 && session && authorSessions(context.cwd, ledger.value.rows, branch, { base: key.base, head: key.head }).has(session))
21633
- return err("blocked", `author_verdict: session ${session} authored ${branch}; a verdict must come from a different session`, 'have a non-author session record the verdict, or pass --self (a self verdict is never accepted by merge:"verified")');
21632
+ const authors = authorSessions(context.cwd, ledger.value.rows, branch, {
21633
+ base: key.base,
21634
+ head: key.head
21635
+ });
21636
+ const authoring = [session, input.derivedFrom].find((candidate) => typeof candidate === "string" && authors.has(candidate));
21637
+ if (!self2 && authoring)
21638
+ return err("blocked", `author_verdict: session ${authoring} authored ${branch}; a verdict must come from a different session`, input.derivedFrom === undefined ? 'have a non-author session record the verdict, or pass --self (a self verdict is never accepted by merge:"verified")' : "run the verifier as a separate session: the lead spawns it with its own WORKIT_SESSION_ID (Claude Code: subagents get one from the SubagentStart hook)");
21634
21639
  const link = checkSupersede(context, "verdict", self2);
21635
21640
  if (!link.ok)
21636
21641
  return link;
@@ -23602,7 +23607,7 @@ var run3 = (root, args) => {
23602
23607
  cwd: target.data
23603
23608
  }
23604
23609
  });
23605
- }, prBabysitNext = (output) => `PR ready: ${output}. Babysitting was explicitly requested. Follow workit-babysit to resolve conflicts, review threads, and get checks green. Stop at PR-ready; a PR or babysit request does not authorize merge or release.`, executeConcreteExternalAction = async (request, root, marker, dateMs, step, workText, caller, approvedBeforeDigest, approvedBeforeExists, coordinationRoot = root, approvedTip, approvedRemote, approvedAccount, approvedApiHost, approvedSourceCommit, approvedCommit, approvedRemoteBase, approvedLocalBase, writerActionLease, approvedSourceBranch, approvedMergeBaseCommit, expectedWorkspaceRevision) => {
23610
+ }, prBabysitNext = (output) => `PR ready: ${output}. Babysitting was explicitly requested. Follow workit-ship to resolve conflicts, review threads, and get checks green. Stop at PR-ready; a PR or babysit request does not authorize merge or release.`, executeConcreteExternalAction = async (request, root, marker, dateMs, step, workText, caller, approvedBeforeDigest, approvedBeforeExists, coordinationRoot = root, approvedTip, approvedRemote, approvedAccount, approvedApiHost, approvedSourceCommit, approvedCommit, approvedRemoteBase, approvedLocalBase, writerActionLease, approvedSourceBranch, approvedMergeBaseCommit, expectedWorkspaceRevision) => {
23606
23611
  if (localAction(request.operation)) {
23607
23612
  if (!caller)
23608
23613
  return failure2("capability_unavailable", "local external action writer authority is unavailable", { outcome: "not_started" });
@@ -23717,7 +23722,7 @@ var run3 = (root, args) => {
23717
23722
  ...result,
23718
23723
  ...request.payload.babysit !== undefined ? { babysit: request.payload.babysit } : {},
23719
23724
  ...babysit ? {
23720
- babysitSkill: "workit-babysit",
23725
+ babysitSkill: "workit-ship",
23721
23726
  next: prBabysitNext(String(result.output ?? ""))
23722
23727
  } : {}
23723
23728
  });
@@ -68239,22 +68244,17 @@ var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync12(root) ? re
68239
68244
  };
68240
68245
  var init_skill_manifests = __esm(() => {
68241
68246
  WORKIT_METHOD_SKILLS = [
68242
- "workit-challenge",
68243
- "workit-behavioral-tdd",
68244
- "workit-review",
68245
- "workit-plan",
68247
+ "workit-shape",
68246
68248
  "workit-implement",
68249
+ "workit-review",
68247
68250
  "workit-debug",
68248
- "workit-handoff",
68249
- "workit-babysit",
68250
- "workit-blast-radius",
68251
- "workit-deslop",
68252
- "workit-diagram",
68253
- "workit-mockup",
68254
- "workit-green-run",
68255
- "workit-steer",
68251
+ "workit-ship",
68252
+ "workit-continue",
68256
68253
  "workit-bdd",
68257
- "workit-test-audit"
68254
+ "workit-test-audit",
68255
+ "workit-deslop",
68256
+ "workit-fanout",
68257
+ "workit-verify-app"
68258
68258
  ];
68259
68259
  if (false) {}
68260
68260
  });
@@ -68531,8 +68531,11 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
68531
68531
  }, assetPathsFor = (host, dev) => {
68532
68532
  const pkg = path32.join(dev, "packages", `workit-${host}`);
68533
68533
  switch (host) {
68534
- case "opencode":
68535
- return WORKIT_METHOD_SKILLS.map((skill) => path32.join(pkg, "assets", "skills", skill, "SKILL.md"));
68534
+ case "opencode": {
68535
+ const packaged = path32.join(pkg, "assets", "skills");
68536
+ const root = existsSync13(packaged) ? packaged : path32.join(dev, "packages", "workit-core", "skills");
68537
+ return WORKIT_METHOD_SKILLS.map((skill) => path32.join(root, skill, "SKILL.md"));
68538
+ }
68536
68539
  case "cursor":
68537
68540
  return [
68538
68541
  path32.join(pkg, "assets", "templates", "workit-contract.md"),
@@ -79819,6 +79822,7 @@ var exports_ledger = {};
79819
79822
  __export(exports_ledger, {
79820
79823
  run: () => run18
79821
79824
  });
79825
+ import { randomBytes as randomBytes4 } from "node:crypto";
79822
79826
  import { parseArgs } from "node:util";
79823
79827
  function targetBranch(io, rows, branch, pr) {
79824
79828
  if (pr !== undefined) {
@@ -79901,9 +79905,13 @@ async function run18(argv, io) {
79901
79905
  const target = targetBranch(io, rows, values.branch, pr);
79902
79906
  if (!target.ok)
79903
79907
  return failed(io, target);
79908
+ const acting = actorFor(io, values);
79909
+ if (acting instanceof Error)
79910
+ return usage3(io, acting.message);
79911
+ const { actor } = acting;
79904
79912
  const context = {
79905
79913
  cwd: io.cwd,
79906
- actor: actorFromEnv(io.env),
79914
+ actor,
79907
79915
  branch: target.value,
79908
79916
  base: values.base ?? null,
79909
79917
  ...pr === undefined ? {} : { pr },
@@ -79931,10 +79939,30 @@ async function run18(argv, io) {
79931
79939
  how: values.how,
79932
79940
  surface: values.surface ?? null,
79933
79941
  self: values.self === true,
79934
- evidenceRefs: values.evidence
79935
- })), (row) => `recorded verdict ${row.id}: ${row.result} [${row.kind}] for ${row.branch} @ ${(row.head ?? "").slice(0, 12)}${row.self ? ` (self${row.selfReason === "no_session" ? ": WORKIT_SESSION_ID unset" : ""}; never accepted)` : ""}`);
79942
+ evidenceRefs: values.evidence,
79943
+ ..."derivedFrom" in acting ? { derivedFrom: acting.derivedFrom } : {}
79944
+ })), (row) => `recorded verdict ${row.id}: ${row.result} [${row.kind}] for ${row.branch} @ ${(row.head ?? "").slice(0, 12)} as ${actor.session ?? "no session"}${row.self ? ` (self${row.selfReason === "no_session" ? ": WORKIT_SESSION_ID unset" : ""}; never accepted)` : ""}`);
79936
79945
  }
79937
- var USAGE7 = "workit ledger decision|ruling|verdict|list|check ... (workit help ledger for the grammar)", OPTIONS, positiveInt2 = (value, flag) => {
79946
+ var USAGE7 = "workit ledger decision|ruling|verdict|list|check ... (workit help ledger for the grammar)", OPTIONS, SESSION_SAFE2, ROLE_SAFE, actorFor = (io, values) => {
79947
+ const actor = actorFromEnv(io.env);
79948
+ if (values.session !== undefined && values.as !== undefined)
79949
+ return new Error("pass --session or --as, not both");
79950
+ if (values.session !== undefined) {
79951
+ if (!SESSION_SAFE2.test(values.session))
79952
+ return new Error("--session must be 1-128 characters of [A-Za-z0-9_.:@/+-]");
79953
+ return { actor: { ...actor, session: values.session } };
79954
+ }
79955
+ if (values.as !== undefined) {
79956
+ if (!ROLE_SAFE.test(values.as))
79957
+ return new Error("--as takes a lowercase role, e.g. verifier");
79958
+ const prefix = (actor.session ?? actor.host).slice(0, 96);
79959
+ return {
79960
+ actor: { ...actor, session: `${prefix}:${values.as}:${randomBytes4(4).toString("hex")}` },
79961
+ derivedFrom: actor.session
79962
+ };
79963
+ }
79964
+ return { actor };
79965
+ }, positiveInt2 = (value, flag) => {
79938
79966
  if (value === undefined)
79939
79967
  return;
79940
79968
  const parsed = Number(value);
@@ -79967,8 +79995,12 @@ var init_ledger2 = __esm(() => {
79967
79995
  type: { type: "string" },
79968
79996
  last: { type: "string" },
79969
79997
  supersedes: { type: "string" },
79998
+ session: { type: "string" },
79999
+ as: { type: "string" },
79970
80000
  json: { type: "boolean" }
79971
80001
  };
80002
+ SESSION_SAFE2 = /^[A-Za-z0-9_.:@/+-]{1,128}$/;
80003
+ ROLE_SAFE = /^[a-z][a-z0-9-]{0,31}$/;
79972
80004
  });
79973
80005
 
79974
80006
  // node_modules/@babel/parser/lib/index.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cli",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "private": false,
5
5
  "description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
6
6
  "keywords": [
@@ -38,9 +38,9 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@babel/parser": "7.29.9",
41
- "@brainervirus/workit-core": "^4.0.0",
42
- "@brainervirus/workit-cursor": "^4.0.0",
43
- "@brainervirus/workit-opencode": "^4.0.0",
41
+ "@brainervirus/workit-core": "^5.0.0",
42
+ "@brainervirus/workit-cursor": "^5.0.0",
43
+ "@brainervirus/workit-opencode": "^5.0.0",
44
44
  "@inkjs/ui": "2.0.0",
45
45
  "ink": "7.1.1",
46
46
  "react": "19.2.8"
@@ -1,40 +0,0 @@
1
- Load resolved method skills through the host skill loader when policy selects them. Implement the existing plan; do not re-plan.
2
-
3
- **Spec:** <SPEC_PATH>
4
- **Plan:** <PLAN_PATH>
5
- **Branch:** <BRANCH>
6
-
7
- ## Hard gates
8
-
9
- - Inspect task state before acting. On OpenCode, Cursor, Codex, and Pi use the eight shared `workit_*` families (`workit_task`, `workit_policy`, `workit_evidence`, `workit_finding`, `workit_decision`, `workit_worker`, `workit_writer`, `workit_state`). On the CLI host use `workit <family> <action>` with the same actions (hyphenated on the CLI).
10
- - Never use a worktree. Branch changes are in-place through the approved `git.branch_setup` external action (CLI: `workit action git.branch_setup --payload …`).
11
- - Task metadata lives under `.workit/`; never edit it directly. Record progress, evidence, findings, decisions, and worker state only through the shared operations.
12
- - Helpers cannot widen scope, record binding decisions, close or pause the task, assign further helpers, or resolve blockers for the lead.
13
- - On Cursor, pass the active workspace as `workspace_root` on every repository-scoped call.
14
-
15
- ## Setup
16
-
17
- 1. If there is no active or paused task, call `workit_task` with `action: "start"` then `workit_policy` with `action: "assess"` (CLI: `workit task start …` then `workit policy assess …`).
18
- 2. Load `workit-plan`, list tasks with `workit_task` `action: "list"`, and mirror visible todo state to the host UI.
19
- 3. When policy requires a feature branch, resolve it with read-only `context.read` and apply `git.branch_setup` only after native approval.
20
-
21
- ## Remaining-task loop
22
-
23
- For each bounded plan task:
24
-
25
- 1. Mark the item in progress in the host todo UI and record boundary progress with `workit_task` `action: "progress"`.
26
- 2. Route by policy: assign bounded workers with `workit_worker` `action: "assign"` when delegation is available; otherwise implement inline. Acquire product-write ownership with `workit_writer` `action: "acquire"` before repository mutations; release it when done.
27
- 3. Record checks and artifacts with `workit_evidence` `action: "record"`. Record review concerns with `workit_finding` `action: "record"`; resolve or defer them with `finding.resolve`. Blocking findings may trigger at most **two** fix+re-review rounds per task; advisory taste/YAGNI items still use `finding.record` and never pause the loop by direct file edit.
28
- 4. Never advance while a foreign writer is active or blocking findings remain open for the current candidate.
29
-
30
- ## Final gate
31
-
32
- Run repository verification (CLI: `workit doctor`; hosts: approved project verify when policy requires it). **Mandatory:** close the lead task with `workit_task` `action: "close"` (CLI: `workit task close --payload … [--confirm]`) once requirements are satisfied and verification passes — never finish while the task is still `active` or `paused`.
33
-
34
- ## Task order
35
-
36
- <TASK_LIST>
37
-
38
- ## Quality gate
39
-
40
- - Specs/plans follow `templates/spec-template.md` / `templates/plan-template.md`.