@brainervirus/workit-cli 1.0.7 → 1.0.9

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.
Files changed (2) hide show
  1. package/dist/index.js +72 -11
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -50965,7 +50965,7 @@ var workerReportSchema = object({
50965
50965
  }).strict();
50966
50966
  var workerSchema = object({
50967
50967
  assignment: assignmentSchema,
50968
- state: _enum(["assigned", "running", "cancelling", "stopped", "unknown"]),
50968
+ state: _enum(["assigned", "dispatching", "running", "cancelling", "stopped", "unknown"]),
50969
50969
  session: refSchema.nullable(),
50970
50970
  report: workerReportSchema.nullable()
50971
50971
  }).strict();
@@ -58945,6 +58945,52 @@ function evaluateClosure(requestedOutcome, view) {
58945
58945
  });
58946
58946
  }
58947
58947
 
58948
+ // packages/workit-core/src/core/methods.ts
58949
+ var METHODS = {
58950
+ "workit-challenge": { dimensions: ["challenge", "decisions"] },
58951
+ "workit-behavioral-tdd": { dimensions: ["testing"] },
58952
+ "workit-review": { dimensions: ["review"] },
58953
+ "workit-plan": { dimensions: ["artifacts", "continuity"] },
58954
+ "workit-implement": { dimensions: ["delegation"] },
58955
+ "workit-debug": { ruleIds: ["root-cause-investigation"] },
58956
+ "workit-handoff": { ruleIds: ["durable-handoff"] },
58957
+ "workit-deslop": { ruleIds: ["pre-pr-cleanup"] }
58958
+ };
58959
+ var methodMatches = (id, definition, requirement) => definition.dimensions?.includes(requirement.dimension) === true && !(id === "workit-review" && requirement.ruleId === "self-review") || definition.ruleIds?.includes(requirement.ruleId) === true;
58960
+ var assuranceFor = (id, definition, capabilities) => {
58961
+ const keys = new Set([
58962
+ id,
58963
+ ...definition.dimensions ?? [],
58964
+ ...definition.ruleIds ?? []
58965
+ ]);
58966
+ const matches = capabilities.filter((capability) => keys.has(capability.name) || keys.has(capability.surface));
58967
+ if (id === "workit-review" && matches.length === 0)
58968
+ return { assurance: "unavailable", reasons: ["independent review capability is unavailable"] };
58969
+ if (matches.some((capability) => capability.assurance === "unavailable"))
58970
+ return {
58971
+ assurance: "unavailable",
58972
+ reasons: matches.filter((capability) => capability.assurance === "unavailable").map((capability) => capability.reason)
58973
+ };
58974
+ if (matches.some((capability) => capability.assurance === "enforced"))
58975
+ return { assurance: "enforced", reasons: matches.map((capability) => capability.reason) };
58976
+ return { assurance: "agent_guided", reasons: matches.map((capability) => capability.reason) };
58977
+ };
58978
+ function selectMethods(policy, capabilities) {
58979
+ return Object.entries(METHODS).flatMap(([id, definition]) => {
58980
+ const requirements = policy.requirements.filter((requirement) => methodMatches(id, definition, requirement));
58981
+ if (requirements.length === 0)
58982
+ return [];
58983
+ const capability = assuranceFor(id, definition, capabilities);
58984
+ const reasons = [
58985
+ ...new Set(requirements.map((requirement) => requirement.reason)),
58986
+ ...capability.reasons
58987
+ ];
58988
+ if (capability.assurance === "unavailable")
58989
+ reasons.unshift("required capability is unavailable");
58990
+ return [{ id, reason: reasons.join("; "), assurance: capability.assurance }];
58991
+ });
58992
+ }
58993
+
58948
58994
  // packages/workit-core/src/core/task-context.ts
58949
58995
  function reconcileResume(view, observations = []) {
58950
58996
  if (observations.length > 0)
@@ -58954,7 +59000,7 @@ function reconcileResume(view, observations = []) {
58954
59000
  return candidate;
58955
59001
  const staleEvidenceIds = evaluateEvidence(view.task, candidate.data).filter((entry) => entry.status === "stale").map((entry) => entry.evidenceId);
58956
59002
  const blockers = [...view.task.progress.blockers];
58957
- if (view.task.workers.some((entry) => ["running", "cancelling", "unknown"].includes(entry.data.state)))
59003
+ if (view.task.workers.some((entry) => ["dispatching", "running", "cancelling", "unknown"].includes(entry.data.state)))
58958
59004
  blockers.push({
58959
59005
  reason: "worker state requires reconciliation",
58960
59006
  dependentAction: "resume",
@@ -59004,6 +59050,11 @@ function compactTaskContext(view) {
59004
59050
  digest: entry.data.digest,
59005
59051
  references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference)
59006
59052
  }));
59053
+ const methods = view.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
59054
+ id: method.id,
59055
+ assurance: method.assurance,
59056
+ reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
59057
+ })) : [];
59007
59058
  const gaps = Array.from(new Set([
59008
59059
  ...view.evidence.filter((entry) => entry.status === "stale").map((entry) => `stale evidence: ${entry.evidenceId}`),
59009
59060
  ...view.requirements.filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
@@ -59013,15 +59064,18 @@ function compactTaskContext(view) {
59013
59064
  objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
59014
59065
  status: view.task.status,
59015
59066
  decisions,
59067
+ methods,
59016
59068
  gaps,
59017
59069
  nextAction: compactText(view.task.progress.nextAction, COMPACT_TEXT_BYTES)
59018
59070
  };
59019
59071
  let encoded = JSON.stringify(context);
59020
- while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.gaps.length)) {
59072
+ while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
59021
59073
  if (context.gaps.length)
59022
59074
  context.gaps.pop();
59023
- else
59075
+ else if (context.decisions.length)
59024
59076
  context.decisions.pop();
59077
+ else
59078
+ context.methods.pop();
59025
59079
  encoded = JSON.stringify(context);
59026
59080
  }
59027
59081
  if (compactBytes(encoded) > COMPACT_MAX_BYTES) {
@@ -59796,10 +59850,10 @@ var applyWorkerLifecycle = (input) => {
59796
59850
  const notStarted = input.dispatch === true;
59797
59851
  if (notStarted && (input.state !== "stopped" || input.session !== null))
59798
59852
  return failure("invalid_input", "a never-dispatched worker stops with no session");
59799
- if (notStarted && (entry.data.state === "stopped" || entry.data.state === "unknown"))
59800
- return failure("invalid_transition", "worker is no longer awaiting dispatch");
59801
- if (notStarted && (entry.data.session !== null || entry.data.state === "running"))
59853
+ if (notStarted && entry.data.session !== null)
59802
59854
  return failure("invalid_transition", "worker already has an observed session");
59855
+ if (notStarted && !["dispatching", "cancelling"].includes(entry.data.state))
59856
+ return failure("invalid_transition", "worker launch was not claimed");
59803
59857
  if ((input.state === "running" || input.state === "cancelling" || input.state === "stopped" && !notStarted) && !input.session)
59804
59858
  return failure("invalid_input", "running worker observations require a session");
59805
59859
  if (entry.data.session && !sameValue(entry.data.session, input.session))
@@ -60186,7 +60240,7 @@ class WorkitCore {
60186
60240
  activeWorkerBlocker(task, workspace) {
60187
60241
  if (workspace.writer)
60188
60242
  return failure("recovery_required", "writer ownership must be released first");
60189
- if (task.workers.some((entry) => ["running", "cancelling", "unknown"].includes(entry.data.state)))
60243
+ if (task.workers.some((entry) => ["dispatching", "running", "cancelling", "unknown"].includes(entry.data.state)))
60190
60244
  return failure("recovery_required", "worker state requires reconciliation");
60191
60245
  return null;
60192
60246
  }
@@ -60950,7 +61004,12 @@ class WorkitCore {
60950
61004
  return failure("invalid_transition", "worker is not awaiting dispatch");
60951
61005
  return success(mutation.revision, null, {
60952
61006
  ...current,
60953
- workers: current.workers.map((item) => item.id === input.workerId ? { ...item, recordedAt: mutation.now, provenance: attested.data } : item)
61007
+ workers: current.workers.map((item) => item.id === input.workerId ? {
61008
+ ...item,
61009
+ recordedAt: mutation.now,
61010
+ provenance: attested.data,
61011
+ data: { ...item.data, state: "dispatching" }
61012
+ } : item)
60954
61013
  });
60955
61014
  }
60956
61015
  });
@@ -61419,7 +61478,7 @@ class WorkitCore {
61419
61478
  const base = reconcileResume(effectiveView);
61420
61479
  if (!base.ok)
61421
61480
  return base;
61422
- const needsReconciliation = view.task.workers.some((entry) => ["running", "cancelling", "unknown"].includes(observedStates.get(entry.id) ?? entry.data.state));
61481
+ const needsReconciliation = view.task.workers.some((entry) => ["dispatching", "running", "cancelling", "unknown"].includes(observedStates.get(entry.id) ?? entry.data.state));
61423
61482
  const blockers = [...base.data.blockers];
61424
61483
  if (needsReconciliation && !blockers.some((entry) => entry.reason === "worker state requires reconciliation"))
61425
61484
  blockers.push({
@@ -64434,6 +64493,7 @@ var resolveExternalActionRequest = (root, request, preservedDateMs) => {
64434
64493
  return failure("storage_error", "external action target could not be resolved");
64435
64494
  }
64436
64495
  };
64496
+ var prBabysitNext = (output) => `Babysit ${output} to merge-ready (drive mode default). Follow skill workit-babysit: declare mode in this turn, work conflicts, review threads, then CI, and record a frontier brief in task progress per pass. Opt out with babysit:false.`;
64437
64497
  var executeConcreteExternalAction = async (request, root, marker, dateMs, step, workText, caller, approvedBeforeDigest, approvedBeforeExists) => {
64438
64498
  if (localAction(request.operation)) {
64439
64499
  if (!caller)
@@ -64477,7 +64537,8 @@ var executeConcreteExternalAction = async (request, root, marker, dateMs, step,
64477
64537
  return result.error || result.ok === false ? unknown2(request.operation) : success(null, null, {
64478
64538
  ...result,
64479
64539
  babysit: request.payload.babysit ?? true,
64480
- babysitSkill: "workit-babysit"
64540
+ babysitSkill: "workit-babysit",
64541
+ ...request.payload.babysit ?? true ? { next: prBabysitNext(String(result.output ?? "")) } : {}
64481
64542
  });
64482
64543
  }
64483
64544
  case "changelog.apply": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cli",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "private": false,
5
5
  "description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
6
6
  "keywords": [
@@ -37,9 +37,9 @@
37
37
  "typecheck": "tsc --noEmit"
38
38
  },
39
39
  "dependencies": {
40
- "@brainervirus/workit-core": "^1.0.7",
41
- "@brainervirus/workit-cursor": "^1.0.7",
42
- "@brainervirus/workit-opencode": "^1.0.7",
40
+ "@brainervirus/workit-core": "^1.0.9",
41
+ "@brainervirus/workit-cursor": "^1.0.9",
42
+ "@brainervirus/workit-opencode": "^1.0.9",
43
43
  "@inkjs/ui": "2.0.0",
44
44
  "ink": "7.1.1",
45
45
  "react": "19.2.8"