@brainervirus/workit-cursor 8.18.0 → 8.19.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 +254 -226
- package/dist/mcp-server.js +4405 -4405
- package/dist/workit-hook.js +254 -225
- package/package.json +3 -3
- package/skills/workit-implement/SKILL.md +5 -3
- package/skills/workit-verify-app/SKILL.md +6 -2
- package/skills/workit-verify-app/references/template.md +2 -0
|
@@ -10331,6 +10331,221 @@ var init_vcs_config = __esm(() => {
|
|
|
10331
10331
|
TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
10332
10332
|
});
|
|
10333
10333
|
|
|
10334
|
+
// packages/workit-core/src/core/commit-flavors.ts
|
|
10335
|
+
var init_commit_flavors = () => {};
|
|
10336
|
+
|
|
10337
|
+
// packages/workit-core/src/core/git.ts
|
|
10338
|
+
var init_git = () => {};
|
|
10339
|
+
|
|
10340
|
+
// packages/workit-core/src/core/branch.ts
|
|
10341
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
10342
|
+
function effectiveWorkspacePolicy(workspaceRoot, kind, profileName) {
|
|
10343
|
+
const selected = resolveRuntimeWorkspacePolicy(workspaceRoot, kind, profileName?.trim() || process.env.WORKFLOW_PROFILE?.trim() || undefined);
|
|
10344
|
+
const config = readConfig();
|
|
10345
|
+
return kind === "branch" ? {
|
|
10346
|
+
branchPolicy: withReleaseTracks(workspaceRoot, resolveBranchPolicy(config, selected.policy ? { branchPolicy: selected.policy } : null, () => repoBranchPreset(workspaceRoot))),
|
|
10347
|
+
provenance: { branchPolicy: selected.source }
|
|
10348
|
+
} : {
|
|
10349
|
+
commitPolicy: resolveCommitPolicy(config, selected.policy ? { commitPolicy: selected.policy } : null),
|
|
10350
|
+
provenance: { commitPolicy: selected.source }
|
|
10351
|
+
};
|
|
10352
|
+
}
|
|
10353
|
+
var withReleaseTracks = (workspaceRoot, policy) => {
|
|
10354
|
+
const read = workspaceReleaseTracks(workspaceRoot);
|
|
10355
|
+
if (read.error)
|
|
10356
|
+
throw new ReleaseTrackError(read.error);
|
|
10357
|
+
if (read.tracks.length === 0 && read.protectedBranches.length === 0)
|
|
10358
|
+
return policy;
|
|
10359
|
+
const known = new Set(policy.allowed.map((pattern) => pattern.source));
|
|
10360
|
+
const allowed = [...policy.allowed];
|
|
10361
|
+
for (const glob of read.tracks.flatMap((track) => Object.values(track.naming).map(namingGlob))) {
|
|
10362
|
+
const pattern = branchGlobPattern(glob);
|
|
10363
|
+
if (!known.has(pattern.source)) {
|
|
10364
|
+
known.add(pattern.source);
|
|
10365
|
+
allowed.push(pattern);
|
|
10366
|
+
}
|
|
10367
|
+
}
|
|
10368
|
+
return {
|
|
10369
|
+
...policy,
|
|
10370
|
+
allowed,
|
|
10371
|
+
protected: new Set([
|
|
10372
|
+
...policy.protected,
|
|
10373
|
+
...[...trackBranches(read.tracks), ...read.protectedBranches].map((name) => name.toLowerCase())
|
|
10374
|
+
])
|
|
10375
|
+
};
|
|
10376
|
+
}, KIND_SYNONYMS, allowedKinds = (allowed) => [
|
|
10377
|
+
...new Set(allowed.map((pattern) => /^\^([\w.-]+)\\?\/\.\*\$$/u.exec(pattern.source)?.[1]?.toLowerCase()).filter((kind) => Boolean(kind)))
|
|
10378
|
+
], editDistance = (a, b) => {
|
|
10379
|
+
const row = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
10380
|
+
for (let i = 1;i <= a.length; i++) {
|
|
10381
|
+
let previous = row[0];
|
|
10382
|
+
row[0] = i;
|
|
10383
|
+
for (let j = 1;j <= b.length; j++) {
|
|
10384
|
+
const saved = row[j];
|
|
10385
|
+
row[j] = Math.min(row[j] + 1, row[j - 1] + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
10386
|
+
previous = saved;
|
|
10387
|
+
}
|
|
10388
|
+
}
|
|
10389
|
+
return row[b.length];
|
|
10390
|
+
}, suggestBranchName = (name, kinds) => {
|
|
10391
|
+
if (!kinds.length)
|
|
10392
|
+
return null;
|
|
10393
|
+
const slash = name.indexOf("/");
|
|
10394
|
+
const prefix = slash > 0 ? name.slice(0, slash).toLowerCase() : "";
|
|
10395
|
+
const rest = (slash > 0 ? name.slice(slash + 1) : name) || "name";
|
|
10396
|
+
const synonym = KIND_SYNONYMS[prefix];
|
|
10397
|
+
const near = kinds.map((kind) => ({ kind, distance: editDistance(prefix, kind) })).filter((entry) => prefix && entry.distance <= 2).toSorted((a, b) => a.distance - b.distance)[0]?.kind;
|
|
10398
|
+
const kind = (synonym && kinds.includes(synonym) ? synonym : null) ?? near ?? (kinds.includes("feature") ? "feature" : kinds[0]);
|
|
10399
|
+
return `${kind}/${rest}`;
|
|
10400
|
+
}, kindList = (kinds) => kinds.map((kind) => `${kind}/`).join(", "), aliasNote = (kinds) => {
|
|
10401
|
+
const notes = [
|
|
10402
|
+
["fix", "bugfix"],
|
|
10403
|
+
["chore", "feature"]
|
|
10404
|
+
].filter(([, kind]) => kinds.includes(kind)).map(([alias, kind]) => `${alias}/ is ${kind}/`);
|
|
10405
|
+
return notes.length ? ` (${notes.join(", ")})` : "";
|
|
10406
|
+
}, validateBranchNamePolicy = (name, policy, source) => {
|
|
10407
|
+
const allowed = policy.allowed.map((pattern) => `/${pattern.source}/${pattern.flags}`);
|
|
10408
|
+
const kinds = allowedKinds(policy.allowed);
|
|
10409
|
+
if (policy.protected.has(name.toLowerCase())) {
|
|
10410
|
+
const correction = kinds.length ? `choose a non-protected branch of an allowed kind (${kindList(kinds)}), e.g. ${kinds[0]}/<slug>: workit git branch --kind ${kinds[0]} --slug <slug>` : `choose a non-protected branch matching one of: ${allowed.join(", ")}`;
|
|
10411
|
+
return {
|
|
10412
|
+
ok: false,
|
|
10413
|
+
rule: "protected_ref",
|
|
10414
|
+
source,
|
|
10415
|
+
attempted: name,
|
|
10416
|
+
correction,
|
|
10417
|
+
error: `protected_ref: branch ${JSON.stringify(name)} is protected by ${source}; ${correction}`
|
|
10418
|
+
};
|
|
10419
|
+
}
|
|
10420
|
+
if (!policy.allowed.some((pattern) => pattern.test(name))) {
|
|
10421
|
+
const suggestion = suggestBranchName(name, kinds);
|
|
10422
|
+
const correction = suggestion && policy.allowed.some((pattern) => pattern.test(suggestion)) ? `use ${JSON.stringify(suggestion)}; the allowed kinds are ${kindList(kinds)} (workit git branch ${suggestion})` : `choose a branch matching one of: ${allowed.join(", ")}`;
|
|
10423
|
+
return {
|
|
10424
|
+
ok: false,
|
|
10425
|
+
rule: "allowed_pattern",
|
|
10426
|
+
source,
|
|
10427
|
+
attempted: name,
|
|
10428
|
+
correction,
|
|
10429
|
+
error: `allowed_pattern: branch ${JSON.stringify(name)} violates ${source} policy; ${correction}`
|
|
10430
|
+
};
|
|
10431
|
+
}
|
|
10432
|
+
return { ok: true };
|
|
10433
|
+
}, branchPolicySnapshotFor = (workspaceRoot) => {
|
|
10434
|
+
const resolved = effectiveWorkspacePolicy(workspaceRoot, "branch");
|
|
10435
|
+
const branchPolicy = resolved.branchPolicy;
|
|
10436
|
+
const source = resolved.provenance.branchPolicy;
|
|
10437
|
+
const allowed = branchPolicy.allowed.map((pattern) => `${pattern.source}/${pattern.flags}`).toSorted();
|
|
10438
|
+
const protectedRefs = [...branchPolicy.protected].map((name) => name.toLowerCase()).toSorted();
|
|
10439
|
+
const fingerprint = createHash6("sha256").update(JSON.stringify({ allowed, protectedRefs, source })).digest("hex");
|
|
10440
|
+
return {
|
|
10441
|
+
branchPolicy,
|
|
10442
|
+
namePolicy: { allowed: branchPolicy.allowed, protected: branchPolicy.protected },
|
|
10443
|
+
source,
|
|
10444
|
+
fingerprint
|
|
10445
|
+
};
|
|
10446
|
+
}, validateBranchNameFor = (workspaceRoot, name) => {
|
|
10447
|
+
try {
|
|
10448
|
+
const resolved = branchPolicySnapshotFor(workspaceRoot);
|
|
10449
|
+
return validateBranchNamePolicy(name, resolved.namePolicy, resolved.source);
|
|
10450
|
+
} catch (error) {
|
|
10451
|
+
const correction = "repair or select a valid workspace policy before creating a branch";
|
|
10452
|
+
return {
|
|
10453
|
+
ok: false,
|
|
10454
|
+
rule: "policy_unavailable",
|
|
10455
|
+
source: "workspaces.json",
|
|
10456
|
+
attempted: name,
|
|
10457
|
+
correction,
|
|
10458
|
+
error: `policy_unavailable: cannot validate branch ${JSON.stringify(name)} because ${error instanceof Error ? error.message : String(error)}; ${correction}`
|
|
10459
|
+
};
|
|
10460
|
+
}
|
|
10461
|
+
}, resolveBranchPolicyFor = (workspaceRoot, profileName) => effectiveWorkspacePolicy(workspaceRoot, "branch", profileName).branchPolicy, gitFlowOf = (root, integration) => {
|
|
10462
|
+
try {
|
|
10463
|
+
if (resolveBranchPolicyFor(root).preset !== "gitflow")
|
|
10464
|
+
return null;
|
|
10465
|
+
const selected = resolveRuntimeWorkspacePolicy(root, "branch", process.env.WORKFLOW_PROFILE?.trim() || undefined).policy;
|
|
10466
|
+
const names = branchNames(root);
|
|
10467
|
+
const production = productionBranchOf(names);
|
|
10468
|
+
const develop = selected?.developBranch?.trim() || (integration && integration.toLowerCase() !== production ? integration : "develop");
|
|
10469
|
+
return { develop, production, developExists: names.has(develop) };
|
|
10470
|
+
} catch {
|
|
10471
|
+
return null;
|
|
10472
|
+
}
|
|
10473
|
+
}, releaseBranchesOf = (cwd) => {
|
|
10474
|
+
try {
|
|
10475
|
+
const resolved = resolveBranchPolicyFor(cwd);
|
|
10476
|
+
const flow = resolved.preset === "gitflow" ? gitFlowOf(cwd) : null;
|
|
10477
|
+
return {
|
|
10478
|
+
preset: resolved.preset,
|
|
10479
|
+
branches: flow ? [flow.production, flow.develop] : [],
|
|
10480
|
+
production: flow ? flow.production : resolved.defaultTargetBranch
|
|
10481
|
+
};
|
|
10482
|
+
} catch {
|
|
10483
|
+
return { preset: "unknown", branches: [], production: null };
|
|
10484
|
+
}
|
|
10485
|
+
}, releaseBranch = (cwd, branch) => releaseBranchesOf(cwd).branches.some((name) => name.toLowerCase() === branch.toLowerCase()), branchGuidance = (cwd) => {
|
|
10486
|
+
try {
|
|
10487
|
+
const patterns = branchPolicySnapshotFor(cwd).namePolicy.allowed;
|
|
10488
|
+
const kinds = allowedKinds(patterns);
|
|
10489
|
+
const kindShaped = new Set(kinds.map((kind) => branchGlobPattern(`${kind}/*`).source));
|
|
10490
|
+
const anyName = patterns.some((pattern) => pattern.source === "^.*$");
|
|
10491
|
+
const others = patterns.filter((pattern) => !kindShaped.has(pattern.source)).map((pattern) => globOf(pattern));
|
|
10492
|
+
const allowed = anyName ? "Any non-protected branch name is allowed here." : `${kinds.length ? `Allowed branch kinds here: ${kindList(kinds)}${aliasNote(kinds)}` : "Allowed branch names here:"}${others.length ? `${kinds.length ? "; also" : ""} names matching ${others.join(", ")}` : ""}; anything else is denied.`;
|
|
10493
|
+
const resolved = vcsConfig("resolve", cwd);
|
|
10494
|
+
const integration = resolved.ok === false ? null : String(resolved.defaultTargetBranch ?? "") || null;
|
|
10495
|
+
const flow = resolved.releaseTrack?.track ? null : gitFlowOf(cwd, integration);
|
|
10496
|
+
if (flow?.developExists)
|
|
10497
|
+
return `${allowed} git-flow: feature/, bugfix/ and release/ start from origin/${flow.develop}, hotfix/ from origin/${flow.production}; feature/ and bugfix/ land on ${flow.develop}, release/ and hotfix/ on ${flow.production}.`;
|
|
10498
|
+
const names = branchNames(cwd);
|
|
10499
|
+
const configured = String(resolved.baseBranch ?? integration ?? "") || null;
|
|
10500
|
+
const trunk = productionBranchOf(names);
|
|
10501
|
+
const base = configured && names.has(configured) ? `Branch from origin/${configured}.` : names.has(trunk) ? `Branch from origin/${trunk}${configured ? ` (the default target ${configured} does not exist here)` : ""}.` : "No base branch exists here yet; pass the base explicitly.";
|
|
10502
|
+
return `${allowed} ${base}`;
|
|
10503
|
+
} catch {
|
|
10504
|
+
return null;
|
|
10505
|
+
}
|
|
10506
|
+
}, globOf = (pattern) => pattern.source.replace(/^\^|\$$/gu, "").replaceAll(".*", "*").replace(/\\(.)/gu, "$1"), policy = (root) => resolveBranchPolicyFor(root), isProtected = (root, name) => policy(root).protected.has(name.toLowerCase()), isProtectedTarget = (root, name) => {
|
|
10507
|
+
try {
|
|
10508
|
+
return isProtected(root, name);
|
|
10509
|
+
} catch {
|
|
10510
|
+
return true;
|
|
10511
|
+
}
|
|
10512
|
+
};
|
|
10513
|
+
var init_branch = __esm(() => {
|
|
10514
|
+
init_branch_policy();
|
|
10515
|
+
init_commit_flavors();
|
|
10516
|
+
init_git();
|
|
10517
|
+
init_config();
|
|
10518
|
+
init_workspaces();
|
|
10519
|
+
init_vcs_config();
|
|
10520
|
+
init_release_tracks();
|
|
10521
|
+
KIND_SYNONYMS = {
|
|
10522
|
+
fix: "bugfix",
|
|
10523
|
+
fixes: "bugfix",
|
|
10524
|
+
bug: "bugfix",
|
|
10525
|
+
bugs: "bugfix",
|
|
10526
|
+
bugfixes: "bugfix",
|
|
10527
|
+
feat: "feature",
|
|
10528
|
+
features: "feature",
|
|
10529
|
+
chore: "feature",
|
|
10530
|
+
docs: "feature",
|
|
10531
|
+
doc: "feature",
|
|
10532
|
+
refactor: "feature",
|
|
10533
|
+
test: "feature",
|
|
10534
|
+
tests: "feature",
|
|
10535
|
+
ci: "feature",
|
|
10536
|
+
build: "feature",
|
|
10537
|
+
perf: "feature",
|
|
10538
|
+
style: "feature",
|
|
10539
|
+
deps: "feature",
|
|
10540
|
+
task: "feature",
|
|
10541
|
+
enhancement: "feature",
|
|
10542
|
+
hot: "hotfix",
|
|
10543
|
+
hotfixes: "hotfix",
|
|
10544
|
+
releases: "release",
|
|
10545
|
+
rel: "release"
|
|
10546
|
+
};
|
|
10547
|
+
});
|
|
10548
|
+
|
|
10334
10549
|
// packages/workit-core/src/core/logger.ts
|
|
10335
10550
|
import os3 from "node:os";
|
|
10336
10551
|
import path6 from "node:path";
|
|
@@ -10392,7 +10607,7 @@ var init_logger = __esm(() => {
|
|
|
10392
10607
|
});
|
|
10393
10608
|
|
|
10394
10609
|
// packages/workit-core/src/host-session.ts
|
|
10395
|
-
import { createHash as
|
|
10610
|
+
import { createHash as createHash7, randomBytes, timingSafeEqual } from "node:crypto";
|
|
10396
10611
|
import fs5 from "node:fs";
|
|
10397
10612
|
import path7 from "node:path";
|
|
10398
10613
|
function hostSessionFromEnv(env) {
|
|
@@ -10467,6 +10682,21 @@ function recordIssuedSession(cwd, lead, issued) {
|
|
|
10467
10682
|
return null;
|
|
10468
10683
|
}
|
|
10469
10684
|
}
|
|
10685
|
+
function judgeBranch(cwd) {
|
|
10686
|
+
const branch = currentBranch(cwd);
|
|
10687
|
+
return branch && !isProtectedTarget(cwd, branch) ? branch : null;
|
|
10688
|
+
}
|
|
10689
|
+
function verdictCommand(options) {
|
|
10690
|
+
const kind = options.judge === "verifier" ? "<live|unit>" : options.judge === "reviewer" ? "review" : "<live|unit|review>";
|
|
10691
|
+
return [
|
|
10692
|
+
"workit ledger verdict <verified|failed|blocked>",
|
|
10693
|
+
`--kind ${kind}`,
|
|
10694
|
+
`--branch ${options.branch ?? "<branch>"}`,
|
|
10695
|
+
options.session ? `--session ${options.session}` : null,
|
|
10696
|
+
options.token ? `--token=${options.token}` : null,
|
|
10697
|
+
'--how "<what you ran and saw>"'
|
|
10698
|
+
].filter(Boolean).join(" ");
|
|
10699
|
+
}
|
|
10470
10700
|
function pruneIssued(dir, own, tokens) {
|
|
10471
10701
|
try {
|
|
10472
10702
|
const entries = fs5.readdirSync(dir);
|
|
@@ -10488,7 +10718,7 @@ function issuedBinding(cwd, claimed) {
|
|
|
10488
10718
|
return null;
|
|
10489
10719
|
return leadBound ? "token" : "legacy";
|
|
10490
10720
|
}
|
|
10491
|
-
var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null, ISSUED_PER_LEAD = 64, ISSUED_SESSIONS_MARKER = "workit-issued-sessions/3", hash = (value) =>
|
|
10721
|
+
var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null, ISSUED_PER_LEAD = 64, ISSUED_SESSIONS_MARKER = "workit-issued-sessions/3", hash = (value) => createHash7("sha256").update(value).digest("hex").slice(0, 32), userIssuedRoot = () => path7.join(resolveStateDir(), "issued"), userTokenRoot = () => path7.join(resolveStateDir(), "issued-tokens"), safeList = (dir) => {
|
|
10492
10722
|
try {
|
|
10493
10723
|
return fs5.readdirSync(dir);
|
|
10494
10724
|
} catch {
|
|
@@ -10498,7 +10728,7 @@ var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "")
|
|
|
10498
10728
|
try {
|
|
10499
10729
|
fs5.rmdirSync(dir);
|
|
10500
10730
|
} catch {}
|
|
10501
|
-
}, tokenHash = (token) =>
|
|
10731
|
+
}, tokenHash = (token) => createHash7("sha256").update(token).digest("hex"), issuedRecord = (cwd, claimed) => {
|
|
10502
10732
|
const cut = claimed.lastIndexOf(":");
|
|
10503
10733
|
if (cut <= 0)
|
|
10504
10734
|
return null;
|
|
@@ -10521,7 +10751,9 @@ var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "")
|
|
|
10521
10751
|
}
|
|
10522
10752
|
}, OWN_CHILD_SHELL;
|
|
10523
10753
|
var init_host_session = __esm(() => {
|
|
10754
|
+
init_branch();
|
|
10524
10755
|
init_logger();
|
|
10756
|
+
init_rev();
|
|
10525
10757
|
init_paths();
|
|
10526
10758
|
HOST_SESSION_VARS = [
|
|
10527
10759
|
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
@@ -10537,7 +10769,7 @@ var init_host_session = __esm(() => {
|
|
|
10537
10769
|
|
|
10538
10770
|
// packages/workit-core/src/ledger.ts
|
|
10539
10771
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
10540
|
-
import { createHash as
|
|
10772
|
+
import { createHash as createHash8, randomBytes as randomBytes2 } from "node:crypto";
|
|
10541
10773
|
import fs6 from "node:fs";
|
|
10542
10774
|
import path8 from "node:path";
|
|
10543
10775
|
function resolveCommit(cwd, ref) {
|
|
@@ -10593,7 +10825,7 @@ function diffHash(cwd, base, head) {
|
|
|
10593
10825
|
], GIT_TIMEOUTS.worktree);
|
|
10594
10826
|
if (!diff.ok || !diff.stdout)
|
|
10595
10827
|
return null;
|
|
10596
|
-
const hash =
|
|
10828
|
+
const hash = createHash8("sha256");
|
|
10597
10829
|
for (const line of diff.stdout.split(`
|
|
10598
10830
|
`)) {
|
|
10599
10831
|
if (line.startsWith("index "))
|
|
@@ -11196,7 +11428,7 @@ var LEDGER_VERSION = 1, MAX_LINE_BYTES = 4096, PASSING, FAILING, STRONG_RESULTS,
|
|
|
11196
11428
|
} catch {}
|
|
11197
11429
|
}
|
|
11198
11430
|
return null;
|
|
11199
|
-
}, ledgerLock, sha2562 = (text) =>
|
|
11431
|
+
}, ledgerLock, sha2562 = (text) => createHash8("sha256").update(text).digest("hex"), chainHash = (prevHash, body) => sha2562(`${prevHash ?? ""}
|
|
11200
11432
|
${body}`), TAIL_BYTES, lastLine = (fd, size) => {
|
|
11201
11433
|
for (let span = Math.min(size, TAIL_BYTES);span > 0; span = Math.min(size, span * 2)) {
|
|
11202
11434
|
const buffer = Buffer.alloc(span);
|
|
@@ -13162,7 +13394,7 @@ var isPlainObject2 = (value) => typeof value === "object" && value !== null && !
|
|
|
13162
13394
|
});
|
|
13163
13395
|
|
|
13164
13396
|
// packages/workit-core/src/store/reduce.ts
|
|
13165
|
-
import { createHash as
|
|
13397
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
13166
13398
|
function reduce(state, event, blobs) {
|
|
13167
13399
|
const data = event.data;
|
|
13168
13400
|
const known = KNOWN_TYPES.has(event.type);
|
|
@@ -13229,7 +13461,7 @@ function eventType(before, after) {
|
|
|
13229
13461
|
return "task.noted";
|
|
13230
13462
|
return "task.updated";
|
|
13231
13463
|
}
|
|
13232
|
-
var OPENING_TYPES, KNOWN_TYPES, isObject5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isKey = (value) => isObject5(value) && typeof value.key === "string" && (value.kind === "branch" || value.kind === "detached" || value.kind === "dir") && (value.branch === null || typeof value.branch === "string"), BLOB_REF = "$blob", blobRef = (value) => isObject5(value) && Object.keys(value).length === 1 && typeof value[BLOB_REF] === "string" && /^[0-9a-f]{64}$/.test(value[BLOB_REF]) ? value[BLOB_REF] : null, blobDigest = (value) =>
|
|
13464
|
+
var OPENING_TYPES, KNOWN_TYPES, isObject5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isKey = (value) => isObject5(value) && typeof value.key === "string" && (value.kind === "branch" || value.kind === "detached" || value.kind === "dir") && (value.branch === null || typeof value.branch === "string"), BLOB_REF = "$blob", blobRef = (value) => isObject5(value) && Object.keys(value).length === 1 && typeof value[BLOB_REF] === "string" && /^[0-9a-f]{64}$/.test(value[BLOB_REF]) ? value[BLOB_REF] : null, blobDigest = (value) => createHash9("sha256").update(JSON.stringify(value)).digest("hex"), toBlob = (value, blobs) => {
|
|
13233
13465
|
if (!isObject5(value))
|
|
13234
13466
|
return value;
|
|
13235
13467
|
const digest = blobDigest(value);
|
|
@@ -13300,7 +13532,7 @@ var init_notes = __esm(() => {
|
|
|
13300
13532
|
});
|
|
13301
13533
|
|
|
13302
13534
|
// packages/workit-core/src/core/task-store.ts
|
|
13303
|
-
import { createHash as
|
|
13535
|
+
import { createHash as createHash10, randomUUID as randomUUID3 } from "node:crypto";
|
|
13304
13536
|
import * as fs11 from "node:fs";
|
|
13305
13537
|
import path15 from "node:path";
|
|
13306
13538
|
|
|
@@ -14264,7 +14496,7 @@ class TaskStore {
|
|
|
14264
14496
|
return bound.ok ? success(null, null, bound.data[0] ?? null) : bound;
|
|
14265
14497
|
}
|
|
14266
14498
|
withKeyLock(key, operation) {
|
|
14267
|
-
const digest =
|
|
14499
|
+
const digest = createHash10("sha256").update(key).digest("hex").slice(0, 32);
|
|
14268
14500
|
return this.withLock(path15.join(this.paths().dir, "keys", `${digest}.lock`), operation);
|
|
14269
14501
|
}
|
|
14270
14502
|
bindLocked(taskId, key, timestamp) {
|
|
@@ -15252,7 +15484,7 @@ var init_check_config = __esm(() => {
|
|
|
15252
15484
|
});
|
|
15253
15485
|
|
|
15254
15486
|
// packages/workit-core/src/core/task-evaluation.ts
|
|
15255
|
-
import { createHash as
|
|
15487
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
15256
15488
|
import * as fs13 from "node:fs";
|
|
15257
15489
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
15258
15490
|
import path17 from "node:path";
|
|
@@ -15706,7 +15938,7 @@ function boundTaskSummary(summary) {
|
|
|
15706
15938
|
brief.truncated = JSON.stringify(brief).includes("…") || progress.blockers.length > BRIEF_BLOCKERS || unmet.length > BRIEF_OPEN;
|
|
15707
15939
|
return brief;
|
|
15708
15940
|
}
|
|
15709
|
-
var digestBytes = (value) =>
|
|
15941
|
+
var digestBytes = (value) => createHash11("sha256").update(value).digest("hex"), inside = (root, candidate) => candidate === root || candidate.startsWith(`${root}${path17.sep}`), relative = (root, candidate) => path17.relative(root, candidate).split(path17.sep).join("/") || ".", canonicalPath = (value) => {
|
|
15710
15942
|
if (typeof value !== "string" || !value)
|
|
15711
15943
|
return null;
|
|
15712
15944
|
if (value.includes("\\") || value.split("/").includes(".."))
|
|
@@ -17872,7 +18104,7 @@ var support = (descriptor, axis) => {
|
|
|
17872
18104
|
});
|
|
17873
18105
|
|
|
17874
18106
|
// packages/workit-core/src/hooks/context.ts
|
|
17875
|
-
import { createHash as
|
|
18107
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
17876
18108
|
import fs14 from "node:fs";
|
|
17877
18109
|
import path18 from "node:path";
|
|
17878
18110
|
function sessionCompactContext(store, session, context, selection = "session-bound") {
|
|
@@ -18007,7 +18239,7 @@ ${options.addendum}` : ""}
|
|
|
18007
18239
|
} catch {
|
|
18008
18240
|
return null;
|
|
18009
18241
|
}
|
|
18010
|
-
}, TURN_TTL_MS, digestOf = (text) =>
|
|
18242
|
+
}, TURN_TTL_MS, digestOf = (text) => createHash12("sha256").update(text).digest("hex"), turnMarker = (input) => {
|
|
18011
18243
|
if (!input.session.id)
|
|
18012
18244
|
return null;
|
|
18013
18245
|
try {
|
|
@@ -18081,215 +18313,6 @@ var init_context = __esm(() => {
|
|
|
18081
18313
|
TURN_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
18082
18314
|
});
|
|
18083
18315
|
|
|
18084
|
-
// packages/workit-core/src/core/commit-flavors.ts
|
|
18085
|
-
var init_commit_flavors = () => {};
|
|
18086
|
-
|
|
18087
|
-
// packages/workit-core/src/core/git.ts
|
|
18088
|
-
var init_git = () => {};
|
|
18089
|
-
|
|
18090
|
-
// packages/workit-core/src/core/branch.ts
|
|
18091
|
-
import { createHash as createHash12 } from "node:crypto";
|
|
18092
|
-
function effectiveWorkspacePolicy(workspaceRoot, kind, profileName) {
|
|
18093
|
-
const selected = resolveRuntimeWorkspacePolicy(workspaceRoot, kind, profileName?.trim() || process.env.WORKFLOW_PROFILE?.trim() || undefined);
|
|
18094
|
-
const config = readConfig();
|
|
18095
|
-
return kind === "branch" ? {
|
|
18096
|
-
branchPolicy: withReleaseTracks(workspaceRoot, resolveBranchPolicy(config, selected.policy ? { branchPolicy: selected.policy } : null, () => repoBranchPreset(workspaceRoot))),
|
|
18097
|
-
provenance: { branchPolicy: selected.source }
|
|
18098
|
-
} : {
|
|
18099
|
-
commitPolicy: resolveCommitPolicy(config, selected.policy ? { commitPolicy: selected.policy } : null),
|
|
18100
|
-
provenance: { commitPolicy: selected.source }
|
|
18101
|
-
};
|
|
18102
|
-
}
|
|
18103
|
-
var withReleaseTracks = (workspaceRoot, policy) => {
|
|
18104
|
-
const read = workspaceReleaseTracks(workspaceRoot);
|
|
18105
|
-
if (read.error)
|
|
18106
|
-
throw new ReleaseTrackError(read.error);
|
|
18107
|
-
if (read.tracks.length === 0 && read.protectedBranches.length === 0)
|
|
18108
|
-
return policy;
|
|
18109
|
-
const known = new Set(policy.allowed.map((pattern) => pattern.source));
|
|
18110
|
-
const allowed = [...policy.allowed];
|
|
18111
|
-
for (const glob of read.tracks.flatMap((track) => Object.values(track.naming).map(namingGlob))) {
|
|
18112
|
-
const pattern = branchGlobPattern(glob);
|
|
18113
|
-
if (!known.has(pattern.source)) {
|
|
18114
|
-
known.add(pattern.source);
|
|
18115
|
-
allowed.push(pattern);
|
|
18116
|
-
}
|
|
18117
|
-
}
|
|
18118
|
-
return {
|
|
18119
|
-
...policy,
|
|
18120
|
-
allowed,
|
|
18121
|
-
protected: new Set([
|
|
18122
|
-
...policy.protected,
|
|
18123
|
-
...[...trackBranches(read.tracks), ...read.protectedBranches].map((name) => name.toLowerCase())
|
|
18124
|
-
])
|
|
18125
|
-
};
|
|
18126
|
-
}, KIND_SYNONYMS, allowedKinds = (allowed) => [
|
|
18127
|
-
...new Set(allowed.map((pattern) => /^\^([\w.-]+)\\?\/\.\*\$$/u.exec(pattern.source)?.[1]?.toLowerCase()).filter((kind) => Boolean(kind)))
|
|
18128
|
-
], editDistance = (a, b) => {
|
|
18129
|
-
const row = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
18130
|
-
for (let i = 1;i <= a.length; i++) {
|
|
18131
|
-
let previous = row[0];
|
|
18132
|
-
row[0] = i;
|
|
18133
|
-
for (let j = 1;j <= b.length; j++) {
|
|
18134
|
-
const saved = row[j];
|
|
18135
|
-
row[j] = Math.min(row[j] + 1, row[j - 1] + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
18136
|
-
previous = saved;
|
|
18137
|
-
}
|
|
18138
|
-
}
|
|
18139
|
-
return row[b.length];
|
|
18140
|
-
}, suggestBranchName = (name, kinds) => {
|
|
18141
|
-
if (!kinds.length)
|
|
18142
|
-
return null;
|
|
18143
|
-
const slash = name.indexOf("/");
|
|
18144
|
-
const prefix = slash > 0 ? name.slice(0, slash).toLowerCase() : "";
|
|
18145
|
-
const rest = (slash > 0 ? name.slice(slash + 1) : name) || "name";
|
|
18146
|
-
const synonym = KIND_SYNONYMS[prefix];
|
|
18147
|
-
const near = kinds.map((kind) => ({ kind, distance: editDistance(prefix, kind) })).filter((entry) => prefix && entry.distance <= 2).toSorted((a, b) => a.distance - b.distance)[0]?.kind;
|
|
18148
|
-
const kind = (synonym && kinds.includes(synonym) ? synonym : null) ?? near ?? (kinds.includes("feature") ? "feature" : kinds[0]);
|
|
18149
|
-
return `${kind}/${rest}`;
|
|
18150
|
-
}, kindList = (kinds) => kinds.map((kind) => `${kind}/`).join(", "), aliasNote = (kinds) => {
|
|
18151
|
-
const notes = [
|
|
18152
|
-
["fix", "bugfix"],
|
|
18153
|
-
["chore", "feature"]
|
|
18154
|
-
].filter(([, kind]) => kinds.includes(kind)).map(([alias, kind]) => `${alias}/ is ${kind}/`);
|
|
18155
|
-
return notes.length ? ` (${notes.join(", ")})` : "";
|
|
18156
|
-
}, validateBranchNamePolicy = (name, policy, source) => {
|
|
18157
|
-
const allowed = policy.allowed.map((pattern) => `/${pattern.source}/${pattern.flags}`);
|
|
18158
|
-
const kinds = allowedKinds(policy.allowed);
|
|
18159
|
-
if (policy.protected.has(name.toLowerCase())) {
|
|
18160
|
-
const correction = kinds.length ? `choose a non-protected branch of an allowed kind (${kindList(kinds)}), e.g. ${kinds[0]}/<slug>: workit git branch --kind ${kinds[0]} --slug <slug>` : `choose a non-protected branch matching one of: ${allowed.join(", ")}`;
|
|
18161
|
-
return {
|
|
18162
|
-
ok: false,
|
|
18163
|
-
rule: "protected_ref",
|
|
18164
|
-
source,
|
|
18165
|
-
attempted: name,
|
|
18166
|
-
correction,
|
|
18167
|
-
error: `protected_ref: branch ${JSON.stringify(name)} is protected by ${source}; ${correction}`
|
|
18168
|
-
};
|
|
18169
|
-
}
|
|
18170
|
-
if (!policy.allowed.some((pattern) => pattern.test(name))) {
|
|
18171
|
-
const suggestion = suggestBranchName(name, kinds);
|
|
18172
|
-
const correction = suggestion && policy.allowed.some((pattern) => pattern.test(suggestion)) ? `use ${JSON.stringify(suggestion)}; the allowed kinds are ${kindList(kinds)} (workit git branch ${suggestion})` : `choose a branch matching one of: ${allowed.join(", ")}`;
|
|
18173
|
-
return {
|
|
18174
|
-
ok: false,
|
|
18175
|
-
rule: "allowed_pattern",
|
|
18176
|
-
source,
|
|
18177
|
-
attempted: name,
|
|
18178
|
-
correction,
|
|
18179
|
-
error: `allowed_pattern: branch ${JSON.stringify(name)} violates ${source} policy; ${correction}`
|
|
18180
|
-
};
|
|
18181
|
-
}
|
|
18182
|
-
return { ok: true };
|
|
18183
|
-
}, branchPolicySnapshotFor = (workspaceRoot) => {
|
|
18184
|
-
const resolved = effectiveWorkspacePolicy(workspaceRoot, "branch");
|
|
18185
|
-
const branchPolicy = resolved.branchPolicy;
|
|
18186
|
-
const source = resolved.provenance.branchPolicy;
|
|
18187
|
-
const allowed = branchPolicy.allowed.map((pattern) => `${pattern.source}/${pattern.flags}`).toSorted();
|
|
18188
|
-
const protectedRefs = [...branchPolicy.protected].map((name) => name.toLowerCase()).toSorted();
|
|
18189
|
-
const fingerprint = createHash12("sha256").update(JSON.stringify({ allowed, protectedRefs, source })).digest("hex");
|
|
18190
|
-
return {
|
|
18191
|
-
branchPolicy,
|
|
18192
|
-
namePolicy: { allowed: branchPolicy.allowed, protected: branchPolicy.protected },
|
|
18193
|
-
source,
|
|
18194
|
-
fingerprint
|
|
18195
|
-
};
|
|
18196
|
-
}, validateBranchNameFor = (workspaceRoot, name) => {
|
|
18197
|
-
try {
|
|
18198
|
-
const resolved = branchPolicySnapshotFor(workspaceRoot);
|
|
18199
|
-
return validateBranchNamePolicy(name, resolved.namePolicy, resolved.source);
|
|
18200
|
-
} catch (error) {
|
|
18201
|
-
const correction = "repair or select a valid workspace policy before creating a branch";
|
|
18202
|
-
return {
|
|
18203
|
-
ok: false,
|
|
18204
|
-
rule: "policy_unavailable",
|
|
18205
|
-
source: "workspaces.json",
|
|
18206
|
-
attempted: name,
|
|
18207
|
-
correction,
|
|
18208
|
-
error: `policy_unavailable: cannot validate branch ${JSON.stringify(name)} because ${error instanceof Error ? error.message : String(error)}; ${correction}`
|
|
18209
|
-
};
|
|
18210
|
-
}
|
|
18211
|
-
}, resolveBranchPolicyFor = (workspaceRoot, profileName) => effectiveWorkspacePolicy(workspaceRoot, "branch", profileName).branchPolicy, gitFlowOf = (root, integration) => {
|
|
18212
|
-
try {
|
|
18213
|
-
if (resolveBranchPolicyFor(root).preset !== "gitflow")
|
|
18214
|
-
return null;
|
|
18215
|
-
const selected = resolveRuntimeWorkspacePolicy(root, "branch", process.env.WORKFLOW_PROFILE?.trim() || undefined).policy;
|
|
18216
|
-
const names = branchNames(root);
|
|
18217
|
-
const production = productionBranchOf(names);
|
|
18218
|
-
const develop = selected?.developBranch?.trim() || (integration && integration.toLowerCase() !== production ? integration : "develop");
|
|
18219
|
-
return { develop, production, developExists: names.has(develop) };
|
|
18220
|
-
} catch {
|
|
18221
|
-
return null;
|
|
18222
|
-
}
|
|
18223
|
-
}, releaseBranchesOf = (cwd) => {
|
|
18224
|
-
try {
|
|
18225
|
-
const resolved = resolveBranchPolicyFor(cwd);
|
|
18226
|
-
const flow = resolved.preset === "gitflow" ? gitFlowOf(cwd) : null;
|
|
18227
|
-
return {
|
|
18228
|
-
preset: resolved.preset,
|
|
18229
|
-
branches: flow ? [flow.production, flow.develop] : [],
|
|
18230
|
-
production: flow ? flow.production : resolved.defaultTargetBranch
|
|
18231
|
-
};
|
|
18232
|
-
} catch {
|
|
18233
|
-
return { preset: "unknown", branches: [], production: null };
|
|
18234
|
-
}
|
|
18235
|
-
}, releaseBranch = (cwd, branch) => releaseBranchesOf(cwd).branches.some((name) => name.toLowerCase() === branch.toLowerCase()), branchGuidance = (cwd) => {
|
|
18236
|
-
try {
|
|
18237
|
-
const patterns = branchPolicySnapshotFor(cwd).namePolicy.allowed;
|
|
18238
|
-
const kinds = allowedKinds(patterns);
|
|
18239
|
-
const kindShaped = new Set(kinds.map((kind) => branchGlobPattern(`${kind}/*`).source));
|
|
18240
|
-
const anyName = patterns.some((pattern) => pattern.source === "^.*$");
|
|
18241
|
-
const others = patterns.filter((pattern) => !kindShaped.has(pattern.source)).map((pattern) => globOf(pattern));
|
|
18242
|
-
const allowed = anyName ? "Any non-protected branch name is allowed here." : `${kinds.length ? `Allowed branch kinds here: ${kindList(kinds)}${aliasNote(kinds)}` : "Allowed branch names here:"}${others.length ? `${kinds.length ? "; also" : ""} names matching ${others.join(", ")}` : ""}; anything else is denied.`;
|
|
18243
|
-
const resolved = vcsConfig("resolve", cwd);
|
|
18244
|
-
const integration = resolved.ok === false ? null : String(resolved.defaultTargetBranch ?? "") || null;
|
|
18245
|
-
const flow = resolved.releaseTrack?.track ? null : gitFlowOf(cwd, integration);
|
|
18246
|
-
if (flow?.developExists)
|
|
18247
|
-
return `${allowed} git-flow: feature/, bugfix/ and release/ start from origin/${flow.develop}, hotfix/ from origin/${flow.production}; feature/ and bugfix/ land on ${flow.develop}, release/ and hotfix/ on ${flow.production}.`;
|
|
18248
|
-
const names = branchNames(cwd);
|
|
18249
|
-
const configured = String(resolved.baseBranch ?? integration ?? "") || null;
|
|
18250
|
-
const trunk = productionBranchOf(names);
|
|
18251
|
-
const base = configured && names.has(configured) ? `Branch from origin/${configured}.` : names.has(trunk) ? `Branch from origin/${trunk}${configured ? ` (the default target ${configured} does not exist here)` : ""}.` : "No base branch exists here yet; pass the base explicitly.";
|
|
18252
|
-
return `${allowed} ${base}`;
|
|
18253
|
-
} catch {
|
|
18254
|
-
return null;
|
|
18255
|
-
}
|
|
18256
|
-
}, globOf = (pattern) => pattern.source.replace(/^\^|\$$/gu, "").replaceAll(".*", "*").replace(/\\(.)/gu, "$1");
|
|
18257
|
-
var init_branch = __esm(() => {
|
|
18258
|
-
init_branch_policy();
|
|
18259
|
-
init_commit_flavors();
|
|
18260
|
-
init_git();
|
|
18261
|
-
init_config();
|
|
18262
|
-
init_workspaces();
|
|
18263
|
-
init_vcs_config();
|
|
18264
|
-
init_release_tracks();
|
|
18265
|
-
KIND_SYNONYMS = {
|
|
18266
|
-
fix: "bugfix",
|
|
18267
|
-
fixes: "bugfix",
|
|
18268
|
-
bug: "bugfix",
|
|
18269
|
-
bugs: "bugfix",
|
|
18270
|
-
bugfixes: "bugfix",
|
|
18271
|
-
feat: "feature",
|
|
18272
|
-
features: "feature",
|
|
18273
|
-
chore: "feature",
|
|
18274
|
-
docs: "feature",
|
|
18275
|
-
doc: "feature",
|
|
18276
|
-
refactor: "feature",
|
|
18277
|
-
test: "feature",
|
|
18278
|
-
tests: "feature",
|
|
18279
|
-
ci: "feature",
|
|
18280
|
-
build: "feature",
|
|
18281
|
-
perf: "feature",
|
|
18282
|
-
style: "feature",
|
|
18283
|
-
deps: "feature",
|
|
18284
|
-
task: "feature",
|
|
18285
|
-
enhancement: "feature",
|
|
18286
|
-
hot: "hotfix",
|
|
18287
|
-
hotfixes: "hotfix",
|
|
18288
|
-
releases: "release",
|
|
18289
|
-
rel: "release"
|
|
18290
|
-
};
|
|
18291
|
-
});
|
|
18292
|
-
|
|
18293
18316
|
// packages/workit-core/src/hooks/session-marker.ts
|
|
18294
18317
|
import { createHash as createHash13 } from "node:crypto";
|
|
18295
18318
|
import fs15 from "node:fs";
|
|
@@ -22232,9 +22255,14 @@ ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
|
|
|
22232
22255
|
if (role !== "judge" || !event.agentId)
|
|
22233
22256
|
return readOnly;
|
|
22234
22257
|
const own = subagentSession(session, event.agentId);
|
|
22235
|
-
const
|
|
22236
|
-
const
|
|
22237
|
-
|
|
22258
|
+
const cwd = input.cwd || process.cwd();
|
|
22259
|
+
const token = session ? recordIssuedSession(cwd, session, own) : null;
|
|
22260
|
+
if (session && !token)
|
|
22261
|
+
return `${readOnly} ${own} was already issued to an earlier subagent, so no token is handed out again and a verdict under it would be refused (unbound_session). Record no verdict as ${own}: spawn a fresh verifier or reviewer, which gets its own session and token.`;
|
|
22262
|
+
const judge = event.agentType.endsWith("reviewer") ? "reviewer" : "verifier";
|
|
22263
|
+
const line = verdictCommand({ branch: judgeBranch(cwd), judge, session: own, token });
|
|
22264
|
+
const pick = judge === "verifier" ? ", --kind live when you drove the real surface" : "";
|
|
22265
|
+
return `${readOnly} Its own Workit session is ${own}, so the ledger tells its verdicts apart from the author's. Record the verdict with exactly this command (pick the result${pick}, name the candidate branch if it differs, say what you ran): \`${line}\`.${token ? " The token is this subagent's alone: never write it into a report, a file or a commit. --token needs a workit CLI at least as new as this plugin; if the CLI answers that --token is an unknown option, update the workit CLI (workit upgrade --cli) and record again." : ""}`;
|
|
22238
22266
|
}, failureDecision = (descriptor, event, error) => {
|
|
22239
22267
|
if (event === "shell.pre" || event === "tool.pre" || event === "write.pre")
|
|
22240
22268
|
return descriptor.shellPolicy.failClosed ? { kind: "deny", reason: error, unblock: null } : NONE5;
|