@brainervirus/workit-mcp 8.9.0 → 8.10.0
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 +240 -105
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -18436,64 +18436,11 @@ function acquireFileLockSync(targetPath, options) {
|
|
|
18436
18436
|
}
|
|
18437
18437
|
}
|
|
18438
18438
|
}
|
|
18439
|
-
// packages/workit-core/src/host-session.ts
|
|
18440
|
-
var HOST_SESSION_VARS = [
|
|
18441
|
-
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
18442
|
-
["PI_SESSION_ID", () => "pi"],
|
|
18443
|
-
[
|
|
18444
|
-
"CODEX_THREAD_ID",
|
|
18445
|
-
(env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
|
|
18446
|
-
]
|
|
18447
|
-
];
|
|
18448
|
-
var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
|
|
18449
|
-
function hostSessionFromEnv(env) {
|
|
18450
|
-
const value = (key) => env[key]?.trim() || null;
|
|
18451
|
-
let inner = null;
|
|
18452
|
-
for (const [key, host] of HOST_SESSION_VARS) {
|
|
18453
|
-
const session = value(key);
|
|
18454
|
-
if (session) {
|
|
18455
|
-
inner = { host: host(env), session };
|
|
18456
|
-
break;
|
|
18457
|
-
}
|
|
18458
|
-
}
|
|
18459
|
-
const declared = value("WORKIT_HOST");
|
|
18460
|
-
if (env.WORKIT_SESSION_ID !== undefined) {
|
|
18461
|
-
const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
|
|
18462
|
-
if (!inherited)
|
|
18463
|
-
return { host: declared, session: value("WORKIT_SESSION_ID") };
|
|
18464
|
-
}
|
|
18465
|
-
return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
|
|
18466
|
-
}
|
|
18467
|
-
|
|
18468
|
-
// packages/workit-core/src/core/package-root.ts
|
|
18469
|
-
import { existsSync } from "node:fs";
|
|
18470
|
-
import path3 from "node:path";
|
|
18471
|
-
import { fileURLToPath } from "node:url";
|
|
18472
|
-
var packageRoot = () => {
|
|
18473
|
-
let dir = path3.dirname(fileURLToPath(import.meta.url));
|
|
18474
|
-
while (true) {
|
|
18475
|
-
const parent = path3.dirname(dir);
|
|
18476
|
-
if (existsSync(path3.join(dir, "package.json")) || parent === dir)
|
|
18477
|
-
return dir;
|
|
18478
|
-
dir = parent;
|
|
18479
|
-
}
|
|
18480
|
-
};
|
|
18481
|
-
var assetRoot = () => {
|
|
18482
|
-
const root = packageRoot();
|
|
18483
|
-
const assets = path3.join(root, "assets");
|
|
18484
|
-
return existsSync(assets) ? assets : root;
|
|
18485
|
-
};
|
|
18486
|
-
|
|
18487
|
-
// packages/workit-core/src/core/store-lock.ts
|
|
18488
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
18489
|
-
import fs5 from "node:fs";
|
|
18490
|
-
import { hostname } from "node:os";
|
|
18491
|
-
|
|
18492
18439
|
// packages/workit-core/src/store/paths.ts
|
|
18493
18440
|
import { spawnSync } from "node:child_process";
|
|
18494
18441
|
import { createHash as createHash2 } from "node:crypto";
|
|
18495
18442
|
import fs4 from "node:fs";
|
|
18496
|
-
import
|
|
18443
|
+
import path3 from "node:path";
|
|
18497
18444
|
var NOT_A_REPO = /not a git repository \(or any (of the parent directories|parent up to)/u;
|
|
18498
18445
|
var gitRun = (cwd, args) => {
|
|
18499
18446
|
const run = spawnSync("git", args, {
|
|
@@ -18535,14 +18482,14 @@ var DISCOVERY_ENV = [
|
|
|
18535
18482
|
];
|
|
18536
18483
|
var isGitDir = (dir) => {
|
|
18537
18484
|
try {
|
|
18538
|
-
return fs4.statSync(
|
|
18485
|
+
return fs4.statSync(path3.join(dir, "HEAD")).isFile() && fs4.statSync(path3.join(dir, "objects")).isDirectory() && fs4.statSync(path3.join(dir, "refs")).isDirectory();
|
|
18539
18486
|
} catch {
|
|
18540
18487
|
return false;
|
|
18541
18488
|
}
|
|
18542
18489
|
};
|
|
18543
18490
|
var reftableRefs = (common) => {
|
|
18544
18491
|
try {
|
|
18545
|
-
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(
|
|
18492
|
+
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(path3.join(common, "config"), "utf8"));
|
|
18546
18493
|
} catch {
|
|
18547
18494
|
return false;
|
|
18548
18495
|
}
|
|
@@ -18562,7 +18509,7 @@ function fastGit(root) {
|
|
|
18562
18509
|
if (device !== null && stat.dev !== device)
|
|
18563
18510
|
return { kind: "none" };
|
|
18564
18511
|
device = stat.dev;
|
|
18565
|
-
const dotGit =
|
|
18512
|
+
const dotGit = path3.join(dir, ".git");
|
|
18566
18513
|
let entry = null;
|
|
18567
18514
|
try {
|
|
18568
18515
|
entry = fs4.statSync(dotGit);
|
|
@@ -18583,19 +18530,19 @@ function fastGit(root) {
|
|
|
18583
18530
|
const match = /^gitdir: (.+)$/mu.exec(text);
|
|
18584
18531
|
if (!match)
|
|
18585
18532
|
return null;
|
|
18586
|
-
gitDir =
|
|
18533
|
+
gitDir = path3.resolve(dir, match[1].trim());
|
|
18587
18534
|
} else
|
|
18588
18535
|
return null;
|
|
18589
|
-
if (!fs4.existsSync(
|
|
18536
|
+
if (!fs4.existsSync(path3.join(gitDir, "HEAD")))
|
|
18590
18537
|
return null;
|
|
18591
18538
|
} else if (isGitDir(dir))
|
|
18592
18539
|
gitDir = dir;
|
|
18593
18540
|
if (gitDir) {
|
|
18594
18541
|
let common = gitDir;
|
|
18595
18542
|
try {
|
|
18596
|
-
common =
|
|
18543
|
+
common = path3.resolve(gitDir, fs4.readFileSync(path3.join(gitDir, "commondir"), "utf8").trim());
|
|
18597
18544
|
} catch {}
|
|
18598
|
-
if (!fs4.existsSync(
|
|
18545
|
+
if (!fs4.existsSync(path3.join(common, "objects")))
|
|
18599
18546
|
return null;
|
|
18600
18547
|
return {
|
|
18601
18548
|
kind: "repo",
|
|
@@ -18605,26 +18552,26 @@ function fastGit(root) {
|
|
|
18605
18552
|
reftable: reftableRefs(common)
|
|
18606
18553
|
};
|
|
18607
18554
|
}
|
|
18608
|
-
const parent =
|
|
18555
|
+
const parent = path3.dirname(dir);
|
|
18609
18556
|
if (parent === dir)
|
|
18610
18557
|
return { kind: "none" };
|
|
18611
18558
|
dir = parent;
|
|
18612
18559
|
}
|
|
18613
18560
|
}
|
|
18614
18561
|
function resolveStore(root) {
|
|
18615
|
-
root =
|
|
18562
|
+
root = path3.resolve(root);
|
|
18616
18563
|
let directory = false;
|
|
18617
18564
|
try {
|
|
18618
18565
|
directory = fs4.statSync(root).isDirectory();
|
|
18619
18566
|
} catch {}
|
|
18620
18567
|
if (!directory)
|
|
18621
|
-
return { dir:
|
|
18568
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
18622
18569
|
const fast = fastGit(root);
|
|
18623
18570
|
if (fast?.kind === "none")
|
|
18624
|
-
return { dir:
|
|
18571
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
18625
18572
|
if (fast?.kind === "repo")
|
|
18626
18573
|
return {
|
|
18627
|
-
dir:
|
|
18574
|
+
dir: path3.join(fast.common, "workit"),
|
|
18628
18575
|
shared: true,
|
|
18629
18576
|
top: fast.top,
|
|
18630
18577
|
git: { gitDir: fast.gitDir, top: fast.top, reftable: fast.reftable }
|
|
@@ -18634,20 +18581,20 @@ function resolveStore(root) {
|
|
|
18634
18581
|
if (run.ok && common) {
|
|
18635
18582
|
const top = gitRun(root, ["rev-parse", "--path-format=absolute", "--show-toplevel"]);
|
|
18636
18583
|
return {
|
|
18637
|
-
dir:
|
|
18584
|
+
dir: path3.join(real(path3.resolve(root, common)), "workit"),
|
|
18638
18585
|
shared: true,
|
|
18639
18586
|
top: top.ok && top.stdout.trim() ? real(top.stdout.trim()) : null
|
|
18640
18587
|
};
|
|
18641
18588
|
}
|
|
18642
18589
|
if (run.missing || !run.ok && NOT_A_REPO.test(run.stderr))
|
|
18643
|
-
return { dir:
|
|
18590
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
18644
18591
|
return new Error(`cannot locate the workit store: git rev-parse failed (${run.stderr.trim().split(`
|
|
18645
18592
|
`)[0] || "no output"}); fix the repository (git status should work here)`);
|
|
18646
18593
|
}
|
|
18647
18594
|
var rebasingBranch = (gitDir) => {
|
|
18648
18595
|
for (const state of ["rebase-merge", "rebase-apply"]) {
|
|
18649
18596
|
try {
|
|
18650
|
-
const ref = fs4.readFileSync(
|
|
18597
|
+
const ref = fs4.readFileSync(path3.join(gitDir, state, "head-name"), "utf8").trim();
|
|
18651
18598
|
const match = /^refs\/heads\/(.+)$/u.exec(ref);
|
|
18652
18599
|
if (match)
|
|
18653
18600
|
return match[1];
|
|
@@ -18662,7 +18609,7 @@ function resolveTaskKey(root, location) {
|
|
|
18662
18609
|
if (location.git && !location.git.reftable) {
|
|
18663
18610
|
let head = "";
|
|
18664
18611
|
try {
|
|
18665
|
-
head = fs4.readFileSync(
|
|
18612
|
+
head = fs4.readFileSync(path3.join(location.git.gitDir, "HEAD"), "utf8").trim();
|
|
18666
18613
|
} catch {}
|
|
18667
18614
|
const ref = /^ref: refs\/heads\/(.+)$/u.exec(head);
|
|
18668
18615
|
if (ref && ref[1] !== ".invalid")
|
|
@@ -18693,7 +18640,7 @@ function resolveTaskKey(root, location) {
|
|
|
18693
18640
|
return { key: `detached-${shortHash(real(worktree))}`, kind: "detached", branch: null };
|
|
18694
18641
|
}
|
|
18695
18642
|
function checkoutRootOf(root, location) {
|
|
18696
|
-
const resolved =
|
|
18643
|
+
const resolved = path3.resolve(root);
|
|
18697
18644
|
let canonical = resolved;
|
|
18698
18645
|
try {
|
|
18699
18646
|
canonical = fs4.realpathSync(resolved);
|
|
@@ -18724,13 +18671,13 @@ function branchRenames(location) {
|
|
|
18724
18671
|
}
|
|
18725
18672
|
for (const entry of entries)
|
|
18726
18673
|
if (entry.isDirectory())
|
|
18727
|
-
walk(
|
|
18674
|
+
walk(path3.join(dir, entry.name));
|
|
18728
18675
|
else
|
|
18729
|
-
files.push(
|
|
18676
|
+
files.push(path3.join(dir, entry.name));
|
|
18730
18677
|
};
|
|
18731
|
-
walk(
|
|
18678
|
+
walk(path3.join(path3.dirname(location.dir), "logs", "refs", "heads"));
|
|
18732
18679
|
if (location.git)
|
|
18733
|
-
files.push(
|
|
18680
|
+
files.push(path3.join(location.git.gitDir, "logs", "HEAD"));
|
|
18734
18681
|
const seen = new Set;
|
|
18735
18682
|
const renames = [];
|
|
18736
18683
|
for (const file of files) {
|
|
@@ -18765,11 +18712,63 @@ var checkoutSlug = (root) => {
|
|
|
18765
18712
|
let canonical = real(root);
|
|
18766
18713
|
if (process.platform === "win32")
|
|
18767
18714
|
canonical = canonical.toLowerCase();
|
|
18768
|
-
const base =
|
|
18715
|
+
const base = path3.basename(canonical).replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 40) || "root";
|
|
18769
18716
|
return `${base}-${shortHash(canonical)}`;
|
|
18770
18717
|
};
|
|
18771
18718
|
|
|
18719
|
+
// packages/workit-core/src/host-session.ts
|
|
18720
|
+
var HOST_SESSION_VARS = [
|
|
18721
|
+
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
18722
|
+
["PI_SESSION_ID", () => "pi"],
|
|
18723
|
+
[
|
|
18724
|
+
"CODEX_THREAD_ID",
|
|
18725
|
+
(env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
|
|
18726
|
+
]
|
|
18727
|
+
];
|
|
18728
|
+
var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
|
|
18729
|
+
function hostSessionFromEnv(env) {
|
|
18730
|
+
const value = (key) => env[key]?.trim() || null;
|
|
18731
|
+
let inner = null;
|
|
18732
|
+
for (const [key, host] of HOST_SESSION_VARS) {
|
|
18733
|
+
const session = value(key);
|
|
18734
|
+
if (session) {
|
|
18735
|
+
inner = { host: host(env), session };
|
|
18736
|
+
break;
|
|
18737
|
+
}
|
|
18738
|
+
}
|
|
18739
|
+
const declared = value("WORKIT_HOST");
|
|
18740
|
+
if (env.WORKIT_SESSION_ID !== undefined) {
|
|
18741
|
+
const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
|
|
18742
|
+
if (!inherited)
|
|
18743
|
+
return { host: declared, session: value("WORKIT_SESSION_ID") };
|
|
18744
|
+
}
|
|
18745
|
+
return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
|
|
18746
|
+
}
|
|
18747
|
+
var OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
|
|
18748
|
+
|
|
18749
|
+
// packages/workit-core/src/core/package-root.ts
|
|
18750
|
+
import { existsSync } from "node:fs";
|
|
18751
|
+
import path4 from "node:path";
|
|
18752
|
+
import { fileURLToPath } from "node:url";
|
|
18753
|
+
var packageRoot = () => {
|
|
18754
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
18755
|
+
while (true) {
|
|
18756
|
+
const parent = path4.dirname(dir);
|
|
18757
|
+
if (existsSync(path4.join(dir, "package.json")) || parent === dir)
|
|
18758
|
+
return dir;
|
|
18759
|
+
dir = parent;
|
|
18760
|
+
}
|
|
18761
|
+
};
|
|
18762
|
+
var assetRoot = () => {
|
|
18763
|
+
const root = packageRoot();
|
|
18764
|
+
const assets = path4.join(root, "assets");
|
|
18765
|
+
return existsSync(assets) ? assets : root;
|
|
18766
|
+
};
|
|
18767
|
+
|
|
18772
18768
|
// packages/workit-core/src/core/store-lock.ts
|
|
18769
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
18770
|
+
import fs5 from "node:fs";
|
|
18771
|
+
import { hostname } from "node:os";
|
|
18773
18772
|
var metadataLockSchema = object2({
|
|
18774
18773
|
pid: number2().int().nonnegative().safe(),
|
|
18775
18774
|
processStart: string2().nullable(),
|
|
@@ -19403,6 +19402,38 @@ var isNewerVersion = (candidate, current) => {
|
|
|
19403
19402
|
return false;
|
|
19404
19403
|
};
|
|
19405
19404
|
var validId = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value);
|
|
19405
|
+
var readText = (file) => {
|
|
19406
|
+
try {
|
|
19407
|
+
return fs7.readFileSync(file, "utf8");
|
|
19408
|
+
} catch {
|
|
19409
|
+
return "";
|
|
19410
|
+
}
|
|
19411
|
+
};
|
|
19412
|
+
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
19413
|
+
var branchStart = (location, branch, aliases) => {
|
|
19414
|
+
const first = readText(path6.join(path6.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
19415
|
+
`, 1)[0];
|
|
19416
|
+
const created = REFLOG_LINE.exec(first);
|
|
19417
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
19418
|
+
if (!created || !start)
|
|
19419
|
+
return null;
|
|
19420
|
+
if (start !== "HEAD")
|
|
19421
|
+
return start;
|
|
19422
|
+
if (!location.git)
|
|
19423
|
+
return null;
|
|
19424
|
+
for (const line of readText(path6.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
19425
|
+
`)) {
|
|
19426
|
+
const entry = REFLOG_LINE.exec(line);
|
|
19427
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
19428
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
19429
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
19430
|
+
return moved[1];
|
|
19431
|
+
}
|
|
19432
|
+
return null;
|
|
19433
|
+
};
|
|
19434
|
+
var refExists = (common, ref) => fs7.existsSync(path6.join(common, ref)) || readText(path6.join(common, "packed-refs")).includes(` ${ref}
|
|
19435
|
+
`);
|
|
19436
|
+
var origins = new Map;
|
|
19406
19437
|
var sameDirectoryIdentity = (left, right) => {
|
|
19407
19438
|
if (!path6.isAbsolute(left) || !path6.isAbsolute(right))
|
|
19408
19439
|
return false;
|
|
@@ -19655,6 +19686,66 @@ class TaskStore {
|
|
|
19655
19686
|
return bound;
|
|
19656
19687
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
19657
19688
|
}
|
|
19689
|
+
taskForWorker(workerId) {
|
|
19690
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
19691
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
19692
|
+
const listed = this.listTaskIndex();
|
|
19693
|
+
if (!listed.ok)
|
|
19694
|
+
return listed;
|
|
19695
|
+
for (const entry of listed.data) {
|
|
19696
|
+
if (entry.status === "closed")
|
|
19697
|
+
continue;
|
|
19698
|
+
const loaded = this.load(entry.id);
|
|
19699
|
+
if (!loaded.ok)
|
|
19700
|
+
return loaded;
|
|
19701
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
19702
|
+
return success(null, null, entry.id);
|
|
19703
|
+
}
|
|
19704
|
+
return success(null, null, null);
|
|
19705
|
+
}
|
|
19706
|
+
originTaskEntry() {
|
|
19707
|
+
const key = this.currentKey();
|
|
19708
|
+
const location = this.location();
|
|
19709
|
+
const branch = key.ok ? key.data.branch : null;
|
|
19710
|
+
if (!branch || !location.ok)
|
|
19711
|
+
return success(null, null, null);
|
|
19712
|
+
const common = path6.dirname(location.data.dir);
|
|
19713
|
+
const heads = path6.join(common, "logs", "refs", "heads");
|
|
19714
|
+
const headLog = location.data.git ? path6.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
19715
|
+
const signatures = [
|
|
19716
|
+
path6.join(heads, branch),
|
|
19717
|
+
headLog,
|
|
19718
|
+
heads,
|
|
19719
|
+
path6.join(common, "packed-refs")
|
|
19720
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
19721
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
19722
|
+
let resolved = origins.get(slot);
|
|
19723
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
19724
|
+
const renames = branchRenames(location.data);
|
|
19725
|
+
const aliases = [branch];
|
|
19726
|
+
for (const rename of renames.toReversed())
|
|
19727
|
+
if (rename.to === aliases.at(-1))
|
|
19728
|
+
aliases.push(rename.from);
|
|
19729
|
+
const start = branchStart(location.data, branch, aliases);
|
|
19730
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
19731
|
+
const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path6.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
|
|
19732
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
19733
|
+
resolved = {
|
|
19734
|
+
signature: signatures.join("|"),
|
|
19735
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
19736
|
+
renames
|
|
19737
|
+
};
|
|
19738
|
+
origins.set(slot, resolved);
|
|
19739
|
+
}
|
|
19740
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
19741
|
+
if (entry && !entry.ok)
|
|
19742
|
+
return entry;
|
|
19743
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
19744
|
+
}
|
|
19745
|
+
readStoreTask(taskId) {
|
|
19746
|
+
const loaded = this.load(taskId);
|
|
19747
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
19748
|
+
}
|
|
19658
19749
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
19659
19750
|
const value = "intent" in input ? input : {
|
|
19660
19751
|
intent: input,
|
|
@@ -20324,12 +20415,12 @@ class TaskStore {
|
|
|
20324
20415
|
return 0;
|
|
20325
20416
|
}
|
|
20326
20417
|
}
|
|
20327
|
-
openTasksForKey(key) {
|
|
20418
|
+
openTasksForKey(key, known) {
|
|
20328
20419
|
const all = this.listStoreIndex();
|
|
20329
20420
|
if (!all.ok)
|
|
20330
20421
|
return all;
|
|
20331
|
-
const location = this.location();
|
|
20332
|
-
const renames = location
|
|
20422
|
+
const location = known ? null : this.location();
|
|
20423
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
20333
20424
|
return success(null, null, all.data.filter((entry) => entry.key !== null && entry.status !== "closed").filter((entry) => (renames.length ? followRenames(entry.key, entry.boundAt ?? entry.createdAt, renames) : entry.key) === key).toSorted(oldestFirst));
|
|
20334
20425
|
}
|
|
20335
20426
|
openTaskForKey(key) {
|
|
@@ -23310,11 +23401,20 @@ function authorSessions(cwd, rows, branch, range = { base: null, head: null }, s
|
|
|
23310
23401
|
sessions.add(session);
|
|
23311
23402
|
return sessions;
|
|
23312
23403
|
}
|
|
23404
|
+
var derivesFrom = (derived, bare) => !bare.includes(":") && derived.endsWith(`:${bare}`);
|
|
23405
|
+
var authoredBy = (authors, session) => {
|
|
23406
|
+
if (authors.has(session))
|
|
23407
|
+
return true;
|
|
23408
|
+
for (const author of authors)
|
|
23409
|
+
if (derivesFrom(author, session) || derivesFrom(session, author))
|
|
23410
|
+
return true;
|
|
23411
|
+
return false;
|
|
23412
|
+
};
|
|
23313
23413
|
var independenceReasons = (row, authors) => {
|
|
23314
23414
|
const reasons = [];
|
|
23315
23415
|
if (!row.actor.session)
|
|
23316
23416
|
reasons.push("no_session");
|
|
23317
|
-
else if (authors
|
|
23417
|
+
else if (authoredBy(authors, row.actor.session))
|
|
23318
23418
|
reasons.push("author_session");
|
|
23319
23419
|
if (row.self === true && !reasons.includes("no_session"))
|
|
23320
23420
|
reasons.push("self");
|
|
@@ -24415,38 +24515,45 @@ var compactReference = (ref) => {
|
|
|
24415
24515
|
};
|
|
24416
24516
|
return { kind: ref.kind };
|
|
24417
24517
|
};
|
|
24418
|
-
|
|
24419
|
-
const
|
|
24420
|
-
|
|
24421
|
-
|
|
24422
|
-
|
|
24423
|
-
|
|
24424
|
-
|
|
24425
|
-
|
|
24426
|
-
|
|
24427
|
-
|
|
24428
|
-
|
|
24429
|
-
|
|
24430
|
-
|
|
24431
|
-
|
|
24432
|
-
|
|
24433
|
-
|
|
24518
|
+
var newestDecisionFirst = (left, right) => {
|
|
24519
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
24520
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
24521
|
+
if (leftAt !== rightAt)
|
|
24522
|
+
return leftAt > rightAt ? -1 : 1;
|
|
24523
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
24524
|
+
};
|
|
24525
|
+
var compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
24526
|
+
id: entry.id,
|
|
24527
|
+
purpose: entry.data.purpose,
|
|
24528
|
+
status: entry.data.response,
|
|
24529
|
+
digest: entry.data.digest,
|
|
24530
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
24531
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
24532
|
+
origin: source.origin ?? undefined
|
|
24533
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS);
|
|
24534
|
+
function compactTaskContext(view, inherited = null) {
|
|
24535
|
+
const decisions = compactDecisions([
|
|
24536
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
24537
|
+
inherited
|
|
24538
|
+
]);
|
|
24539
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
24434
24540
|
id: method.id,
|
|
24435
24541
|
assurance: method.assurance,
|
|
24436
24542
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
24437
24543
|
})) : [];
|
|
24544
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
24438
24545
|
const gaps = Array.from(new Set([
|
|
24439
|
-
...
|
|
24440
|
-
...view
|
|
24441
|
-
...view
|
|
24546
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
24547
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
24548
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
24442
24549
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
24443
24550
|
const context = {
|
|
24444
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
24445
|
-
status: view
|
|
24551
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
24552
|
+
status: view?.task.status ?? null,
|
|
24446
24553
|
decisions,
|
|
24447
24554
|
methods,
|
|
24448
24555
|
gaps,
|
|
24449
|
-
nextAction: compactText(view
|
|
24556
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
24450
24557
|
};
|
|
24451
24558
|
let encoded = JSON.stringify(context);
|
|
24452
24559
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -25051,6 +25158,13 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
25051
25158
|
"worker.cancel",
|
|
25052
25159
|
"state.export"
|
|
25053
25160
|
]);
|
|
25161
|
+
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
25162
|
+
var workerCommand = (taskId, request) => {
|
|
25163
|
+
const { action, workerId, reason, report } = request;
|
|
25164
|
+
const rest = JSON.stringify({ reason, report });
|
|
25165
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
25166
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
25167
|
+
};
|
|
25054
25168
|
var CREATING_ACTIONS = new Set([
|
|
25055
25169
|
"task.revise",
|
|
25056
25170
|
"task.progress",
|
|
@@ -25301,6 +25415,17 @@ class WorkitCore {
|
|
|
25301
25415
|
const root = this.contextRootError();
|
|
25302
25416
|
if (!root.ok)
|
|
25303
25417
|
return root;
|
|
25418
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
25419
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
25420
|
+
if (workerId !== null) {
|
|
25421
|
+
const owner = this.store.taskForWorker(workerId);
|
|
25422
|
+
if (!owner.ok)
|
|
25423
|
+
return owner;
|
|
25424
|
+
if (owner.data)
|
|
25425
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
25426
|
+
if (addressed)
|
|
25427
|
+
return failure2("not_found", `worker ${workerId} is on no open task; find its task with \`workit task status --all\`, then run \`${workerCommand("<task-id>", request)}\``);
|
|
25428
|
+
}
|
|
25304
25429
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
25305
25430
|
const found = this.store.implicitTask({
|
|
25306
25431
|
provenance: provenance(this.context),
|
|
@@ -26007,7 +26132,9 @@ class WorkitCore {
|
|
|
26007
26132
|
if (!resolved.ok)
|
|
26008
26133
|
return resolved;
|
|
26009
26134
|
const value = resolved.data;
|
|
26010
|
-
|
|
26135
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
26136
|
+
const { action, taskId } = value ?? {};
|
|
26137
|
+
return result.ok || request?.taskId !== undefined || typeof taskId !== "string" || !WORKER_ADDRESSED_ACTIONS.has(`worker.${String(action)}`) ? result : { ...result, error: `${result.error}; run \`${workerCommand(taskId, value)}\`` };
|
|
26011
26138
|
}
|
|
26012
26139
|
workerOnce(request) {
|
|
26013
26140
|
const root = this.contextRootError();
|
|
@@ -26212,10 +26339,18 @@ class WorkitCore {
|
|
|
26212
26339
|
requirements
|
|
26213
26340
|
});
|
|
26214
26341
|
}
|
|
26215
|
-
compactContext(taskId, freshness) {
|
|
26342
|
+
compactContext(taskId, freshness, origin = null) {
|
|
26216
26343
|
const root = this.contextRootError();
|
|
26217
26344
|
if (!root.ok)
|
|
26218
26345
|
return root;
|
|
26346
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
26347
|
+
const inherited = base?.ok && base.data ? {
|
|
26348
|
+
origin: origin.origin,
|
|
26349
|
+
taskId: base.data.id,
|
|
26350
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
26351
|
+
} : null;
|
|
26352
|
+
if (taskId === null)
|
|
26353
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
26219
26354
|
const task = this.store.readTask(taskId);
|
|
26220
26355
|
if (!task.ok)
|
|
26221
26356
|
return task;
|
|
@@ -26225,7 +26360,7 @@ class WorkitCore {
|
|
|
26225
26360
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
26226
26361
|
if (!view.ok)
|
|
26227
26362
|
return view;
|
|
26228
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
26363
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
26229
26364
|
}
|
|
26230
26365
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
26231
26366
|
const workspace = this.store.readWorkspace();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-mcp",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.10.0",
|
|
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": "^8.
|
|
45
|
+
"@brainervirus/workit-core": "^8.10.0",
|
|
46
46
|
"@modelcontextprotocol/sdk": "1.32.0",
|
|
47
47
|
"zod": "4.6.5"
|
|
48
48
|
},
|