@brainervirus/workit-core 1.0.0 → 1.0.2
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/package.json
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Workit
|
|
5
|
+
"description": "Workit shared core — task, policy, evidence, review, decision, worker, and writer state for agentic coding workflows",
|
|
6
6
|
"keywords": [
|
|
7
|
-
"
|
|
7
|
+
"agentic-coding",
|
|
8
|
+
"ai-agents",
|
|
9
|
+
"codex",
|
|
8
10
|
"cursor",
|
|
9
11
|
"mcp",
|
|
10
12
|
"opencode",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
+
"pi",
|
|
14
|
+
"policy-engine",
|
|
15
|
+
"task-management",
|
|
16
|
+
"typescript",
|
|
17
|
+
"workflow"
|
|
13
18
|
],
|
|
19
|
+
"homepage": "https://github.com/BrainerVirus/workit#readme",
|
|
14
20
|
"bugs": {
|
|
15
21
|
"url": "https://github.com/BrainerVirus/workit/issues"
|
|
16
22
|
},
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
// AR-16: path-gated releases.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// AR-16: path-gated releases. A releasable commit counts only when it touches
|
|
3
|
+
// a PRODUCT PATH (any of the four package dirs). Tooling-only merges produce no
|
|
4
|
+
// release at all. A payload change typed docs/chore still publishes as patch —
|
|
5
|
+
// skills and metadata live in the tarball, so installed users must receive
|
|
6
|
+
// them; merge-backs and the release's own manifest sync never do.
|
|
5
7
|
import { execFileSync } from "node:child_process";
|
|
6
8
|
import { resolve } from "node:path";
|
|
7
9
|
|
|
@@ -15,6 +17,9 @@ export const RELEASE_PACKAGES = [
|
|
|
15
17
|
"workit-pi",
|
|
16
18
|
] as const;
|
|
17
19
|
|
|
20
|
+
/** The release pipeline's own version-sync commit: never a release trigger. */
|
|
21
|
+
const RELEASE_SYNC = /^chore\(release\): sync manifests\b/;
|
|
22
|
+
|
|
18
23
|
const g = (root: string, args: string[]): string =>
|
|
19
24
|
execFileSync("git", args, { cwd: root, encoding: "utf8" }).trim();
|
|
20
25
|
|
|
@@ -64,9 +69,10 @@ const commitsSince = (root: string, from: string): { message: string; files: str
|
|
|
64
69
|
}));
|
|
65
70
|
};
|
|
66
71
|
|
|
67
|
-
export function analyzeReleaseScope(
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
export function analyzeReleaseScope(root = process.cwd()): {
|
|
73
|
+
level: Level | null;
|
|
74
|
+
productPkgs: string[];
|
|
75
|
+
} {
|
|
70
76
|
const from = latestTag(root);
|
|
71
77
|
if (from === null) {
|
|
72
78
|
return { level: "minor", productPkgs: [...RELEASE_PACKAGES] };
|
|
@@ -74,18 +80,27 @@ export function analyzeReleaseScope(
|
|
|
74
80
|
const commits = commitsSince(root, from);
|
|
75
81
|
const levels: Level[] = [];
|
|
76
82
|
const pkgs = new Set<string>();
|
|
83
|
+
let payloadOnly = false;
|
|
77
84
|
for (const { message, files } of commits) {
|
|
78
|
-
const
|
|
85
|
+
const subject = (message.split("\n")[0] ?? "").trim();
|
|
86
|
+
if (RELEASE_SYNC.test(subject)) continue;
|
|
87
|
+
const touched = files.filter((f) =>
|
|
88
|
+
RELEASE_PACKAGES.some((p) => f.startsWith(`packages/${p}/`)),
|
|
89
|
+
);
|
|
79
90
|
if (touched.length === 0) continue;
|
|
80
91
|
const lvl = subjectLevel(message);
|
|
81
92
|
if (lvl) levels.push(lvl);
|
|
93
|
+
else if (!subject.startsWith("Merge ")) payloadOnly = true;
|
|
82
94
|
for (const f of touched) {
|
|
83
95
|
const pkg = RELEASE_PACKAGES.find((p) => f.startsWith(`packages/${p}/`));
|
|
84
96
|
if (pkg) pkgs.add(pkg);
|
|
85
97
|
}
|
|
86
98
|
}
|
|
87
|
-
if (levels.length === 0) return { level: null, productPkgs: [...pkgs] };
|
|
88
|
-
const level = levels.reduce<Level>(
|
|
99
|
+
if (levels.length === 0) return { level: payloadOnly ? "patch" : null, productPkgs: [...pkgs] };
|
|
100
|
+
const level = levels.reduce<Level>(
|
|
101
|
+
(best, l) => (LEVEL_RANK[l] > LEVEL_RANK[best] ? l : best),
|
|
102
|
+
"patch",
|
|
103
|
+
);
|
|
89
104
|
return { level, productPkgs: [...pkgs] };
|
|
90
105
|
}
|
|
91
106
|
|
|
@@ -31,3 +31,8 @@ selects requirements; do not wait for a rule that can only exist after assess.
|
|
|
31
31
|
|
|
32
32
|
PR merged per settings, or a status brief (frontier state, next action) when
|
|
33
33
|
blocked on the human. Record evidence for fixes, findings for blockers.
|
|
34
|
+
|
|
35
|
+
A squash merge creates a new commit on the base branch, so the pre-merge
|
|
36
|
+
candidate identity changes: re-record verification and review evidence against
|
|
37
|
+
the merged commit before `task.close`, or the close will report unsatisfied
|
|
38
|
+
requirements.
|
|
@@ -28,8 +28,10 @@ selects requirements; do not wait for a rule that can only exist after assess.
|
|
|
28
28
|
dependency order and recompute after every answer — a wall of questions is
|
|
29
29
|
not an interview.
|
|
30
30
|
4. Funnel every resolution: the moment a consequential choice settles, bind it
|
|
31
|
-
with a receipt-shaped question
|
|
32
|
-
|
|
31
|
+
with a receipt-shaped question — header `Workit decision: <purpose>` and the
|
|
32
|
+
same label repeated in the question text (host UIs may not render headers) —
|
|
33
|
+
exactly `approved`/`rejected` options, the approved description carrying the
|
|
34
|
+
exact content.
|
|
33
35
|
If the user already stated the choice in conversation and no receipt can be
|
|
34
36
|
minted, record it in task progress and reassess so the settled requirement
|
|
35
37
|
retires — never re-ask to mint a receipt, and never leave it for close to
|
|
@@ -20,11 +20,14 @@ selects requirements; do not wait for a rule that can only exist after assess.
|
|
|
20
20
|
blockers. Never trust memory across an interruption.
|
|
21
21
|
2. Classify the steering:
|
|
22
22
|
- same-task: fold into scope (reassess if facts changed), continue.
|
|
23
|
-
- new-task: `task.
|
|
23
|
+
- new-task: `task.pause` the parked lead task, then `task.start` +
|
|
24
|
+
`policy.assess` for the new one. Keep exactly one active lead per
|
|
25
|
+
session: external actions bind to that single active task, and a second
|
|
26
|
+
active lead makes writer authority ambiguous.
|
|
24
27
|
- quick-question: answer from the parked state, then resume.
|
|
25
28
|
3. Handle it with the same rigor as the parked work (no drive-by edits).
|
|
26
29
|
4. Re-anchor: one-line resume brief (where we were, what changed, what
|
|
27
|
-
is next)
|
|
30
|
+
is next), then `task.resume` the parked task before touching it again.
|
|
28
31
|
|
|
29
32
|
## Completion
|
|
30
33
|
|
package/src/core/methods.ts
CHANGED
|
@@ -101,7 +101,10 @@ check and review kinds auto-bind the current tree and need no digests. Record
|
|
|
101
101
|
verification evidence last: later evidence or commits can reopen fixed findings
|
|
102
102
|
for re-verification, so verify, resolve, then close with nothing in between.
|
|
103
103
|
decision.record {binding with taskId/workspaceId from inspect plus presented and
|
|
104
|
-
approvedContent} only through a native approval question
|
|
104
|
+
approvedContent} only through a native approval question asked receipt-shaped:
|
|
105
|
+
header Workit decision: <purpose>, the same label repeated in the question
|
|
106
|
+
text (some host UIs do not render headers), exactly two options approved and
|
|
107
|
+
rejected; ask once, never re-ask to mint a receipt. task.close {outcome,
|
|
105
108
|
summary, decisionIds}. A completed native subagent run stops its bound worker
|
|
106
109
|
by itself; if a worker strands in cancelling with its run verifiably over,
|
|
107
110
|
repeat worker.cancel {reason} to confirm the stop. Check and review evidence
|