@brainervirus/workit-mcp 1.2.0 → 1.2.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.
- package/dist/index.js +109 -36
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -20402,6 +20402,7 @@ var workerSchema = object4({
|
|
|
20402
20402
|
assignment: assignmentSchema,
|
|
20403
20403
|
state: _enum2(["assigned", "dispatching", "running", "cancelling", "stopped", "unknown"]),
|
|
20404
20404
|
session: refSchema.nullable(),
|
|
20405
|
+
coordinator: refSchema.optional(),
|
|
20405
20406
|
report: workerReportSchema.nullable()
|
|
20406
20407
|
}).strict();
|
|
20407
20408
|
var ownerSchema = object4({
|
|
@@ -20513,6 +20514,7 @@ var taskSummarySchema = object4({
|
|
|
20513
20514
|
requirements: array3(requirementEvaluationSchema),
|
|
20514
20515
|
writer: workspaceRecordSchema.shape.writer
|
|
20515
20516
|
}).strict();
|
|
20517
|
+
var taskListItemSchema = taskSummarySchema.omit({ policy: true, requirements: true });
|
|
20516
20518
|
var exportBundleSchema = object4({
|
|
20517
20519
|
schemaVersion: literal3(1),
|
|
20518
20520
|
exportedAt: utc,
|
|
@@ -20534,11 +20536,15 @@ var taskOperations = {
|
|
|
20534
20536
|
expectedWorkspaceRevision: revision.nullable().optional(),
|
|
20535
20537
|
intent: intentSchema
|
|
20536
20538
|
}),
|
|
20537
|
-
list: operation({
|
|
20539
|
+
list: operation({
|
|
20540
|
+
action: literal3("list"),
|
|
20541
|
+
status: _enum2(["open", "closed", "all"]).optional(),
|
|
20542
|
+
limit: number5().int().min(1).max(50).optional()
|
|
20543
|
+
}),
|
|
20538
20544
|
inspect: operation({
|
|
20539
20545
|
action: literal3("inspect"),
|
|
20540
20546
|
...taskId,
|
|
20541
|
-
view: _enum2(["summary", "full"])
|
|
20547
|
+
view: _enum2(["summary", "full"]).optional()
|
|
20542
20548
|
}),
|
|
20543
20549
|
revise: operation({
|
|
20544
20550
|
action: literal3("revise"),
|
|
@@ -20566,7 +20572,7 @@ var taskOperations = {
|
|
|
20566
20572
|
...taskId,
|
|
20567
20573
|
...revisions,
|
|
20568
20574
|
expectedWorkspaceRevision: revision.optional(),
|
|
20569
|
-
authorityRefs: array3(refSchema)
|
|
20575
|
+
authorityRefs: array3(refSchema).optional()
|
|
20570
20576
|
}),
|
|
20571
20577
|
close: operation({
|
|
20572
20578
|
action: literal3("close"),
|
|
@@ -22399,6 +22405,10 @@ var validPath = (value) => typeof value === "string" && value.length > 0 && ![..
|
|
|
22399
22405
|
}) && !value.split(/[\\/]/).includes("..");
|
|
22400
22406
|
var callerValue = (value) => ({ host: value.host, actor: value.actor });
|
|
22401
22407
|
var workerIdOf = (value) => value.workerId ?? null;
|
|
22408
|
+
var currentWriterOwnsTask = (task, workspace, caller) => {
|
|
22409
|
+
const owner = workspace.writer?.owner;
|
|
22410
|
+
return task.status === "active" && task.workspaceId === workspace.id && owner?.taskId === task.id && owner.session.host === caller.host && owner.session.handle === caller.actor;
|
|
22411
|
+
};
|
|
22402
22412
|
function assertProductWriteAllowed(input) {
|
|
22403
22413
|
if (!Array.isArray(input.paths) || input.paths.some((path) => !validPath(path)))
|
|
22404
22414
|
return failure("invalid_input", "invalid product write path");
|
|
@@ -23115,9 +23125,11 @@ var standingReceiptFor = (root, workspace, cls, dir) => {
|
|
|
23115
23125
|
var verifyStandingApproval = (root, task, caller, binding) => {
|
|
23116
23126
|
if (task.status !== "active")
|
|
23117
23127
|
return failure("invalid_transition", "only active tasks can authorize actions");
|
|
23118
|
-
const
|
|
23119
|
-
if (!
|
|
23120
|
-
return
|
|
23128
|
+
const workspace = new TaskStore(root).readWorkspace();
|
|
23129
|
+
if (!workspace.ok)
|
|
23130
|
+
return workspace;
|
|
23131
|
+
if (!workspace.data || !currentWriterOwnsTask(task, workspace.data, caller))
|
|
23132
|
+
return failure("permission_denied", "standing approval requires the current writer session");
|
|
23121
23133
|
const standing = binding.standing;
|
|
23122
23134
|
if (!standing || typeof standing.workspace !== "string" || typeof standing.class !== "string")
|
|
23123
23135
|
return failure("invalid_input", "standing approval needs a workspace and class");
|
|
@@ -23354,6 +23366,20 @@ var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
|
|
|
23354
23366
|
};
|
|
23355
23367
|
var verifyContentRefs = (store, binding) => verifyDecisionContentAtRoot(store.root, binding);
|
|
23356
23368
|
var storedDecisionApplicable = (store, task, purpose, binding) => task.decisions.filter((entry) => entry.provenance.kind !== "imported" && decisionMatches(entry, purpose, binding) && verifyDecisionContentAtRoot(store.root, entry.data.binding).ok);
|
|
23369
|
+
var approvalAuthorityMatches = (store, task, approval, current) => {
|
|
23370
|
+
if (approval.kind !== "host_observed" || approval.receipts.length === 0)
|
|
23371
|
+
return false;
|
|
23372
|
+
if (provenanceMatches(approval, current))
|
|
23373
|
+
return true;
|
|
23374
|
+
const session = current.kind === "host_observed" ? current.session : null;
|
|
23375
|
+
if (!session || session.kind !== "host")
|
|
23376
|
+
return false;
|
|
23377
|
+
const workspace = store.readWorkspace();
|
|
23378
|
+
return workspace.ok && workspace.data !== null && currentWriterOwnsTask(task, workspace.data, {
|
|
23379
|
+
host: session.host,
|
|
23380
|
+
actor: session.handle
|
|
23381
|
+
});
|
|
23382
|
+
};
|
|
23357
23383
|
var validateAction = (store, task, workspaceId, input, authority) => {
|
|
23358
23384
|
if (task.status !== "active")
|
|
23359
23385
|
return failure("invalid_transition", "only active tasks can authorize actions");
|
|
@@ -23379,7 +23405,7 @@ var validateAction = (store, task, workspaceId, input, authority) => {
|
|
|
23379
23405
|
return failure("permission_denied", "native reservation authority does not match decision");
|
|
23380
23406
|
if (decision.response !== "approved")
|
|
23381
23407
|
return failure("permission_denied", "decision was rejected");
|
|
23382
|
-
if (
|
|
23408
|
+
if (!approvalAuthorityMatches(store, task, entry.provenance, authority.provenance))
|
|
23383
23409
|
return failure("permission_denied", "action approval lacks native receipt assurance");
|
|
23384
23410
|
const receipts = entry.provenance.receipts;
|
|
23385
23411
|
const standing = receipts.filter((receipt) => typeof receipt === "object" && receipt !== null && receipt.kind === "standing");
|
|
@@ -23546,7 +23572,7 @@ function settleAction(input) {
|
|
|
23546
23572
|
return failure("not_found", "decision not found");
|
|
23547
23573
|
if (!authorityDecisionMatches(authority, entry.data))
|
|
23548
23574
|
return failure("permission_denied", "native settlement authority does not match decision");
|
|
23549
|
-
if (!
|
|
23575
|
+
if (!approvalAuthorityMatches(input.store, current, entry.provenance, authority.provenance))
|
|
23550
23576
|
return failure("permission_denied", "native settlement caller does not match approval");
|
|
23551
23577
|
if (entry.data.purpose !== "action" || entry.data.digest !== decisionDigest(entry.data))
|
|
23552
23578
|
return failure("permission_denied", "decision binding is invalid");
|
|
@@ -23645,7 +23671,7 @@ function reconcileAction(input) {
|
|
|
23645
23671
|
const entry = current.decisions.find((candidate) => candidate.id === input.decisionId);
|
|
23646
23672
|
if (!entry || entry.data.purpose !== "action")
|
|
23647
23673
|
return failure("not_found", "decision not found");
|
|
23648
|
-
if (!authorityDecisionMatches(authority, entry.data) || !
|
|
23674
|
+
if (!authorityDecisionMatches(authority, entry.data) || !approvalAuthorityMatches(input.store, current, entry.provenance, authority.provenance))
|
|
23649
23675
|
return failure("permission_denied", "native reconciliation caller does not match approval");
|
|
23650
23676
|
if (entry.data.response !== "approved" || entry.data.revoked !== null || entry.data.digest !== decisionDigest(entry.data) || entry.data.binding.taskId !== current.id || entry.data.binding.workspaceId !== current.workspaceId || entry.data.binding.workspaceId !== workspace.data.id)
|
|
23651
23677
|
return failure("permission_denied", "reconciliation decision binding is invalid");
|
|
@@ -23982,7 +24008,7 @@ var resolveBinding = (evidence, pin, currentCandidateId) => {
|
|
|
23982
24008
|
candidateId: evidence.candidateId ?? fallback
|
|
23983
24009
|
};
|
|
23984
24010
|
};
|
|
23985
|
-
var findingVerificationPasses = (findingCandidateId, evidence) => evidence.status === "passed" && (evidence.kind === "check" || evidence.kind === "review") && ((findingCandidateId ?? null) === null || evidence.candidateId
|
|
24011
|
+
var findingVerificationPasses = (findingCandidateId, evidence) => evidence.status === "passed" && (evidence.kind === "check" || evidence.kind === "review") && ((findingCandidateId ?? null) === null || evidence.candidateId != null);
|
|
23986
24012
|
var applicableDecision2 = (task, workspace, requirement, checkoutRoot) => task.decisions.filter((entry) => entry.provenance.kind !== "imported").map((entry) => entry.data).filter((decision) => decision.purpose === "limitation" && decision.response === "approved" && decision.revoked === null && decision.binding.taskId === task.id && decision.binding.workspaceId === workspace.id && decision.requirementIds.includes(requirement.id) && decision.binding.scope && scopeCovers2(decision.binding.scope, requirement.scope) && decision.digest === decisionDigest(decision) && (checkoutRoot ? verifyDecisionContentAtRoot(checkoutRoot, decision.binding).ok : decision.binding.contentRefs.every((reference) => reference.kind !== "file")));
|
|
23987
24013
|
var applicableRequirementDecision = (task, workspace, requirement, checkoutRoot) => task.decisions.filter(({ data, provenance }) => provenance.kind !== "imported" && data.purpose !== "limitation" && (data.response === "approved" || data.response === "stated") && data.revoked === null && data.binding.taskId === task.id && data.binding.workspaceId === workspace.id && data.requirementIds.includes(requirement.id) && scopeCovers2(data.binding.scope, requirement.scope) && data.digest === decisionDigest(data) && (checkoutRoot ? verifyDecisionContentAtRoot(checkoutRoot, data.binding).ok : data.binding.contentRefs.every((reference) => reference.kind !== "file"))).map(({ id }) => ({ id }));
|
|
23988
24014
|
var evidenceMatchesRequirement = (kind, evidenceKind, dimension, ruleId) => {
|
|
@@ -24217,6 +24243,11 @@ var exportDigest = (bundle) => sha256({
|
|
|
24217
24243
|
task: bundle.task
|
|
24218
24244
|
});
|
|
24219
24245
|
// packages/workit-core/src/core/external-action.ts
|
|
24246
|
+
var chainStepSchema = union3([
|
|
24247
|
+
string5().min(1),
|
|
24248
|
+
object4({ branch: string5().min(1) }).strict(),
|
|
24249
|
+
object4({ pr: literal3(true) }).strict()
|
|
24250
|
+
]);
|
|
24220
24251
|
var externalActionSchema = discriminatedUnion2("operation", [
|
|
24221
24252
|
object4({
|
|
24222
24253
|
operation: literal3("git.branch_setup"),
|
|
@@ -24231,7 +24262,7 @@ var externalActionSchema = discriminatedUnion2("operation", [
|
|
|
24231
24262
|
operation: literal3("git.commit"),
|
|
24232
24263
|
payload: object4({
|
|
24233
24264
|
message: string5().min(1).optional(),
|
|
24234
|
-
plan_steps: array3(
|
|
24265
|
+
plan_steps: array3(chainStepSchema).min(1).max(32).optional(),
|
|
24235
24266
|
plan_branch: string5().min(1).optional()
|
|
24236
24267
|
}).strict()
|
|
24237
24268
|
}).strict(),
|
|
@@ -24717,6 +24748,7 @@ var verifyNativeWorker = (verifier, input, binding) => {
|
|
|
24717
24748
|
expectedWorkspaceRevision: expected.expectedWorkspaceRevision,
|
|
24718
24749
|
state: expected.state,
|
|
24719
24750
|
session: expected.session,
|
|
24751
|
+
report: expected.report ?? null,
|
|
24720
24752
|
provenance: result.data,
|
|
24721
24753
|
...binding
|
|
24722
24754
|
});
|
|
@@ -24727,7 +24759,7 @@ var takeWorker = (token, binding, expected) => {
|
|
|
24727
24759
|
verifiedWorkers.delete(token);
|
|
24728
24760
|
if (!value)
|
|
24729
24761
|
return null;
|
|
24730
|
-
if (value.owner !== binding.owner || value.store !== binding.store || value.root !== binding.root || value.root !== value.store.root || !sameValue(value.caller, binding.caller) || value.taskId !== expected.taskId || value.workerId !== expected.workerId || value.expectedRevision !== expected.expectedRevision || value.expectedWorkspaceRevision !== expected.expectedWorkspaceRevision || value.state !== expected.state || !sameValue(value.session, expected.session))
|
|
24762
|
+
if (value.owner !== binding.owner || value.store !== binding.store || value.root !== binding.root || value.root !== value.store.root || !sameValue(value.caller, binding.caller) || value.taskId !== expected.taskId || value.workerId !== expected.workerId || value.expectedRevision !== expected.expectedRevision || value.expectedWorkspaceRevision !== expected.expectedWorkspaceRevision || value.state !== expected.state || !sameValue(value.session, expected.session) || !sameValue(value.report, expected.report ?? null))
|
|
24731
24763
|
return null;
|
|
24732
24764
|
return value;
|
|
24733
24765
|
};
|
|
@@ -24768,6 +24800,8 @@ var applyWorkerLifecycle = (input) => {
|
|
|
24768
24800
|
return failure("invalid_transition", "worker already has an observed session");
|
|
24769
24801
|
if (notStarted && !["dispatching", "cancelling"].includes(entry.data.state))
|
|
24770
24802
|
return failure("invalid_transition", "worker launch was not claimed");
|
|
24803
|
+
if (input.report && input.state !== "stopped")
|
|
24804
|
+
return failure("invalid_input", "worker reports require a stopped worker");
|
|
24771
24805
|
if ((input.state === "running" || input.state === "cancelling" || input.state === "stopped" && !notStarted) && !input.session)
|
|
24772
24806
|
return failure("invalid_input", "running worker observations require a session");
|
|
24773
24807
|
if (entry.data.session && !sameValue(entry.data.session, input.session))
|
|
@@ -24784,12 +24818,13 @@ var applyWorkerLifecycle = (input) => {
|
|
|
24784
24818
|
data: {
|
|
24785
24819
|
...entry.data,
|
|
24786
24820
|
state: terminalCancel ? "cancelling" : input.state,
|
|
24787
|
-
session: input.session
|
|
24821
|
+
session: input.session,
|
|
24822
|
+
report: entry.data.report ?? input.report ?? null
|
|
24788
24823
|
}
|
|
24789
24824
|
};
|
|
24790
24825
|
const shouldClear = input.state === "stopped" && workspace.data.writer !== null && workspace.data.writer.owner.taskId === task.data.id && workspace.data.writer.owner.workerId === input.workerId;
|
|
24791
24826
|
const shouldUncertain = input.state === "unknown" && workspace.data.writer !== null && workspace.data.writer.owner.taskId === task.data.id && workspace.data.writer.owner.workerId === input.workerId;
|
|
24792
|
-
if (entry.data.state === nextEntry.data.state && sameValue(entry.data.session, input.session) && !shouldClear && !shouldUncertain)
|
|
24827
|
+
if (entry.data.state === nextEntry.data.state && sameValue(entry.data.session, input.session) && sameValue(entry.data.report, nextEntry.data.report) && !shouldClear && !shouldUncertain)
|
|
24793
24828
|
return success(task.data.revision, workspace.data.revision, entry);
|
|
24794
24829
|
const changed = input.store.mutateTaskAndWorkspace({
|
|
24795
24830
|
taskId: task.data.id,
|
|
@@ -25207,14 +25242,30 @@ class WorkitCore {
|
|
|
25207
25242
|
const listed = this.store.listTasks();
|
|
25208
25243
|
if (!listed.ok)
|
|
25209
25244
|
return listed;
|
|
25210
|
-
const
|
|
25211
|
-
|
|
25212
|
-
|
|
25213
|
-
|
|
25214
|
-
|
|
25215
|
-
|
|
25216
|
-
|
|
25217
|
-
|
|
25245
|
+
const status = input.status ?? "open";
|
|
25246
|
+
const limit = input.limit ?? 20;
|
|
25247
|
+
const selected = listed.data.filter((task) => status === "all" ? true : status === "closed" ? task.status === "closed" : task.status !== "closed").sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)).slice(0, limit);
|
|
25248
|
+
if (selected.length === 0)
|
|
25249
|
+
return success(null, null, []);
|
|
25250
|
+
const workspace = this.store.readWorkspace();
|
|
25251
|
+
if (!workspace.ok)
|
|
25252
|
+
return workspace;
|
|
25253
|
+
if (!workspace.data)
|
|
25254
|
+
return failure("not_found", "workspace not found");
|
|
25255
|
+
const tasks = selected.map((task) => ({
|
|
25256
|
+
id: task.id,
|
|
25257
|
+
revision: task.revision,
|
|
25258
|
+
workspaceRevision: workspace.data.revision,
|
|
25259
|
+
createdAt: task.createdAt,
|
|
25260
|
+
updatedAt: task.updatedAt,
|
|
25261
|
+
runtime: task.runtime ?? null,
|
|
25262
|
+
objective: task.intent.data.objective,
|
|
25263
|
+
status: task.status,
|
|
25264
|
+
closure: task.closure,
|
|
25265
|
+
progress: task.progress,
|
|
25266
|
+
writer: task.status === "closed" ? null : workspace.data.writer
|
|
25267
|
+
}));
|
|
25268
|
+
return success(null, null, tasks);
|
|
25218
25269
|
}
|
|
25219
25270
|
case "inspect": {
|
|
25220
25271
|
const task = this.store.readTask(input.taskId);
|
|
@@ -25223,7 +25274,7 @@ class WorkitCore {
|
|
|
25223
25274
|
const helper = this.helperTaskGuard(task.data, true);
|
|
25224
25275
|
if (!helper.ok)
|
|
25225
25276
|
return helper;
|
|
25226
|
-
if (input.view === "summary")
|
|
25277
|
+
if ((input.view ?? "summary") === "summary")
|
|
25227
25278
|
return this.summary(task.data);
|
|
25228
25279
|
return this.view(task.data);
|
|
25229
25280
|
}
|
|
@@ -25567,7 +25618,7 @@ class WorkitCore {
|
|
|
25567
25618
|
const evaluations = evaluateEvidence(task.data, current.data);
|
|
25568
25619
|
const verified = evidence.some((entry) => {
|
|
25569
25620
|
const evaluation = evaluations.find((item) => item.evidenceId === entry.id);
|
|
25570
|
-
return findingVerificationPasses(finding.data.candidateId, {
|
|
25621
|
+
return entry.recordedAt >= finding.recordedAt && findingVerificationPasses(finding.data.candidateId, {
|
|
25571
25622
|
kind: entry.data.kind,
|
|
25572
25623
|
candidateId: entry.data.candidateId,
|
|
25573
25624
|
status: evaluation?.status ?? "missing"
|
|
@@ -25647,7 +25698,18 @@ class WorkitCore {
|
|
|
25647
25698
|
if (task.data.status !== "active")
|
|
25648
25699
|
return failure("invalid_transition", "paused or closed tasks cannot assign workers");
|
|
25649
25700
|
if (!bindingCovers(task.data.intent.data.scope, input.assignment.scope))
|
|
25650
|
-
return failure("permission_denied", "worker assignment is outside task scope"
|
|
25701
|
+
return failure("permission_denied", "worker assignment is outside task scope", {
|
|
25702
|
+
fields: [
|
|
25703
|
+
{
|
|
25704
|
+
path: "assignment.scope",
|
|
25705
|
+
reason: `paths ${JSON.stringify(input.assignment.scope.paths)} must be contained by lead paths ${JSON.stringify(task.data.intent.data.scope.paths)}`
|
|
25706
|
+
},
|
|
25707
|
+
{
|
|
25708
|
+
path: "task.intent.scope",
|
|
25709
|
+
reason: `lead paths are ${JSON.stringify(task.data.intent.data.scope.paths)}`
|
|
25710
|
+
}
|
|
25711
|
+
]
|
|
25712
|
+
});
|
|
25651
25713
|
if (input.assignment.decisionIds.some((id) => !task.data.decisions.some((entry) => entry.id === id)))
|
|
25652
25714
|
return failure("invalid_input", "worker assignment references an unknown decision");
|
|
25653
25715
|
if (input.assignment.requirementIds.some((id) => !task.data.policy?.requirements.some((requirement) => requirement.id === id)))
|
|
@@ -25854,7 +25916,15 @@ class WorkitCore {
|
|
|
25854
25916
|
...item,
|
|
25855
25917
|
recordedAt: mutation.now,
|
|
25856
25918
|
provenance: attested.data,
|
|
25857
|
-
data: {
|
|
25919
|
+
data: {
|
|
25920
|
+
...item.data,
|
|
25921
|
+
state: "dispatching",
|
|
25922
|
+
coordinator: {
|
|
25923
|
+
kind: "host",
|
|
25924
|
+
host: this.context.caller.host,
|
|
25925
|
+
handle: this.context.caller.actor
|
|
25926
|
+
}
|
|
25927
|
+
}
|
|
25858
25928
|
} : item)
|
|
25859
25929
|
});
|
|
25860
25930
|
}
|
|
@@ -25930,6 +26000,7 @@ class WorkitCore {
|
|
|
25930
26000
|
expectedWorkspaceRevision: input.expectedWorkspaceRevision,
|
|
25931
26001
|
state: "stopped",
|
|
25932
26002
|
session: null,
|
|
26003
|
+
report: null,
|
|
25933
26004
|
provenance: attested.data,
|
|
25934
26005
|
owner: this.authorityOwner,
|
|
25935
26006
|
store: this.store,
|
|
@@ -26237,10 +26308,12 @@ class WorkitCore {
|
|
|
26237
26308
|
return workspace;
|
|
26238
26309
|
if (!workspace.data)
|
|
26239
26310
|
return failure("not_found", "workspace not found");
|
|
26240
|
-
const
|
|
26311
|
+
const historical = task.status === "closed" ? task.candidates.at(-1) : undefined;
|
|
26312
|
+
const current = historical ? success(null, null, historical) : captureCandidate(this.store.root, task.intent.data.scope, environment());
|
|
26241
26313
|
if (!current.ok)
|
|
26242
26314
|
return current;
|
|
26243
|
-
const
|
|
26315
|
+
const evaluationWorkspace = task.status === "closed" ? { ...workspace.data, writer: null } : workspace.data;
|
|
26316
|
+
const requirements = evaluateRequirements(task, evaluationWorkspace, this.context.capabilities, current.data, this.store.root, this.context.caller);
|
|
26244
26317
|
return success(task.revision, workspace.data.revision, {
|
|
26245
26318
|
id: task.id,
|
|
26246
26319
|
revision: task.revision,
|
|
@@ -26254,7 +26327,7 @@ class WorkitCore {
|
|
|
26254
26327
|
progress: task.progress,
|
|
26255
26328
|
policy: task.policy,
|
|
26256
26329
|
requirements,
|
|
26257
|
-
writer:
|
|
26330
|
+
writer: evaluationWorkspace.writer
|
|
26258
26331
|
});
|
|
26259
26332
|
}
|
|
26260
26333
|
view(task) {
|
|
@@ -26263,13 +26336,15 @@ class WorkitCore {
|
|
|
26263
26336
|
return workspace;
|
|
26264
26337
|
if (!workspace.data)
|
|
26265
26338
|
return failure("not_found", "workspace not found");
|
|
26266
|
-
const
|
|
26339
|
+
const historical = task.status === "closed" ? task.candidates.at(-1) : undefined;
|
|
26340
|
+
const current = historical ? success(null, null, historical) : captureCandidate(this.store.root, task.intent.data.scope, environment());
|
|
26267
26341
|
if (!current.ok)
|
|
26268
26342
|
return current;
|
|
26269
|
-
const
|
|
26343
|
+
const evaluationWorkspace = task.status === "closed" ? { ...workspace.data, writer: null } : workspace.data;
|
|
26344
|
+
const requirements = evaluateRequirements(task, evaluationWorkspace, this.context.capabilities, current.data, this.store.root, this.context.caller);
|
|
26270
26345
|
return success(task.revision, workspace.data.revision, {
|
|
26271
26346
|
task,
|
|
26272
|
-
workspace:
|
|
26347
|
+
workspace: evaluationWorkspace,
|
|
26273
26348
|
capabilities: this.context.capabilities,
|
|
26274
26349
|
requirements,
|
|
26275
26350
|
evidence: evaluateEvidence(task, current.data)
|
|
@@ -26360,8 +26435,6 @@ class WorkitCore {
|
|
|
26360
26435
|
return helper;
|
|
26361
26436
|
if (status === "paused" && task.data.status !== "active" || status === "active" && task.data.status !== "paused")
|
|
26362
26437
|
return failure("invalid_transition", `cannot transition ${task.data.status} to ${status}`);
|
|
26363
|
-
if (status === "active" && input.authorityRefs.length === 0)
|
|
26364
|
-
return failure("permission_denied", "resuming a task requires authority references");
|
|
26365
26438
|
const workspace = this.store.readWorkspace();
|
|
26366
26439
|
if (!workspace.ok)
|
|
26367
26440
|
return workspace;
|
|
@@ -26391,7 +26464,7 @@ class WorkitCore {
|
|
|
26391
26464
|
return failure("needs_input", "imported task requires fresh destination evidence");
|
|
26392
26465
|
if (current.data.blockers.some((blocker) => blocker.dependentAction === "resume" || blocker.reason === "worker state requires reconciliation"))
|
|
26393
26466
|
return failure("recovery_required", "imported task requires resume reconciliation");
|
|
26394
|
-
if (!validResumeApproval(task.data, workspace.data, input.authorityRefs, this.context))
|
|
26467
|
+
if (!validResumeApproval(task.data, workspace.data, input.authorityRefs ?? [], this.context))
|
|
26395
26468
|
return failure("permission_denied", "imported resume requires native destination approval");
|
|
26396
26469
|
resumeCandidate = current.data.candidate;
|
|
26397
26470
|
}
|
|
@@ -26521,7 +26594,7 @@ class WorkitCore {
|
|
|
26521
26594
|
task: (value, context) => success(context.revision, null, {
|
|
26522
26595
|
...value,
|
|
26523
26596
|
status: "closed",
|
|
26524
|
-
candidates:
|
|
26597
|
+
candidates: taskForView.candidates,
|
|
26525
26598
|
closure: {
|
|
26526
26599
|
outcome: closure.data.outcome,
|
|
26527
26600
|
at: context.now,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-mcp",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit shared MCP transport for the eight task and policy operation families",
|
|
6
6
|
"keywords": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"build": "bun scripts/build.ts"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@brainervirus/workit-core": "^1.2.
|
|
45
|
+
"@brainervirus/workit-core": "^1.2.1",
|
|
46
46
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
47
47
|
"zod": "4.5.4"
|
|
48
48
|
},
|