@brainervirus/workit-cursor 8.11.0 → 8.12.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/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +340 -225
- package/dist/mcp-server.js +277 -276
- package/dist/workit-hook.js +341 -227
- package/package.json +3 -3
- package/skills/workit-fanout/references/brief.md +23 -8
- package/skills/workit-fanout/references/orchestration.md +9 -4
package/dist/mcp-server.js
CHANGED
|
@@ -16582,7 +16582,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
16582
16582
|
// packages/workit-core/src/core.ts
|
|
16583
16583
|
import { spawnSync as spawnSync14 } from "node:child_process";
|
|
16584
16584
|
import { existsSync as existsSync7, realpathSync as realpathSync5 } from "node:fs";
|
|
16585
|
-
import
|
|
16585
|
+
import path20 from "node:path";
|
|
16586
16586
|
|
|
16587
16587
|
// packages/workit-core/src/core/task-contract.ts
|
|
16588
16588
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -17839,7 +17839,7 @@ function parseAdvertisedOperation(family, input, host) {
|
|
|
17839
17839
|
// packages/workit-core/src/core/task-store.ts
|
|
17840
17840
|
import { createHash as createHash4, randomUUID as randomUUID3 } from "node:crypto";
|
|
17841
17841
|
import * as fs7 from "node:fs";
|
|
17842
|
-
import
|
|
17842
|
+
import path7 from "node:path";
|
|
17843
17843
|
|
|
17844
17844
|
// node_modules/@openclaw/fs-safe/dist/errors.js
|
|
17845
17845
|
var OPERATIONAL_CODES = new Set([
|
|
@@ -18442,11 +18442,85 @@ function acquireFileLockSync(targetPath, options) {
|
|
|
18442
18442
|
}
|
|
18443
18443
|
}
|
|
18444
18444
|
}
|
|
18445
|
+
// packages/workit-core/src/core/logger.ts
|
|
18446
|
+
import os from "node:os";
|
|
18447
|
+
import path3 from "node:path";
|
|
18448
|
+
var REDACTED = "[REDACTED]";
|
|
18449
|
+
var SECRET_VALUE = /\b(?:Bearer|Basic|Digest|Token)\s+\S+/gi;
|
|
18450
|
+
var KEY_EQ_VALUE = /\b([A-Za-z0-9_-]*(?:token|secret|password|passwd|apikey|api[_-]?key|authorization|credential|bearer)[A-Za-z0-9_-]*)([:=]\s*).+/gi;
|
|
18451
|
+
var URL_QUERY = /(https?:\/\/[^?#\s]+)\?[^#\s]*/g;
|
|
18452
|
+
var SENSITIVE_WORDS = new Set([
|
|
18453
|
+
"token",
|
|
18454
|
+
"secret",
|
|
18455
|
+
"password",
|
|
18456
|
+
"passwd",
|
|
18457
|
+
"authorization",
|
|
18458
|
+
"credential",
|
|
18459
|
+
"credentials",
|
|
18460
|
+
"cookie",
|
|
18461
|
+
"api",
|
|
18462
|
+
"apikey",
|
|
18463
|
+
"apitoken",
|
|
18464
|
+
"accesstoken",
|
|
18465
|
+
"clientsecret",
|
|
18466
|
+
"refreshtoken",
|
|
18467
|
+
"key",
|
|
18468
|
+
"bearer",
|
|
18469
|
+
"prompt",
|
|
18470
|
+
"message",
|
|
18471
|
+
"messages",
|
|
18472
|
+
"content",
|
|
18473
|
+
"body",
|
|
18474
|
+
"args",
|
|
18475
|
+
"argument",
|
|
18476
|
+
"result",
|
|
18477
|
+
"results",
|
|
18478
|
+
"output",
|
|
18479
|
+
"issue",
|
|
18480
|
+
"description",
|
|
18481
|
+
"summary",
|
|
18482
|
+
"payload",
|
|
18483
|
+
"script",
|
|
18484
|
+
"command",
|
|
18485
|
+
"text",
|
|
18486
|
+
"query"
|
|
18487
|
+
]);
|
|
18488
|
+
var STACK_WORDS = new Set(["stack", "stacktrace", "trace"]);
|
|
18489
|
+
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18490
|
+
var resolveStateDir = () => {
|
|
18491
|
+
const override = process.env.WORKFLOW_TOOLKIT_STATE;
|
|
18492
|
+
if (override)
|
|
18493
|
+
return override;
|
|
18494
|
+
const home = os.homedir();
|
|
18495
|
+
if (process.env.XDG_STATE_HOME)
|
|
18496
|
+
return path3.join(process.env.XDG_STATE_HOME, "workit");
|
|
18497
|
+
switch (os.platform()) {
|
|
18498
|
+
case "darwin":
|
|
18499
|
+
return path3.join(home, "Library", "Application Support", "workit");
|
|
18500
|
+
case "win32":
|
|
18501
|
+
return path3.join(process.env.LOCALAPPDATA ?? path3.join(home, "AppData", "Local"), "workit");
|
|
18502
|
+
default:
|
|
18503
|
+
return path3.join(process.env.HOME ?? home, ".local", "state", "workit");
|
|
18504
|
+
}
|
|
18505
|
+
};
|
|
18506
|
+
var homePattern = new RegExp(`${escapeRegExp(os.homedir())}(?=[/\\\\]|$)|\\$HOME(?=[/\\\\]|$)`, "g");
|
|
18507
|
+
var applyPatterns = (value) => {
|
|
18508
|
+
let out = value;
|
|
18509
|
+
out = out.replace(SECRET_VALUE, REDACTED);
|
|
18510
|
+
out = out.replace(KEY_EQ_VALUE, "$1$2[REDACTED]");
|
|
18511
|
+
out = out.replace(URL_QUERY, "$1?[REDACTED]");
|
|
18512
|
+
out = out.replace(homePattern, "~");
|
|
18513
|
+
if (process.platform === "win32")
|
|
18514
|
+
out = out.replace(/\\/g, "/");
|
|
18515
|
+
return out;
|
|
18516
|
+
};
|
|
18517
|
+
var redactSecrets = (value) => applyPatterns(value);
|
|
18518
|
+
|
|
18445
18519
|
// packages/workit-core/src/store/paths.ts
|
|
18446
18520
|
import { spawnSync } from "node:child_process";
|
|
18447
18521
|
import { createHash as createHash2 } from "node:crypto";
|
|
18448
18522
|
import fs4 from "node:fs";
|
|
18449
|
-
import
|
|
18523
|
+
import path4 from "node:path";
|
|
18450
18524
|
var NOT_A_REPO = /not a git repository \(or any (of the parent directories|parent up to)/u;
|
|
18451
18525
|
var gitRun = (cwd, args) => {
|
|
18452
18526
|
const run = spawnSync("git", args, {
|
|
@@ -18488,14 +18562,14 @@ var DISCOVERY_ENV = [
|
|
|
18488
18562
|
];
|
|
18489
18563
|
var isGitDir = (dir) => {
|
|
18490
18564
|
try {
|
|
18491
|
-
return fs4.statSync(
|
|
18565
|
+
return fs4.statSync(path4.join(dir, "HEAD")).isFile() && fs4.statSync(path4.join(dir, "objects")).isDirectory() && fs4.statSync(path4.join(dir, "refs")).isDirectory();
|
|
18492
18566
|
} catch {
|
|
18493
18567
|
return false;
|
|
18494
18568
|
}
|
|
18495
18569
|
};
|
|
18496
18570
|
var reftableRefs = (common) => {
|
|
18497
18571
|
try {
|
|
18498
|
-
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(
|
|
18572
|
+
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(path4.join(common, "config"), "utf8"));
|
|
18499
18573
|
} catch {
|
|
18500
18574
|
return false;
|
|
18501
18575
|
}
|
|
@@ -18515,7 +18589,7 @@ function fastGit(root) {
|
|
|
18515
18589
|
if (device !== null && stat.dev !== device)
|
|
18516
18590
|
return { kind: "none" };
|
|
18517
18591
|
device = stat.dev;
|
|
18518
|
-
const dotGit =
|
|
18592
|
+
const dotGit = path4.join(dir, ".git");
|
|
18519
18593
|
let entry = null;
|
|
18520
18594
|
try {
|
|
18521
18595
|
entry = fs4.statSync(dotGit);
|
|
@@ -18536,19 +18610,19 @@ function fastGit(root) {
|
|
|
18536
18610
|
const match = /^gitdir: (.+)$/mu.exec(text);
|
|
18537
18611
|
if (!match)
|
|
18538
18612
|
return null;
|
|
18539
|
-
gitDir =
|
|
18613
|
+
gitDir = path4.resolve(dir, match[1].trim());
|
|
18540
18614
|
} else
|
|
18541
18615
|
return null;
|
|
18542
|
-
if (!fs4.existsSync(
|
|
18616
|
+
if (!fs4.existsSync(path4.join(gitDir, "HEAD")))
|
|
18543
18617
|
return null;
|
|
18544
18618
|
} else if (isGitDir(dir))
|
|
18545
18619
|
gitDir = dir;
|
|
18546
18620
|
if (gitDir) {
|
|
18547
18621
|
let common = gitDir;
|
|
18548
18622
|
try {
|
|
18549
|
-
common =
|
|
18623
|
+
common = path4.resolve(gitDir, fs4.readFileSync(path4.join(gitDir, "commondir"), "utf8").trim());
|
|
18550
18624
|
} catch {}
|
|
18551
|
-
if (!fs4.existsSync(
|
|
18625
|
+
if (!fs4.existsSync(path4.join(common, "objects")))
|
|
18552
18626
|
return null;
|
|
18553
18627
|
return {
|
|
18554
18628
|
kind: "repo",
|
|
@@ -18558,26 +18632,26 @@ function fastGit(root) {
|
|
|
18558
18632
|
reftable: reftableRefs(common)
|
|
18559
18633
|
};
|
|
18560
18634
|
}
|
|
18561
|
-
const parent =
|
|
18635
|
+
const parent = path4.dirname(dir);
|
|
18562
18636
|
if (parent === dir)
|
|
18563
18637
|
return { kind: "none" };
|
|
18564
18638
|
dir = parent;
|
|
18565
18639
|
}
|
|
18566
18640
|
}
|
|
18567
18641
|
function resolveStore(root) {
|
|
18568
|
-
root =
|
|
18642
|
+
root = path4.resolve(root);
|
|
18569
18643
|
let directory = false;
|
|
18570
18644
|
try {
|
|
18571
18645
|
directory = fs4.statSync(root).isDirectory();
|
|
18572
18646
|
} catch {}
|
|
18573
18647
|
if (!directory)
|
|
18574
|
-
return { dir:
|
|
18648
|
+
return { dir: path4.join(root, ".workit"), shared: false, top: null };
|
|
18575
18649
|
const fast = fastGit(root);
|
|
18576
18650
|
if (fast?.kind === "none")
|
|
18577
|
-
return { dir:
|
|
18651
|
+
return { dir: path4.join(root, ".workit"), shared: false, top: null };
|
|
18578
18652
|
if (fast?.kind === "repo")
|
|
18579
18653
|
return {
|
|
18580
|
-
dir:
|
|
18654
|
+
dir: path4.join(fast.common, "workit"),
|
|
18581
18655
|
shared: true,
|
|
18582
18656
|
top: fast.top,
|
|
18583
18657
|
git: { gitDir: fast.gitDir, top: fast.top, reftable: fast.reftable }
|
|
@@ -18587,20 +18661,20 @@ function resolveStore(root) {
|
|
|
18587
18661
|
if (run.ok && common) {
|
|
18588
18662
|
const top = gitRun(root, ["rev-parse", "--path-format=absolute", "--show-toplevel"]);
|
|
18589
18663
|
return {
|
|
18590
|
-
dir:
|
|
18664
|
+
dir: path4.join(real(path4.resolve(root, common)), "workit"),
|
|
18591
18665
|
shared: true,
|
|
18592
18666
|
top: top.ok && top.stdout.trim() ? real(top.stdout.trim()) : null
|
|
18593
18667
|
};
|
|
18594
18668
|
}
|
|
18595
18669
|
if (run.missing || !run.ok && NOT_A_REPO.test(run.stderr))
|
|
18596
|
-
return { dir:
|
|
18670
|
+
return { dir: path4.join(root, ".workit"), shared: false, top: null };
|
|
18597
18671
|
return new Error(`cannot locate the workit store: git rev-parse failed (${run.stderr.trim().split(`
|
|
18598
18672
|
`)[0] || "no output"}); fix the repository (git status should work here)`);
|
|
18599
18673
|
}
|
|
18600
18674
|
var rebasingBranch = (gitDir) => {
|
|
18601
18675
|
for (const state of ["rebase-merge", "rebase-apply"]) {
|
|
18602
18676
|
try {
|
|
18603
|
-
const ref = fs4.readFileSync(
|
|
18677
|
+
const ref = fs4.readFileSync(path4.join(gitDir, state, "head-name"), "utf8").trim();
|
|
18604
18678
|
const match = /^refs\/heads\/(.+)$/u.exec(ref);
|
|
18605
18679
|
if (match)
|
|
18606
18680
|
return match[1];
|
|
@@ -18615,7 +18689,7 @@ function resolveTaskKey(root, location) {
|
|
|
18615
18689
|
if (location.git && !location.git.reftable) {
|
|
18616
18690
|
let head = "";
|
|
18617
18691
|
try {
|
|
18618
|
-
head = fs4.readFileSync(
|
|
18692
|
+
head = fs4.readFileSync(path4.join(location.git.gitDir, "HEAD"), "utf8").trim();
|
|
18619
18693
|
} catch {}
|
|
18620
18694
|
const ref = /^ref: refs\/heads\/(.+)$/u.exec(head);
|
|
18621
18695
|
if (ref && ref[1] !== ".invalid")
|
|
@@ -18646,7 +18720,7 @@ function resolveTaskKey(root, location) {
|
|
|
18646
18720
|
return { key: `detached-${shortHash(real(worktree))}`, kind: "detached", branch: null };
|
|
18647
18721
|
}
|
|
18648
18722
|
function checkoutRootOf(root, location) {
|
|
18649
|
-
const resolved =
|
|
18723
|
+
const resolved = path4.resolve(root);
|
|
18650
18724
|
let canonical = resolved;
|
|
18651
18725
|
try {
|
|
18652
18726
|
canonical = fs4.realpathSync(resolved);
|
|
@@ -18677,13 +18751,13 @@ function branchRenames(location) {
|
|
|
18677
18751
|
}
|
|
18678
18752
|
for (const entry of entries)
|
|
18679
18753
|
if (entry.isDirectory())
|
|
18680
|
-
walk(
|
|
18754
|
+
walk(path4.join(dir, entry.name));
|
|
18681
18755
|
else
|
|
18682
|
-
files.push(
|
|
18756
|
+
files.push(path4.join(dir, entry.name));
|
|
18683
18757
|
};
|
|
18684
|
-
walk(
|
|
18758
|
+
walk(path4.join(path4.dirname(location.dir), "logs", "refs", "heads"));
|
|
18685
18759
|
if (location.git)
|
|
18686
|
-
files.push(
|
|
18760
|
+
files.push(path4.join(location.git.gitDir, "logs", "HEAD"));
|
|
18687
18761
|
const seen = new Set;
|
|
18688
18762
|
const renames = [];
|
|
18689
18763
|
for (const file of files) {
|
|
@@ -18718,7 +18792,7 @@ var checkoutSlug = (root) => {
|
|
|
18718
18792
|
let canonical = real(root);
|
|
18719
18793
|
if (process.platform === "win32")
|
|
18720
18794
|
canonical = canonical.toLowerCase();
|
|
18721
|
-
const base =
|
|
18795
|
+
const base = path4.basename(canonical).replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 40) || "root";
|
|
18722
18796
|
return `${base}-${shortHash(canonical)}`;
|
|
18723
18797
|
};
|
|
18724
18798
|
|
|
@@ -18754,20 +18828,20 @@ var OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
|
|
|
18754
18828
|
|
|
18755
18829
|
// packages/workit-core/src/core/package-root.ts
|
|
18756
18830
|
import { existsSync } from "node:fs";
|
|
18757
|
-
import
|
|
18831
|
+
import path5 from "node:path";
|
|
18758
18832
|
import { fileURLToPath } from "node:url";
|
|
18759
18833
|
var packageRoot = () => {
|
|
18760
|
-
let dir =
|
|
18834
|
+
let dir = path5.dirname(fileURLToPath(import.meta.url));
|
|
18761
18835
|
while (true) {
|
|
18762
|
-
const parent =
|
|
18763
|
-
if (existsSync(
|
|
18836
|
+
const parent = path5.dirname(dir);
|
|
18837
|
+
if (existsSync(path5.join(dir, "package.json")) || parent === dir)
|
|
18764
18838
|
return dir;
|
|
18765
18839
|
dir = parent;
|
|
18766
18840
|
}
|
|
18767
18841
|
};
|
|
18768
18842
|
var assetRoot = () => {
|
|
18769
18843
|
const root = packageRoot();
|
|
18770
|
-
const assets =
|
|
18844
|
+
const assets = path5.join(root, "assets");
|
|
18771
18845
|
return existsSync(assets) ? assets : root;
|
|
18772
18846
|
};
|
|
18773
18847
|
|
|
@@ -18914,7 +18988,7 @@ var clearAbandonedReclaimGuard = (lockPath, nowMs = Date.now()) => {
|
|
|
18914
18988
|
// packages/workit-core/src/store/event-log.ts
|
|
18915
18989
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
18916
18990
|
import fs6 from "node:fs";
|
|
18917
|
-
import
|
|
18991
|
+
import path6 from "node:path";
|
|
18918
18992
|
var EVENT_VERSION = 1;
|
|
18919
18993
|
|
|
18920
18994
|
class LogDamage extends Error {
|
|
@@ -19025,7 +19099,7 @@ function appendEvent(file, event, validEnd) {
|
|
|
19025
19099
|
fs6.closeSync(fd);
|
|
19026
19100
|
}
|
|
19027
19101
|
if (created)
|
|
19028
|
-
fsyncDirectory(
|
|
19102
|
+
fsyncDirectory(path6.dirname(file));
|
|
19029
19103
|
return validEnd;
|
|
19030
19104
|
}
|
|
19031
19105
|
function replaceFile(file, bytes, durable) {
|
|
@@ -19041,7 +19115,7 @@ function replaceFile(file, bytes, durable) {
|
|
|
19041
19115
|
}
|
|
19042
19116
|
renameWithRetry(temporary, file);
|
|
19043
19117
|
if (durable)
|
|
19044
|
-
fsyncDirectory(
|
|
19118
|
+
fsyncDirectory(path6.dirname(file));
|
|
19045
19119
|
} catch (error) {
|
|
19046
19120
|
try {
|
|
19047
19121
|
fs6.unlinkSync(temporary);
|
|
@@ -19384,7 +19458,7 @@ var cachedRuntimeVersion = null;
|
|
|
19384
19458
|
var runtimeVersion = () => {
|
|
19385
19459
|
if (cachedRuntimeVersion === null) {
|
|
19386
19460
|
try {
|
|
19387
|
-
const pkg = JSON.parse(fs7.readFileSync(
|
|
19461
|
+
const pkg = JSON.parse(fs7.readFileSync(path7.join(packageRoot(), "package.json"), "utf8"));
|
|
19388
19462
|
cachedRuntimeVersion = typeof pkg.version === "string" && pkg.version ? pkg.version : "0.0.0";
|
|
19389
19463
|
} catch {
|
|
19390
19464
|
cachedRuntimeVersion = "0.0.0";
|
|
@@ -19417,7 +19491,7 @@ var readText = (file) => {
|
|
|
19417
19491
|
};
|
|
19418
19492
|
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
19419
19493
|
var branchStart = (location, branch, aliases) => {
|
|
19420
|
-
const first = readText(
|
|
19494
|
+
const first = readText(path7.join(path7.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
19421
19495
|
`, 1)[0];
|
|
19422
19496
|
const created = REFLOG_LINE.exec(first);
|
|
19423
19497
|
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
@@ -19427,7 +19501,7 @@ var branchStart = (location, branch, aliases) => {
|
|
|
19427
19501
|
return start;
|
|
19428
19502
|
if (!location.git)
|
|
19429
19503
|
return null;
|
|
19430
|
-
for (const line of readText(
|
|
19504
|
+
for (const line of readText(path7.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
19431
19505
|
`)) {
|
|
19432
19506
|
const entry = REFLOG_LINE.exec(line);
|
|
19433
19507
|
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
@@ -19437,14 +19511,14 @@ var branchStart = (location, branch, aliases) => {
|
|
|
19437
19511
|
}
|
|
19438
19512
|
return null;
|
|
19439
19513
|
};
|
|
19440
|
-
var refExists = (common, ref) => fs7.existsSync(
|
|
19514
|
+
var refExists = (common, ref) => fs7.existsSync(path7.join(common, ref)) || readText(path7.join(common, "packed-refs")).includes(` ${ref}
|
|
19441
19515
|
`);
|
|
19442
19516
|
var origins = new Map;
|
|
19443
19517
|
var sameDirectoryIdentity = (left, right) => {
|
|
19444
|
-
if (!
|
|
19518
|
+
if (!path7.isAbsolute(left) || !path7.isAbsolute(right))
|
|
19445
19519
|
return false;
|
|
19446
|
-
const normalizedLeft =
|
|
19447
|
-
const normalizedRight =
|
|
19520
|
+
const normalizedLeft = path7.resolve(left);
|
|
19521
|
+
const normalizedRight = path7.resolve(right);
|
|
19448
19522
|
try {
|
|
19449
19523
|
const a = fs7.statSync(normalizedLeft, { bigint: true });
|
|
19450
19524
|
const b = fs7.statSync(normalizedRight, { bigint: true });
|
|
@@ -19490,7 +19564,7 @@ class TaskStore {
|
|
|
19490
19564
|
migrationChecked = false;
|
|
19491
19565
|
compactDue = new Set;
|
|
19492
19566
|
constructor(root, options = {}) {
|
|
19493
|
-
const resolved =
|
|
19567
|
+
const resolved = path7.resolve(root);
|
|
19494
19568
|
this.origin = fs7.existsSync(resolved) ? fs7.realpathSync(resolved) : resolved;
|
|
19495
19569
|
this.located = resolveStore(this.origin);
|
|
19496
19570
|
this.root = checkoutRootOf(this.origin, this.located);
|
|
@@ -19499,7 +19573,7 @@ class TaskStore {
|
|
|
19499
19573
|
this.migrateOnRead = options.migrateOnRead;
|
|
19500
19574
|
}
|
|
19501
19575
|
location() {
|
|
19502
|
-
if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs7.existsSync(
|
|
19576
|
+
if (this.located !== undefined && !(this.located instanceof Error) && !this.located.shared && fs7.existsSync(path7.join(this.root, ".git"))) {
|
|
19503
19577
|
this.located = undefined;
|
|
19504
19578
|
this.migrationChecked = false;
|
|
19505
19579
|
}
|
|
@@ -19655,7 +19729,7 @@ class TaskStore {
|
|
|
19655
19729
|
const moved = this.bindLocked(again.data.id, key, input.now);
|
|
19656
19730
|
return moved.ok ? success(moved.data.revision, null, { task: moved.data, created: false, key }) : moved;
|
|
19657
19731
|
}
|
|
19658
|
-
const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" :
|
|
19732
|
+
const label = key.kind === "branch" ? `branch ${key.branch}` : key.kind === "detached" ? "a detached HEAD" : path7.basename(this.root) || this.root;
|
|
19659
19733
|
const intent = {
|
|
19660
19734
|
objective: input.objective?.trim() || `Work on ${label}`,
|
|
19661
19735
|
scope: { description: `the checkout (${label})`, paths: ["."], exclusions: [] },
|
|
@@ -19715,14 +19789,14 @@ class TaskStore {
|
|
|
19715
19789
|
const branch = key.ok ? key.data.branch : null;
|
|
19716
19790
|
if (!branch || !location.ok)
|
|
19717
19791
|
return success(null, null, null);
|
|
19718
|
-
const common =
|
|
19719
|
-
const heads =
|
|
19720
|
-
const headLog = location.data.git ?
|
|
19792
|
+
const common = path7.dirname(location.data.dir);
|
|
19793
|
+
const heads = path7.join(common, "logs", "refs", "heads");
|
|
19794
|
+
const headLog = location.data.git ? path7.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
19721
19795
|
const signatures = [
|
|
19722
|
-
|
|
19796
|
+
path7.join(heads, branch),
|
|
19723
19797
|
headLog,
|
|
19724
19798
|
heads,
|
|
19725
|
-
|
|
19799
|
+
path7.join(common, "packed-refs")
|
|
19726
19800
|
].map((file) => fileSignature(file) ?? "-");
|
|
19727
19801
|
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
19728
19802
|
let resolved = origins.get(slot);
|
|
@@ -19734,7 +19808,7 @@ class TaskStore {
|
|
|
19734
19808
|
aliases.push(rename.from);
|
|
19735
19809
|
const start = branchStart(location.data, branch, aliases);
|
|
19736
19810
|
const slash = start?.indexOf("/") ?? -1;
|
|
19737
|
-
const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(
|
|
19811
|
+
const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path7.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
|
|
19738
19812
|
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
19739
19813
|
resolved = {
|
|
19740
19814
|
signature: signatures.join("|"),
|
|
@@ -19972,13 +20046,13 @@ class TaskStore {
|
|
|
19972
20046
|
if (!ready.ok)
|
|
19973
20047
|
return ready;
|
|
19974
20048
|
const dirs = this.paths();
|
|
19975
|
-
const recovery =
|
|
20049
|
+
const recovery = path7.join(this.root, ".workit", "recovery");
|
|
19976
20050
|
if (fs7.existsSync(recovery)) {
|
|
19977
20051
|
let files = 0;
|
|
19978
20052
|
let bytes = 0;
|
|
19979
20053
|
try {
|
|
19980
20054
|
for (const name of fs7.readdirSync(recovery)) {
|
|
19981
|
-
const stat = fs7.lstatSync(
|
|
20055
|
+
const stat = fs7.lstatSync(path7.join(recovery, name));
|
|
19982
20056
|
if (!stat.isFile())
|
|
19983
20057
|
continue;
|
|
19984
20058
|
files += 1;
|
|
@@ -20031,7 +20105,7 @@ class TaskStore {
|
|
|
20031
20105
|
if (fs7.existsSync(dirs.blobs))
|
|
20032
20106
|
for (const name of fs7.readdirSync(dirs.blobs)) {
|
|
20033
20107
|
const digest = name.replace(/\.json$/, "");
|
|
20034
|
-
const file =
|
|
20108
|
+
const file = path7.join(dirs.blobs, name);
|
|
20035
20109
|
let stat;
|
|
20036
20110
|
try {
|
|
20037
20111
|
stat = fs7.lstatSync(file);
|
|
@@ -20049,7 +20123,7 @@ class TaskStore {
|
|
|
20049
20123
|
}
|
|
20050
20124
|
return success(null, null, null);
|
|
20051
20125
|
};
|
|
20052
|
-
const swept = dryRun ? sweep() : this.withLock(
|
|
20126
|
+
const swept = dryRun ? sweep() : this.withLock(path7.join(dirs.dir, "gc.lock"), sweep);
|
|
20053
20127
|
if (!swept.ok)
|
|
20054
20128
|
return swept;
|
|
20055
20129
|
const temporaryDirs = [
|
|
@@ -20057,7 +20131,7 @@ class TaskStore {
|
|
|
20057
20131
|
dirs.tasks,
|
|
20058
20132
|
dirs.blobs,
|
|
20059
20133
|
dirs.checkout,
|
|
20060
|
-
...names.map((name) =>
|
|
20134
|
+
...names.map((name) => path7.join(dirs.tasks, name))
|
|
20061
20135
|
];
|
|
20062
20136
|
for (const directory of temporaryDirs) {
|
|
20063
20137
|
if (!fs7.existsSync(directory))
|
|
@@ -20065,7 +20139,7 @@ class TaskStore {
|
|
|
20065
20139
|
for (const name of fs7.readdirSync(directory)) {
|
|
20066
20140
|
if (!name.endsWith(".tmp") && !name.endsWith(".probe"))
|
|
20067
20141
|
continue;
|
|
20068
|
-
const file =
|
|
20142
|
+
const file = path7.join(directory, name);
|
|
20069
20143
|
try {
|
|
20070
20144
|
const stat = fs7.lstatSync(file);
|
|
20071
20145
|
if (!stat.isFile() || nowMs - stat.mtimeMs <= STALE_TEMPORARY_MS)
|
|
@@ -20082,30 +20156,30 @@ class TaskStore {
|
|
|
20082
20156
|
}
|
|
20083
20157
|
paths() {
|
|
20084
20158
|
const location = this.location();
|
|
20085
|
-
const dir = location.ok ? location.data.dir :
|
|
20086
|
-
const checkout =
|
|
20159
|
+
const dir = location.ok ? location.data.dir : path7.join(this.root, ".workit");
|
|
20160
|
+
const checkout = path7.join(dir, "checkouts", checkoutSlug(this.root));
|
|
20087
20161
|
return {
|
|
20088
20162
|
dir,
|
|
20089
20163
|
shared: location.ok ? location.data.shared : false,
|
|
20090
|
-
marker:
|
|
20164
|
+
marker: path7.join(dir, "store.json"),
|
|
20091
20165
|
checkout,
|
|
20092
|
-
workspace:
|
|
20093
|
-
checkoutLock:
|
|
20094
|
-
tasks:
|
|
20095
|
-
index:
|
|
20096
|
-
blobs:
|
|
20097
|
-
legacy:
|
|
20098
|
-
v2:
|
|
20166
|
+
workspace: path7.join(checkout, "workspace.json"),
|
|
20167
|
+
checkoutLock: path7.join(checkout, "metadata.lock"),
|
|
20168
|
+
tasks: path7.join(dir, "tasks"),
|
|
20169
|
+
index: path7.join(dir, "task-index.json"),
|
|
20170
|
+
blobs: path7.join(dir, "blobs", "candidates"),
|
|
20171
|
+
legacy: path7.join(dir, "legacy", checkoutSlug(this.root), "v2"),
|
|
20172
|
+
v2: path7.join(this.root, ".workit")
|
|
20099
20173
|
};
|
|
20100
20174
|
}
|
|
20101
20175
|
eventsPath(taskId) {
|
|
20102
|
-
return
|
|
20176
|
+
return path7.join(this.paths().tasks, taskId, "events.jsonl");
|
|
20103
20177
|
}
|
|
20104
20178
|
snapshotPath(taskId) {
|
|
20105
|
-
return
|
|
20179
|
+
return path7.join(this.paths().tasks, taskId, "snapshot.json");
|
|
20106
20180
|
}
|
|
20107
20181
|
taskLockPath(taskId) {
|
|
20108
|
-
return
|
|
20182
|
+
return path7.join(this.paths().tasks, taskId, "lock");
|
|
20109
20183
|
}
|
|
20110
20184
|
ready(write = false) {
|
|
20111
20185
|
const location = this.location();
|
|
@@ -20144,13 +20218,13 @@ class TaskStore {
|
|
|
20144
20218
|
return {
|
|
20145
20219
|
read: (digest) => {
|
|
20146
20220
|
try {
|
|
20147
|
-
return JSON.parse(fs7.readFileSync(
|
|
20221
|
+
return JSON.parse(fs7.readFileSync(path7.join(dir, `${digest}.json`), "utf8"));
|
|
20148
20222
|
} catch (error) {
|
|
20149
20223
|
throw new LogDamage(`stored candidate ${digest} is missing or unreadable: ${String(error)}`);
|
|
20150
20224
|
}
|
|
20151
20225
|
},
|
|
20152
20226
|
write: (digest, value) => {
|
|
20153
|
-
const file =
|
|
20227
|
+
const file = path7.join(dir, `${digest}.json`);
|
|
20154
20228
|
if (fs7.existsSync(file)) {
|
|
20155
20229
|
const stamp = new Date;
|
|
20156
20230
|
try {
|
|
@@ -20342,7 +20416,7 @@ class TaskStore {
|
|
|
20342
20416
|
}
|
|
20343
20417
|
}
|
|
20344
20418
|
openTask(record, type, key, legacy = null) {
|
|
20345
|
-
const dir =
|
|
20419
|
+
const dir = path7.join(this.paths().tasks, record.id);
|
|
20346
20420
|
fs7.mkdirSync(dir, { recursive: true });
|
|
20347
20421
|
const blobs = this.blobStore();
|
|
20348
20422
|
const bound = key ? { ...key, boundAt: key.boundAt ?? new Date().toISOString() } : null;
|
|
@@ -20435,7 +20509,7 @@ class TaskStore {
|
|
|
20435
20509
|
}
|
|
20436
20510
|
withKeyLock(key, operation) {
|
|
20437
20511
|
const digest = createHash4("sha256").update(key).digest("hex").slice(0, 32);
|
|
20438
|
-
return this.withLock(
|
|
20512
|
+
return this.withLock(path7.join(this.paths().dir, "keys", `${digest}.lock`), operation);
|
|
20439
20513
|
}
|
|
20440
20514
|
bindLocked(taskId, key, timestamp) {
|
|
20441
20515
|
const current = this.readWorkspace();
|
|
@@ -20576,7 +20650,7 @@ class TaskStore {
|
|
|
20576
20650
|
writeWorkspace(record) {
|
|
20577
20651
|
const file = this.paths().workspace;
|
|
20578
20652
|
try {
|
|
20579
|
-
fs7.mkdirSync(
|
|
20653
|
+
fs7.mkdirSync(path7.dirname(file), { recursive: true });
|
|
20580
20654
|
replaceFile(file, `${canonicalJson(record)}
|
|
20581
20655
|
`, true);
|
|
20582
20656
|
return success(null, null, null);
|
|
@@ -20654,23 +20728,23 @@ class TaskStore {
|
|
|
20654
20728
|
return failure2("revision_conflict", "workspace revision does not match; omit expectedWorkspaceRevision to use the current record", { expectedWorkspaceRevision: expected, actualWorkspaceRevision: actual });
|
|
20655
20729
|
}
|
|
20656
20730
|
v2Dirs() {
|
|
20657
|
-
return [...new Set([this.root, this.origin])].map((dir) =>
|
|
20731
|
+
return [...new Set([this.root, this.origin])].map((dir) => path7.join(dir, ".workit"));
|
|
20658
20732
|
}
|
|
20659
20733
|
pendingMigrations() {
|
|
20660
20734
|
return this.v2Dirs().filter((dir) => {
|
|
20661
|
-
const raw = this.readV2Workspace(
|
|
20735
|
+
const raw = this.readV2Workspace(path7.join(dir, "workspace.json"));
|
|
20662
20736
|
return raw !== null && raw !== TOMBSTONE;
|
|
20663
20737
|
});
|
|
20664
20738
|
}
|
|
20665
20739
|
migrateV2(v2) {
|
|
20666
20740
|
const dirs = this.paths();
|
|
20667
|
-
const v2Workspace =
|
|
20668
|
-
const v2Tasks =
|
|
20669
|
-
const legacy =
|
|
20741
|
+
const v2Workspace = path7.join(v2, "workspace.json");
|
|
20742
|
+
const v2Tasks = path7.join(v2, "tasks");
|
|
20743
|
+
const legacy = path7.join(dirs.dir, "legacy", checkoutSlug(path7.dirname(v2)), "v2");
|
|
20670
20744
|
const raw = this.readV2Workspace(v2Workspace);
|
|
20671
20745
|
if (raw === null || raw === TOMBSTONE)
|
|
20672
20746
|
return success(null, null, null);
|
|
20673
|
-
return this.withLock(dirs.checkoutLock, () => this.withLock(
|
|
20747
|
+
return this.withLock(dirs.checkoutLock, () => this.withLock(path7.join(v2, "metadata.lock"), () => {
|
|
20674
20748
|
const workspace = this.readV2Workspace(v2Workspace);
|
|
20675
20749
|
if (workspace === null || workspace === TOMBSTONE)
|
|
20676
20750
|
return success(null, null, null);
|
|
@@ -20679,7 +20753,7 @@ class TaskStore {
|
|
|
20679
20753
|
return failure2("recovery_required", `cannot migrate the 2.x store at ${v2}: ${parsedWorkspace.error}; move it aside to start fresh`, { path: v2Workspace });
|
|
20680
20754
|
let files = [];
|
|
20681
20755
|
try {
|
|
20682
|
-
files = fs7.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(
|
|
20756
|
+
files = fs7.readdirSync(v2Tasks).filter((name) => name.endsWith(".json") && validId(name.slice(0, -5))).filter((name) => !this.isStub(path7.join(v2Tasks, name)));
|
|
20683
20757
|
} catch {}
|
|
20684
20758
|
const current = this.readWorkspace();
|
|
20685
20759
|
if (!current.ok)
|
|
@@ -20697,21 +20771,21 @@ class TaskStore {
|
|
|
20697
20771
|
let skipped = 0;
|
|
20698
20772
|
const done = new Map;
|
|
20699
20773
|
try {
|
|
20700
|
-
fs7.mkdirSync(
|
|
20774
|
+
fs7.mkdirSync(path7.join(legacy, "tasks"), { recursive: true });
|
|
20701
20775
|
for (const name of ["workspace.json", "index.json"])
|
|
20702
|
-
if (fs7.existsSync(
|
|
20703
|
-
fs7.copyFileSync(
|
|
20776
|
+
if (fs7.existsSync(path7.join(v2, name)))
|
|
20777
|
+
fs7.copyFileSync(path7.join(v2, name), path7.join(legacy, name));
|
|
20704
20778
|
for (const name of files) {
|
|
20705
20779
|
const id = name.slice(0, -5);
|
|
20706
|
-
const file =
|
|
20780
|
+
const file = path7.join(v2Tasks, name);
|
|
20707
20781
|
const bytes = fs7.readFileSync(file, "utf8");
|
|
20708
20782
|
const digest = sha256(bytes);
|
|
20709
|
-
fs7.writeFileSync(
|
|
20783
|
+
fs7.writeFileSync(path7.join(legacy, "tasks", name), bytes);
|
|
20710
20784
|
const parsed = this.parseRecord(bytes, taskRecordSchema, "2.x task");
|
|
20711
20785
|
if (!parsed.ok || parsed.data.id !== id)
|
|
20712
20786
|
return failure2("recovery_required", `cannot migrate 2.x task ${id}: ${parsed.ok ? "file name and record ID differ" : parsed.error}; move ${file} aside to continue`, { path: file });
|
|
20713
20787
|
const record = { ...parsed.data, workspaceId: target.id };
|
|
20714
|
-
const origin = { path:
|
|
20788
|
+
const origin = { path: path7.join(legacy, "tasks", name), digest };
|
|
20715
20789
|
if (!fs7.existsSync(this.eventsPath(id))) {
|
|
20716
20790
|
this.openTask(record, "migrated.from_v2", null, origin);
|
|
20717
20791
|
migrated += 1;
|
|
@@ -20747,7 +20821,7 @@ class TaskStore {
|
|
|
20747
20821
|
try {
|
|
20748
20822
|
let complete = true;
|
|
20749
20823
|
for (const [name, digest] of done) {
|
|
20750
|
-
const file =
|
|
20824
|
+
const file = path7.join(v2Tasks, name);
|
|
20751
20825
|
if (sha256(fs7.readFileSync(file, "utf8")) !== digest) {
|
|
20752
20826
|
complete = false;
|
|
20753
20827
|
continue;
|
|
@@ -20758,7 +20832,7 @@ class TaskStore {
|
|
|
20758
20832
|
return failure2("busy", `the 2.x store at ${v2} changed during migration; retry`, {
|
|
20759
20833
|
path: v2
|
|
20760
20834
|
});
|
|
20761
|
-
fs7.rmSync(
|
|
20835
|
+
fs7.rmSync(path7.join(v2, "index.json"), { force: true });
|
|
20762
20836
|
this.writeTombstone(v2, target.id);
|
|
20763
20837
|
} catch (error) {
|
|
20764
20838
|
return failure2("storage_error", `cannot finish the 2.x migration: ${String(error)}`, {
|
|
@@ -20778,7 +20852,7 @@ class TaskStore {
|
|
|
20778
20852
|
}
|
|
20779
20853
|
adoptLocalStore() {
|
|
20780
20854
|
const dirs = this.paths();
|
|
20781
|
-
const marker =
|
|
20855
|
+
const marker = path7.join(dirs.v2, "store.json");
|
|
20782
20856
|
if (!dirs.shared || !fs7.existsSync(marker))
|
|
20783
20857
|
return success(null, null, null);
|
|
20784
20858
|
return this.withLock(dirs.checkoutLock, () => {
|
|
@@ -20788,7 +20862,7 @@ class TaskStore {
|
|
|
20788
20862
|
try {
|
|
20789
20863
|
const merge = (from, to) => {
|
|
20790
20864
|
if (!fs7.existsSync(to)) {
|
|
20791
|
-
fs7.mkdirSync(
|
|
20865
|
+
fs7.mkdirSync(path7.dirname(to), { recursive: true });
|
|
20792
20866
|
try {
|
|
20793
20867
|
fs7.renameSync(from, to);
|
|
20794
20868
|
} catch {
|
|
@@ -20799,24 +20873,24 @@ class TaskStore {
|
|
|
20799
20873
|
}
|
|
20800
20874
|
if (fs7.lstatSync(from).isDirectory() && fs7.lstatSync(to).isDirectory())
|
|
20801
20875
|
for (const name of fs7.readdirSync(from))
|
|
20802
|
-
merge(
|
|
20876
|
+
merge(path7.join(from, name), path7.join(to, name));
|
|
20803
20877
|
};
|
|
20804
20878
|
for (const sub of ["tasks", "checkouts", "blobs", "legacy"]) {
|
|
20805
|
-
const from =
|
|
20879
|
+
const from = path7.join(dirs.v2, sub);
|
|
20806
20880
|
if (!fs7.existsSync(from))
|
|
20807
20881
|
continue;
|
|
20808
20882
|
if (sub === "tasks") {
|
|
20809
20883
|
for (const name of fs7.readdirSync(from))
|
|
20810
|
-
if (validId(name) && !fs7.existsSync(
|
|
20884
|
+
if (validId(name) && !fs7.existsSync(path7.join(dirs.dir, sub, name)))
|
|
20811
20885
|
tasks += 1;
|
|
20812
20886
|
}
|
|
20813
|
-
merge(from,
|
|
20887
|
+
merge(from, path7.join(dirs.dir, sub));
|
|
20814
20888
|
}
|
|
20815
|
-
const ledger =
|
|
20816
|
-
if (fs7.existsSync(ledger) && !fs7.existsSync(
|
|
20817
|
-
merge(ledger,
|
|
20818
|
-
fs7.rmSync(
|
|
20819
|
-
fs7.renameSync(marker,
|
|
20889
|
+
const ledger = path7.join(dirs.v2, "ledger");
|
|
20890
|
+
if (fs7.existsSync(ledger) && !fs7.existsSync(path7.join(dirs.dir, "ledger")))
|
|
20891
|
+
merge(ledger, path7.join(dirs.dir, "ledger"));
|
|
20892
|
+
fs7.rmSync(path7.join(dirs.v2, "task-index.json"), { force: true });
|
|
20893
|
+
fs7.renameSync(marker, path7.join(dirs.v2, "store.moved.json"));
|
|
20820
20894
|
} catch (error) {
|
|
20821
20895
|
return failure2("storage_error", `cannot move ${dirs.v2} into ${dirs.dir}: ${String(error)}`, {
|
|
20822
20896
|
path: dirs.v2
|
|
@@ -20854,7 +20928,7 @@ class TaskStore {
|
|
|
20854
20928
|
schemaVersion: SCHEMA_VERSION,
|
|
20855
20929
|
id: workspaceId ?? newId(),
|
|
20856
20930
|
revision: newRevision(),
|
|
20857
|
-
root:
|
|
20931
|
+
root: path7.dirname(v2),
|
|
20858
20932
|
runtime: { createdWith: version, updatedWith: version },
|
|
20859
20933
|
writer: null,
|
|
20860
20934
|
store: {
|
|
@@ -20866,11 +20940,11 @@ class TaskStore {
|
|
|
20866
20940
|
critical: ["store"]
|
|
20867
20941
|
};
|
|
20868
20942
|
fs7.mkdirSync(v2, { recursive: true });
|
|
20869
|
-
const ignore =
|
|
20943
|
+
const ignore = path7.join(v2, ".gitignore");
|
|
20870
20944
|
if (!fs7.existsSync(ignore))
|
|
20871
20945
|
fs7.writeFileSync(ignore, `*
|
|
20872
20946
|
`);
|
|
20873
|
-
replaceFile(
|
|
20947
|
+
replaceFile(path7.join(v2, "workspace.json"), `${JSON.stringify(marker, null, 2)}
|
|
20874
20948
|
`, true);
|
|
20875
20949
|
}
|
|
20876
20950
|
stubFor(taskId) {
|
|
@@ -20894,8 +20968,8 @@ class TaskStore {
|
|
|
20894
20968
|
}
|
|
20895
20969
|
writeTombstoneIfMissing() {
|
|
20896
20970
|
try {
|
|
20897
|
-
const v2 =
|
|
20898
|
-
if (fs7.existsSync(
|
|
20971
|
+
const v2 = path7.join(this.root, ".workit");
|
|
20972
|
+
if (fs7.existsSync(path7.join(v2, "workspace.json")))
|
|
20899
20973
|
return;
|
|
20900
20974
|
let id = null;
|
|
20901
20975
|
try {
|
|
@@ -20912,7 +20986,7 @@ class TaskStore {
|
|
|
20912
20986
|
replaceFile(dirs.marker, `${JSON.stringify({ format: "workit-store", version: STORE_FORMAT, createdWith: runtimeVersion() })}
|
|
20913
20987
|
`, false);
|
|
20914
20988
|
if (!dirs.shared) {
|
|
20915
|
-
const ignore =
|
|
20989
|
+
const ignore = path7.join(dirs.dir, ".gitignore");
|
|
20916
20990
|
let current = null;
|
|
20917
20991
|
try {
|
|
20918
20992
|
current = fs7.readFileSync(ignore, "utf8");
|
|
@@ -20972,7 +21046,7 @@ class TaskStore {
|
|
|
20972
21046
|
withLock(lockPath, operation) {
|
|
20973
21047
|
try {
|
|
20974
21048
|
this.initializeStorage();
|
|
20975
|
-
fs7.mkdirSync(
|
|
21049
|
+
fs7.mkdirSync(path7.dirname(lockPath), { recursive: true });
|
|
20976
21050
|
} catch (error) {
|
|
20977
21051
|
return failure2("storage_error", `unable to initialize store: ${String(error)}`, {
|
|
20978
21052
|
path: this.paths().dir
|
|
@@ -21035,7 +21109,7 @@ class TaskStore {
|
|
|
21035
21109
|
if (isTransientWindowsError(error) && !this.lockHolderPresent(lockPath) && !this.lockDirWritable(lockPath))
|
|
21036
21110
|
return failure2("storage_error", `cannot create the workit lock (${code}); no other Workit call holds it`, {
|
|
21037
21111
|
path: lockPath,
|
|
21038
|
-
guidance: `Check permissions and the read-only attribute on ${
|
|
21112
|
+
guidance: `Check permissions and the read-only attribute on ${path7.dirname(lockPath)}.`
|
|
21039
21113
|
});
|
|
21040
21114
|
if (code === "EEXIST" || code === "file_lock_timeout" || code === "file_lock_stale" || isTransientWindowsError(error)) {
|
|
21041
21115
|
let lock = null;
|
|
@@ -21061,12 +21135,12 @@ var workerBlocksTransition = (transition, state) => transition === "pause" ? fal
|
|
|
21061
21135
|
import { createHash as createHash9 } from "node:crypto";
|
|
21062
21136
|
import * as fs12 from "node:fs";
|
|
21063
21137
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
21064
|
-
import
|
|
21138
|
+
import path15 from "node:path";
|
|
21065
21139
|
|
|
21066
21140
|
// packages/workit-core/src/check-config.ts
|
|
21067
21141
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
21068
21142
|
import fs8 from "node:fs";
|
|
21069
|
-
import
|
|
21143
|
+
import path8 from "node:path";
|
|
21070
21144
|
var SCRIPT_CHECKS = ["test", "lint", "typecheck", "check"];
|
|
21071
21145
|
var CHECKS_FILE = "workit.checks.json";
|
|
21072
21146
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -21119,10 +21193,10 @@ var git = (cwd, args) => {
|
|
|
21119
21193
|
return value || null;
|
|
21120
21194
|
};
|
|
21121
21195
|
function checkRoot(cwd) {
|
|
21122
|
-
return
|
|
21196
|
+
return path8.resolve(git(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd);
|
|
21123
21197
|
}
|
|
21124
21198
|
var packageManager = (root) => {
|
|
21125
|
-
const has = (file) => fs8.existsSync(
|
|
21199
|
+
const has = (file) => fs8.existsSync(path8.join(root, file));
|
|
21126
21200
|
if (has("bun.lock") || has("bun.lockb"))
|
|
21127
21201
|
return "bun";
|
|
21128
21202
|
if (has("pnpm-lock.yaml"))
|
|
@@ -21142,7 +21216,7 @@ var CHECK_NAME = /^[a-z0-9][a-z0-9:._-]{0,63}$/u;
|
|
|
21142
21216
|
function detectedChecks(root) {
|
|
21143
21217
|
const read = (file) => {
|
|
21144
21218
|
try {
|
|
21145
|
-
return fs8.readFileSync(
|
|
21219
|
+
return fs8.readFileSync(path8.join(root, file), "utf8");
|
|
21146
21220
|
} catch {
|
|
21147
21221
|
return null;
|
|
21148
21222
|
}
|
|
@@ -21181,7 +21255,7 @@ function detectedChecks(root) {
|
|
|
21181
21255
|
var GATES = ["testing", "verification"];
|
|
21182
21256
|
function loadCheckConfig(cwd) {
|
|
21183
21257
|
const root = checkRoot(cwd);
|
|
21184
|
-
const file =
|
|
21258
|
+
const file = path8.join(root, CHECKS_FILE);
|
|
21185
21259
|
const none = (error = null) => ({
|
|
21186
21260
|
source: error ? CHECKS_FILE : "none",
|
|
21187
21261
|
root,
|
|
@@ -21230,7 +21304,7 @@ function loadCheckConfig(cwd) {
|
|
|
21230
21304
|
gates[gate] = names;
|
|
21231
21305
|
}
|
|
21232
21306
|
}
|
|
21233
|
-
return { source: CHECKS_FILE, root, checks, gates, error: null };
|
|
21307
|
+
return { source: CHECKS_FILE, root, checks, gates, error: null, resources: parsed.resources };
|
|
21234
21308
|
}
|
|
21235
21309
|
var sameArgv = (left, right) => left.length === right.length && left.every((item, index) => item === right[index]);
|
|
21236
21310
|
function matchesNamedCheck(config, name, argv, cwd) {
|
|
@@ -21254,10 +21328,10 @@ function workitAvailable(env = process.env) {
|
|
|
21254
21328
|
return workitOnPath;
|
|
21255
21329
|
const windows = process.platform === "win32";
|
|
21256
21330
|
const exts = windows ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
|
|
21257
|
-
const dirs = (env.PATH ?? env.Path ?? "").split(
|
|
21331
|
+
const dirs = (env.PATH ?? env.Path ?? "").split(path8.delimiter).filter(Boolean);
|
|
21258
21332
|
workitOnPath = dirs.some((dir) => exts.some((ext) => {
|
|
21259
21333
|
try {
|
|
21260
|
-
return fs8.statSync(
|
|
21334
|
+
return fs8.statSync(path8.join(dir, `workit${ext}`)).isFile();
|
|
21261
21335
|
} catch {
|
|
21262
21336
|
return false;
|
|
21263
21337
|
}
|
|
@@ -21272,8 +21346,8 @@ function checkCommand(args, version, onPath = workitAvailable()) {
|
|
|
21272
21346
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
21273
21347
|
import { createHash as createHash5 } from "node:crypto";
|
|
21274
21348
|
import fs9 from "node:fs";
|
|
21275
|
-
import
|
|
21276
|
-
import
|
|
21349
|
+
import os2 from "node:os";
|
|
21350
|
+
import path9 from "node:path";
|
|
21277
21351
|
var MAX_BUFFER = 256 * 1024 * 1024;
|
|
21278
21352
|
var GIT_TIMEOUTS = { local: 20000, worktree: 120000, network: 15000 };
|
|
21279
21353
|
var git2 = (cwd, args, options = {}) => {
|
|
@@ -21320,9 +21394,9 @@ function worktreeTree(cwd, options = {}) {
|
|
|
21320
21394
|
return null;
|
|
21321
21395
|
const cap = options.maxUntrackedBytes ?? MAX_UNTRACKED_BYTES;
|
|
21322
21396
|
const timeoutMs = options.timeoutMs ?? GIT_TIMEOUTS.worktree;
|
|
21323
|
-
const scratch = fs9.mkdtempSync(
|
|
21397
|
+
const scratch = fs9.mkdtempSync(path9.join(os2.tmpdir(), "workit-tree-"));
|
|
21324
21398
|
try {
|
|
21325
|
-
const tempIndex =
|
|
21399
|
+
const tempIndex = path9.join(scratch, "index");
|
|
21326
21400
|
if (fs9.existsSync(indexPath))
|
|
21327
21401
|
seedIndex(indexPath, tempIndex);
|
|
21328
21402
|
const env = { ...process.env, GIT_INDEX_FILE: tempIndex };
|
|
@@ -21335,7 +21409,7 @@ function worktreeTree(cwd, options = {}) {
|
|
|
21335
21409
|
const skipped = [];
|
|
21336
21410
|
for (const file of untracked.stdout.split("\x00").filter(Boolean)) {
|
|
21337
21411
|
try {
|
|
21338
|
-
const stat = fs9.statSync(
|
|
21412
|
+
const stat = fs9.statSync(path9.join(top, file));
|
|
21339
21413
|
if (stat.isFile() && stat.size > cap)
|
|
21340
21414
|
skipped.push({ path: file, size: stat.size, mtimeMs: Math.trunc(stat.mtimeMs) });
|
|
21341
21415
|
} catch {}
|
|
@@ -21381,7 +21455,7 @@ function worktreeSignal(cwd, options = {}) {
|
|
|
21381
21455
|
if (entry.length < 4)
|
|
21382
21456
|
continue;
|
|
21383
21457
|
const file = entry.slice(3);
|
|
21384
|
-
const absolute =
|
|
21458
|
+
const absolute = path9.join(top, file);
|
|
21385
21459
|
let stat = "-";
|
|
21386
21460
|
try {
|
|
21387
21461
|
const info = fs9.lstatSync(absolute, { bigint: true });
|
|
@@ -21451,17 +21525,17 @@ function pushRemoteName(cwd, branch) {
|
|
|
21451
21525
|
|
|
21452
21526
|
// packages/workit-core/src/core/policy/derive.ts
|
|
21453
21527
|
import { existsSync as existsSync4 } from "node:fs";
|
|
21454
|
-
import
|
|
21528
|
+
import path14 from "node:path";
|
|
21455
21529
|
|
|
21456
21530
|
// packages/workit-core/src/ledger.ts
|
|
21457
21531
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
21458
21532
|
import { createHash as createHash8, randomBytes as randomBytes2 } from "node:crypto";
|
|
21459
21533
|
import fs11 from "node:fs";
|
|
21460
|
-
import
|
|
21534
|
+
import path13 from "node:path";
|
|
21461
21535
|
|
|
21462
21536
|
// packages/workit-core/src/core/vcs-config.ts
|
|
21463
21537
|
import fs10 from "node:fs";
|
|
21464
|
-
import
|
|
21538
|
+
import path12 from "node:path";
|
|
21465
21539
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
21466
21540
|
|
|
21467
21541
|
// packages/workit-core/src/core/config.ts
|
|
@@ -21474,8 +21548,8 @@ import {
|
|
|
21474
21548
|
readdirSync as readdirSync2,
|
|
21475
21549
|
writeFileSync as writeFileSync2
|
|
21476
21550
|
} from "node:fs";
|
|
21477
|
-
import
|
|
21478
|
-
import
|
|
21551
|
+
import os3 from "node:os";
|
|
21552
|
+
import path10 from "node:path";
|
|
21479
21553
|
|
|
21480
21554
|
// packages/workit-core/src/core/boundary.ts
|
|
21481
21555
|
import { statSync as statSync2 } from "node:fs";
|
|
@@ -21534,7 +21608,7 @@ var mergePreset = (preset, input = {}, current = {
|
|
|
21534
21608
|
protected: preset === "custom" ? input.protectedNames ?? current.branchPolicy.protected : [...defs.protected]
|
|
21535
21609
|
};
|
|
21536
21610
|
};
|
|
21537
|
-
var resolveConfigDir = () => process.env.WORKFLOW_TOOLKIT_CONFIG ?? process.env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
21611
|
+
var resolveConfigDir = () => process.env.WORKFLOW_TOOLKIT_CONFIG ?? process.env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path10.join(process.env.XDG_CONFIG_HOME || path10.join(os3.homedir(), ".config"), "workit");
|
|
21538
21612
|
var migratedDir = null;
|
|
21539
21613
|
var migrationFailed = false;
|
|
21540
21614
|
var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
@@ -21544,7 +21618,7 @@ var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
|
21544
21618
|
migratedDir = dir;
|
|
21545
21619
|
return dir;
|
|
21546
21620
|
}
|
|
21547
|
-
const legacy =
|
|
21621
|
+
const legacy = path10.join(process.env.XDG_CONFIG_HOME || path10.join(os3.homedir(), ".config"), "workflow-toolkit");
|
|
21548
21622
|
if (!existsSync3(legacy)) {
|
|
21549
21623
|
migratedDir = dir;
|
|
21550
21624
|
return dir;
|
|
@@ -21557,8 +21631,8 @@ var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
|
21557
21631
|
mkdirSync2(dir, { recursive: true });
|
|
21558
21632
|
diagnosticLogger?.info(EVENT.migration, { from: legacy, to: dir });
|
|
21559
21633
|
for (const entry of readdirSync2(legacy, { withFileTypes: true })) {
|
|
21560
|
-
const src =
|
|
21561
|
-
const dest =
|
|
21634
|
+
const src = path10.join(legacy, entry.name);
|
|
21635
|
+
const dest = path10.join(dir, entry.name);
|
|
21562
21636
|
if (existsSync3(dest))
|
|
21563
21637
|
continue;
|
|
21564
21638
|
try {
|
|
@@ -21630,7 +21704,7 @@ var parseConfigResult = (raw, file) => {
|
|
|
21630
21704
|
return { status: "valid", path: file, config };
|
|
21631
21705
|
};
|
|
21632
21706
|
var readConfigTyped = (dir) => {
|
|
21633
|
-
const file =
|
|
21707
|
+
const file = path10.join(dir ?? configDir(), "config.json");
|
|
21634
21708
|
return parseConfigResult(readSafe(file), file);
|
|
21635
21709
|
};
|
|
21636
21710
|
var readConfig = () => {
|
|
@@ -21639,7 +21713,7 @@ var readConfig = () => {
|
|
|
21639
21713
|
throw new Error(result.error);
|
|
21640
21714
|
return result.config ?? DEFAULTS;
|
|
21641
21715
|
};
|
|
21642
|
-
var vcsConfigPath = () => process.env.WORKFLOW_VCS_CONFIG ??
|
|
21716
|
+
var vcsConfigPath = () => process.env.WORKFLOW_VCS_CONFIG ?? path10.join(configDir(), "vcs.json");
|
|
21643
21717
|
var branchGlobPattern = (glob) => new RegExp(`^${glob.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")}$`, "i");
|
|
21644
21718
|
var resolveBranchPolicy = (config, workspace, repoPreset) => {
|
|
21645
21719
|
const wp = workspace?.branchPolicy ?? {};
|
|
@@ -21673,7 +21747,7 @@ var COMMIT_PRESETS = [
|
|
|
21673
21747
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
21674
21748
|
import { createHash as createHash6 } from "node:crypto";
|
|
21675
21749
|
import { readFileSync as readFileSync3, realpathSync as realpathSync2 } from "node:fs";
|
|
21676
|
-
import
|
|
21750
|
+
import path11 from "node:path";
|
|
21677
21751
|
|
|
21678
21752
|
// packages/workit-core/src/core/branch-policy.ts
|
|
21679
21753
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
@@ -21798,7 +21872,7 @@ var releaseTrackSchema = object2({
|
|
|
21798
21872
|
context.addIssue({ code: "custom", path: [field], message: "entries must be unique" });
|
|
21799
21873
|
}
|
|
21800
21874
|
}
|
|
21801
|
-
if (track.versionSource?.kind === "package-json" && (
|
|
21875
|
+
if (track.versionSource?.kind === "package-json" && (path11.posix.isAbsolute(track.versionSource.path.replaceAll("\\", "/")) || /^[A-Za-z]:\//u.test(track.versionSource.path.replaceAll("\\", "/")) || track.versionSource.path.replaceAll("\\", "/").split("/").includes(".."))) {
|
|
21802
21876
|
context.addIssue({
|
|
21803
21877
|
code: "custom",
|
|
21804
21878
|
path: ["versionSource", "path"],
|
|
@@ -21818,6 +21892,7 @@ var workspaceConfigSchema = object2({
|
|
|
21818
21892
|
autoApprove: union([boolean2(), array(nonBlank)]).optional(),
|
|
21819
21893
|
defaultEndpoint: unknown().optional(),
|
|
21820
21894
|
verification: _enum(["self", "independent"]).optional(),
|
|
21895
|
+
trailers: boolean2().optional(),
|
|
21821
21896
|
autonomy: object2(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
21822
21897
|
kind,
|
|
21823
21898
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -21896,7 +21971,7 @@ var validateWorkspacesDocument = (parsed, file) => {
|
|
|
21896
21971
|
};
|
|
21897
21972
|
};
|
|
21898
21973
|
var readWorkspacesResult = (dir = configDir()) => {
|
|
21899
|
-
const file =
|
|
21974
|
+
const file = path11.join(dir, "workspaces.json");
|
|
21900
21975
|
let raw;
|
|
21901
21976
|
try {
|
|
21902
21977
|
raw = readFileSync3(file, "utf8");
|
|
@@ -22007,9 +22082,9 @@ var mainCheckoutOf = (cwd) => {
|
|
|
22007
22082
|
let main = null;
|
|
22008
22083
|
const dirs = git(["rev-parse", "--path-format=absolute", "--git-dir", "--git-common-dir"]);
|
|
22009
22084
|
const [gitDir, common] = (dirs ?? "").trim().split(/\r?\n/u);
|
|
22010
|
-
if (gitDir && common &&
|
|
22085
|
+
if (gitDir && common && path11.resolve(gitDir) !== path11.resolve(common)) {
|
|
22011
22086
|
const listed = /^worktree (.+)$/mu.exec(git(["worktree", "list", "--porcelain"]) ?? "")?.[1];
|
|
22012
|
-
main = listed?.trim() || (
|
|
22087
|
+
main = listed?.trim() || (path11.basename(common) === ".git" ? path11.dirname(common) : common);
|
|
22013
22088
|
}
|
|
22014
22089
|
mainCheckouts.set(cwd, main);
|
|
22015
22090
|
return main;
|
|
@@ -22099,8 +22174,8 @@ var resolveRuntimeWorkspaceVcs = (cwd) => resolveRuntimeWorkspaceCandidate(cwd,
|
|
|
22099
22174
|
var runtimeWorkspaceIndexSchema = object2({
|
|
22100
22175
|
workspaces: array(object2({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
22101
22176
|
}).passthrough();
|
|
22102
|
-
var matchRuntimeWorkspace = (cwd) => {
|
|
22103
|
-
const file =
|
|
22177
|
+
var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
|
|
22178
|
+
const file = path11.join(dir, "workspaces.json");
|
|
22104
22179
|
let raw;
|
|
22105
22180
|
try {
|
|
22106
22181
|
raw = readFileSync3(file, "utf8");
|
|
@@ -22129,7 +22204,7 @@ var matchRuntimeWorkspace = (cwd) => {
|
|
|
22129
22204
|
const matches = matchingEntries(cwd, entries ?? []);
|
|
22130
22205
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
22131
22206
|
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
22132
|
-
return selected ? { file, selected } : null;
|
|
22207
|
+
return selected ? { file, selected, matches } : null;
|
|
22133
22208
|
};
|
|
22134
22209
|
var resolveRuntimeReleaseTracks = (cwd) => {
|
|
22135
22210
|
const matched = matchRuntimeWorkspace(cwd);
|
|
@@ -22458,7 +22533,7 @@ var git3 = (cwd, args) => {
|
|
|
22458
22533
|
return run.status === 0 ? (run.stdout ?? "").trim() : null;
|
|
22459
22534
|
};
|
|
22460
22535
|
var recordedBaseKey = (branch) => `branch.${branch}.workitBase`;
|
|
22461
|
-
var
|
|
22536
|
+
var escapeRegExp2 = (text) => text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
22462
22537
|
var reflog = (cwd, ref) => (git3(cwd, ["log", "-g", "--date=unix", "--format=%H%x09%gd%x09%gs", ref, "--"]) ?? "").split(`
|
|
22463
22538
|
`).map((line) => {
|
|
22464
22539
|
const [sha = "", selector = "", ...subject] = line.split("\t");
|
|
@@ -22490,7 +22565,7 @@ function gitTrackProbe(cwd) {
|
|
|
22490
22565
|
const created = own.at(-1);
|
|
22491
22566
|
if (!created || created.subject !== "branch: Created from HEAD")
|
|
22492
22567
|
return null;
|
|
22493
|
-
const pattern = new RegExp(`^checkout: moving from (\\S+) to ${
|
|
22568
|
+
const pattern = new RegExp(`^checkout: moving from (\\S+) to ${escapeRegExp2(branch)}$`, "u");
|
|
22494
22569
|
const entry = reflog(cwd, "HEAD").findLast((item) => item.time >= created.time && item.sha === created.sha && pattern.test(item.subject));
|
|
22495
22570
|
return entry ? pattern.exec(entry.subject)?.[1] ?? null : null;
|
|
22496
22571
|
},
|
|
@@ -22560,7 +22635,7 @@ function resolveTrackFor(cwd, options) {
|
|
|
22560
22635
|
}
|
|
22561
22636
|
|
|
22562
22637
|
// packages/workit-core/src/core/vcs-config.ts
|
|
22563
|
-
var workspacesPath = () =>
|
|
22638
|
+
var workspacesPath = () => path12.join(configDir(), "workspaces.json");
|
|
22564
22639
|
var vcsCwd = (cwd) => cwd ?? process.env.WORKFLOW_WORKSPACE_ROOT ?? process.cwd();
|
|
22565
22640
|
var remoteProvider = (cwd) => {
|
|
22566
22641
|
const r = spawnSync8("git", ["remote", "get-url", "origin"], { cwd, encoding: "utf8" });
|
|
@@ -22735,7 +22810,7 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
22735
22810
|
const prov = cfg[provider] ?? {};
|
|
22736
22811
|
const out = {
|
|
22737
22812
|
ok: true,
|
|
22738
|
-
configPath:
|
|
22813
|
+
configPath: path12.resolve(cfgPath),
|
|
22739
22814
|
provider,
|
|
22740
22815
|
defaultTargetBranch: workspaceDefault,
|
|
22741
22816
|
pr: cfg.pr ?? {},
|
|
@@ -22958,14 +23033,14 @@ function diffHash(cwd, base, head) {
|
|
|
22958
23033
|
return `sha256:${hash.digest("hex")}`;
|
|
22959
23034
|
}
|
|
22960
23035
|
function storeRoot(cwd) {
|
|
22961
|
-
const location = resolveStore(
|
|
23036
|
+
const location = resolveStore(path13.resolve(cwd));
|
|
22962
23037
|
if (location instanceof Error)
|
|
22963
23038
|
return err("unavailable", location.message.replace(/; fix the repository.*$/u, ""), "fix the repository (git status should work here) or run from a non-git directory");
|
|
22964
23039
|
return { ok: true, value: { root: location.dir, shared: location.shared } };
|
|
22965
23040
|
}
|
|
22966
23041
|
function ledgerPath(cwd) {
|
|
22967
23042
|
const root = storeRoot(cwd);
|
|
22968
|
-
return root.ok ? { ok: true, value:
|
|
23043
|
+
return root.ok ? { ok: true, value: path13.join(root.value.root, "ledger", "ledger.jsonl") } : root;
|
|
22969
23044
|
}
|
|
22970
23045
|
var newId2 = () => `${Date.now().toString(36)}-${randomBytes2(6).toString("hex")}`;
|
|
22971
23046
|
var NETWORK_FS_TYPES = new Set([
|
|
@@ -22995,13 +23070,13 @@ var LOCK_STALE_MS = 30000;
|
|
|
22995
23070
|
var LOCK_OWNER = "owner";
|
|
22996
23071
|
var lockToken = (lock) => {
|
|
22997
23072
|
try {
|
|
22998
|
-
return fs11.readFileSync(
|
|
23073
|
+
return fs11.readFileSync(path13.join(lock, LOCK_OWNER), "utf8");
|
|
22999
23074
|
} catch {
|
|
23000
23075
|
return null;
|
|
23001
23076
|
}
|
|
23002
23077
|
};
|
|
23003
23078
|
var lockAgeMs = (lock) => {
|
|
23004
|
-
for (const target of [
|
|
23079
|
+
for (const target of [path13.join(lock, LOCK_OWNER), lock]) {
|
|
23005
23080
|
try {
|
|
23006
23081
|
return Date.now() - fs11.statSync(target).mtimeMs;
|
|
23007
23082
|
} catch {}
|
|
@@ -23018,7 +23093,7 @@ var ledgerLock = {
|
|
|
23018
23093
|
throw error;
|
|
23019
23094
|
}
|
|
23020
23095
|
const token = `${process.pid}-${randomBytes2(8).toString("hex")}`;
|
|
23021
|
-
fs11.writeFileSync(
|
|
23096
|
+
fs11.writeFileSync(path13.join(lock, LOCK_OWNER), token);
|
|
23022
23097
|
return token;
|
|
23023
23098
|
},
|
|
23024
23099
|
release(lock, token) {
|
|
@@ -23143,8 +23218,8 @@ function appendLine(file, build, options) {
|
|
|
23143
23218
|
}
|
|
23144
23219
|
};
|
|
23145
23220
|
try {
|
|
23146
|
-
fs11.mkdirSync(
|
|
23147
|
-
if (!options.forceLock && !onNetworkFs(
|
|
23221
|
+
fs11.mkdirSync(path13.dirname(file), { recursive: true });
|
|
23222
|
+
if (!options.forceLock && !onNetworkFs(path13.dirname(file)))
|
|
23148
23223
|
return write();
|
|
23149
23224
|
const locked = withLedgerLock(file, write);
|
|
23150
23225
|
return locked ?? err("busy", `ledger lock ${file}.lock is held`, "retry; remove the .lock directory if no workit process is running");
|
|
@@ -23704,7 +23779,7 @@ var productDecision = (task, ledger) => {
|
|
|
23704
23779
|
};
|
|
23705
23780
|
};
|
|
23706
23781
|
var planRecorded = (task, root) => {
|
|
23707
|
-
const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync4(
|
|
23782
|
+
const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync4(path14.resolve(root, ref.path)));
|
|
23708
23783
|
if (cited)
|
|
23709
23784
|
return {
|
|
23710
23785
|
met: true,
|
|
@@ -23753,14 +23828,14 @@ function derivedRuleStatus(task, requirement, root, ledger) {
|
|
|
23753
23828
|
|
|
23754
23829
|
// packages/workit-core/src/core/task-evaluation.ts
|
|
23755
23830
|
var digestBytes = (value) => createHash9("sha256").update(value).digest("hex");
|
|
23756
|
-
var inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${
|
|
23757
|
-
var relative = (root, candidate) =>
|
|
23831
|
+
var inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path15.sep}`);
|
|
23832
|
+
var relative = (root, candidate) => path15.relative(root, candidate).split(path15.sep).join("/") || ".";
|
|
23758
23833
|
var canonicalPath = (value) => {
|
|
23759
23834
|
if (typeof value !== "string" || !value)
|
|
23760
23835
|
return null;
|
|
23761
23836
|
if (value.includes("\\") || value.split("/").includes(".."))
|
|
23762
23837
|
return null;
|
|
23763
|
-
const normalized =
|
|
23838
|
+
const normalized = path15.posix.normalize(value);
|
|
23764
23839
|
if (normalized === ".." || normalized.startsWith("../") || normalized.startsWith("/"))
|
|
23765
23840
|
return null;
|
|
23766
23841
|
return normalized === "." ? "." : normalized.replace(/\/$/, "");
|
|
@@ -23808,14 +23883,14 @@ var gitPaths = (root) => {
|
|
|
23808
23883
|
git: !/not a git repository/i.test(stderr)
|
|
23809
23884
|
};
|
|
23810
23885
|
}
|
|
23811
|
-
const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(
|
|
23886
|
+
const paths = result.stdout ? result.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path15.sep).join("/")) : [];
|
|
23812
23887
|
const stagedDeleted = spawnSync10("git", ["diff", "--cached", "--name-only", "--diff-filter=D", "-z"], { cwd: root, encoding: "buffer" });
|
|
23813
23888
|
if (stagedDeleted.status !== 0) {
|
|
23814
23889
|
const stderr = stagedDeleted.stderr?.toString("utf8") ?? "";
|
|
23815
23890
|
if (!/not a git repository/i.test(stderr))
|
|
23816
23891
|
return { paths, uncertain: true, git: true };
|
|
23817
23892
|
} else if (stagedDeleted.stdout) {
|
|
23818
|
-
paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(
|
|
23893
|
+
paths.push(...stagedDeleted.stdout.toString("utf8").split("\x00").filter(Boolean).map((item) => item.split(path15.sep).join("/")));
|
|
23819
23894
|
}
|
|
23820
23895
|
return { paths: [...new Set(paths)], uncertain: false, git: true };
|
|
23821
23896
|
};
|
|
@@ -23830,7 +23905,7 @@ var walk = (root, directory, output) => {
|
|
|
23830
23905
|
for (const name of names) {
|
|
23831
23906
|
if (name === ".git" || name === ".workit")
|
|
23832
23907
|
continue;
|
|
23833
|
-
const target =
|
|
23908
|
+
const target = path15.join(directory, name);
|
|
23834
23909
|
let stat;
|
|
23835
23910
|
try {
|
|
23836
23911
|
stat = fs12.lstatSync(target);
|
|
@@ -23848,12 +23923,12 @@ var walk = (root, directory, output) => {
|
|
|
23848
23923
|
var scopeRoots = (root, scope) => {
|
|
23849
23924
|
const roots = [];
|
|
23850
23925
|
for (const item of scope.paths.length ? scope.paths : ["."]) {
|
|
23851
|
-
const target =
|
|
23926
|
+
const target = path15.resolve(root, item);
|
|
23852
23927
|
if (!inside(root, target))
|
|
23853
23928
|
return failure2("invalid_input", `candidate scope escapes checkout: ${item} — keep one task per repository and coordinate a separate linked task in the other checkout`, { fields: [{ path: "scope.paths", reason: `${item} is outside the checkout` }] });
|
|
23854
23929
|
let ancestor = target;
|
|
23855
23930
|
while (!fs12.existsSync(ancestor) && ancestor !== root)
|
|
23856
|
-
ancestor =
|
|
23931
|
+
ancestor = path15.dirname(ancestor);
|
|
23857
23932
|
try {
|
|
23858
23933
|
if (!inside(root, fs12.realpathSync(ancestor)))
|
|
23859
23934
|
return failure2("invalid_input", `candidate scope escapes checkout through a symlink: ${item} — keep one task per repository and coordinate a separate linked task in the other checkout`, { fields: [{ path: "scope.paths", reason: `${item} resolves outside the checkout` }] });
|
|
@@ -23905,7 +23980,7 @@ function captureCandidate(root, scope, environment = []) {
|
|
|
23905
23980
|
for (const item of [...names].toSorted()) {
|
|
23906
23981
|
if (!scopeMatches(item, normalizedScope))
|
|
23907
23982
|
continue;
|
|
23908
|
-
const target =
|
|
23983
|
+
const target = path15.join(checkout, item);
|
|
23909
23984
|
try {
|
|
23910
23985
|
const stat = fs12.lstatSync(target);
|
|
23911
23986
|
if (stat.isSymbolicLink()) {
|
|
@@ -24089,23 +24164,23 @@ var verifyDecisionContentAtRoot = (checkoutRoot, binding) => {
|
|
|
24089
24164
|
continue;
|
|
24090
24165
|
if (!reference.digest)
|
|
24091
24166
|
return failure2("invalid_input", "document references require a byte digest");
|
|
24092
|
-
const target =
|
|
24093
|
-
if (target !== root && !target.startsWith(`${root}${
|
|
24167
|
+
const target = path15.resolve(root, reference.path);
|
|
24168
|
+
if (target !== root && !target.startsWith(`${root}${path15.sep}`))
|
|
24094
24169
|
return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
|
|
24095
24170
|
fields: [
|
|
24096
24171
|
{ path: "contentRefs.path", reason: `${reference.path} is outside the checkout` }
|
|
24097
24172
|
]
|
|
24098
24173
|
});
|
|
24099
24174
|
try {
|
|
24100
|
-
const below =
|
|
24175
|
+
const below = path15.relative(root, target);
|
|
24101
24176
|
let current = root;
|
|
24102
|
-
for (const segment of below.split(
|
|
24177
|
+
for (const segment of below.split(path15.sep)) {
|
|
24103
24178
|
if (!segment)
|
|
24104
24179
|
continue;
|
|
24105
|
-
current =
|
|
24180
|
+
current = path15.join(current, segment);
|
|
24106
24181
|
const stat = fs12.lstatSync(current);
|
|
24107
24182
|
const real = fs12.realpathSync(current);
|
|
24108
|
-
if (real !== root && !real.startsWith(`${root}${
|
|
24183
|
+
if (real !== root && !real.startsWith(`${root}${path15.sep}`))
|
|
24109
24184
|
return failure2("invalid_input", "document reference escapes checkout; cite it as an external file:// reference instead", {
|
|
24110
24185
|
fields: [
|
|
24111
24186
|
{
|
|
@@ -24930,20 +25005,20 @@ var judgeInputSummary = (raw) => {
|
|
|
24930
25005
|
};
|
|
24931
25006
|
|
|
24932
25007
|
// packages/workit-core/src/autonomy.ts
|
|
24933
|
-
import
|
|
24934
|
-
import
|
|
25008
|
+
import os4 from "node:os";
|
|
25009
|
+
import path16 from "node:path";
|
|
24935
25010
|
var accountHome = () => {
|
|
24936
25011
|
try {
|
|
24937
|
-
return
|
|
25012
|
+
return os4.userInfo().homedir;
|
|
24938
25013
|
} catch {
|
|
24939
|
-
return
|
|
25014
|
+
return os4.homedir();
|
|
24940
25015
|
}
|
|
24941
25016
|
};
|
|
24942
25017
|
var grantsHome = { resolve: accountHome };
|
|
24943
|
-
var grantsDir = () =>
|
|
25018
|
+
var grantsDir = () => path16.join(grantsHome.resolve(), ".config", "workit");
|
|
24944
25019
|
var grantsOverride = () => {
|
|
24945
|
-
const configured =
|
|
24946
|
-
return configured ===
|
|
25020
|
+
const configured = path16.resolve(resolveConfigDir());
|
|
25021
|
+
return configured === path16.resolve(grantsDir()) ? null : `the config directory is redirected to ${configured} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${path16.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
|
|
24947
25022
|
};
|
|
24948
25023
|
var GRANT_KINDS = ["push", "pr", "merge", "release", "rerun"];
|
|
24949
25024
|
var DEFAULT_GRANTS = Object.freeze({
|
|
@@ -26715,7 +26790,7 @@ class WorkitCore {
|
|
|
26715
26790
|
// packages/workit-core/src/core/repo-context.ts
|
|
26716
26791
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
26717
26792
|
import { existsSync as existsSync6, readFileSync as readFileSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
26718
|
-
import
|
|
26793
|
+
import path17 from "node:path";
|
|
26719
26794
|
var isSafeContextRange = (value) => value.length <= 4096 && (() => {
|
|
26720
26795
|
try {
|
|
26721
26796
|
gitRevisionParts(value);
|
|
@@ -26849,7 +26924,7 @@ var findPrTemplate = (cwd) => {
|
|
|
26849
26924
|
]) {
|
|
26850
26925
|
const parts = rel.split("/");
|
|
26851
26926
|
const base = parts[parts.length - 1];
|
|
26852
|
-
const dir = parts.length > 1 ?
|
|
26927
|
+
const dir = parts.length > 1 ? path17.join(cwd, ...parts.slice(0, -1)) : cwd;
|
|
26853
26928
|
const actual = probeCaseInsensitive(dir, base);
|
|
26854
26929
|
if (actual)
|
|
26855
26930
|
return [...parts.slice(0, -1), actual].join("/");
|
|
@@ -26880,7 +26955,7 @@ var diffStatForRange = (cwd, range) => {
|
|
|
26880
26955
|
return runGit(cwd, ["diff", "--stat", "--"]).stdout;
|
|
26881
26956
|
};
|
|
26882
26957
|
var packageScripts = (cwd, keys) => {
|
|
26883
|
-
const pkgPath =
|
|
26958
|
+
const pkgPath = path17.join(cwd, "package.json");
|
|
26884
26959
|
if (!existsSync6(pkgPath))
|
|
26885
26960
|
return [];
|
|
26886
26961
|
try {
|
|
@@ -26906,9 +26981,9 @@ var documentationFiles = (cwd) => {
|
|
|
26906
26981
|
if (entry.isDirectory()) {
|
|
26907
26982
|
if (excluded.has(entry.name))
|
|
26908
26983
|
continue;
|
|
26909
|
-
walk(
|
|
26984
|
+
walk(path17.join(dir, entry.name), depth + 1);
|
|
26910
26985
|
} else if (entry.isFile() && (entry.name === "README.md" || entry.name.endsWith(".md"))) {
|
|
26911
|
-
matches.push("./" +
|
|
26986
|
+
matches.push("./" + path17.relative(cwd, path17.join(dir, entry.name)).replaceAll("\\", "/"));
|
|
26912
26987
|
}
|
|
26913
26988
|
}
|
|
26914
26989
|
};
|
|
@@ -26924,7 +26999,7 @@ var readTrimmed2 = (file, maxLines) => {
|
|
|
26924
26999
|
`);
|
|
26925
27000
|
};
|
|
26926
27001
|
function prReadyContext(root, range) {
|
|
26927
|
-
const cwd =
|
|
27002
|
+
const cwd = path17.resolve(repoRoot(root));
|
|
26928
27003
|
if (range !== undefined && !isResolvableContextRange(cwd, range))
|
|
26929
27004
|
return invalidRange(cwd);
|
|
26930
27005
|
let stdout = "";
|
|
@@ -26982,7 +27057,7 @@ ${status.stderr}` : "");
|
|
|
26982
27057
|
stdout += `template_path: ${template}
|
|
26983
27058
|
|
|
26984
27059
|
`;
|
|
26985
|
-
stdout += readTrimmed2(
|
|
27060
|
+
stdout += readTrimmed2(path17.join(cwd, template), 220);
|
|
26986
27061
|
} else {
|
|
26987
27062
|
stdout += `template_path: none
|
|
26988
27063
|
|
|
@@ -26992,7 +27067,7 @@ ${status.stderr}` : "");
|
|
|
26992
27067
|
stdout += `
|
|
26993
27068
|
`;
|
|
26994
27069
|
stdout += printSection("Recent Validation Signals");
|
|
26995
|
-
if (existsSync6(
|
|
27070
|
+
if (existsSync6(path17.join(cwd, "package.json"))) {
|
|
26996
27071
|
stdout += `package.json detected. Common scripts:
|
|
26997
27072
|
`;
|
|
26998
27073
|
const found = packageScripts(cwd, ["lint", "format:check", "test", "build"]);
|
|
@@ -27001,7 +27076,7 @@ ${status.stderr}` : "");
|
|
|
27001
27076
|
`) + `
|
|
27002
27077
|
`;
|
|
27003
27078
|
}
|
|
27004
|
-
if (existsSync6(
|
|
27079
|
+
if (existsSync6(path17.join(cwd, "Cargo.toml")) || existsSync6(path17.join(cwd, "src-tauri/Cargo.toml"))) {
|
|
27005
27080
|
stdout += `Rust project detected.
|
|
27006
27081
|
`;
|
|
27007
27082
|
}
|
|
@@ -27034,7 +27109,7 @@ var CHANGELOG_RULES = `- Use an [Unreleased] section.
|
|
|
27034
27109
|
- Apply with the host-native editor, preserving the repository changelog conventions.
|
|
27035
27110
|
- If Unreleased already has duplicate category headings, normalize_only first.`;
|
|
27036
27111
|
function changelogContext(root, range) {
|
|
27037
|
-
const cwd =
|
|
27112
|
+
const cwd = path17.resolve(repoRoot(root));
|
|
27038
27113
|
if (range !== undefined && !isResolvableContextRange(cwd, range))
|
|
27039
27114
|
return invalidRange(cwd);
|
|
27040
27115
|
const resolvedRange = rangeArgOrDefault(range, cwd);
|
|
@@ -27052,7 +27127,7 @@ function changelogContext(root, range) {
|
|
|
27052
27127
|
stdout += CHANGELOG_RULES + `
|
|
27053
27128
|
`;
|
|
27054
27129
|
stdout += printSection("Existing CHANGELOG.md");
|
|
27055
|
-
const changelogPath =
|
|
27130
|
+
const changelogPath = path17.join(cwd, "CHANGELOG.md");
|
|
27056
27131
|
if (existsSync6(changelogPath)) {
|
|
27057
27132
|
stdout += readTrimmed2(changelogPath, 260) + `
|
|
27058
27133
|
`;
|
|
@@ -27072,7 +27147,7 @@ function changelogContext(root, range) {
|
|
|
27072
27147
|
return { stdout, stderr: "", exitCode: 0, cwd };
|
|
27073
27148
|
}
|
|
27074
27149
|
function docsRefreshContext(root, range) {
|
|
27075
|
-
const cwd =
|
|
27150
|
+
const cwd = path17.resolve(repoRoot(root));
|
|
27076
27151
|
if (range !== undefined && !isResolvableContextRange(cwd, range))
|
|
27077
27152
|
return invalidRange(cwd);
|
|
27078
27153
|
const resolvedRange = rangeArgOrDefault(range, cwd);
|
|
@@ -27094,7 +27169,7 @@ function docsRefreshContext(root, range) {
|
|
|
27094
27169
|
`) + `
|
|
27095
27170
|
`;
|
|
27096
27171
|
stdout += printSection("README Preview");
|
|
27097
|
-
const readme =
|
|
27172
|
+
const readme = path17.join(cwd, "README.md");
|
|
27098
27173
|
if (existsSync6(readme)) {
|
|
27099
27174
|
stdout += readTrimmed2(readme, 220) + `
|
|
27100
27175
|
`;
|
|
@@ -27103,7 +27178,7 @@ function docsRefreshContext(root, range) {
|
|
|
27103
27178
|
`;
|
|
27104
27179
|
}
|
|
27105
27180
|
stdout += printSection("Package Scripts");
|
|
27106
|
-
const pkgPath =
|
|
27181
|
+
const pkgPath = path17.join(cwd, "package.json");
|
|
27107
27182
|
if (existsSync6(pkgPath)) {
|
|
27108
27183
|
try {
|
|
27109
27184
|
const pkg = JSON.parse(readFileSync5(pkgPath, "utf8"));
|
|
@@ -27117,7 +27192,7 @@ function docsRefreshContext(root, range) {
|
|
|
27117
27192
|
return { stdout, stderr: "", exitCode: 0, cwd };
|
|
27118
27193
|
}
|
|
27119
27194
|
function releaseNotesContext(root, rangeOrTag) {
|
|
27120
|
-
const cwd =
|
|
27195
|
+
const cwd = path17.resolve(repoRoot(root));
|
|
27121
27196
|
if (!rangeOrTag) {
|
|
27122
27197
|
return { stdout: "", stderr: `ERROR: release tag or range required
|
|
27123
27198
|
`, exitCode: 1, cwd };
|
|
@@ -27155,7 +27230,7 @@ function releaseNotesContext(root, rangeOrTag) {
|
|
|
27155
27230
|
`;
|
|
27156
27231
|
stdout += printSection("Existing Release Files");
|
|
27157
27232
|
for (const rel of ["CHANGELOG.md", "RELEASE_NOTES.md", ".github/releases.md"]) {
|
|
27158
|
-
if (existsSync6(
|
|
27233
|
+
if (existsSync6(path17.join(cwd, rel)))
|
|
27159
27234
|
stdout += rel + `
|
|
27160
27235
|
`;
|
|
27161
27236
|
}
|
|
@@ -27187,7 +27262,7 @@ import { spawnSync as spawnSync13 } from "node:child_process";
|
|
|
27187
27262
|
|
|
27188
27263
|
// packages/workit-core/src/core/pr-create.ts
|
|
27189
27264
|
import fs13 from "node:fs";
|
|
27190
|
-
import
|
|
27265
|
+
import path18 from "node:path";
|
|
27191
27266
|
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
27192
27267
|
// packages/workit-core/src/forge/pr-body.ts
|
|
27193
27268
|
function parseGhIssue(value) {
|
|
@@ -27198,11 +27273,11 @@ function parseGhIssue(value) {
|
|
|
27198
27273
|
// packages/workit-core/src/core/pr-create.ts
|
|
27199
27274
|
function whichOnPath(tool) {
|
|
27200
27275
|
const names = process.platform === "win32" ? [tool, `${tool}.exe`, `${tool}.cmd`] : [tool];
|
|
27201
|
-
for (const dir of (process.env.PATH ?? "").split(
|
|
27276
|
+
for (const dir of (process.env.PATH ?? "").split(path18.delimiter)) {
|
|
27202
27277
|
if (!dir)
|
|
27203
27278
|
continue;
|
|
27204
27279
|
for (const name of names) {
|
|
27205
|
-
const candidate =
|
|
27280
|
+
const candidate = path18.join(dir, name);
|
|
27206
27281
|
try {
|
|
27207
27282
|
fs13.accessSync(candidate, fs13.constants.X_OK);
|
|
27208
27283
|
return candidate;
|
|
@@ -27323,7 +27398,7 @@ var fetchGitLabIssueBody = async (ref, root, deps = {}) => {
|
|
|
27323
27398
|
|
|
27324
27399
|
// packages/workit-core/src/core/youtrack.ts
|
|
27325
27400
|
import fs14 from "node:fs";
|
|
27326
|
-
import
|
|
27401
|
+
import path19 from "node:path";
|
|
27327
27402
|
|
|
27328
27403
|
// packages/workit-core/src/core/templates.ts
|
|
27329
27404
|
var repoRoot2 = assetRoot();
|
|
@@ -27336,8 +27411,8 @@ var resolveWorkspaceRoot = (explicit) => explicit || process.cwd();
|
|
|
27336
27411
|
// packages/workit-core/src/core/youtrack.ts
|
|
27337
27412
|
var ISSUE_RE = /^[A-Z]+-\d+$/;
|
|
27338
27413
|
var TOKEN_PLACEHOLDER = "YOUR_TOKEN_HERE";
|
|
27339
|
-
var youTrackConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ??
|
|
27340
|
-
var youTrackReadOnlyConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ??
|
|
27414
|
+
var youTrackConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ?? path19.join(configDir(), "youtrack.json");
|
|
27415
|
+
var youTrackReadOnlyConfigPath = () => process.env.WORKFLOW_YOUTRACK_CONFIG ?? path19.join(resolveConfigDir(), "youtrack.json");
|
|
27341
27416
|
var youTrackTokenModeOk = (p) => {
|
|
27342
27417
|
if (process.platform === "win32")
|
|
27343
27418
|
return true;
|
|
@@ -27405,7 +27480,7 @@ var youTrackToken = () => {
|
|
|
27405
27480
|
if ("error" in loaded)
|
|
27406
27481
|
return loaded;
|
|
27407
27482
|
const tokenFile = String(loaded.config.tokenFile ?? "");
|
|
27408
|
-
const tokenPath = tokenFile ?
|
|
27483
|
+
const tokenPath = tokenFile ? path19.isAbsolute(tokenFile) ? path19.resolve(tokenFile) : path19.resolve(process.cwd(), tokenFile) : "";
|
|
27409
27484
|
if (!tokenPath || !fs14.existsSync(tokenPath))
|
|
27410
27485
|
return { error: "missing youtrack.token" };
|
|
27411
27486
|
if (!youTrackTokenModeOk(tokenPath))
|
|
@@ -27747,15 +27822,15 @@ function resolveGitRevision(root, value) {
|
|
|
27747
27822
|
}
|
|
27748
27823
|
function resolveInside(root, candidate) {
|
|
27749
27824
|
const base = realpathSync5(root);
|
|
27750
|
-
const target =
|
|
27751
|
-
if (target !== base && !target.startsWith(base +
|
|
27825
|
+
const target = path20.resolve(base, candidate);
|
|
27826
|
+
if (target !== base && !target.startsWith(base + path20.sep)) {
|
|
27752
27827
|
throw new Error("path must stay inside repository root");
|
|
27753
27828
|
}
|
|
27754
27829
|
let ancestor = target;
|
|
27755
27830
|
while (!existsSync7(ancestor))
|
|
27756
|
-
ancestor =
|
|
27831
|
+
ancestor = path20.dirname(ancestor);
|
|
27757
27832
|
const canonicalAncestor = realpathSync5(ancestor);
|
|
27758
|
-
if (canonicalAncestor !== base && !canonicalAncestor.startsWith(base +
|
|
27833
|
+
if (canonicalAncestor !== base && !canonicalAncestor.startsWith(base + path20.sep)) {
|
|
27759
27834
|
throw new Error("path must stay inside repository root");
|
|
27760
27835
|
}
|
|
27761
27836
|
return target;
|
|
@@ -27775,80 +27850,6 @@ function run2(root, executable, args, env = {}) {
|
|
|
27775
27850
|
};
|
|
27776
27851
|
}
|
|
27777
27852
|
|
|
27778
|
-
// packages/workit-core/src/core/logger.ts
|
|
27779
|
-
import os4 from "node:os";
|
|
27780
|
-
import path20 from "node:path";
|
|
27781
|
-
var REDACTED = "[REDACTED]";
|
|
27782
|
-
var SECRET_VALUE = /\b(?:Bearer|Basic|Digest|Token)\s+\S+/gi;
|
|
27783
|
-
var KEY_EQ_VALUE = /\b([A-Za-z0-9_-]*(?:token|secret|password|passwd|apikey|api[_-]?key|authorization|credential|bearer)[A-Za-z0-9_-]*)([:=]\s*).+/gi;
|
|
27784
|
-
var URL_QUERY = /(https?:\/\/[^?#\s]+)\?[^#\s]*/g;
|
|
27785
|
-
var SENSITIVE_WORDS = new Set([
|
|
27786
|
-
"token",
|
|
27787
|
-
"secret",
|
|
27788
|
-
"password",
|
|
27789
|
-
"passwd",
|
|
27790
|
-
"authorization",
|
|
27791
|
-
"credential",
|
|
27792
|
-
"credentials",
|
|
27793
|
-
"cookie",
|
|
27794
|
-
"api",
|
|
27795
|
-
"apikey",
|
|
27796
|
-
"apitoken",
|
|
27797
|
-
"accesstoken",
|
|
27798
|
-
"clientsecret",
|
|
27799
|
-
"refreshtoken",
|
|
27800
|
-
"key",
|
|
27801
|
-
"bearer",
|
|
27802
|
-
"prompt",
|
|
27803
|
-
"message",
|
|
27804
|
-
"messages",
|
|
27805
|
-
"content",
|
|
27806
|
-
"body",
|
|
27807
|
-
"args",
|
|
27808
|
-
"argument",
|
|
27809
|
-
"result",
|
|
27810
|
-
"results",
|
|
27811
|
-
"output",
|
|
27812
|
-
"issue",
|
|
27813
|
-
"description",
|
|
27814
|
-
"summary",
|
|
27815
|
-
"payload",
|
|
27816
|
-
"script",
|
|
27817
|
-
"command",
|
|
27818
|
-
"text",
|
|
27819
|
-
"query"
|
|
27820
|
-
]);
|
|
27821
|
-
var STACK_WORDS = new Set(["stack", "stacktrace", "trace"]);
|
|
27822
|
-
var escapeRegExp2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27823
|
-
var resolveStateDir = () => {
|
|
27824
|
-
const override = process.env.WORKFLOW_TOOLKIT_STATE;
|
|
27825
|
-
if (override)
|
|
27826
|
-
return override;
|
|
27827
|
-
const home = os4.homedir();
|
|
27828
|
-
if (process.env.XDG_STATE_HOME)
|
|
27829
|
-
return path20.join(process.env.XDG_STATE_HOME, "workit");
|
|
27830
|
-
switch (os4.platform()) {
|
|
27831
|
-
case "darwin":
|
|
27832
|
-
return path20.join(home, "Library", "Application Support", "workit");
|
|
27833
|
-
case "win32":
|
|
27834
|
-
return path20.join(process.env.LOCALAPPDATA ?? path20.join(home, "AppData", "Local"), "workit");
|
|
27835
|
-
default:
|
|
27836
|
-
return path20.join(process.env.HOME ?? home, ".local", "state", "workit");
|
|
27837
|
-
}
|
|
27838
|
-
};
|
|
27839
|
-
var homePattern = new RegExp(`${escapeRegExp2(os4.homedir())}(?=[/\\\\]|$)|\\$HOME(?=[/\\\\]|$)`, "g");
|
|
27840
|
-
var applyPatterns = (value) => {
|
|
27841
|
-
let out = value;
|
|
27842
|
-
out = out.replace(SECRET_VALUE, REDACTED);
|
|
27843
|
-
out = out.replace(KEY_EQ_VALUE, "$1$2[REDACTED]");
|
|
27844
|
-
out = out.replace(URL_QUERY, "$1?[REDACTED]");
|
|
27845
|
-
out = out.replace(homePattern, "~");
|
|
27846
|
-
if (process.platform === "win32")
|
|
27847
|
-
out = out.replace(/\\/g, "/");
|
|
27848
|
-
return out;
|
|
27849
|
-
};
|
|
27850
|
-
var redactSecrets = (value) => applyPatterns(value);
|
|
27851
|
-
|
|
27852
27853
|
// packages/workit-mcp/src/server.ts
|
|
27853
27854
|
class McpCapabilityUnavailableError extends Error {
|
|
27854
27855
|
capability;
|