@brainervirus/workit-pi 1.0.8 → 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.
- package/dist/worker.js +1 -1
- package/dist/workit.js +161 -100
- package/package.json +1 -1
- package/skills/workit-babysit/SKILL.md +3 -1
package/dist/worker.js
CHANGED
|
@@ -7591,7 +7591,7 @@ var workerReportSchema = object({
|
|
|
7591
7591
|
}).strict();
|
|
7592
7592
|
var workerSchema = object({
|
|
7593
7593
|
assignment: assignmentSchema,
|
|
7594
|
-
state: _enum(["assigned", "running", "cancelling", "stopped", "unknown"]),
|
|
7594
|
+
state: _enum(["assigned", "dispatching", "running", "cancelling", "stopped", "unknown"]),
|
|
7595
7595
|
session: refSchema.nullable(),
|
|
7596
7596
|
report: workerReportSchema.nullable()
|
|
7597
7597
|
}).strict();
|
package/dist/workit.js
CHANGED
|
@@ -7834,7 +7834,7 @@ var workerReportSchema = object({
|
|
|
7834
7834
|
}).strict();
|
|
7835
7835
|
var workerSchema = object({
|
|
7836
7836
|
assignment: assignmentSchema,
|
|
7837
|
-
state: _enum(["assigned", "running", "cancelling", "stopped", "unknown"]),
|
|
7837
|
+
state: _enum(["assigned", "dispatching", "running", "cancelling", "stopped", "unknown"]),
|
|
7838
7838
|
session: refSchema.nullable(),
|
|
7839
7839
|
report: workerReportSchema.nullable()
|
|
7840
7840
|
}).strict();
|
|
@@ -10659,6 +10659,95 @@ function evaluateClosure(requestedOutcome, view) {
|
|
|
10659
10659
|
});
|
|
10660
10660
|
}
|
|
10661
10661
|
|
|
10662
|
+
// packages/workit-core/src/core/methods.ts
|
|
10663
|
+
var METHODS = {
|
|
10664
|
+
"workit-challenge": { dimensions: ["challenge", "decisions"] },
|
|
10665
|
+
"workit-behavioral-tdd": { dimensions: ["testing"] },
|
|
10666
|
+
"workit-review": { dimensions: ["review"] },
|
|
10667
|
+
"workit-plan": { dimensions: ["artifacts", "continuity"] },
|
|
10668
|
+
"workit-implement": { dimensions: ["delegation"] },
|
|
10669
|
+
"workit-debug": { ruleIds: ["root-cause-investigation"] },
|
|
10670
|
+
"workit-handoff": { ruleIds: ["durable-handoff"] },
|
|
10671
|
+
"workit-deslop": { ruleIds: ["pre-pr-cleanup"] }
|
|
10672
|
+
};
|
|
10673
|
+
var methodMatches = (id, definition, requirement) => definition.dimensions?.includes(requirement.dimension) === true && !(id === "workit-review" && requirement.ruleId === "self-review") || definition.ruleIds?.includes(requirement.ruleId) === true;
|
|
10674
|
+
var assuranceFor = (id, definition, capabilities) => {
|
|
10675
|
+
const keys = new Set([
|
|
10676
|
+
id,
|
|
10677
|
+
...definition.dimensions ?? [],
|
|
10678
|
+
...definition.ruleIds ?? []
|
|
10679
|
+
]);
|
|
10680
|
+
const matches = capabilities.filter((capability) => keys.has(capability.name) || keys.has(capability.surface));
|
|
10681
|
+
if (id === "workit-review" && matches.length === 0)
|
|
10682
|
+
return { assurance: "unavailable", reasons: ["independent review capability is unavailable"] };
|
|
10683
|
+
if (matches.some((capability) => capability.assurance === "unavailable"))
|
|
10684
|
+
return {
|
|
10685
|
+
assurance: "unavailable",
|
|
10686
|
+
reasons: matches.filter((capability) => capability.assurance === "unavailable").map((capability) => capability.reason)
|
|
10687
|
+
};
|
|
10688
|
+
if (matches.some((capability) => capability.assurance === "enforced"))
|
|
10689
|
+
return { assurance: "enforced", reasons: matches.map((capability) => capability.reason) };
|
|
10690
|
+
return { assurance: "agent_guided", reasons: matches.map((capability) => capability.reason) };
|
|
10691
|
+
};
|
|
10692
|
+
function selectMethods(policy, capabilities) {
|
|
10693
|
+
return Object.entries(METHODS).flatMap(([id, definition]) => {
|
|
10694
|
+
const requirements = policy.requirements.filter((requirement) => methodMatches(id, definition, requirement));
|
|
10695
|
+
if (requirements.length === 0)
|
|
10696
|
+
return [];
|
|
10697
|
+
const capability = assuranceFor(id, definition, capabilities);
|
|
10698
|
+
const reasons = [
|
|
10699
|
+
...new Set(requirements.map((requirement) => requirement.reason)),
|
|
10700
|
+
...capability.reasons
|
|
10701
|
+
];
|
|
10702
|
+
if (capability.assurance === "unavailable")
|
|
10703
|
+
reasons.unshift("required capability is unavailable");
|
|
10704
|
+
return [{ id, reason: reasons.join("; "), assurance: capability.assurance }];
|
|
10705
|
+
});
|
|
10706
|
+
}
|
|
10707
|
+
var invariantBootstrap = () => `
|
|
10708
|
+
Workit keeps one accountable lead and one shared task state. Inspect current task
|
|
10709
|
+
state before acting. An empty task.list means no session yet, not permission to
|
|
10710
|
+
skip Workit; for user-requested product, debug, or behavior work with no active
|
|
10711
|
+
or paused task, run task.start then policy.assess before other product mutations.
|
|
10712
|
+
Omitted expectedRevision, expectedWorkspaceRevision, and writer workerId default
|
|
10713
|
+
to the current records; explicit values are still concurrency-checked, so never
|
|
10714
|
+
copy revisions between calls. Happy path: task.list, task.start {intent} with no
|
|
10715
|
+
revisions, policy.assess {assessment: {facts, signals, consequences,
|
|
10716
|
+
verification}} where facts are inferred or observed with file refs,
|
|
10717
|
+
writer.acquire {taskId} before product writes, evidence.record {evidence} where
|
|
10718
|
+
check and review kinds auto-bind the current tree and need no digests. Record
|
|
10719
|
+
self-review requirements with kind review and reviewContext matching your own
|
|
10720
|
+
host session; the lead may also record checks. Fresh-context review requires a
|
|
10721
|
+
session distinct from the task creator and every other evidence recorder. Record
|
|
10722
|
+
verification evidence last: later evidence or commits can reopen fixed findings
|
|
10723
|
+
for re-verification, so verify, resolve, then close with nothing in between.
|
|
10724
|
+
decision.record {binding with taskId/workspaceId from inspect plus presented and
|
|
10725
|
+
approvedContent} only through a native approval question asked receipt-shaped:
|
|
10726
|
+
header Workit decision: <purpose>, the same label repeated in the question
|
|
10727
|
+
text (some host UIs do not render headers), exactly two options approved and
|
|
10728
|
+
rejected; ask once, never re-ask to mint a receipt. task.close {outcome,
|
|
10729
|
+
summary, decisionIds}. A completed native subagent run stops its bound worker
|
|
10730
|
+
by itself; if a worker strands in cancelling with its run verifiably over,
|
|
10731
|
+
repeat worker.cancel {reason} to confirm the stop. Check and review evidence
|
|
10732
|
+
without a bound candidate goes stale; findings close only as fixed with passing
|
|
10733
|
+
verification, dismissed with supporting evidence, or deferred under an approved
|
|
10734
|
+
limitation. Use only the
|
|
10735
|
+
shared operations for task, policy, evidence, finding, decision, worker, writer,
|
|
10736
|
+
and state changes. Authority is bounded by the requested scope, current
|
|
10737
|
+
revision, caller/session provenance, and observed capabilities. Never claim host
|
|
10738
|
+
enforcement or evidence that the host cannot provide. Shell-executed writes are
|
|
10739
|
+
unattested agent-guided work even when a writer is held. Preserve unresolved
|
|
10740
|
+
requirements, gaps, and uncertain workers. Skill routing: slash aliases /wk-*
|
|
10741
|
+
always load on demand. Model-invoked: new instructions, interruptions, or
|
|
10742
|
+
forgotten items mid-task → load workit-steer before responding; about to open
|
|
10743
|
+
a PR or fresh from implementing → load workit-deslop; CI red → load
|
|
10744
|
+
workit-green-run; small-looking change before close or merge → load
|
|
10745
|
+
workit-blast-radius; ambiguous, consequential, or disputed proposal before
|
|
10746
|
+
recommending → load workit-challenge; spec or plan needs a flow diagram →
|
|
10747
|
+
load workit-diagram, a UI sketch → load workit-mockup. Load the skill; never
|
|
10748
|
+
act from memory of it.
|
|
10749
|
+
`.trim();
|
|
10750
|
+
|
|
10662
10751
|
// packages/workit-core/src/core/task-context.ts
|
|
10663
10752
|
function reconcileResume(view, observations = []) {
|
|
10664
10753
|
if (observations.length > 0)
|
|
@@ -10668,7 +10757,7 @@ function reconcileResume(view, observations = []) {
|
|
|
10668
10757
|
return candidate;
|
|
10669
10758
|
const staleEvidenceIds = evaluateEvidence(view.task, candidate.data).filter((entry) => entry.status === "stale").map((entry) => entry.evidenceId);
|
|
10670
10759
|
const blockers = [...view.task.progress.blockers];
|
|
10671
|
-
if (view.task.workers.some((entry) => ["running", "cancelling", "unknown"].includes(entry.data.state)))
|
|
10760
|
+
if (view.task.workers.some((entry) => ["dispatching", "running", "cancelling", "unknown"].includes(entry.data.state)))
|
|
10672
10761
|
blockers.push({
|
|
10673
10762
|
reason: "worker state requires reconciliation",
|
|
10674
10763
|
dependentAction: "resume",
|
|
@@ -10718,6 +10807,11 @@ function compactTaskContext(view) {
|
|
|
10718
10807
|
digest: entry.data.digest,
|
|
10719
10808
|
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference)
|
|
10720
10809
|
}));
|
|
10810
|
+
const methods = view.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
10811
|
+
id: method.id,
|
|
10812
|
+
assurance: method.assurance,
|
|
10813
|
+
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
10814
|
+
})) : [];
|
|
10721
10815
|
const gaps = Array.from(new Set([
|
|
10722
10816
|
...view.evidence.filter((entry) => entry.status === "stale").map((entry) => `stale evidence: ${entry.evidenceId}`),
|
|
10723
10817
|
...view.requirements.filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
@@ -10727,15 +10821,18 @@ function compactTaskContext(view) {
|
|
|
10727
10821
|
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
10728
10822
|
status: view.task.status,
|
|
10729
10823
|
decisions,
|
|
10824
|
+
methods,
|
|
10730
10825
|
gaps,
|
|
10731
10826
|
nextAction: compactText(view.task.progress.nextAction, COMPACT_TEXT_BYTES)
|
|
10732
10827
|
};
|
|
10733
10828
|
let encoded = JSON.stringify(context);
|
|
10734
|
-
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.gaps.length)) {
|
|
10829
|
+
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
10735
10830
|
if (context.gaps.length)
|
|
10736
10831
|
context.gaps.pop();
|
|
10737
|
-
else
|
|
10832
|
+
else if (context.decisions.length)
|
|
10738
10833
|
context.decisions.pop();
|
|
10834
|
+
else
|
|
10835
|
+
context.methods.pop();
|
|
10739
10836
|
encoded = JSON.stringify(context);
|
|
10740
10837
|
}
|
|
10741
10838
|
if (compactBytes(encoded) > COMPACT_MAX_BYTES) {
|
|
@@ -10751,94 +10848,47 @@ var exportDigest = (bundle) => sha256({
|
|
|
10751
10848
|
sourceWorkspaceId: bundle.sourceWorkspaceId,
|
|
10752
10849
|
task: bundle.task
|
|
10753
10850
|
});
|
|
10754
|
-
// packages/workit-core/src/core/
|
|
10755
|
-
var
|
|
10756
|
-
"
|
|
10757
|
-
"
|
|
10758
|
-
"workit-review": { dimensions: ["review"] },
|
|
10759
|
-
"workit-plan": { dimensions: ["artifacts", "continuity"] },
|
|
10760
|
-
"workit-implement": { dimensions: ["delegation"] },
|
|
10761
|
-
"workit-debug": { ruleIds: ["root-cause-investigation"] },
|
|
10762
|
-
"workit-handoff": { ruleIds: ["durable-handoff"] },
|
|
10763
|
-
"workit-deslop": { ruleIds: ["pre-pr-cleanup"] }
|
|
10851
|
+
// packages/workit-core/src/core/route-intent.ts
|
|
10852
|
+
var GUIDANCE = {
|
|
10853
|
+
"git.branch_setup": "use the Workit git.branch_setup action (workit_external_action in hosts, or `workit action git.branch_setup --payload '{}' --confirm --json` in the CLI)",
|
|
10854
|
+
"hosting.pull_request": "use the Workit hosting.pull_request action (workit_external_action in hosts, or `workit action hosting.pull_request --payload '{...}' --confirm --json` in the CLI), then drive the created PR through workit-babysit"
|
|
10764
10855
|
};
|
|
10765
|
-
var
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
id,
|
|
10769
|
-
...definition.dimensions ?? [],
|
|
10770
|
-
...definition.ruleIds ?? []
|
|
10771
|
-
]);
|
|
10772
|
-
const matches = capabilities.filter((capability) => keys.has(capability.name) || keys.has(capability.surface));
|
|
10773
|
-
if (id === "workit-review" && matches.length === 0)
|
|
10774
|
-
return { assurance: "unavailable", reasons: ["independent review capability is unavailable"] };
|
|
10775
|
-
if (matches.some((capability) => capability.assurance === "unavailable"))
|
|
10776
|
-
return {
|
|
10777
|
-
assurance: "unavailable",
|
|
10778
|
-
reasons: matches.filter((capability) => capability.assurance === "unavailable").map((capability) => capability.reason)
|
|
10779
|
-
};
|
|
10780
|
-
if (matches.some((capability) => capability.assurance === "enforced"))
|
|
10781
|
-
return { assurance: "enforced", reasons: matches.map((capability) => capability.reason) };
|
|
10782
|
-
return { assurance: "agent_guided", reasons: matches.map((capability) => capability.reason) };
|
|
10856
|
+
var unbalancedQuotes = (segment) => {
|
|
10857
|
+
const text = segment.replace(/\\./gu, "");
|
|
10858
|
+
return (text.match(/"/gu)?.length ?? 0) % 2 !== 0 || (text.match(/'/gu)?.length ?? 0) % 2 !== 0;
|
|
10783
10859
|
};
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
|
|
10795
|
-
|
|
10796
|
-
|
|
10797
|
-
|
|
10860
|
+
var segmentTokens = (segment) => {
|
|
10861
|
+
if (segment.includes("`") || segment.includes("$("))
|
|
10862
|
+
return null;
|
|
10863
|
+
if (unbalancedQuotes(segment))
|
|
10864
|
+
return null;
|
|
10865
|
+
const parts = segment.trim().split(/\s+/u);
|
|
10866
|
+
while (parts.length > 0 && /^[A-Za-z_][A-Za-z0-9_]*=/u.test(parts[0]))
|
|
10867
|
+
parts.shift();
|
|
10868
|
+
return parts.length > 0 ? parts : null;
|
|
10869
|
+
};
|
|
10870
|
+
var unquote = (token) => token.replace(/^['"]|['"]$/gu, "");
|
|
10871
|
+
function shellRouteIntent(command) {
|
|
10872
|
+
if (typeof command !== "string" || command.trim() === "")
|
|
10873
|
+
return null;
|
|
10874
|
+
for (const raw of command.split(/&&|\|\||;|\n/u)) {
|
|
10875
|
+
const parts = segmentTokens(raw);
|
|
10876
|
+
if (!parts)
|
|
10877
|
+
continue;
|
|
10878
|
+
const head = unquote(parts[0]);
|
|
10879
|
+
const second = unquote(parts[1] ?? "");
|
|
10880
|
+
const third = unquote(parts[2] ?? "");
|
|
10881
|
+
if (head === "git" && second === "switch" && (third === "-c" || third === "--create"))
|
|
10882
|
+
return { route: "git.branch_setup", guidance: GUIDANCE["git.branch_setup"] };
|
|
10883
|
+
if (head === "git" && second === "checkout" && (third === "-b" || third === "-B"))
|
|
10884
|
+
return { route: "git.branch_setup", guidance: GUIDANCE["git.branch_setup"] };
|
|
10885
|
+
if (head === "gh" && second === "pr" && third === "create")
|
|
10886
|
+
return { route: "hosting.pull_request", guidance: GUIDANCE["hosting.pull_request"] };
|
|
10887
|
+
if (head === "glab" && second === "mr" && third === "create")
|
|
10888
|
+
return { route: "hosting.pull_request", guidance: GUIDANCE["hosting.pull_request"] };
|
|
10889
|
+
}
|
|
10890
|
+
return null;
|
|
10798
10891
|
}
|
|
10799
|
-
var invariantBootstrap = () => `
|
|
10800
|
-
Workit keeps one accountable lead and one shared task state. Inspect current task
|
|
10801
|
-
state before acting. An empty task.list means no session yet, not permission to
|
|
10802
|
-
skip Workit; for user-requested product, debug, or behavior work with no active
|
|
10803
|
-
or paused task, run task.start then policy.assess before other product mutations.
|
|
10804
|
-
Omitted expectedRevision, expectedWorkspaceRevision, and writer workerId default
|
|
10805
|
-
to the current records; explicit values are still concurrency-checked, so never
|
|
10806
|
-
copy revisions between calls. Happy path: task.list, task.start {intent} with no
|
|
10807
|
-
revisions, policy.assess {assessment: {facts, signals, consequences,
|
|
10808
|
-
verification}} where facts are inferred or observed with file refs,
|
|
10809
|
-
writer.acquire {taskId} before product writes, evidence.record {evidence} where
|
|
10810
|
-
check and review kinds auto-bind the current tree and need no digests. Record
|
|
10811
|
-
self-review requirements with kind review and reviewContext matching your own
|
|
10812
|
-
host session; the lead may also record checks. Fresh-context review requires a
|
|
10813
|
-
session distinct from the task creator and every other evidence recorder. Record
|
|
10814
|
-
verification evidence last: later evidence or commits can reopen fixed findings
|
|
10815
|
-
for re-verification, so verify, resolve, then close with nothing in between.
|
|
10816
|
-
decision.record {binding with taskId/workspaceId from inspect plus presented and
|
|
10817
|
-
approvedContent} only through a native approval question asked receipt-shaped:
|
|
10818
|
-
header Workit decision: <purpose>, the same label repeated in the question
|
|
10819
|
-
text (some host UIs do not render headers), exactly two options approved and
|
|
10820
|
-
rejected; ask once, never re-ask to mint a receipt. task.close {outcome,
|
|
10821
|
-
summary, decisionIds}. A completed native subagent run stops its bound worker
|
|
10822
|
-
by itself; if a worker strands in cancelling with its run verifiably over,
|
|
10823
|
-
repeat worker.cancel {reason} to confirm the stop. Check and review evidence
|
|
10824
|
-
without a bound candidate goes stale; findings close only as fixed with passing
|
|
10825
|
-
verification, dismissed with supporting evidence, or deferred under an approved
|
|
10826
|
-
limitation. Use only the
|
|
10827
|
-
shared operations for task, policy, evidence, finding, decision, worker, writer,
|
|
10828
|
-
and state changes. Authority is bounded by the requested scope, current
|
|
10829
|
-
revision, caller/session provenance, and observed capabilities. Never claim host
|
|
10830
|
-
enforcement or evidence that the host cannot provide. Shell-executed writes are
|
|
10831
|
-
unattested agent-guided work even when a writer is held. Preserve unresolved
|
|
10832
|
-
requirements, gaps, and uncertain workers. Skill routing: slash aliases /wk-*
|
|
10833
|
-
always load on demand. Model-invoked: new instructions, interruptions, or
|
|
10834
|
-
forgotten items mid-task → load workit-steer before responding; about to open
|
|
10835
|
-
a PR or fresh from implementing → load workit-deslop; CI red → load
|
|
10836
|
-
workit-green-run; small-looking change before close or merge → load
|
|
10837
|
-
workit-blast-radius; ambiguous, consequential, or disputed proposal before
|
|
10838
|
-
recommending → load workit-challenge; spec or plan needs a flow diagram →
|
|
10839
|
-
load workit-diagram, a UI sketch → load workit-mockup. Load the skill; never
|
|
10840
|
-
act from memory of it.
|
|
10841
|
-
`.trim();
|
|
10842
10892
|
// packages/workit-core/src/core/external-action.ts
|
|
10843
10893
|
var externalActionSchema = discriminatedUnion("operation", [
|
|
10844
10894
|
object({
|
|
@@ -11617,10 +11667,10 @@ var applyWorkerLifecycle = (input) => {
|
|
|
11617
11667
|
const notStarted = input.dispatch === true;
|
|
11618
11668
|
if (notStarted && (input.state !== "stopped" || input.session !== null))
|
|
11619
11669
|
return failure("invalid_input", "a never-dispatched worker stops with no session");
|
|
11620
|
-
if (notStarted &&
|
|
11621
|
-
return failure("invalid_transition", "worker is no longer awaiting dispatch");
|
|
11622
|
-
if (notStarted && (entry.data.session !== null || entry.data.state === "running"))
|
|
11670
|
+
if (notStarted && entry.data.session !== null)
|
|
11623
11671
|
return failure("invalid_transition", "worker already has an observed session");
|
|
11672
|
+
if (notStarted && !["dispatching", "cancelling"].includes(entry.data.state))
|
|
11673
|
+
return failure("invalid_transition", "worker launch was not claimed");
|
|
11624
11674
|
if ((input.state === "running" || input.state === "cancelling" || input.state === "stopped" && !notStarted) && !input.session)
|
|
11625
11675
|
return failure("invalid_input", "running worker observations require a session");
|
|
11626
11676
|
if (entry.data.session && !sameValue(entry.data.session, input.session))
|
|
@@ -12007,7 +12057,7 @@ class WorkitCore {
|
|
|
12007
12057
|
activeWorkerBlocker(task, workspace) {
|
|
12008
12058
|
if (workspace.writer)
|
|
12009
12059
|
return failure("recovery_required", "writer ownership must be released first");
|
|
12010
|
-
if (task.workers.some((entry) => ["running", "cancelling", "unknown"].includes(entry.data.state)))
|
|
12060
|
+
if (task.workers.some((entry) => ["dispatching", "running", "cancelling", "unknown"].includes(entry.data.state)))
|
|
12011
12061
|
return failure("recovery_required", "worker state requires reconciliation");
|
|
12012
12062
|
return null;
|
|
12013
12063
|
}
|
|
@@ -12771,7 +12821,12 @@ class WorkitCore {
|
|
|
12771
12821
|
return failure("invalid_transition", "worker is not awaiting dispatch");
|
|
12772
12822
|
return success(mutation.revision, null, {
|
|
12773
12823
|
...current,
|
|
12774
|
-
workers: current.workers.map((item) => item.id === input.workerId ? {
|
|
12824
|
+
workers: current.workers.map((item) => item.id === input.workerId ? {
|
|
12825
|
+
...item,
|
|
12826
|
+
recordedAt: mutation.now,
|
|
12827
|
+
provenance: attested.data,
|
|
12828
|
+
data: { ...item.data, state: "dispatching" }
|
|
12829
|
+
} : item)
|
|
12775
12830
|
});
|
|
12776
12831
|
}
|
|
12777
12832
|
});
|
|
@@ -13240,7 +13295,7 @@ class WorkitCore {
|
|
|
13240
13295
|
const base = reconcileResume(effectiveView);
|
|
13241
13296
|
if (!base.ok)
|
|
13242
13297
|
return base;
|
|
13243
|
-
const needsReconciliation = view.task.workers.some((entry) => ["running", "cancelling", "unknown"].includes(observedStates.get(entry.id) ?? entry.data.state));
|
|
13298
|
+
const needsReconciliation = view.task.workers.some((entry) => ["dispatching", "running", "cancelling", "unknown"].includes(observedStates.get(entry.id) ?? entry.data.state));
|
|
13244
13299
|
const blockers = [...base.data.blockers];
|
|
13245
13300
|
if (needsReconciliation && !blockers.some((entry) => entry.reason === "worker state requires reconciliation"))
|
|
13246
13301
|
blockers.push({
|
|
@@ -13534,14 +13589,12 @@ var workitContext = (ctx) => {
|
|
|
13534
13589
|
|
|
13535
13590
|
Native Pi session: ${session}. Project-local Workit state is unavailable until Pi trusts this project.`;
|
|
13536
13591
|
let taskContext = null;
|
|
13537
|
-
let methods = [];
|
|
13538
13592
|
try {
|
|
13539
13593
|
const store = new TaskStore(ctx.cwd);
|
|
13540
13594
|
const tasks = store.listTasks();
|
|
13541
13595
|
if (tasks.ok) {
|
|
13542
13596
|
const task = tasks.data.filter((entry) => entry.status !== "closed" && (entry.intent.provenance.session?.kind === "host" && entry.intent.provenance.session.host === "pi" && entry.intent.provenance.session.handle === session || entry.workers.some((worker) => worker.data.session?.kind === "host" && worker.data.session.host === "pi" && worker.data.session.handle === session))).sort((left, right) => right.updatedAt.localeCompare(left.updatedAt))[0];
|
|
13543
13597
|
if (task) {
|
|
13544
|
-
methods = task.policy ? selectMethods(task.policy, piCapabilities(ctx)) : [];
|
|
13545
13598
|
const core = new WorkitCore(store, piContext(ctx));
|
|
13546
13599
|
const view = core.task({
|
|
13547
13600
|
schemaVersion: 1,
|
|
@@ -13554,13 +13607,11 @@ Native Pi session: ${session}. Project-local Workit state is unavailable until P
|
|
|
13554
13607
|
}
|
|
13555
13608
|
}
|
|
13556
13609
|
} catch {}
|
|
13557
|
-
const methodText = methods.length ? `
|
|
13558
|
-
Selected methods: ${methods.map((method) => `${method.id} (${method.assurance})`).join(", ")}.` : "";
|
|
13559
13610
|
const taskText = taskContext ? `
|
|
13560
13611
|
Current task context: ${taskContext}` : "";
|
|
13561
13612
|
return `${invariantBootstrap()}
|
|
13562
13613
|
|
|
13563
|
-
Native Pi session: ${session}.${
|
|
13614
|
+
Native Pi session: ${session}.${taskText}`;
|
|
13564
13615
|
};
|
|
13565
13616
|
|
|
13566
13617
|
// packages/workit-core/src/core/skill-manifests.ts
|
|
@@ -17415,6 +17466,16 @@ var registerWorkitTools = (pi, options = {}) => {
|
|
|
17415
17466
|
});
|
|
17416
17467
|
};
|
|
17417
17468
|
var enforceNativeWriter = (event, ctx) => {
|
|
17469
|
+
if (event.toolName === "bash") {
|
|
17470
|
+
const command = event.input?.command;
|
|
17471
|
+
const route = typeof command === "string" ? shellRouteIntent(command) : null;
|
|
17472
|
+
if (route)
|
|
17473
|
+
return {
|
|
17474
|
+
block: true,
|
|
17475
|
+
reason: `direct branch or PR creation bypasses the Workit route; ${route.guidance}`
|
|
17476
|
+
};
|
|
17477
|
+
return;
|
|
17478
|
+
}
|
|
17418
17479
|
if (event.toolName !== "write" && event.toolName !== "edit")
|
|
17419
17480
|
return;
|
|
17420
17481
|
if (!ctx.isProjectTrusted())
|
package/package.json
CHANGED
|
@@ -7,7 +7,9 @@ description: Use after creating a PR (auto-starts, drive default), when a PR nee
|
|
|
7
7
|
|
|
8
8
|
Babysit starts automatically on PR creation unless declined (`babysit:false`).
|
|
9
9
|
One babysitter per PR; never mutate PR topology (no rebase strategy changes,
|
|
10
|
-
no force-push).
|
|
10
|
+
no force-push). When a PR URL is observed from a route Workit did not enforce
|
|
11
|
+
(for example a raw `gh pr create` the host allowed), load this skill and drive
|
|
12
|
+
that PR anyway; do not claim the Workit route was enforced.
|
|
11
13
|
|
|
12
14
|
## Before method work
|
|
13
15
|
|