@brainervirus/workit-cursor 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/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +585 -421
- package/dist/mcp-server.js +240 -105
- package/dist/workit-hook.js +594 -416
- package/package.json +3 -3
- package/rules/workit-contract.mdc +4 -1
- package/skills/workit-fanout/references/brief.md +1 -1
- package/skills/workit-fanout/references/orchestration.md +16 -6
- package/skills/workit-implement/SKILL.md +3 -2
- package/skills/workit-review/SKILL.md +4 -2
package/dist/mcp-server.js
CHANGED
|
@@ -18442,64 +18442,11 @@ function acquireFileLockSync(targetPath, options) {
|
|
|
18442
18442
|
}
|
|
18443
18443
|
}
|
|
18444
18444
|
}
|
|
18445
|
-
// packages/workit-core/src/host-session.ts
|
|
18446
|
-
var HOST_SESSION_VARS = [
|
|
18447
|
-
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
18448
|
-
["PI_SESSION_ID", () => "pi"],
|
|
18449
|
-
[
|
|
18450
|
-
"CODEX_THREAD_ID",
|
|
18451
|
-
(env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
|
|
18452
|
-
]
|
|
18453
|
-
];
|
|
18454
|
-
var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
|
|
18455
|
-
function hostSessionFromEnv(env) {
|
|
18456
|
-
const value = (key) => env[key]?.trim() || null;
|
|
18457
|
-
let inner = null;
|
|
18458
|
-
for (const [key, host] of HOST_SESSION_VARS) {
|
|
18459
|
-
const session = value(key);
|
|
18460
|
-
if (session) {
|
|
18461
|
-
inner = { host: host(env), session };
|
|
18462
|
-
break;
|
|
18463
|
-
}
|
|
18464
|
-
}
|
|
18465
|
-
const declared = value("WORKIT_HOST");
|
|
18466
|
-
if (env.WORKIT_SESSION_ID !== undefined) {
|
|
18467
|
-
const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
|
|
18468
|
-
if (!inherited)
|
|
18469
|
-
return { host: declared, session: value("WORKIT_SESSION_ID") };
|
|
18470
|
-
}
|
|
18471
|
-
return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
|
|
18472
|
-
}
|
|
18473
|
-
|
|
18474
|
-
// packages/workit-core/src/core/package-root.ts
|
|
18475
|
-
import { existsSync } from "node:fs";
|
|
18476
|
-
import path3 from "node:path";
|
|
18477
|
-
import { fileURLToPath } from "node:url";
|
|
18478
|
-
var packageRoot = () => {
|
|
18479
|
-
let dir = path3.dirname(fileURLToPath(import.meta.url));
|
|
18480
|
-
while (true) {
|
|
18481
|
-
const parent = path3.dirname(dir);
|
|
18482
|
-
if (existsSync(path3.join(dir, "package.json")) || parent === dir)
|
|
18483
|
-
return dir;
|
|
18484
|
-
dir = parent;
|
|
18485
|
-
}
|
|
18486
|
-
};
|
|
18487
|
-
var assetRoot = () => {
|
|
18488
|
-
const root = packageRoot();
|
|
18489
|
-
const assets = path3.join(root, "assets");
|
|
18490
|
-
return existsSync(assets) ? assets : root;
|
|
18491
|
-
};
|
|
18492
|
-
|
|
18493
|
-
// packages/workit-core/src/core/store-lock.ts
|
|
18494
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
18495
|
-
import fs5 from "node:fs";
|
|
18496
|
-
import { hostname } from "node:os";
|
|
18497
|
-
|
|
18498
18445
|
// packages/workit-core/src/store/paths.ts
|
|
18499
18446
|
import { spawnSync } from "node:child_process";
|
|
18500
18447
|
import { createHash as createHash2 } from "node:crypto";
|
|
18501
18448
|
import fs4 from "node:fs";
|
|
18502
|
-
import
|
|
18449
|
+
import path3 from "node:path";
|
|
18503
18450
|
var NOT_A_REPO = /not a git repository \(or any (of the parent directories|parent up to)/u;
|
|
18504
18451
|
var gitRun = (cwd, args) => {
|
|
18505
18452
|
const run = spawnSync("git", args, {
|
|
@@ -18541,14 +18488,14 @@ var DISCOVERY_ENV = [
|
|
|
18541
18488
|
];
|
|
18542
18489
|
var isGitDir = (dir) => {
|
|
18543
18490
|
try {
|
|
18544
|
-
return fs4.statSync(
|
|
18491
|
+
return fs4.statSync(path3.join(dir, "HEAD")).isFile() && fs4.statSync(path3.join(dir, "objects")).isDirectory() && fs4.statSync(path3.join(dir, "refs")).isDirectory();
|
|
18545
18492
|
} catch {
|
|
18546
18493
|
return false;
|
|
18547
18494
|
}
|
|
18548
18495
|
};
|
|
18549
18496
|
var reftableRefs = (common) => {
|
|
18550
18497
|
try {
|
|
18551
|
-
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(
|
|
18498
|
+
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(path3.join(common, "config"), "utf8"));
|
|
18552
18499
|
} catch {
|
|
18553
18500
|
return false;
|
|
18554
18501
|
}
|
|
@@ -18568,7 +18515,7 @@ function fastGit(root) {
|
|
|
18568
18515
|
if (device !== null && stat.dev !== device)
|
|
18569
18516
|
return { kind: "none" };
|
|
18570
18517
|
device = stat.dev;
|
|
18571
|
-
const dotGit =
|
|
18518
|
+
const dotGit = path3.join(dir, ".git");
|
|
18572
18519
|
let entry = null;
|
|
18573
18520
|
try {
|
|
18574
18521
|
entry = fs4.statSync(dotGit);
|
|
@@ -18589,19 +18536,19 @@ function fastGit(root) {
|
|
|
18589
18536
|
const match = /^gitdir: (.+)$/mu.exec(text);
|
|
18590
18537
|
if (!match)
|
|
18591
18538
|
return null;
|
|
18592
|
-
gitDir =
|
|
18539
|
+
gitDir = path3.resolve(dir, match[1].trim());
|
|
18593
18540
|
} else
|
|
18594
18541
|
return null;
|
|
18595
|
-
if (!fs4.existsSync(
|
|
18542
|
+
if (!fs4.existsSync(path3.join(gitDir, "HEAD")))
|
|
18596
18543
|
return null;
|
|
18597
18544
|
} else if (isGitDir(dir))
|
|
18598
18545
|
gitDir = dir;
|
|
18599
18546
|
if (gitDir) {
|
|
18600
18547
|
let common = gitDir;
|
|
18601
18548
|
try {
|
|
18602
|
-
common =
|
|
18549
|
+
common = path3.resolve(gitDir, fs4.readFileSync(path3.join(gitDir, "commondir"), "utf8").trim());
|
|
18603
18550
|
} catch {}
|
|
18604
|
-
if (!fs4.existsSync(
|
|
18551
|
+
if (!fs4.existsSync(path3.join(common, "objects")))
|
|
18605
18552
|
return null;
|
|
18606
18553
|
return {
|
|
18607
18554
|
kind: "repo",
|
|
@@ -18611,26 +18558,26 @@ function fastGit(root) {
|
|
|
18611
18558
|
reftable: reftableRefs(common)
|
|
18612
18559
|
};
|
|
18613
18560
|
}
|
|
18614
|
-
const parent =
|
|
18561
|
+
const parent = path3.dirname(dir);
|
|
18615
18562
|
if (parent === dir)
|
|
18616
18563
|
return { kind: "none" };
|
|
18617
18564
|
dir = parent;
|
|
18618
18565
|
}
|
|
18619
18566
|
}
|
|
18620
18567
|
function resolveStore(root) {
|
|
18621
|
-
root =
|
|
18568
|
+
root = path3.resolve(root);
|
|
18622
18569
|
let directory = false;
|
|
18623
18570
|
try {
|
|
18624
18571
|
directory = fs4.statSync(root).isDirectory();
|
|
18625
18572
|
} catch {}
|
|
18626
18573
|
if (!directory)
|
|
18627
|
-
return { dir:
|
|
18574
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
18628
18575
|
const fast = fastGit(root);
|
|
18629
18576
|
if (fast?.kind === "none")
|
|
18630
|
-
return { dir:
|
|
18577
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
18631
18578
|
if (fast?.kind === "repo")
|
|
18632
18579
|
return {
|
|
18633
|
-
dir:
|
|
18580
|
+
dir: path3.join(fast.common, "workit"),
|
|
18634
18581
|
shared: true,
|
|
18635
18582
|
top: fast.top,
|
|
18636
18583
|
git: { gitDir: fast.gitDir, top: fast.top, reftable: fast.reftable }
|
|
@@ -18640,20 +18587,20 @@ function resolveStore(root) {
|
|
|
18640
18587
|
if (run.ok && common) {
|
|
18641
18588
|
const top = gitRun(root, ["rev-parse", "--path-format=absolute", "--show-toplevel"]);
|
|
18642
18589
|
return {
|
|
18643
|
-
dir:
|
|
18590
|
+
dir: path3.join(real(path3.resolve(root, common)), "workit"),
|
|
18644
18591
|
shared: true,
|
|
18645
18592
|
top: top.ok && top.stdout.trim() ? real(top.stdout.trim()) : null
|
|
18646
18593
|
};
|
|
18647
18594
|
}
|
|
18648
18595
|
if (run.missing || !run.ok && NOT_A_REPO.test(run.stderr))
|
|
18649
|
-
return { dir:
|
|
18596
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
18650
18597
|
return new Error(`cannot locate the workit store: git rev-parse failed (${run.stderr.trim().split(`
|
|
18651
18598
|
`)[0] || "no output"}); fix the repository (git status should work here)`);
|
|
18652
18599
|
}
|
|
18653
18600
|
var rebasingBranch = (gitDir) => {
|
|
18654
18601
|
for (const state of ["rebase-merge", "rebase-apply"]) {
|
|
18655
18602
|
try {
|
|
18656
|
-
const ref = fs4.readFileSync(
|
|
18603
|
+
const ref = fs4.readFileSync(path3.join(gitDir, state, "head-name"), "utf8").trim();
|
|
18657
18604
|
const match = /^refs\/heads\/(.+)$/u.exec(ref);
|
|
18658
18605
|
if (match)
|
|
18659
18606
|
return match[1];
|
|
@@ -18668,7 +18615,7 @@ function resolveTaskKey(root, location) {
|
|
|
18668
18615
|
if (location.git && !location.git.reftable) {
|
|
18669
18616
|
let head = "";
|
|
18670
18617
|
try {
|
|
18671
|
-
head = fs4.readFileSync(
|
|
18618
|
+
head = fs4.readFileSync(path3.join(location.git.gitDir, "HEAD"), "utf8").trim();
|
|
18672
18619
|
} catch {}
|
|
18673
18620
|
const ref = /^ref: refs\/heads\/(.+)$/u.exec(head);
|
|
18674
18621
|
if (ref && ref[1] !== ".invalid")
|
|
@@ -18699,7 +18646,7 @@ function resolveTaskKey(root, location) {
|
|
|
18699
18646
|
return { key: `detached-${shortHash(real(worktree))}`, kind: "detached", branch: null };
|
|
18700
18647
|
}
|
|
18701
18648
|
function checkoutRootOf(root, location) {
|
|
18702
|
-
const resolved =
|
|
18649
|
+
const resolved = path3.resolve(root);
|
|
18703
18650
|
let canonical = resolved;
|
|
18704
18651
|
try {
|
|
18705
18652
|
canonical = fs4.realpathSync(resolved);
|
|
@@ -18730,13 +18677,13 @@ function branchRenames(location) {
|
|
|
18730
18677
|
}
|
|
18731
18678
|
for (const entry of entries)
|
|
18732
18679
|
if (entry.isDirectory())
|
|
18733
|
-
walk(
|
|
18680
|
+
walk(path3.join(dir, entry.name));
|
|
18734
18681
|
else
|
|
18735
|
-
files.push(
|
|
18682
|
+
files.push(path3.join(dir, entry.name));
|
|
18736
18683
|
};
|
|
18737
|
-
walk(
|
|
18684
|
+
walk(path3.join(path3.dirname(location.dir), "logs", "refs", "heads"));
|
|
18738
18685
|
if (location.git)
|
|
18739
|
-
files.push(
|
|
18686
|
+
files.push(path3.join(location.git.gitDir, "logs", "HEAD"));
|
|
18740
18687
|
const seen = new Set;
|
|
18741
18688
|
const renames = [];
|
|
18742
18689
|
for (const file of files) {
|
|
@@ -18771,11 +18718,63 @@ var checkoutSlug = (root) => {
|
|
|
18771
18718
|
let canonical = real(root);
|
|
18772
18719
|
if (process.platform === "win32")
|
|
18773
18720
|
canonical = canonical.toLowerCase();
|
|
18774
|
-
const base =
|
|
18721
|
+
const base = path3.basename(canonical).replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 40) || "root";
|
|
18775
18722
|
return `${base}-${shortHash(canonical)}`;
|
|
18776
18723
|
};
|
|
18777
18724
|
|
|
18725
|
+
// packages/workit-core/src/host-session.ts
|
|
18726
|
+
var HOST_SESSION_VARS = [
|
|
18727
|
+
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
18728
|
+
["PI_SESSION_ID", () => "pi"],
|
|
18729
|
+
[
|
|
18730
|
+
"CODEX_THREAD_ID",
|
|
18731
|
+
(env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
|
|
18732
|
+
]
|
|
18733
|
+
];
|
|
18734
|
+
var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
|
|
18735
|
+
function hostSessionFromEnv(env) {
|
|
18736
|
+
const value = (key) => env[key]?.trim() || null;
|
|
18737
|
+
let inner = null;
|
|
18738
|
+
for (const [key, host] of HOST_SESSION_VARS) {
|
|
18739
|
+
const session = value(key);
|
|
18740
|
+
if (session) {
|
|
18741
|
+
inner = { host: host(env), session };
|
|
18742
|
+
break;
|
|
18743
|
+
}
|
|
18744
|
+
}
|
|
18745
|
+
const declared = value("WORKIT_HOST");
|
|
18746
|
+
if (env.WORKIT_SESSION_ID !== undefined) {
|
|
18747
|
+
const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
|
|
18748
|
+
if (!inherited)
|
|
18749
|
+
return { host: declared, session: value("WORKIT_SESSION_ID") };
|
|
18750
|
+
}
|
|
18751
|
+
return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
|
|
18752
|
+
}
|
|
18753
|
+
var OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
|
|
18754
|
+
|
|
18755
|
+
// packages/workit-core/src/core/package-root.ts
|
|
18756
|
+
import { existsSync } from "node:fs";
|
|
18757
|
+
import path4 from "node:path";
|
|
18758
|
+
import { fileURLToPath } from "node:url";
|
|
18759
|
+
var packageRoot = () => {
|
|
18760
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
18761
|
+
while (true) {
|
|
18762
|
+
const parent = path4.dirname(dir);
|
|
18763
|
+
if (existsSync(path4.join(dir, "package.json")) || parent === dir)
|
|
18764
|
+
return dir;
|
|
18765
|
+
dir = parent;
|
|
18766
|
+
}
|
|
18767
|
+
};
|
|
18768
|
+
var assetRoot = () => {
|
|
18769
|
+
const root = packageRoot();
|
|
18770
|
+
const assets = path4.join(root, "assets");
|
|
18771
|
+
return existsSync(assets) ? assets : root;
|
|
18772
|
+
};
|
|
18773
|
+
|
|
18778
18774
|
// packages/workit-core/src/core/store-lock.ts
|
|
18775
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
18776
|
+
import fs5 from "node:fs";
|
|
18777
|
+
import { hostname } from "node:os";
|
|
18779
18778
|
var metadataLockSchema = object2({
|
|
18780
18779
|
pid: number2().int().nonnegative().safe(),
|
|
18781
18780
|
processStart: string2().nullable(),
|
|
@@ -19409,6 +19408,38 @@ var isNewerVersion = (candidate, current) => {
|
|
|
19409
19408
|
return false;
|
|
19410
19409
|
};
|
|
19411
19410
|
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);
|
|
19411
|
+
var readText = (file) => {
|
|
19412
|
+
try {
|
|
19413
|
+
return fs7.readFileSync(file, "utf8");
|
|
19414
|
+
} catch {
|
|
19415
|
+
return "";
|
|
19416
|
+
}
|
|
19417
|
+
};
|
|
19418
|
+
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
19419
|
+
var branchStart = (location, branch, aliases) => {
|
|
19420
|
+
const first = readText(path6.join(path6.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
19421
|
+
`, 1)[0];
|
|
19422
|
+
const created = REFLOG_LINE.exec(first);
|
|
19423
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
19424
|
+
if (!created || !start)
|
|
19425
|
+
return null;
|
|
19426
|
+
if (start !== "HEAD")
|
|
19427
|
+
return start;
|
|
19428
|
+
if (!location.git)
|
|
19429
|
+
return null;
|
|
19430
|
+
for (const line of readText(path6.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
19431
|
+
`)) {
|
|
19432
|
+
const entry = REFLOG_LINE.exec(line);
|
|
19433
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
19434
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
19435
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
19436
|
+
return moved[1];
|
|
19437
|
+
}
|
|
19438
|
+
return null;
|
|
19439
|
+
};
|
|
19440
|
+
var refExists = (common, ref) => fs7.existsSync(path6.join(common, ref)) || readText(path6.join(common, "packed-refs")).includes(` ${ref}
|
|
19441
|
+
`);
|
|
19442
|
+
var origins = new Map;
|
|
19412
19443
|
var sameDirectoryIdentity = (left, right) => {
|
|
19413
19444
|
if (!path6.isAbsolute(left) || !path6.isAbsolute(right))
|
|
19414
19445
|
return false;
|
|
@@ -19661,6 +19692,66 @@ class TaskStore {
|
|
|
19661
19692
|
return bound;
|
|
19662
19693
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
19663
19694
|
}
|
|
19695
|
+
taskForWorker(workerId) {
|
|
19696
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
19697
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
19698
|
+
const listed = this.listTaskIndex();
|
|
19699
|
+
if (!listed.ok)
|
|
19700
|
+
return listed;
|
|
19701
|
+
for (const entry of listed.data) {
|
|
19702
|
+
if (entry.status === "closed")
|
|
19703
|
+
continue;
|
|
19704
|
+
const loaded = this.load(entry.id);
|
|
19705
|
+
if (!loaded.ok)
|
|
19706
|
+
return loaded;
|
|
19707
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
19708
|
+
return success(null, null, entry.id);
|
|
19709
|
+
}
|
|
19710
|
+
return success(null, null, null);
|
|
19711
|
+
}
|
|
19712
|
+
originTaskEntry() {
|
|
19713
|
+
const key = this.currentKey();
|
|
19714
|
+
const location = this.location();
|
|
19715
|
+
const branch = key.ok ? key.data.branch : null;
|
|
19716
|
+
if (!branch || !location.ok)
|
|
19717
|
+
return success(null, null, null);
|
|
19718
|
+
const common = path6.dirname(location.data.dir);
|
|
19719
|
+
const heads = path6.join(common, "logs", "refs", "heads");
|
|
19720
|
+
const headLog = location.data.git ? path6.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
19721
|
+
const signatures = [
|
|
19722
|
+
path6.join(heads, branch),
|
|
19723
|
+
headLog,
|
|
19724
|
+
heads,
|
|
19725
|
+
path6.join(common, "packed-refs")
|
|
19726
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
19727
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
19728
|
+
let resolved = origins.get(slot);
|
|
19729
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
19730
|
+
const renames = branchRenames(location.data);
|
|
19731
|
+
const aliases = [branch];
|
|
19732
|
+
for (const rename of renames.toReversed())
|
|
19733
|
+
if (rename.to === aliases.at(-1))
|
|
19734
|
+
aliases.push(rename.from);
|
|
19735
|
+
const start = branchStart(location.data, branch, aliases);
|
|
19736
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
19737
|
+
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)}"]`));
|
|
19738
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
19739
|
+
resolved = {
|
|
19740
|
+
signature: signatures.join("|"),
|
|
19741
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
19742
|
+
renames
|
|
19743
|
+
};
|
|
19744
|
+
origins.set(slot, resolved);
|
|
19745
|
+
}
|
|
19746
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
19747
|
+
if (entry && !entry.ok)
|
|
19748
|
+
return entry;
|
|
19749
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
19750
|
+
}
|
|
19751
|
+
readStoreTask(taskId) {
|
|
19752
|
+
const loaded = this.load(taskId);
|
|
19753
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
19754
|
+
}
|
|
19664
19755
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
19665
19756
|
const value = "intent" in input ? input : {
|
|
19666
19757
|
intent: input,
|
|
@@ -20330,12 +20421,12 @@ class TaskStore {
|
|
|
20330
20421
|
return 0;
|
|
20331
20422
|
}
|
|
20332
20423
|
}
|
|
20333
|
-
openTasksForKey(key) {
|
|
20424
|
+
openTasksForKey(key, known) {
|
|
20334
20425
|
const all = this.listStoreIndex();
|
|
20335
20426
|
if (!all.ok)
|
|
20336
20427
|
return all;
|
|
20337
|
-
const location = this.location();
|
|
20338
|
-
const renames = location
|
|
20428
|
+
const location = known ? null : this.location();
|
|
20429
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
20339
20430
|
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));
|
|
20340
20431
|
}
|
|
20341
20432
|
openTaskForKey(key) {
|
|
@@ -23316,11 +23407,20 @@ function authorSessions(cwd, rows, branch, range = { base: null, head: null }, s
|
|
|
23316
23407
|
sessions.add(session);
|
|
23317
23408
|
return sessions;
|
|
23318
23409
|
}
|
|
23410
|
+
var derivesFrom = (derived, bare) => !bare.includes(":") && derived.endsWith(`:${bare}`);
|
|
23411
|
+
var authoredBy = (authors, session) => {
|
|
23412
|
+
if (authors.has(session))
|
|
23413
|
+
return true;
|
|
23414
|
+
for (const author of authors)
|
|
23415
|
+
if (derivesFrom(author, session) || derivesFrom(session, author))
|
|
23416
|
+
return true;
|
|
23417
|
+
return false;
|
|
23418
|
+
};
|
|
23319
23419
|
var independenceReasons = (row, authors) => {
|
|
23320
23420
|
const reasons = [];
|
|
23321
23421
|
if (!row.actor.session)
|
|
23322
23422
|
reasons.push("no_session");
|
|
23323
|
-
else if (authors
|
|
23423
|
+
else if (authoredBy(authors, row.actor.session))
|
|
23324
23424
|
reasons.push("author_session");
|
|
23325
23425
|
if (row.self === true && !reasons.includes("no_session"))
|
|
23326
23426
|
reasons.push("self");
|
|
@@ -24421,38 +24521,45 @@ var compactReference = (ref) => {
|
|
|
24421
24521
|
};
|
|
24422
24522
|
return { kind: ref.kind };
|
|
24423
24523
|
};
|
|
24424
|
-
|
|
24425
|
-
const
|
|
24426
|
-
|
|
24427
|
-
|
|
24428
|
-
|
|
24429
|
-
|
|
24430
|
-
|
|
24431
|
-
|
|
24432
|
-
|
|
24433
|
-
|
|
24434
|
-
|
|
24435
|
-
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
|
|
24439
|
-
|
|
24524
|
+
var newestDecisionFirst = (left, right) => {
|
|
24525
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
24526
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
24527
|
+
if (leftAt !== rightAt)
|
|
24528
|
+
return leftAt > rightAt ? -1 : 1;
|
|
24529
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
24530
|
+
};
|
|
24531
|
+
var compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
24532
|
+
id: entry.id,
|
|
24533
|
+
purpose: entry.data.purpose,
|
|
24534
|
+
status: entry.data.response,
|
|
24535
|
+
digest: entry.data.digest,
|
|
24536
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
24537
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
24538
|
+
origin: source.origin ?? undefined
|
|
24539
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS);
|
|
24540
|
+
function compactTaskContext(view, inherited = null) {
|
|
24541
|
+
const decisions = compactDecisions([
|
|
24542
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
24543
|
+
inherited
|
|
24544
|
+
]);
|
|
24545
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
24440
24546
|
id: method.id,
|
|
24441
24547
|
assurance: method.assurance,
|
|
24442
24548
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
24443
24549
|
})) : [];
|
|
24550
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
24444
24551
|
const gaps = Array.from(new Set([
|
|
24445
|
-
...
|
|
24446
|
-
...view
|
|
24447
|
-
...view
|
|
24552
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
24553
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
24554
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
24448
24555
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
24449
24556
|
const context = {
|
|
24450
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
24451
|
-
status: view
|
|
24557
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
24558
|
+
status: view?.task.status ?? null,
|
|
24452
24559
|
decisions,
|
|
24453
24560
|
methods,
|
|
24454
24561
|
gaps,
|
|
24455
|
-
nextAction: compactText(view
|
|
24562
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
24456
24563
|
};
|
|
24457
24564
|
let encoded = JSON.stringify(context);
|
|
24458
24565
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -25057,6 +25164,13 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
25057
25164
|
"worker.cancel",
|
|
25058
25165
|
"state.export"
|
|
25059
25166
|
]);
|
|
25167
|
+
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
25168
|
+
var workerCommand = (taskId, request) => {
|
|
25169
|
+
const { action, workerId, reason, report } = request;
|
|
25170
|
+
const rest = JSON.stringify({ reason, report });
|
|
25171
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
25172
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
25173
|
+
};
|
|
25060
25174
|
var CREATING_ACTIONS = new Set([
|
|
25061
25175
|
"task.revise",
|
|
25062
25176
|
"task.progress",
|
|
@@ -25307,6 +25421,17 @@ class WorkitCore {
|
|
|
25307
25421
|
const root = this.contextRootError();
|
|
25308
25422
|
if (!root.ok)
|
|
25309
25423
|
return root;
|
|
25424
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
25425
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
25426
|
+
if (workerId !== null) {
|
|
25427
|
+
const owner = this.store.taskForWorker(workerId);
|
|
25428
|
+
if (!owner.ok)
|
|
25429
|
+
return owner;
|
|
25430
|
+
if (owner.data)
|
|
25431
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
25432
|
+
if (addressed)
|
|
25433
|
+
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)}\``);
|
|
25434
|
+
}
|
|
25310
25435
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
25311
25436
|
const found = this.store.implicitTask({
|
|
25312
25437
|
provenance: provenance(this.context),
|
|
@@ -26013,7 +26138,9 @@ class WorkitCore {
|
|
|
26013
26138
|
if (!resolved.ok)
|
|
26014
26139
|
return resolved;
|
|
26015
26140
|
const value = resolved.data;
|
|
26016
|
-
|
|
26141
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
26142
|
+
const { action, taskId } = value ?? {};
|
|
26143
|
+
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)}\`` };
|
|
26017
26144
|
}
|
|
26018
26145
|
workerOnce(request) {
|
|
26019
26146
|
const root = this.contextRootError();
|
|
@@ -26218,10 +26345,18 @@ class WorkitCore {
|
|
|
26218
26345
|
requirements
|
|
26219
26346
|
});
|
|
26220
26347
|
}
|
|
26221
|
-
compactContext(taskId, freshness) {
|
|
26348
|
+
compactContext(taskId, freshness, origin = null) {
|
|
26222
26349
|
const root = this.contextRootError();
|
|
26223
26350
|
if (!root.ok)
|
|
26224
26351
|
return root;
|
|
26352
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
26353
|
+
const inherited = base?.ok && base.data ? {
|
|
26354
|
+
origin: origin.origin,
|
|
26355
|
+
taskId: base.data.id,
|
|
26356
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
26357
|
+
} : null;
|
|
26358
|
+
if (taskId === null)
|
|
26359
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
26225
26360
|
const task = this.store.readTask(taskId);
|
|
26226
26361
|
if (!task.ok)
|
|
26227
26362
|
return task;
|
|
@@ -26231,7 +26366,7 @@ class WorkitCore {
|
|
|
26231
26366
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
26232
26367
|
if (!view.ok)
|
|
26233
26368
|
return view;
|
|
26234
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
26369
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
26235
26370
|
}
|
|
26236
26371
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
26237
26372
|
const workspace = this.store.readWorkspace();
|