@brainervirus/workit-opencode 8.11.0 → 8.12.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.
|
@@ -25,7 +25,7 @@ REPORT: branch, head SHA, files changed, each VERIFY command with its exit code,
|
|
|
25
25
|
each ACCEPTANCE line met / not met, rulings you made (`workit ledger ruling`),
|
|
26
26
|
anything out of scope as a follow-up, not a diff.
|
|
27
27
|
STANDING: <the standing orders, verbatim: `workit ledger standing add` records each one>
|
|
28
|
-
|
|
28
|
+
<identity line, per the lead's host: see "Identity and git rules per host" below>
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
## Worked example
|
|
@@ -97,17 +97,32 @@ is the slice's STUCK threshold in `workit fanout status`. `"fanIn":
|
|
|
97
97
|
}
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
## Identity and git rules per host
|
|
101
|
+
|
|
102
|
+
`workit fanout brief` renders the identity line and RULES 1 and 3 for the
|
|
103
|
+
lead's host (`WORKIT_HOST`, or the host's own session variable):
|
|
104
|
+
|
|
105
|
+
| Lead's host | Identity line | RULES 1 and 3 |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| Claude Code | `Session: your env already has WORKIT_SESSION_ID (the lead's id)`; no `export`, no hand-minted id (SubagentStart issues `<lead>:<agent id>` only to verifiers and reviewers, never to an implementer, so the worker's commits carry the lead's id) | plain git: `git fetch origin && git switch -c <branch> origin/<base>` and `git commit -m <msg> --trailer "Workit-Session: <the env WORKIT_SESSION_ID>" --trailer "<host attribution>" -- <paths in SCOPE>`, because worktree isolation refuses every `workit git` form |
|
|
108
|
+
| OpenCode, Pi, Codex | `Session: your host already sets WORKIT_SESSION_ID in your shell`; export nothing (the host derives the id and an export cannot replace it) | `workit git branch <branch> --base <base>`, `workit git commit -m <msg> -- <paths in SCOPE>` |
|
|
109
|
+
| Cursor, CI, a plain terminal | `export WORKIT_SESSION_ID=<lead>-w-<slice>` (`+try<n>` for a race attempt): declared, not checked | the same `workit git` forms |
|
|
110
|
+
|
|
111
|
+
`MODE: resume` is `git switch <branch>` on every host (the branch exists; the
|
|
112
|
+
lead removed the dead worker's worktree after its exit, so the switch
|
|
113
|
+
succeeds), then continue from its head. A race attempt (`--attempt <n>`)
|
|
114
|
+
follows its host's row with the branch `<branch>-try<n>`.
|
|
115
|
+
|
|
100
116
|
## Worker rules (`workit fanout brief` appends them as RULES)
|
|
101
117
|
|
|
102
|
-
1. First command
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
worker's worktree after its exit, so the switch succeeds), then continue
|
|
106
|
-
from its head.
|
|
118
|
+
1. First command: create the branch (`MODE: new`; the worktree may start on a
|
|
119
|
+
name that breaks branch policy) or `git switch` to it (`MODE: resume`),
|
|
120
|
+
as the table above says for your host.
|
|
107
121
|
2. Decide ambiguities yourself and record them:
|
|
108
122
|
`workit ledger ruling "<what>" --why "<why>" --cost-if-wrong "<cost>"`.
|
|
109
123
|
Stop only for an irreversible action, a security-sensitive one, or a side
|
|
110
124
|
effect outside the worktree.
|
|
111
|
-
3. Commit
|
|
112
|
-
the brief says
|
|
125
|
+
3. Commit as the table says (`workit git commit -m "<msg>" -- <paths in SCOPE>`,
|
|
126
|
+
or plain git with the trailers on Claude Code); push only if the brief says
|
|
127
|
+
so.
|
|
113
128
|
4. Never record a verdict on your own work.
|
|
@@ -73,8 +73,8 @@ Which session id a verdict carries, per host:
|
|
|
73
73
|
- Claude Code: subagents inherit your `WORKIT_SESSION_ID`, so the
|
|
74
74
|
SubagentStart hook names each `verifier` and `reviewer` its own session
|
|
75
75
|
(`<lead>:<agent id>`), passed exactly as `--session`: the hook records the
|
|
76
|
-
ids it issues, and only those are accepted. An `implementer`
|
|
77
|
-
|
|
76
|
+
ids it issues, and only those are accepted. An `implementer` is issued
|
|
77
|
+
none: it keeps your id in its env for its workit commands and commits.
|
|
78
78
|
- Codex: the `workit-verifier` and `workit-reviewer` agents get the same
|
|
79
79
|
issued `--session` from SubagentStart; any other verifier passes
|
|
80
80
|
`--as verifier`.
|
|
@@ -84,8 +84,13 @@ Which session id a verdict carries, per host:
|
|
|
84
84
|
- Cursor (no session id in the shell): the brief sets the verifier's
|
|
85
85
|
`WORKIT_SESSION_ID=<lead>:verifier-<random hex>`, a fresh suffix per
|
|
86
86
|
verifier. Cursor cannot check it: it is declared, not derived.
|
|
87
|
-
- A worker's commits
|
|
88
|
-
|
|
87
|
+
- A worker's commits: on Claude Code the lead's `WORKIT_SESSION_ID` already in
|
|
88
|
+
its env (SubagentStart issues no implementer id; plain git, no export, so the
|
|
89
|
+
lead authored those commits: a verifier or reviewer records the verdict, not
|
|
90
|
+
the lead); on OpenCode, Pi and Codex the id the host already
|
|
91
|
+
puts in its shell; on Cursor, CI and a plain terminal the brief's
|
|
92
|
+
`export WORKIT_SESSION_ID=<lead>-w-<slice>` (see `brief.md`, "Identity and
|
|
93
|
+
git rules per host"). A verdict under an id you made up (`<lead>-v1`,
|
|
89
94
|
`<lead>:v1`) is refused as `forged_session` on Claude Code, Codex,
|
|
90
95
|
OpenCode and Pi.
|
|
91
96
|
|
package/dist/plugin.js
CHANGED
|
@@ -9597,6 +9597,48 @@ function acquireFileLockSync(targetPath, options) {
|
|
|
9597
9597
|
}
|
|
9598
9598
|
}
|
|
9599
9599
|
}
|
|
9600
|
+
// packages/workit-core/src/core/logger.ts
|
|
9601
|
+
import os from "node:os";
|
|
9602
|
+
var SENSITIVE_WORDS = new Set([
|
|
9603
|
+
"token",
|
|
9604
|
+
"secret",
|
|
9605
|
+
"password",
|
|
9606
|
+
"passwd",
|
|
9607
|
+
"authorization",
|
|
9608
|
+
"credential",
|
|
9609
|
+
"credentials",
|
|
9610
|
+
"cookie",
|
|
9611
|
+
"api",
|
|
9612
|
+
"apikey",
|
|
9613
|
+
"apitoken",
|
|
9614
|
+
"accesstoken",
|
|
9615
|
+
"clientsecret",
|
|
9616
|
+
"refreshtoken",
|
|
9617
|
+
"key",
|
|
9618
|
+
"bearer",
|
|
9619
|
+
"prompt",
|
|
9620
|
+
"message",
|
|
9621
|
+
"messages",
|
|
9622
|
+
"content",
|
|
9623
|
+
"body",
|
|
9624
|
+
"args",
|
|
9625
|
+
"argument",
|
|
9626
|
+
"result",
|
|
9627
|
+
"results",
|
|
9628
|
+
"output",
|
|
9629
|
+
"issue",
|
|
9630
|
+
"description",
|
|
9631
|
+
"summary",
|
|
9632
|
+
"payload",
|
|
9633
|
+
"script",
|
|
9634
|
+
"command",
|
|
9635
|
+
"text",
|
|
9636
|
+
"query"
|
|
9637
|
+
]);
|
|
9638
|
+
var STACK_WORDS = new Set(["stack", "stacktrace", "trace"]);
|
|
9639
|
+
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9640
|
+
var homePattern = new RegExp(`${escapeRegExp(os.homedir())}(?=[/\\\\]|$)|\\$HOME(?=[/\\\\]|$)`, "g");
|
|
9641
|
+
|
|
9600
9642
|
// packages/workit-core/src/store/paths.ts
|
|
9601
9643
|
import { spawnSync } from "node:child_process";
|
|
9602
9644
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -12391,7 +12433,7 @@ function loadCheckConfig(cwd) {
|
|
|
12391
12433
|
gates[gate] = names;
|
|
12392
12434
|
}
|
|
12393
12435
|
}
|
|
12394
|
-
return { source: CHECKS_FILE, root, checks, gates, error: null };
|
|
12436
|
+
return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
|
|
12395
12437
|
}
|
|
12396
12438
|
var sameArgv = (left, right) => left.length === right.length && left.every((item, index) => item === right[index]);
|
|
12397
12439
|
function matchesNamedCheck(config, name, argv, cwd) {
|
|
@@ -12433,7 +12475,7 @@ function checkCommand(args, version, onPath = workitAvailable()) {
|
|
|
12433
12475
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
12434
12476
|
import { createHash as createHash5 } from "node:crypto";
|
|
12435
12477
|
import fs9 from "node:fs";
|
|
12436
|
-
import
|
|
12478
|
+
import os2 from "node:os";
|
|
12437
12479
|
import path8 from "node:path";
|
|
12438
12480
|
var MAX_BUFFER = 256 * 1024 * 1024;
|
|
12439
12481
|
var GIT_TIMEOUTS = { local: 20000, worktree: 120000, network: 15000 };
|
|
@@ -12481,7 +12523,7 @@ function worktreeTree(cwd, options = {}) {
|
|
|
12481
12523
|
return null;
|
|
12482
12524
|
const cap = options.maxUntrackedBytes ?? MAX_UNTRACKED_BYTES;
|
|
12483
12525
|
const timeoutMs = options.timeoutMs ?? GIT_TIMEOUTS.worktree;
|
|
12484
|
-
const scratch = fs9.mkdtempSync(path8.join(
|
|
12526
|
+
const scratch = fs9.mkdtempSync(path8.join(os2.tmpdir(), "workit-tree-"));
|
|
12485
12527
|
try {
|
|
12486
12528
|
const tempIndex = path8.join(scratch, "index");
|
|
12487
12529
|
if (fs9.existsSync(indexPath))
|
|
@@ -12635,7 +12677,7 @@ import {
|
|
|
12635
12677
|
readdirSync as readdirSync2,
|
|
12636
12678
|
writeFileSync as writeFileSync2
|
|
12637
12679
|
} from "node:fs";
|
|
12638
|
-
import
|
|
12680
|
+
import os3 from "node:os";
|
|
12639
12681
|
import path9 from "node:path";
|
|
12640
12682
|
|
|
12641
12683
|
// packages/workit-core/src/core/boundary.ts
|
|
@@ -12695,7 +12737,7 @@ var mergePreset = (preset, input = {}, current = {
|
|
|
12695
12737
|
protected: preset === "custom" ? input.protectedNames ?? current.branchPolicy.protected : [...defs.protected]
|
|
12696
12738
|
};
|
|
12697
12739
|
};
|
|
12698
|
-
var resolveConfigDir = () => process.env.WORKFLOW_TOOLKIT_CONFIG ?? process.env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path9.join(process.env.XDG_CONFIG_HOME || path9.join(
|
|
12740
|
+
var resolveConfigDir = () => process.env.WORKFLOW_TOOLKIT_CONFIG ?? process.env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path9.join(process.env.XDG_CONFIG_HOME || path9.join(os3.homedir(), ".config"), "workit");
|
|
12699
12741
|
var migratedDir = null;
|
|
12700
12742
|
var migrationFailed = false;
|
|
12701
12743
|
var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
@@ -12705,7 +12747,7 @@ var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
|
12705
12747
|
migratedDir = dir;
|
|
12706
12748
|
return dir;
|
|
12707
12749
|
}
|
|
12708
|
-
const legacy = path9.join(process.env.XDG_CONFIG_HOME || path9.join(
|
|
12750
|
+
const legacy = path9.join(process.env.XDG_CONFIG_HOME || path9.join(os3.homedir(), ".config"), "workflow-toolkit");
|
|
12709
12751
|
if (!existsSync3(legacy)) {
|
|
12710
12752
|
migratedDir = dir;
|
|
12711
12753
|
return dir;
|
|
@@ -13002,6 +13044,7 @@ var workspaceConfigSchema = object({
|
|
|
13002
13044
|
autoApprove: union([boolean2(), array(nonBlank)]).optional(),
|
|
13003
13045
|
defaultEndpoint: unknown().optional(),
|
|
13004
13046
|
verification: _enum(["self", "independent"]).optional(),
|
|
13047
|
+
trailers: boolean2().optional(),
|
|
13005
13048
|
autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
13006
13049
|
kind,
|
|
13007
13050
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -13283,8 +13326,8 @@ var resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd,
|
|
|
13283
13326
|
var runtimeWorkspaceIndexSchema = object({
|
|
13284
13327
|
workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
13285
13328
|
}).passthrough();
|
|
13286
|
-
var matchRuntimeWorkspace = (cwd) => {
|
|
13287
|
-
const file = path10.join(
|
|
13329
|
+
var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
|
|
13330
|
+
const file = path10.join(dir, "workspaces.json");
|
|
13288
13331
|
let raw;
|
|
13289
13332
|
try {
|
|
13290
13333
|
raw = readFileSync3(file, "utf8");
|
|
@@ -13313,7 +13356,7 @@ var matchRuntimeWorkspace = (cwd) => {
|
|
|
13313
13356
|
const matches = matchingEntries(cwd, entries ?? []);
|
|
13314
13357
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
13315
13358
|
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
13316
|
-
return selected ? { file, selected } : null;
|
|
13359
|
+
return selected ? { file, selected, matches } : null;
|
|
13317
13360
|
};
|
|
13318
13361
|
var resolveRuntimeReleaseTracks = (cwd) => {
|
|
13319
13362
|
const matched = matchRuntimeWorkspace(cwd);
|
|
@@ -13655,7 +13698,7 @@ var git3 = (cwd, args) => {
|
|
|
13655
13698
|
return run.status === 0 ? (run.stdout ?? "").trim() : null;
|
|
13656
13699
|
};
|
|
13657
13700
|
var recordedBaseKey = (branch) => `branch.${branch}.workitBase`;
|
|
13658
|
-
var
|
|
13701
|
+
var escapeRegExp2 = (text) => text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
13659
13702
|
var reflog = (cwd, ref) => (git3(cwd, ["log", "-g", "--date=unix", "--format=%H%x09%gd%x09%gs", ref, "--"]) ?? "").split(`
|
|
13660
13703
|
`).map((line) => {
|
|
13661
13704
|
const [sha = "", selector = "", ...subject] = line.split("\t");
|
|
@@ -13687,7 +13730,7 @@ function gitTrackProbe(cwd) {
|
|
|
13687
13730
|
const created = own.at(-1);
|
|
13688
13731
|
if (!created || created.subject !== "branch: Created from HEAD")
|
|
13689
13732
|
return null;
|
|
13690
|
-
const pattern = new RegExp(`^checkout: moving from (\\S+) to ${
|
|
13733
|
+
const pattern = new RegExp(`^checkout: moving from (\\S+) to ${escapeRegExp2(branch)}$`, "u");
|
|
13691
13734
|
const entry = reflog(cwd, "HEAD").findLast((item) => item.time >= created.time && item.sha === created.sha && pattern.test(item.subject));
|
|
13692
13735
|
return entry ? pattern.exec(entry.subject)?.[1] ?? null : null;
|
|
13693
13736
|
},
|
|
@@ -15691,9 +15734,9 @@ Autonomy contract:
|
|
|
15691
15734
|
ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
|
|
15692
15735
|
the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
|
|
15693
15736
|
never merging; \`merged\` also lands it with \`workit pr merge\`.
|
|
15694
|
-
Merge and release need a workspace grant
|
|
15695
|
-
|
|
15696
|
-
|
|
15737
|
+
Merge and release need a workspace grant only the user raises from their
|
|
15738
|
+
own terminal (a blocked verb names how); never edit workspaces.json or route
|
|
15739
|
+
around a grant_required.
|
|
15697
15740
|
- Ask only for a product or preference choice, or for authority you lack, with
|
|
15698
15741
|
your recommended answer. Facts are yours: read, run or prototype.
|
|
15699
15742
|
- Label claims measured (run and seen this session), inferred, or guess.
|
|
@@ -15702,17 +15745,19 @@ Autonomy contract:
|
|
|
15702
15745
|
- Author is not verifier: your own verdict is \`--self\`, shown as
|
|
15703
15746
|
self-reviewed, never verified. High risk, \`verification: independent\` and
|
|
15704
15747
|
merge need a verifier with its own host-derived session (a subagent's
|
|
15705
|
-
\`<lead>:<child
|
|
15748
|
+
\`<lead>:<child>\`); never hand-mint one (\`<lead>-v1\`).
|
|
15706
15749
|
- A local-commit endpoint does not imply PR readiness, and a local commit alone
|
|
15707
15750
|
is not evidence of a requested remote push. Before reporting delivery,
|
|
15708
15751
|
reconcile every requested item and observe it (\`workit verify-delivery\`).
|
|
15709
15752
|
|
|
15710
15753
|
CLI first: if a step has one right answer, use the \`workit\` verb instead of
|
|
15711
15754
|
hand-running git, gh or glab (\`workit git|pr|ci|check\`; \`workit help\` lists
|
|
15712
|
-
the rest;
|
|
15755
|
+
the rest; lacking \`workit\`, \`npx -y @brainervirus/workit-cli\`).
|
|
15756
|
+
Add Co-Authored-By via \`workit git commit --trailer "K: v" -- <paths>\`, never
|
|
15757
|
+
an amend.
|
|
15713
15758
|
The task families (task, policy, evidence, finding, decision, worker, state)
|
|
15714
15759
|
are optional continuity for tracked work; each branch has one implicit task,
|
|
15715
|
-
|
|
15760
|
+
and a solo edit needs no task. A decision
|
|
15716
15761
|
records a user choice; it never authorizes an effect. Judge work once with
|
|
15717
15762
|
\`workit policy assess --judge risk= behavior= product-choice= plan=\`.
|
|
15718
15763
|
Across repositories, bind each item to its checkout, branch and endpoint,
|
|
@@ -15867,7 +15912,7 @@ import path17 from "node:path";
|
|
|
15867
15912
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
15868
15913
|
import { createHash as createHash12 } from "node:crypto";
|
|
15869
15914
|
import fs14 from "node:fs";
|
|
15870
|
-
import
|
|
15915
|
+
import os4 from "node:os";
|
|
15871
15916
|
import path16 from "node:path";
|
|
15872
15917
|
|
|
15873
15918
|
// packages/workit-core/src/core/branch.ts
|
|
@@ -16293,7 +16338,7 @@ var isAbsolute = (value) => path16.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(v
|
|
|
16293
16338
|
var joinDir = (base, next) => {
|
|
16294
16339
|
if (base === undefined || /[$`*?]/.test(next) || next === "-")
|
|
16295
16340
|
return;
|
|
16296
|
-
const expanded = next === "~" || next.startsWith("~/") ? path16.join(
|
|
16341
|
+
const expanded = next === "~" || next.startsWith("~/") ? path16.join(os4.homedir(), next.slice(1)) : next;
|
|
16297
16342
|
return base === null || isAbsolute(expanded) ? expanded : path16.join(base, expanded);
|
|
16298
16343
|
};
|
|
16299
16344
|
var cdTarget = (words) => {
|
|
@@ -16345,7 +16390,7 @@ function rawInvocations(command, dialect = "posix", depth = 0) {
|
|
|
16345
16390
|
const name = commandName(words[0]);
|
|
16346
16391
|
if (CD.has(name)) {
|
|
16347
16392
|
const target = cdTarget(words);
|
|
16348
|
-
dir = target === null ?
|
|
16393
|
+
dir = target === null ? os4.homedir() : joinDir(dir, target);
|
|
16349
16394
|
continue;
|
|
16350
16395
|
}
|
|
16351
16396
|
if (PUSHD.has(name)) {
|
|
@@ -17179,7 +17224,7 @@ var judgeInputSummary = (raw) => {
|
|
|
17179
17224
|
};
|
|
17180
17225
|
|
|
17181
17226
|
// packages/workit-core/src/autonomy.ts
|
|
17182
|
-
import
|
|
17227
|
+
import os5 from "node:os";
|
|
17183
17228
|
import path18 from "node:path";
|
|
17184
17229
|
|
|
17185
17230
|
// packages/workit-core/src/core/safe-write.ts
|
|
@@ -17208,9 +17253,9 @@ function writeFileExclusive(file, content, mode) {
|
|
|
17208
17253
|
// packages/workit-core/src/autonomy.ts
|
|
17209
17254
|
var accountHome = () => {
|
|
17210
17255
|
try {
|
|
17211
|
-
return
|
|
17256
|
+
return os5.userInfo().homedir;
|
|
17212
17257
|
} catch {
|
|
17213
|
-
return
|
|
17258
|
+
return os5.homedir();
|
|
17214
17259
|
}
|
|
17215
17260
|
};
|
|
17216
17261
|
var grantsHome = { resolve: accountHome };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-opencode",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.12.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit OpenCode plugin — native tools, adaptive policy, and sixteen method skills",
|
|
6
6
|
"keywords": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"typecheck": "tsc --noEmit"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@brainervirus/workit-core": "^8.
|
|
42
|
+
"@brainervirus/workit-core": "^8.12.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@opencode/plugin": "2.0.18"
|